43 #include "config_auto.h" 47 #include "allheaders.h" 58 RGBA_QUAD bwmap[2] = { {255,255,255,255}, {0,0,0,255} };
61 static const l_int32 L_MAX_ALLOWED_NUM_COLORS = 256;
64 static const l_int32 L_MAX_ALLOWED_WIDTH = 1000000;
65 static const l_int32 L_MAX_ALLOWED_HEIGHT = 1000000;
66 static const l_int64 L_MAX_ALLOWED_PIXELS = 400000000LL;
95 PROCNAME(
"pixReadStreamBmp");
98 return (
PIX *)ERROR_PTR(
"fp not defined", procName, NULL);
103 return (
PIX *)ERROR_PTR(
"data not read", procName, NULL);
123 l_uint8 *cmapBuf, *fdata, *data;
124 l_int16 bftype, offset, depth, d;
125 l_int32 width, height, xres, yres, compression, imagebytes;
126 l_int32 cmapbytes, cmapEntries;
127 l_int32 fdatabpl, extrabytes, pixWpl, pixBpl, i, j, k;
128 l_uint32 *line, *pixdata, *pword;
135 PROCNAME(
"pixReadMemBmp");
138 return (
PIX *)ERROR_PTR(
"cdata not defined", procName, NULL);
140 return (
PIX *)ERROR_PTR(
"bmf size error", procName, NULL);
144 bftype = convertOnBigEnd16(bmpfh->
bfType);
146 return (
PIX *)ERROR_PTR(
"not bmf format", procName, NULL);
149 return (
PIX *)ERROR_PTR(
"bmpih not defined", procName, NULL);
151 if (compression != 0)
152 return (
PIX *)ERROR_PTR(
"cannot read compressed BMP files",
156 offset = convertOnBigEnd16(bmpfh->
bfOffBits);
157 width = convertOnBigEnd32(bmpih->
biWidth);
158 height = convertOnBigEnd32(bmpih->
biHeight);
160 imagebytes = convertOnBigEnd32(bmpih->
biSizeImage);
174 return (
PIX *)ERROR_PTR(
"width < 1", procName, NULL);
175 if (width > L_MAX_ALLOWED_WIDTH)
176 return (
PIX *)ERROR_PTR(
"width too large", procName, NULL);
178 return (
PIX *)ERROR_PTR(
"height < 1", procName, NULL);
179 if (height > L_MAX_ALLOWED_HEIGHT)
180 return (
PIX *)ERROR_PTR(
"height too large", procName, NULL);
181 npixels = 1LL * width * height;
182 if (npixels > L_MAX_ALLOWED_PIXELS)
183 return (
PIX *)ERROR_PTR(
"npixels too large", procName, NULL);
184 if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
185 depth != 16 && depth != 24 && depth != 32)
186 return (
PIX *)ERROR_PTR(
"depth not in {1, 2, 4, 8, 16, 24, 32}",
188 fdatabpl = 4 * ((1LL * width * depth + 31)/32);
189 if (imagebytes != 0 && imagebytes != fdatabpl * height)
190 return (
PIX *)ERROR_PTR(
"invalid imagebytes", procName, NULL);
192 cmapEntries = cmapbytes /
sizeof(
RGBA_QUAD);
193 if (cmapEntries < 0 || cmapEntries == 1)
194 return (
PIX *)ERROR_PTR(
"invalid: cmap size < 0 or 1", procName, NULL);
195 if (cmapEntries > L_MAX_ALLOWED_NUM_COLORS)
196 return (
PIX *)ERROR_PTR(
"invalid cmap: too large", procName,NULL);
197 if (size != 1LL * offset + 1LL * fdatabpl * height)
198 return (
PIX *)ERROR_PTR(
"size incommensurate with image data",
203 if (cmapEntries > 0) {
204 if ((cmapBuf = (l_uint8 *)LEPT_CALLOC(cmapEntries,
sizeof(
RGBA_QUAD)))
206 return (
PIX *)ERROR_PTR(
"cmapBuf alloc fail", procName, NULL );
215 d = (depth == 24) ? 32 : depth;
216 if ((pix =
pixCreate(width, height, d)) == NULL) {
218 return (
PIX *)ERROR_PTR(
"pix not made", procName, NULL);
220 pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));
221 pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));
222 pixSetInputFormat(pix, IFF_BMP);
223 pixWpl = pixGetWpl(pix);
228 if (cmapEntries > 0) {
230 LEPT_FREE(cmap->
array);
231 cmap->
array = (
void *)cmapBuf;
232 cmap->
n = L_MIN(cmapEntries, 256);
233 for (i = 0; i < cmap->
n; i++)
239 fdata = (l_uint8 *)cdata + offset;
242 data = (l_uint8 *)pixdata + pixBpl * (height - 1);
243 for (i = 0; i < height; i++) {
244 memcpy(data, fdata, fdatabpl);
285 extrabytes = fdatabpl - 3 * width;
286 line = pixdata + pixWpl * (height - 1);
287 for (i = 0; i < height; i++) {
288 for (j = 0; j < width; j++) {
290 memcpy(&pel, fdata, 3);
292 *((l_uint8 *)pword +
COLOR_RED) = pel[2];
297 for (k = 0; k < extrabytes; k++) {
298 memcpy(&pel, fdata, 1);
318 if (depth == 1 && cmap) {
345 PROCNAME(
"pixWriteStreamBmp");
348 return ERROR_INT(
"stream not defined", procName, 1);
350 return ERROR_INT(
"pix not defined", procName, 1);
354 nbytes = fwrite(data, 1, size, fp);
357 return ERROR_INT(
"Write error", procName, 1);
390 l_uint8 *fdata, *data, *fmdata;
392 l_int32 ncolors, val, stepsize;
393 l_int32 w, h, d, fdepth, xres, yres;
394 l_int32 pixWpl, pixBpl, extrabytes, fBpl, fWpl, i, j, k;
396 l_uint32 offbytes, fimagebytes;
397 l_uint32 *line, *pword;
405 PROCNAME(
"pixWriteMemBmp");
407 if (pfdata) *pfdata = NULL;
408 if (pfsize) *pfsize = 0;
410 return ERROR_INT(
"&fdata not defined", procName, 1 );
412 return ERROR_INT(
"&fsize not defined", procName, 1 );
414 return ERROR_INT(
"pixs not defined", procName, 1);
418 L_WARNING(
"2 bpp files can't be read; converting to 8 bpp\n", procName);
424 fdepth = (d == 32) ? 24 : d;
427 xres = (l_int32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);
428 yres = (l_int32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);
430 pixWpl = pixGetWpl(pix);
432 fWpl = (w * fdepth + 31) / 32;
434 fimagebytes = h * fBpl;
435 if (fimagebytes > 4LL * L_MAX_ALLOWED_PIXELS) {
437 return ERROR_INT(
"image data is too large", procName, 1);
442 if (d == 32 || d == 16) {
445 }
else if ((cmap = pixGetColormap(pix))) {
448 cta = (l_uint8 *)cmap->
array;
451 cmaplen =
sizeof(bwmap);
453 cta = (l_uint8 *)bwmap;
455 ncolors = 1 << fdepth;
458 cta = (l_uint8 *)LEPT_CALLOC(cmaplen, 1);
459 stepsize = 255 / (ncolors - 1);
460 for (i = 0, val = 0, pquad = (
RGBA_QUAD *)cta;
462 i++, val += stepsize, pquad++) {
471 pcmptr = (l_uint8 *)pixGetColormap(pix)->
array;
472 fprintf(stderr,
"Pix colormap[0] = %c%c%c%d\n",
473 pcmptr[0], pcmptr[1], pcmptr[2], pcmptr[3]);
474 fprintf(stderr,
"Pix colormap[1] = %c%c%c%d\n",
475 pcmptr[4], pcmptr[5], pcmptr[6], pcmptr[7]);
480 fsize = offbytes + fimagebytes;
481 fdata = (l_uint8 *)LEPT_CALLOC(fsize, 1);
488 bmpfh->
bfSize = convertOnBigEnd16(fsize & 0x0000ffff);
489 bmpfh->
bfFill1 = convertOnBigEnd16((fsize >> 16) & 0x0000ffff);
490 bmpfh->
bfOffBits = convertOnBigEnd16(offbytes & 0x0000ffff);
491 bmpfh->
bfFill2 = convertOnBigEnd16((offbytes >> 16) & 0x0000ffff);
496 bmpih->
biWidth = convertOnBigEnd32(w);
497 bmpih->
biHeight = convertOnBigEnd32(h);
498 bmpih->
biPlanes = convertOnBigEnd16(1);
499 bmpih->
biBitCount = convertOnBigEnd16(fdepth);
500 bmpih->
biSizeImage = convertOnBigEnd32(fimagebytes);
503 bmpih->
biClrUsed = convertOnBigEnd32(ncolors);
509 if (heapcm) LEPT_FREE(cta);
514 if (fdepth == 1 && cmap && ((l_uint8 *)(cmap->
array))[0] == 0x0) {
522 fmdata = fdata + offbytes;
524 data = (l_uint8 *)
pixGetData(pix) + pixBpl * (h - 1);
525 for (i = 0; i < h; i++) {
526 memcpy(fmdata, data, fBpl);
539 extrabytes = fBpl - 3 * w;
541 for (i = 0; i < h; i++) {
542 for (j = 0; j < w; j++) {
544 pel[2] = *((l_uint8 *)pword +
COLOR_RED);
547 memcpy(fmdata, &pel, 3);
551 for (k = 0; k < extrabytes; k++) {
552 memcpy(fmdata, &pel, 1);
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
l_int32 pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
PIX * pixReadStreamBmp(FILE *fp)
pixReadStreamBmp()
PIX * pixReadMemBmp(const l_uint8 *cdata, size_t size)
pixReadMemBmp()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
l_int32 pixWriteStreamBmp(FILE *fp, PIX *pix)
pixWriteStreamBmp()
l_int32 pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
l_int32 pixWriteMemBmp(l_uint8 **pfdata, size_t *pfsize, PIX *pixs)
pixWriteMemBmp()
void pixDestroy(PIX **ppix)
pixDestroy()
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
PIX * pixConvert2To8(PIX *pixs, l_uint8 val0, l_uint8 val1, l_uint8 val2, l_uint8 val3, l_int32 cmapflag)
pixConvert2To8()
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
l_int32 pixcmapSetAlpha(PIXCMAP *cmap, l_int32 index, l_int32 aval)
pixcmapSetAlpha()