leptonica read bmp with use pixReadMem function |
Yanıt Yaz |
Yazar | |
aziz.alkurt
Admin Group Kayıt Tarihi: 27.Ocak.2012 Bulundugu Yer: FETHİYE Online: Sitede Değil Gönderilenler: 26 |
Alıntı Cevapla
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); //---------------------------------------------------------------------------------------------------------------------- |
|
Yanıt Yaz |
Forum Atla | Forum İzinleri Kapalı Foruma Yeni Konu Gönderme Kapalı Forumdaki Konulara Cevap Yazma Kapalı Forumda Cevapları Silme Kapalı Forumdaki Cevapları Düzenleme Kapalı Forumda Anket Açma Kapalı Forumda Anketlerde Oy Kullanma |