| leptonica read bmp with use pixReadMem function
 
 Nereden Yazdırıldığı: Datakent
 Kategori:  Diğer bölümler
 Forum Adı:  C, C++, Visual C++
 Forum Tanımlaması:  C, C++, Visual C++ Örnekleri
 URL: http://forum.datakent.com/forum_posts.asp?TID=2465
 Tarih: 31.Ekim.2025 Saat 21:40
 
 
 Konu: leptonica read bmp with use pixReadMem function
 Mesajı Yazan: aziz.alkurt
 Konu: leptonica read bmp with use pixReadMem function
 Mesaj Tarihi: 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);
 //----------------------------------------------------------------------------------------------------------------------
 
 
 
 |  
 
 |