Leptonica 1.68
C Image Processing Library

bmpio.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  *  bmpio.c
00018  *
00019  *      Read bmp from file
00020  *           PIX          *pixReadStreamBmp()
00021  *
00022  *      Write bmp to file
00023  *           l_int32       pixWriteStreamBmp()
00024  *
00025  *      Read/write to memory   [only on linux]
00026  *           PIX          *pixReadMemBmp()
00027  *           l_int32       pixWriteMemBmp()
00028  */
00029 
00030 #include <string.h>
00031 #include "allheaders.h"
00032 #include "bmp.h"
00033 
00034 /* --------------------------------------------*/
00035 #if  USE_BMPIO   /* defined in environ.h */
00036 /* --------------------------------------------*/
00037 
00038 RGBA_QUAD   bwmap[2] = { {255,255,255,0}, {0,0,0,0} };
00039 
00040 #ifndef  NO_CONSOLE_IO
00041 #define  DEBUG     0
00042 #endif  /* ~NO_CONSOLE_IO */
00043 
00044 
00045 /*!
00046  *  pixReadStreamBmp()
00047  *
00048  *      Input:  stream opened for read
00049  *      Return: pix, or null on error
00050  *
00051  *  Notes:
00052  *      (1) Here are references on the bmp file format:
00053  *          http://en.wikipedia.org/wiki/BMP_file_format
00054  *          http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html
00055  */
00056 PIX *
00057 pixReadStreamBmp(FILE  *fp)
00058 {
00059 l_uint16   sval;
00060 l_uint32   ival;
00061 l_int16    bfType, bfSize, bfFill1, bfReserved1, bfReserved2;
00062 l_int16    offset, bfFill2, biPlanes, depth, d;
00063 l_int32    biSize, width, height, xres, yres, compression, ignore;
00064 l_int32    imagebytes, biClrUsed, biClrImportant;
00065 l_uint8   *colormapBuf;
00066 l_int32    colormapEntries;
00067 l_int32    fileBpl, extrabytes, readerror;
00068 l_int32    pixWpl, pixBpl;
00069 l_int32    i, j, k;
00070 l_uint8    pel[4];
00071 l_uint8   *data;
00072 l_uint32  *line, *pword;
00073 PIX        *pix, *pixt;
00074 PIXCMAP   *cmap;
00075 
00076     PROCNAME("pixReadStreamBmp");
00077 
00078     if (!fp)
00079         return (PIX *)ERROR_PTR("fp not defined", procName, NULL);
00080 
00081         /* Read bitmap file header */
00082     ignore = fread((char *)&sval, 1, 2, fp);
00083     bfType = convertOnBigEnd16(sval);
00084     if (bfType != BMP_ID)
00085         return (PIX *)ERROR_PTR("not bmf format", procName, NULL);
00086 
00087     ignore = fread((char *)&sval, 1, 2, fp);
00088     bfSize = convertOnBigEnd16(sval);
00089     ignore = fread((char *)&sval, 1, 2, fp);
00090     bfFill1 = convertOnBigEnd16(sval);
00091     ignore = fread((char *)&sval, 1, 2, fp);
00092     bfReserved1 = convertOnBigEnd16(sval);
00093     ignore = fread((char *)&sval, 1, 2, fp);
00094     bfReserved2 = convertOnBigEnd16(sval);
00095     ignore = fread((char *)&sval, 1, 2, fp);
00096     offset = convertOnBigEnd16(sval);
00097     ignore = fread((char *)&sval, 1, 2, fp);
00098     bfFill2 = convertOnBigEnd16(sval);
00099 
00100         /* Read bitmap info header */
00101     ignore = fread((char *)&ival, 1, 4, fp);
00102     biSize = convertOnBigEnd32(ival);
00103     ignore = fread((char *)&ival, 1, 4, fp);
00104     width = convertOnBigEnd32(ival);
00105     ignore = fread((char *)&ival, 1, 4, fp);
00106     height = convertOnBigEnd32(ival);
00107     ignore = fread((char *)&sval, 1, 2, fp);
00108     biPlanes = convertOnBigEnd16(sval);
00109     ignore = fread((char *)&sval, 1, 2, fp);
00110     depth = convertOnBigEnd16(sval);
00111     ignore = fread((char *)&ival, 1, 4, fp);
00112     compression = convertOnBigEnd32(ival);
00113     ignore = fread((char *)&ival, 1, 4, fp);
00114     imagebytes = convertOnBigEnd32(ival);
00115     ignore = fread((char *)&ival, 1, 4, fp);
00116     xres = convertOnBigEnd32(ival);
00117     ignore = fread((char *)&ival, 1, 4, fp);
00118     yres = convertOnBigEnd32(ival);
00119     ignore = fread((char *)&ival, 1, 4, fp);
00120     biClrUsed = convertOnBigEnd32(ival);
00121     ignore = fread((char *)&ival, 1, 4, fp);
00122     biClrImportant = convertOnBigEnd32(ival);
00123 
00124     if (compression != 0)
00125         return (PIX *)ERROR_PTR("cannot read compressed BMP files",
00126                                 procName,NULL);
00127 
00128         /* A little sanity checking.  It would be nice to check
00129          * if the number of bytes in the file equals the offset to
00130          * the data plus the imagedata, but this won't work when
00131          * reading from memory, because fmemopen() doesn't implement
00132          * ftell().  So we can't do that check.  The imagebytes for
00133          * uncompressed images is either 0 or the size of the file data.
00134          * (The fact that it can be 0 is perhaps some legacy glitch).  */
00135     if (width < 1)
00136         return (PIX *)ERROR_PTR("width < 1", procName,NULL);
00137     if (height < 1)
00138         return (PIX *)ERROR_PTR("height < 1", procName,NULL);
00139     if (depth < 1 || depth > 32)
00140         return (PIX *)ERROR_PTR("depth not in [1 ... 32]", procName,NULL);
00141     fileBpl = 4 * ((width * depth + 31)/32);
00142     if (imagebytes != 0 && imagebytes != fileBpl * height)
00143         return (PIX *)ERROR_PTR("invalid imagebytes", procName,NULL);
00144     if (offset < BMP_FHBYTES + BMP_IHBYTES)
00145         return (PIX *)ERROR_PTR("invalid offset: too small", procName,NULL);
00146     if (offset > BMP_FHBYTES + BMP_IHBYTES + 4 * 256)
00147         return (PIX *)ERROR_PTR("invalid offset: too large", procName,NULL);
00148 
00149         /* Handle the colormap */
00150     colormapEntries = (offset - BMP_FHBYTES - BMP_IHBYTES) / sizeof(RGBA_QUAD);
00151     if (colormapEntries > 0) {
00152         if ((colormapBuf = (l_uint8 *)CALLOC(colormapEntries,
00153                                              sizeof(RGBA_QUAD))) == NULL)
00154             return (PIX *)ERROR_PTR("colormapBuf alloc fail", procName, NULL );
00155 
00156             /* Read colormap */
00157         if (fread(colormapBuf, sizeof(RGBA_QUAD), colormapEntries, fp)
00158                  != colormapEntries) {
00159             FREE(colormapBuf);
00160             return (PIX *)ERROR_PTR( "colormap read fail", procName, NULL);
00161         }
00162     }
00163 
00164         /* Make a 32 bpp pix if depth is 24 bpp */
00165     d = depth;
00166     if (depth == 24)
00167         d = 32;
00168     if ((pix = pixCreate(width, height, d)) == NULL)
00169         return (PIX *)ERROR_PTR( "pix not made", procName, NULL);
00170     pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));  /* to ppi */
00171     pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));  /* to ppi */
00172     pixWpl = pixGetWpl(pix);
00173     pixBpl = 4 * pixWpl;
00174 
00175     cmap = NULL;
00176     if (colormapEntries > 256)
00177         L_WARNING("more than 256 colormap entries!", procName);
00178     if (colormapEntries > 0) {  /* import the colormap to the pix cmap */
00179         cmap = pixcmapCreate(L_MIN(d, 8));
00180         FREE(cmap->array);  /* remove generated cmap array */
00181         cmap->array  = (void *)colormapBuf;  /* and replace */
00182         cmap->n = L_MIN(colormapEntries, 256);
00183     }
00184     pixSetColormap(pix, cmap);
00185 
00186         /* Seek to the start of the bitmap in the file */
00187     fseek(fp, offset, 0);
00188 
00189     if (depth != 24) {  /* typ. 1 or 8 bpp */
00190         data = (l_uint8 *)pixGetData(pix) + pixBpl * (height - 1);
00191         for (i = 0; i < height; i++) {
00192             if (fread(data, 1, fileBpl, fp) != fileBpl) {
00193                 pixDestroy(&pix);
00194                 return (PIX *)ERROR_PTR("BMP read fail", procName, NULL);
00195             }
00196             data -= pixBpl;
00197         }
00198     }
00199     else {  /*  24 bpp file; 32 bpp pix
00200              *  Note: for bmp files, pel[0] is blue, pel[1] is green,
00201              *  and pel[2] is red.  This is opposite to the storage
00202              *  in the pix, which puts the red pixel in the 0 byte,
00203              *  the green in the 1 byte and the blue in the 2 byte.
00204              *  Note also that all words are endian flipped after
00205              *  assignment on L_LITTLE_ENDIAN platforms.
00206              *
00207              *  We can then make these assignments for little endians:
00208              *      SET_DATA_BYTE(pword, 1, pel[0]);      blue
00209              *      SET_DATA_BYTE(pword, 2, pel[1]);      green
00210              *      SET_DATA_BYTE(pword, 3, pel[2]);      red
00211              *  This looks like:
00212              *          3  (R)     2  (G)        1  (B)        0
00213              *      |-----------|------------|-----------|-----------|
00214              *  and after byte flipping:
00215              *           3          2  (B)     1  (G)        0  (R)
00216              *      |-----------|------------|-----------|-----------|
00217              *
00218              *  For big endians we set:
00219              *      SET_DATA_BYTE(pword, 2, pel[0]);      blue
00220              *      SET_DATA_BYTE(pword, 1, pel[1]);      green
00221              *      SET_DATA_BYTE(pword, 0, pel[2]);      red
00222              *  This looks like:
00223              *          0  (R)     1  (G)        2  (B)        3
00224              *      |-----------|------------|-----------|-----------|
00225              *  so in both cases we get the correct assignment in the PIX.
00226              *
00227              *  Can we do a platform-independent assignment?
00228              *  Yes, set the bytes without using macros:
00229              *      *((l_uint8 *)pword) = pel[2];           red
00230              *      *((l_uint8 *)pword + 1) = pel[1];       green
00231              *      *((l_uint8 *)pword + 2) = pel[0];       blue
00232              *  For little endians, before flipping, this looks again like:
00233              *          3  (R)     2  (G)        1  (B)        0
00234              *      |-----------|------------|-----------|-----------|
00235              */
00236         readerror = 0;
00237         extrabytes = fileBpl - 3 * width;
00238         line = pixGetData(pix) + pixWpl * (height - 1);
00239         for (i = 0; i < height; i++) {
00240             for (j = 0; j < width; j++) {
00241                 pword = line + j;
00242                 if (fread(&pel, 1, 3, fp) != 3)
00243                     readerror = 1;
00244                 *((l_uint8 *)pword + COLOR_RED) = pel[2];
00245                 *((l_uint8 *)pword + COLOR_GREEN) = pel[1];
00246                 *((l_uint8 *)pword + COLOR_BLUE) = pel[0];
00247             }
00248             if (extrabytes) {
00249                 for (k = 0; k < extrabytes; k++)
00250                     ignore = fread(&pel, 1, 1, fp);
00251             }
00252             line -= pixWpl;
00253         }
00254         if (readerror) {
00255             pixDestroy(&pix);
00256             return (PIX *)ERROR_PTR("BMP read fail", procName, NULL);
00257         }
00258     }
00259 
00260     pixEndianByteSwap(pix);
00261 
00262         /* ----------------------------------------------
00263          * The bmp colormap determines the values of black
00264          * and white pixels for binary in the following way:
00265          * if black = 1 (255), white = 0
00266          *      255, 255, 255, 0, 0, 0, 0, 0
00267          * if black = 0, white = 1 (255)
00268          *      0, 0, 0, 0, 255, 255, 255, 0
00269          * We have no need for a 1 bpp pix with a colormap!
00270          * ---------------------------------------------- */
00271     if (depth == 1 && cmap) {
00272 /*        L_INFO("Removing colormap", procName); */
00273         pixt = pixRemoveColormap(pix, REMOVE_CMAP_BASED_ON_SRC);
00274         pixDestroy(&pix);
00275         pix = pixt;  /* rename */
00276     }
00277 
00278     return pix;
00279 }
00280 
00281 
00282 
00283 /*!
00284  *  pixWriteStreamBmp()
00285  *
00286  *      Input:  stream opened for write
00287  *              pix (1, 4, 8, 32 bpp)
00288  *      Return: 0 if OK, 1 on error
00289  *
00290  *  Notes:
00291  *      (1) We position fp at the beginning of the stream, so it
00292  *          truncates any existing data
00293  *      (2) 2 bpp Bmp files are apparently not valid!.  We can
00294  *          write and read them, but nobody else can read ours.
00295  */
00296 l_int32
00297 pixWriteStreamBmp(FILE  *fp,
00298                   PIX   *pix)
00299 {
00300 l_uint32    offbytes, filebytes, fileimagebytes;
00301 l_int32     width, height, depth, d, xres, yres;
00302 l_uint16    bfType, bfSize, bfFill1, bfReserved1, bfReserved2;
00303 l_uint16    bfOffBits, bfFill2, biPlanes, biBitCount;
00304 l_uint16    sval;
00305 l_uint32    biSize, biWidth, biHeight, biCompression, biSizeImage;
00306 l_uint32    biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant;
00307 l_int32     pixWpl, pixBpl, extrabytes, writeerror;
00308 l_int32     fileBpl, fileWpl;
00309 l_int32     i, j, k;
00310 l_int32     heapcm;  /* extra copy of cta on the heap ? 1 : 0 */
00311 l_uint8    *data;
00312 l_uint8     pel[4];
00313 l_uint32   *line, *pword;
00314 PIXCMAP    *cmap;
00315 l_uint8    *cta;          /* address of the bmp color table array */
00316 l_int32     cmaplen;      /* number of bytes in the bmp colormap */
00317 l_int32     ncolors, val, stepsize;
00318 RGBA_QUAD  *pquad;
00319 
00320     PROCNAME("pixWriteStreamBmp");
00321 
00322     if (!fp)
00323         return ERROR_INT("stream not defined", procName, 1);
00324     if (!pix)
00325         return ERROR_INT("pix not defined", procName, 1);
00326 
00327     width  = pixGetWidth(pix);
00328     height = pixGetHeight(pix);
00329     d  = pixGetDepth(pix);
00330     if (d == 2)
00331         L_WARNING("writing 2 bpp bmp file; nobody else can read", procName);
00332     depth = d;
00333     if (d == 32)
00334         depth = 24;
00335     xres = (l_int32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);  /* to ppm */
00336     yres = (l_int32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);  /* to ppm */
00337 
00338     pixWpl = pixGetWpl(pix);
00339     pixBpl = 4 * pixWpl;
00340     fileWpl = (width * depth + 31) / 32;
00341     fileBpl = 4 * fileWpl;
00342     fileimagebytes = height * fileBpl;
00343 
00344     heapcm = 0;
00345     if (d == 32) {   /* 24 bpp rgb; no colormap */
00346         ncolors = 0;
00347         cmaplen = 0;
00348     }
00349     else if ((cmap = pixGetColormap(pix))) {   /* existing colormap */
00350         ncolors = pixcmapGetCount(cmap);
00351         cmaplen = ncolors * sizeof(RGBA_QUAD);
00352         cta = (l_uint8 *)cmap->array;
00353     }
00354     else {   /* no existing colormap; make a binary or gray one */
00355         if (d == 1) {
00356             cmaplen  = sizeof(bwmap);
00357             ncolors = 2;
00358             cta = (l_uint8 *)bwmap;
00359         }
00360         else {   /* d != 32; output grayscale version */
00361             ncolors = 1 << depth;
00362             cmaplen = ncolors * sizeof(RGBA_QUAD);
00363 
00364             heapcm = 1;
00365             if ((cta = (l_uint8 *)CALLOC(cmaplen, 1)) == NULL)
00366                 return ERROR_INT("colormap alloc fail", procName, 1);
00367 
00368             stepsize = 255 / (ncolors - 1);
00369             for (i = 0, val = 0, pquad = (RGBA_QUAD *)cta;
00370                  i < ncolors;
00371                  i++, val += stepsize, pquad++) {
00372                 pquad->blue = pquad->green = pquad->red = val;
00373             }
00374         }
00375     }
00376 
00377 #if DEBUG
00378     {l_uint8  *pcmptr;
00379         pcmptr = (l_uint8 *)pixGetColormap(pix)->array;
00380         fprintf(stderr, "Pix colormap[0] = %c%c%c%d\n",
00381             pcmptr[0], pcmptr[1], pcmptr[2], pcmptr[3]);
00382         fprintf(stderr, "Pix colormap[1] = %c%c%c%d\n",
00383             pcmptr[4], pcmptr[5], pcmptr[6], pcmptr[7]);
00384     }
00385 #endif  /* DEBUG */
00386 
00387     fseek(fp, 0L, 0);
00388 
00389         /* Convert to little-endian and write the file header data */
00390     bfType = convertOnBigEnd16(BMP_ID);
00391     offbytes = BMP_FHBYTES + BMP_IHBYTES + cmaplen;
00392     filebytes = offbytes + fileimagebytes;
00393     sval = filebytes & 0x0000ffff;
00394     bfSize = convertOnBigEnd16(sval);
00395     sval = (filebytes >> 16) & 0x0000ffff;
00396     bfFill1 = convertOnBigEnd16(sval);
00397     bfReserved1 = 0;
00398     bfReserved2 = 0;
00399     sval = offbytes & 0x0000ffff;
00400     bfOffBits = convertOnBigEnd16(sval);
00401     sval = (offbytes >> 16) & 0x0000ffff;
00402     bfFill2 = convertOnBigEnd16(sval);
00403     fwrite(&bfType, 1, 2, fp);
00404     fwrite(&bfSize, 1, 2, fp);
00405     fwrite(&bfFill1, 1, 2, fp);
00406     fwrite(&bfReserved1, 1, 2, fp);
00407     fwrite(&bfReserved1, 1, 2, fp);
00408     fwrite(&bfOffBits, 1, 2, fp);
00409     fwrite(&bfFill2, 1, 2, fp);
00410 
00411         /* Convert to little-endian and write the info header data */
00412     biSize = convertOnBigEnd32(BMP_IHBYTES);
00413     biWidth = convertOnBigEnd32(width);
00414     biHeight = convertOnBigEnd32(height);
00415     biPlanes = convertOnBigEnd16(1);
00416     biBitCount = convertOnBigEnd16(depth);
00417     biCompression   = 0;
00418     biSizeImage = convertOnBigEnd32(fileimagebytes);
00419     biXPelsPerMeter = convertOnBigEnd32(xres);
00420     biYPelsPerMeter = convertOnBigEnd32(yres);
00421     biClrUsed = convertOnBigEnd32(ncolors);
00422     biClrImportant = convertOnBigEnd32(ncolors);
00423     fwrite(&biSize, 1, 4, fp);
00424     fwrite(&biWidth, 1, 4, fp);
00425     fwrite(&biHeight, 1, 4, fp);
00426     fwrite(&biPlanes, 1, 2, fp);
00427     fwrite(&biBitCount, 1, 2, fp);
00428     fwrite(&biCompression, 1, 4, fp);
00429     fwrite(&biSizeImage, 1, 4, fp);
00430     fwrite(&biXPelsPerMeter, 1, 4, fp);
00431     fwrite(&biYPelsPerMeter, 1, 4, fp);
00432     fwrite(&biClrUsed, 1, 4, fp);
00433     fwrite(&biClrImportant, 1, 4, fp);
00434 
00435         /* Write the colormap data */
00436     if (ncolors > 0) {
00437         if (fwrite(cta, 1, cmaplen, fp) != cmaplen) {
00438             if (heapcm)
00439                 FREE(cta);
00440             return ERROR_INT("colormap write fail", procName, 1);
00441         }
00442         if (heapcm)
00443             FREE(cta);
00444     }
00445 
00446         /* When you write a binary image with a colormap
00447          * that sets BLACK to 0, you must invert the data */
00448     if (depth == 1 && cmap && ((l_uint8 *)(cmap->array))[0] == 0x0) {
00449         pixInvert(pix, pix);
00450     }
00451 
00452     pixEndianByteSwap(pix);
00453 
00454     writeerror = 0;
00455     if (depth != 24) {   /* typ 1 or 8 bpp */
00456         data = (l_uint8 *)pixGetData(pix) + pixBpl * (height - 1);
00457         for (i = 0; i < height; i++) {
00458             if (fwrite(data, 1, fileBpl, fp) != fileBpl)
00459                 writeerror = 1;
00460             data -= pixBpl;
00461         }
00462     }
00463     else {  /* 32 bpp pix; 24 bpp file
00464              * See the comments in pixReadStreamBMP() to
00465              * understand the logic behind the pixel ordering below.
00466              * Note that we have again done an endian swap on
00467              * little endian machines before arriving here, so that
00468              * the bytes are ordered on both platforms as:
00469                         Red         Green        Blue         --
00470                     |-----------|------------|-----------|-----------|
00471              */
00472         extrabytes = fileBpl - 3 * width;
00473         line = pixGetData(pix) + pixWpl * (height - 1);
00474         for (i = 0; i < height; i++) {
00475             for (j = 0; j < width; j++) {
00476                 pword = line + j;
00477                 pel[2] = *((l_uint8 *)pword + COLOR_RED);
00478                 pel[1] = *((l_uint8 *)pword + COLOR_GREEN);
00479                 pel[0] = *((l_uint8 *)pword + COLOR_BLUE);
00480                 if (fwrite(&pel, 1, 3, fp) != 3)
00481                     writeerror = 1;
00482             }
00483             if (extrabytes) {
00484                 for (k = 0; k < extrabytes; k++)
00485                     fwrite(&pel, 1, 1, fp);
00486             }
00487             line -= pixWpl;
00488         }
00489     }
00490 
00491         /* Restore to original state */
00492     pixEndianByteSwap(pix);
00493     if (depth == 1 && cmap && ((l_uint8 *)(cmap->array))[0] == 0x0)
00494         pixInvert(pix, pix);
00495 
00496     if (writeerror)
00497         return ERROR_INT("image write fail", procName, 1);
00498 
00499     return 0;
00500 }
00501 
00502 
00503 /*---------------------------------------------------------------------*
00504  *                         Read/write to memory                        *
00505  *---------------------------------------------------------------------*/
00506 #ifdef HAVE_CONFIG_H
00507 #include "config_auto.h"
00508 #endif  /* HAVE_CONFIG_H */
00509 
00510 #if HAVE_FMEMOPEN
00511 
00512 extern FILE *open_memstream(char **data, size_t *size);
00513 extern FILE *fmemopen(void *data, size_t size, const char *mode);
00514 
00515 /*!
00516  *  pixReadMemBmp()
00517  *
00518  *      Input:  cdata (const; bmp-encoded)
00519  *              size (of data)
00520  *      Return: pix, or null on error
00521  *
00522  *  Notes:
00523  *      (1) The @size byte of @data must be a null character.
00524  */
00525 PIX *
00526 pixReadMemBmp(const l_uint8  *cdata,
00527               size_t          size)
00528 {
00529 l_uint8  *data;
00530 FILE     *fp;
00531 PIX      *pix;
00532 
00533     PROCNAME("pixReadMemBmp");
00534 
00535     if (!cdata)
00536         return (PIX *)ERROR_PTR("cdata not defined", procName, NULL);
00537 
00538     data = (l_uint8 *)cdata;  /* we're really not going to change this */
00539     if ((fp = fmemopen(data, size, "r")) == NULL)
00540         return (PIX *)ERROR_PTR("stream not opened", procName, NULL);
00541     pix = pixReadStreamBmp(fp);
00542     fclose(fp);
00543     return pix;
00544 }
00545 
00546 
00547 /*!
00548  *  pixWriteMemBmp()
00549  *
00550  *      Input:  &data (<return> data of tiff compressed image)
00551  *              &size (<return> size of returned data)
00552  *              pix
00553  *      Return: 0 if OK, 1 on error
00554  *
00555  *  Notes:
00556  *      (1) See pixWriteStreamBmp() for usage.  This version writes to
00557  *          memory instead of to a file stream.
00558  */
00559 l_int32
00560 pixWriteMemBmp(l_uint8  **pdata,
00561                size_t    *psize,
00562                PIX       *pix)
00563 {
00564 l_int32  ret;
00565 FILE    *fp;
00566 
00567     PROCNAME("pixWriteMemBmp");
00568 
00569     if (!pdata)
00570         return ERROR_INT("&data not defined", procName, 1 );
00571     if (!psize)
00572         return ERROR_INT("&size not defined", procName, 1 );
00573     if (!pix)
00574         return ERROR_INT("&pix not defined", procName, 1 );
00575 
00576     if ((fp = open_memstream((char **)pdata, psize)) == NULL)
00577         return ERROR_INT("stream not opened", procName, 1);
00578     ret = pixWriteStreamBmp(fp, pix);
00579     fclose(fp);
00580     return ret;
00581 }
00582 
00583 #else
00584 
00585 PIX *
00586 pixReadMemBmp(const l_uint8  *cdata,
00587               size_t          size)
00588 {
00589     return (PIX *)ERROR_PTR(
00590         "bmp read from memory not implemented on this platform",
00591         "pixReadMemBmp", NULL);
00592 }
00593 
00594 
00595 l_int32
00596 pixWriteMemBmp(l_uint8  **pdata,
00597                size_t    *psize,
00598                PIX       *pix)
00599 {
00600     return ERROR_INT(
00601         "bmp write to memory not implemented on this platform",
00602         "pixWriteMemBmp", 1);
00603 }
00604 
00605 #endif  /* HAVE_FMEMOPEN */
00606 
00607 /* --------------------------------------------*/
00608 #endif  /* USE_BMPIO */
00609 /* --------------------------------------------*/
00610 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines