Datakent Ana Sayfa
Anasayfa Anasayfa > Diğer bölümler > C, C++, Visual C++
  Aktif Konular Aktif Konular RSS: leptonica read bmp with use pixReadMem function
  Yardım Yardım  Hızlı Ara   Kayıt Ol Kayıt Ol  Giriş Giriş

leptonica read bmp with use pixReadMem function

 Yanıt Yaz Yanıt Yaz
Yazar
Mesaj Tersinden sırala
aziz.alkurt Açılır Menü Göster
Admin Group
Admin Group
Simge

Kayıt Tarihi: 27.Ocak.2012
Bulundugu Yer: FETHİYE
Online: Sitede Değil
Gönderilenler: 26
  Alıntı aziz.alkurt Alıntı  Yanıt YazCevapla Mesajın Direkt Linki Konu: leptonica read bmp with use pixReadMem function
    Gönderim Zamanı: 09.Aralik.2012 Saat 12:35
leptonica - bmpio.c
//----------------------------------------------------------------------------------------------------------------------
PIX *
pixReadMemBmp(const l_uint8  *cdata,
              size_t          size)
{
    int hacked;
    l_uint16   sval;
    l_uint32   ival;
    l_int16    bfType, bfSize, bfFill1, bfReserved1, bfReserved2;
    l_int16    offset, bfFill2, biPlanes, depth, d;
    l_int32    biSize, width, height, xres, yres, compression, ignore;
    l_int32    imagebytes, biClrUsed, biClrImportant;
    l_uint8   *colormapBuf;
    l_int32    colormapEntries;
    l_int32    fileBpl, extrabytes, readerror;
    l_int32    pixWpl, pixBpl;
    l_int32    i, j, k;
    l_uint8    pel[4];
    l_uint8   *data;
    l_uint32  *line, *pword;
    PIX        *pix, *pixt;
    PIXCMAP   *cmap;
    PROCNAME("pixReadMemBmp");
   
        /* Read bitmap file header */
    memcpy((char *)&sval,(char *)cdata,2);
    bfType = convertOnBigEnd16(sval);
    if (bfType != BMP_ID)
        return (PIX *)ERROR_PTR("not bmf format", procName, NULL);

    memcpy((char *)&sval,(char *)cdata+2,2);
    bfSize = convertOnBigEnd16(sval);
    memcpy((char *)&sval,(char *)cdata+4,2);
    bfFill1 = convertOnBigEnd16(sval);
    memcpy((char *)&sval,(char *)cdata+6,2);
    bfReserved1 = convertOnBigEnd16(sval);
    memcpy((char *)&sval,(char *)cdata+8,2);
    bfReserved2 = convertOnBigEnd16(sval);
    memcpy((char *)&sval,(char *)cdata+10,2);
    offset = convertOnBigEnd16(sval);
    memcpy((char *)&sval,(char *)cdata+12,2);
    bfFill2 = convertOnBigEnd16(sval);

        /* Read bitmap info header */
    memcpy((char *)&ival,(char *)cdata+14,4);
    biSize = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+18,4);
    width = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+22,4);
    height = convertOnBigEnd32(ival);
    memcpy((char *)&sval,(char *)cdata+26,2);
    biPlanes = convertOnBigEnd16(sval);
    memcpy((char *)&sval,(char *)cdata+28,2);
    depth = convertOnBigEnd16(sval);
    memcpy((char *)&ival,(char *)cdata+30,4);
    compression = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+34,4);
    imagebytes = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+38,4);
    xres = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+42,4);
    yres = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+46,4);
    biClrUsed = convertOnBigEnd32(ival);
    memcpy((char *)&ival,(char *)cdata+50,4);
    biClrImportant = convertOnBigEnd32(ival);

    if (compression != 0)
        return (PIX *)ERROR_PTR("cannot read compressed BMP files",
                                procName,NULL);

        /* A little sanity checking.  It would be nice to check
            * if the number of bytes in the file equals the offset to
            * the data plus the imagedata, but this won't work when
            * reading from memory, because fmemopen() doesn't implement
            * ftell().  So we can't do that check.  The imagebytes for
            * uncompressed images is either 0 or the size of the file data.
            * (The fact that it can be 0 is perhaps some legacy glitch).  */
    if (width < 1)
        return (PIX *)ERROR_PTR("width < 1", procName,NULL);
    if (height < 1)
        return (PIX *)ERROR_PTR("height < 1", procName,NULL);
    if (depth < 1 || depth > 32)
        return (PIX *)ERROR_PTR("depth not in [1 ... 32]", procName,NULL);
    fileBpl = 4 * ((width * depth + 31)/32);
    if (imagebytes != 0 && imagebytes != fileBpl * height)
        return (PIX *)ERROR_PTR("invalid imagebytes", procName,NULL);
    if (offset < BMP_FHBYTES + BMP_IHBYTES)
        return (PIX *)ERROR_PTR("invalid offset: too small", procName,NULL);
    if (offset > BMP_FHBYTES + BMP_IHBYTES + 4 * 256)
        return (PIX *)ERROR_PTR("invalid offset: too large", procName,NULL);

        /* Handle the colormap */
    colormapEntries = (offset - BMP_FHBYTES - BMP_IHBYTES) / sizeof(RGBA_QUAD);
    if (colormapEntries > 0) {
        if ((colormapBuf = (l_uint8 *)CALLOC(colormapEntries,
                                                sizeof(RGBA_QUAD))) == NULL)
            return (PIX *)ERROR_PTR("colormapBuf alloc fail", procName, NULL );

            /* Read colormap */
        if (54+colormapEntries>size)
        {
            FREE(colormapBuf);
            return (PIX *)ERROR_PTR( "colormap read fail", procName, NULL);
        }
        memcpy(colormapBuf,(char *)cdata+54,colormapEntries);


    }

        /* Make a 32 bpp pix if depth is 24 bpp */
    d = depth;
    if (depth == 24)
        d = 32;
    if ((pix = pixCreate(width, height, d)) == NULL)
        return (PIX *)ERROR_PTR( "pix not made", procName, NULL);
    pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));  /* to ppi */
    pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));  /* to ppi */
    pixWpl = pixGetWpl(pix);
    pixBpl = 4 * pixWpl;

    cmap = NULL;
    if (colormapEntries > 256)
        L_WARNING("more than 256 colormap entries!", procName);
    if (colormapEntries > 0) {  /* import the colormap to the pix cmap */
        cmap = pixcmapCreate(L_MIN(d, 8));
        FREE(cmap->array);  /* remove generated cmap array */
        cmap->array  = (void *)colormapBuf;  /* and replace */
        cmap->n = L_MIN(colormapEntries, 256);
    }
    pixSetColormap(pix, cmap);

        /* Seek to the start of the bitmap in the file */
    /*fseek(fp, offset, 0);*/
    hacked=offset;
    if (depth != 24) {  /* typ. 1 or 8 bpp */
        data = (l_uint8 *)pixGetData(pix) + pixBpl * (height - 1);
        for (i = 0; i < height; i++)
        {
            if (hacked+fileBpl>size)
            {
                pixDestroy(&pix);
                return (PIX *)ERROR_PTR("BMP read fail", procName, NULL);
            }
            else
            {
                 //fread(data, 1, fileBpl, fp) != fileBpl
                memcpy(data,(char *)cdata+hacked,fileBpl);
                hacked+=fileBpl;
            }
            data -= pixBpl;
        }
    }
    else {  /*  24 bpp file; 32 bpp pix
                *  Note: for bmp files, pel[0] is blue, pel[1] is green,
                *  and pel[2] is red.  This is opposite to the storage
                *  in the pix, which puts the red pixel in the 0 byte,
                *  the green in the 1 byte and the blue in the 2 byte.
                *  Note also that all words are endian flipped after
                *  assignment on L_LITTLE_ENDIAN platforms.
                *
                *  We can then make these assignments for little endians:
                *      SET_DATA_BYTE(pword, 1, pel[0]);      blue
                *      SET_DATA_BYTE(pword, 2, pel[1]);      green
                *      SET_DATA_BYTE(pword, 3, pel[2]);      red
                *  This looks like:
                *          3  (R)     2  (G)        1  (B)        0
                *      |-----------|------------|-----------|-----------|
                *  and after byte flipping:
                *           3          2  (B)     1  (G)        0  (R)
                *      |-----------|------------|-----------|-----------|
                *
                *  For big endians we set:
                *      SET_DATA_BYTE(pword, 2, pel[0]);      blue
                *      SET_DATA_BYTE(pword, 1, pel[1]);      green
                *      SET_DATA_BYTE(pword, 0, pel[2]);      red
                *  This looks like:
                *          0  (R)     1  (G)        2  (B)        3
                *      |-----------|------------|-----------|-----------|
                *  so in both cases we get the correct assignment in the PIX.
                *
                *  Can we do a platform-independent assignment?
                *  Yes, set the bytes without using macros:
                *      *((l_uint8 *)pword) = pel[2];           red
                *      *((l_uint8 *)pword + 1) = pel[1];       green
                *      *((l_uint8 *)pword + 2) = pel[0];       blue
                *  For little endians, before flipping, this looks again like:
                *          3  (R)     2  (G)        1  (B)        0
                *      |-----------|------------|-----------|-----------|
                */
        readerror = 0;
        extrabytes = fileBpl - 3 * width;
        line = pixGetData(pix) + pixWpl * (height - 1);
        for (i = 0; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                pword = line + j;
                /*if (fread(&pel, 1, 3, fp) != 3)
                    readerror = 1;*/
                if(hacked+3>size)
                    readerror=1;
                memcpy(&pel,(char *)cdata+hacked,3);
                hacked+=3;
                *((l_uint8 *)pword + COLOR_RED) = pel[2];
                *((l_uint8 *)pword + COLOR_GREEN) = pel[1];
                *((l_uint8 *)pword + COLOR_BLUE) = pel[0];
            }
            hacked+=extrabytes;
            line -= pixWpl;
        }
        if (readerror) {
            pixDestroy(&pix);
            return (PIX *)ERROR_PTR("BMP read fail", procName, NULL);
        }
    }

    pixEndianByteSwap(pix);

        /* ----------------------------------------------
            * The bmp colormap determines the values of black
            * and white pixels for binary in the following way:
            * if black = 1 (255), white = 0
            *      255, 255, 255, 0, 0, 0, 0, 0
            * if black = 0, white = 1 (255)
            *      0, 0, 0, 0, 255, 255, 255, 0
            * We have no need for a 1 bpp pix with a colormap!
            * ---------------------------------------------- */
    if (depth == 1 && cmap) {
/*        L_INFO("Removing colormap", procName); */
        pixt = pixRemoveColormap(pix, REMOVE_CMAP_BASED_ON_SRC);
        pixDestroy(&pix);
        pix = pixt;  /* rename */
    }

    return pix;
}
// --------------------------------------------------------------------------------------------------------------------

TEST
//----------------------------------------------------------------------------------------------------------------------
    unsigned char* dstTmp = NULL;
    FILE *file;
    file =fopen("d:/testx.bmp","rb");
    fseek (file , 0 , SEEK_END);
    size_t length=ftell (file);
    rewind (file);
    dstTmp = (unsigned char*) malloc (sizeof(unsigned char)*length);
    fread (dstTmp,1,length,file);
    fclose(file);

    Pix *pix = pixReadMem(dstTmp,length);
//----------------------------------------------------------------------------------------------------------------------


Yukarı Dön
 Yanıt Yaz Yanıt Yaz

Forum Atla Forum İzinleri Açılır Menü Göster



Bu Sayfa 0,350 Saniyede Yüklendi. [power by : WebWiz]