/*! * pixReadRGBAPng() * * Input: filename (of png file) * Return: pix, or null on error * * Notes: * (1) Wrapper to keep the alpha channel of a png, if it exists. * (2) The default behavior of pix read functions is to ignore * the alpha channel. * (3) This always leaves alpha stripping in the same mode as * when this function begins. So if alpha stripping is in * default mode, this disables it, reads the file (including * the alpha channel), and resets back to stripping. Otherwise, * it leaves stripping disabled. */ PIX * pixReadRGBAPng(const char *filename) { l_int32 format; FILE *fp; PIX *pix; PROCNAME("pixReadRGBAPng"); if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); /* If alpha channel reading is enabled, just read it */ if (var_PNG_STRIP_ALPHA == FALSE) return pixRead(filename); /* Make sure it's a png file */ if ((fp = fopenReadStream(filename)) == NULL) return (PIX *)ERROR_PTR("image file not found", procName, NULL); findFileFormat(fp, &format); if (format != IFF_PNG) { fclose(fp); L_ERROR_STRING("file format is %s, not png", procName, ImageFileFormatExtensions[format]); return NULL; } l_pngSetStripAlpha(0); pix = pixReadStreamPng(fp); l_pngSetStripAlpha(1); /* reset to default */ fclose(fp); if (!pix) L_ERROR("pix not read", procName); return pix; }
static l_int32 test_1bpp_color(L_REGPARAMS *rp) { l_int32 same, transp; FILE *fp; PIX *pix1, *pix2; PIXCMAP *cmap; pix1 = pixRead("feyn-fract2.tif"); cmap = pixcmapCreate(1); pixSetColormap(pix1, cmap); pixcmapAddRGBA(cmap, 180, 130, 220, 255); /* color, opaque */ pixcmapAddRGBA(cmap, 20, 120, 0, 255); /* color, opaque */ pixWrite("/tmp/regout/1bpp-color.png", pix1, IFF_PNG); pix2 = pixRead("/tmp/regout/1bpp-color.png"); pixEqual(pix1, pix2, &same); if (same) fprintf(stderr, "1bpp_color: success\n"); else fprintf(stderr, "1bpp_color: bad output\n"); pixDisplayWithTitle(pix2, 700, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); fp = fopenReadStream("/tmp/regout/1bpp-color.png"); fgetPngColormapInfo(fp, &cmap, &transp); fclose(fp); if (transp) fprintf(stderr, "1bpp_color: error -- transparency found!\n"); else fprintf(stderr, "1bpp_color: correct -- no transparency found\n"); if (rp->display) pixcmapWriteStream(stderr, cmap); pixcmapDestroy(&cmap); return same; }
/*! * readHeaderWebP() * * Input: filename * &w (<return> width) * &h (<return> height) * &spp (<return> spp (3 or 4)) * Return: 0 if OK, 1 on error */ l_int32 readHeaderWebP(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pspp) { l_uint8 data[100]; /* expect size info within the first 50 bytes or so */ l_int32 nbytes, bytesread; size_t filesize; FILE *fp; PROCNAME("readHeaderWebP"); if (!pw || !ph || !pspp) return ERROR_INT("input ptr(s) not defined", procName, 1); *pw = *ph = *pspp = 0; if (!filename) return ERROR_INT("filename not defined", procName, 1); /* Read no more than 100 bytes from the file */ if ((filesize = nbytesInFile(filename)) == 0) return ERROR_INT("no file size found", procName, 1); if (filesize < 100) L_WARNING("very small webp file\n", procName); nbytes = L_MIN(filesize, 100); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); bytesread = fread((char *)data, 1, nbytes, fp); fclose(fp); if (bytesread != nbytes) return ERROR_INT("failed to read requested data", procName, 1); return readHeaderMemWebP(data, nbytes, pw, ph, pspp); }
/*! * pixReadJpeg() * * Input: filename * colormap flag (0 means return RGB image if color; * 1 means create colormap and return 8 bpp * palette image if color) * reduction (scaling factor: 1, 2, 4 or 8) * &pnwarn (<optional return> number of warnings about * corrupted data) * Return: pix, or null on error * * Images reduced by factors of 2, 4 or 8 can be returned * significantly faster than full resolution images. * * The jpeg library will return warnings (or exit) if * the jpeg data is bad. Use this function if you want the * jpeg library to create an 8 bpp palette image, or to * tell if the jpeg data has been corrupted. For corrupt jpeg * data, there are two possible outcomes: * (1) a damaged pix will be returned, along with a nonzero * number of warnings, or * (2) for sufficiently serious problems, the library will attempt * to exit (caught by our error handler) and no pix will be returned. */ PIX * pixReadJpeg(const char *filename, l_int32 cmflag, l_int32 reduction, l_int32 *pnwarn) { FILE *fp; PIX *pix; PROCNAME("pixReadJpeg"); if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); if (pnwarn) *pnwarn = 0; /* init */ if (cmflag != 0 && cmflag != 1) cmflag = 0; /* default */ if (reduction != 1 && reduction != 2 && reduction != 4 && reduction != 8) return (PIX *)ERROR_PTR("reduction not in {1,2,4,8}", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (PIX *)ERROR_PTR("image file not found", procName, NULL); pix = pixReadStreamJpeg(fp, cmflag, reduction, pnwarn, 0); fclose(fp); if (!pix) return (PIX *)ERROR_PTR("image not returned", procName, NULL); return pix; }
static l_int32 test_8bpp_trans(L_REGPARAMS *rp) { l_int32 same, transp; FILE *fp; PIX *pix1, *pix2, *pix3; PIXCMAP *cmap; pix1 = pixRead("wyom.jpg"); pix2 = pixColorSegment(pix1, 75, 10, 8, 7); cmap = pixGetColormap(pix2); pixcmapSetAlpha(cmap, 0, 0); /* set blueish sky color to transparent */ pixWrite("/tmp/regout/8bpp-trans.png", pix2, IFF_PNG); pix3 = pixRead("/tmp/regout/8bpp-trans.png"); pixEqual(pix2, pix3, &same); if (same) fprintf(stderr, "8bpp_trans: success\n"); else fprintf(stderr, "8bpp_trans: bad output\n"); pixDisplayWithTitle(pix3, 700, 0, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); fp = fopenReadStream("/tmp/regout/8bpp-trans.png"); fgetPngColormapInfo(fp, &cmap, &transp); fclose(fp); if (transp) fprintf(stderr, "8bpp_trans: correct -- transparency found\n"); else fprintf(stderr, "8bpp_trans: error -- no transparency found!\n"); if (rp->display) pixcmapWriteStream(stderr, cmap); pixcmapDestroy(&cmap); return same; }
/*! * \brief readHeaderPnm() * * \param[in] filename * \param[out] pw [optional] * [out] ph ([optional] * [out] pd ([optional] * [out] ptype ([optional] pnm type * \param[out] pbps [optional] bits/sample * \param[out] pspp [optional] samples/pixel * \return 0 if OK, 1 on error */ l_int32 readHeaderPnm(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pd, l_int32 *ptype, l_int32 *pbps, l_int32 *pspp) { l_int32 ret; FILE *fp; PROCNAME("readHeaderPnm"); if (pw) *pw = 0; if (ph) *ph = 0; if (pd) *pd = 0; if (ptype) *ptype = 0; if (pbps) *pbps = 0; if (pspp) *pspp = 0; if (!filename) return ERROR_INT("filename not defined", procName, 1); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); ret = freadHeaderPnm(fp, pw, ph, pd, ptype, pbps, pspp); fclose(fp); return ret; }
/*! * pixRead() * * Input: filename (with full pathname or in local directory) * Return: pix if OK; null on error * * Notes: * (1) See at top of file for supported formats. */ PIX * pixRead(const char *filename) { FILE *fp; PIX *pix; PROCNAME("pixRead"); if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) { L_ERROR("image file not found: %s\n", procName, filename); return NULL; } if ((pix = pixReadStream(fp, 0)) == NULL) { fclose(fp); return (PIX *)ERROR_PTR("pix not read", procName, NULL); } /* Close the stream except if GIF under windows, because * DGifCloseFile() closes the windows file stream! */ if (pixGetInputFormat(pix) != IFF_GIF) fclose(fp); #ifndef _WIN32 else /* gif file */ fclose(fp); #endif /* ! _WIN32 */ return pix; }
/*! * \brief readHeaderJpeg() * * \param[in] filename * \param[out] pw [optional] * [out] ph ([optional] * [out] pspp ([optional] samples/pixel * \param[out] pycck [optional] 1 if ycck color space; 0 otherwise * \param[out] pcmyk [optional] 1 if cmyk color space; 0 otherwise * \return 0 if OK, 1 on error */ l_int32 readHeaderJpeg(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pspp, l_int32 *pycck, l_int32 *pcmyk) { l_int32 ret; FILE *fp; PROCNAME("readHeaderJpeg"); if (pw) *pw = 0; if (ph) *ph = 0; if (pspp) *pspp = 0; if (pycck) *pycck = 0; if (pcmyk) *pcmyk = 0; if (!filename) return ERROR_INT("filename not defined", procName, 1); if (!pw && !ph && !pspp && !pycck && !pcmyk) return ERROR_INT("no results requested", procName, 1); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); ret = freadHeaderJpeg(fp, pw, ph, pspp, pycck, pcmyk); fclose(fp); return ret; }
/* * writeImageCompressedToPSFile() * * Input: filein (input image file) * fileout (output ps file) * res (output printer resolution) * &firstfile (<input and return> 1 if the first image; * 0 otherwise) * &index (<input and return> index of image in output ps file) * Return: 0 if OK, 1 on error * * Notes: * (1) This wraps a single page image in PS. * (2) The input file can be in any format. It is compressed as follows: * * if in tiffg4 --> use ccittg4 * * if in jpeg --> use dct * * all others --> use flate * (3) @index is incremented if the page is successfully written. */ l_int32 writeImageCompressedToPSFile(const char *filein, const char *fileout, l_int32 res, l_int32 *pfirstfile, l_int32 *pindex) { const char *op; l_int32 format, retval; FILE *fp; PROCNAME("writeImageCompressedToPSFile"); if (!pfirstfile || !pindex) return ERROR_INT("&firstfile and &index not defined", procName, 1); if ((fp = fopenReadStream(filein)) == NULL) return ERROR_INT("filein not found", procName, 1); findFileFormat(fp, &format); fclose(fp); if (format == IFF_UNKNOWN) { L_ERROR_STRING("Format of %s not known", procName, filein); return 1; } op = (*pfirstfile == TRUE) ? "w" : "a"; if (format == IFF_JFIF_JPEG) { retval = convertJpegToPS(filein, fileout, op, 0, 0, res, 1.0, *pindex + 1, TRUE); if (retval == 0) { *pfirstfile = FALSE; (*pindex)++; } } else if (format == IFF_TIFF_G4) { retval = convertTiffG4ToPS(filein, fileout, op, 0, 0, res, 1.0, *pindex + 1, FALSE, TRUE); if (retval == 0) { *pfirstfile = FALSE; (*pindex)++; } } else { /* all other image formats */ retval = convertFlateToPS(filein, fileout, op, 0, 0, res, 1.0, *pindex + 1, TRUE); if (retval == 0) { *pfirstfile = FALSE; (*pindex)++; } } return retval; }
/* leptonica 1.62 doesn't have this function yet, so here it is. */ int fileformat(char *filename){ FILE *fp; int format; if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", "fileformat", 1); #ifdef NEWLEPT findFileFormat(filename,&format); #else format=findFileFormat(fp); #endif fclose(fp); return format; }
/*! * \brief l_getIndexFromFile() * * \param[in] filename * \param[out] pindex found index * \return 0 if found, 1 on error. */ static l_int32 l_getIndexFromFile(const char *filename, l_int32 *pindex) { char buf[256]; char *word; FILE *fp; l_int32 notfound, format; SARRAY *sa; PROCNAME("l_getIndexFromFile"); if (!pindex) return ERROR_INT("&index not defined", procName, 1); *pindex = 0; if (!filename) return ERROR_INT("filename not defined", procName, 1); /* Open the stream, read lines until you find one with more * than a newline, and grab the first word. */ if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("stream not opened", procName, 1); do { if ((fgets(buf, sizeof(buf), fp)) == NULL) { fclose(fp); return ERROR_INT("fgets read fail", procName, 1); } } while (buf[0] == '\n'); fclose(fp); sa = sarrayCreateWordsFromString(buf); word = sarrayGetString(sa, 0, L_NOCOPY); /* Find the index associated with the word. If it is not * found, test to see if the file is a compressed pix. */ notfound = l_getIndexFromStructname(word, pindex); sarrayDestroy(&sa); if (notfound) { /* maybe a Pix */ if (findFileFormat(filename, &format) == 0) { l_getIndexFromStructname("Pix", pindex); } else { return ERROR_INT("no file type identified", procName, 1); } } return 0; }
/*! * l_byteaInitFromFile() * * Input: fname * Return: l_bytea, or null on error */ L_BYTEA * l_byteaInitFromFile(const char *fname) { FILE *fp; L_BYTEA *ba; PROCNAME("l_byteaInitFromFile"); if (!fname) return (L_BYTEA *)ERROR_PTR("fname not defined", procName, NULL); if ((fp = fopenReadStream(fname)) == NULL) return (L_BYTEA *)ERROR_PTR("file stream not opened", procName, NULL); if ((ba = l_byteaInitFromStream(fp)) == NULL) return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL); fclose(fp); return ba; }
/*! * kernelRead() * * Input: filename * Return: kernel, or null on error */ L_KERNEL * kernelRead(const char *fname) { FILE *fp; L_KERNEL *kel; PROCNAME("kernelRead"); if (!fname) return (L_KERNEL *)ERROR_PTR("fname not defined", procName, NULL); if ((fp = fopenReadStream(fname)) == NULL) return (L_KERNEL *)ERROR_PTR("stream not opened", procName, NULL); if ((kel = kernelReadStream(fp)) == NULL) return (L_KERNEL *)ERROR_PTR("kel not returned", procName, NULL); fclose(fp); return kel; }
/*! * \brief numaaRead() * * \param[in] filename * \return naa, or NULL on error */ NUMAA * numaaRead(const char *filename) { FILE *fp; NUMAA *naa; PROCNAME("numaaRead"); if (!filename) return (NUMAA *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (NUMAA *)ERROR_PTR("stream not opened", procName, NULL); naa = numaaReadStream(fp); fclose(fp); if (!naa) return (NUMAA *)ERROR_PTR("naa not read", procName, NULL); return naa; }
/*! * pixaaRead() * * Input: filename * Return: pixaa, or null on error * * Notes: * (1) The pix are stored in the file as png. */ PIXAA * pixaaRead(const char *filename) { FILE *fp; PIXAA *pixaa; PROCNAME("pixaaRead"); if (!filename) return (PIXAA *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (PIXAA *)ERROR_PTR("stream not opened", procName, NULL); if ((pixaa = pixaaReadStream(fp)) == NULL) { fclose(fp); return (PIXAA *)ERROR_PTR("pixaa not read", procName, NULL); } fclose(fp); return pixaa; }
/*! * findFileFormat() * * Input: filename * &format (<return>) * Return: 0 if OK, 1 on error or if format is not recognized */ l_int32 findFileFormat(const char *filename, l_int32 *pformat) { l_int32 ret; FILE *fp; PROCNAME("findFileFormat"); if (!pformat) return ERROR_INT("&format not defined", procName, 1); *pformat = IFF_UNKNOWN; if (!filename) return ERROR_INT("filename not defined", procName, 1); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); ret = findFileFormatStream(fp, pformat); fclose(fp); return ret; }
/*! * dewarpRead() * * Input: filename * Return: dew, or null on error */ L_DEWARP * dewarpRead(const char *filename) { FILE *fp; L_DEWARP *dew; PROCNAME("dewarpRead"); if (!filename) return (L_DEWARP *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL); if ((dew = dewarpReadStream(fp)) == NULL) { fclose(fp); return (L_DEWARP *)ERROR_PTR("dew not read", procName, NULL); } fclose(fp); return dew; }
/*! * boxaaReadVersion2() * * Input: filename * Return: boxaa, or null on error * * Notes: * (1) These old functions only work on version 2 boxaa. * They will go to an archive directory sometime after Sept 2009. * (2) The current format uses BOXAA_VERSION_NUMBER == 3) */ BOXAA * boxaaReadVersion2(const char *filename) { FILE *fp; BOXAA *baa; PROCNAME("boxaaReadVersion2"); if (!filename) return (BOXAA *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (BOXAA *)ERROR_PTR("stream not opened", procName, NULL); if ((baa = boxaaReadStreamVersion2(fp)) == NULL) { fclose(fp); return (BOXAA *)ERROR_PTR("boxaa not read", procName, NULL); } fclose(fp); return baa; }
/*! * pixReadWithHint() * * Input: filename (with full pathname or in local directory) * hint (bitwise OR of L_HINT_* values for jpeg; use 0 for no hint) * Return: pix if OK; null on error * * Notes: * (1) The hint is not binding, but may be used to optimize jpeg decoding. * Use 0 for no hinting. */ PIX * pixReadWithHint(const char *filename, l_int32 hint) { FILE *fp; PIX *pix; PROCNAME("pixReadWithHint"); if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (PIX *)ERROR_PTR("image file not found", procName, NULL); pix = pixReadStream(fp, hint); fclose(fp); if (!pix) return (PIX *)ERROR_PTR("image not returned", procName, NULL); return pix; }
/*! * \brief recogRead() * * \param[in] filename * \return recog, or NULL on error * * <pre> * Notes: * (1) When a recog is serialized, a pixaa of the templates that are * actually used for correlation is saved in the pixaa_u array * of the recog. These can be different from the templates that * were used to generate the recog, because those original templates * can be scaled and turned into normalized lines. When recog1 * is deserialized to recog2, these templates are put in both the * unscaled array (pixaa_u) and the modified array (pixaa) in recog2. * Why not put it in only the unscaled array and let * recogTrainingFinalized() regenerate the modified templates? * The reason is that with normalized lines, the operation of * thinning to a skeleton and dilating back to a fixed width * is not idempotent. Thinning to a skeleton saves pixels at * the end of a line segment, and thickening the skeleton puts * additional pixels at the end of the lines. This tends to * close gaps. * </pre> */ L_RECOG * recogRead(const char *filename) { FILE *fp; L_RECOG *recog; PROCNAME("recogRead"); if (!filename) return (L_RECOG *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (L_RECOG *)ERROR_PTR("stream not opened", procName, NULL); if ((recog = recogReadStream(fp)) == NULL) { fclose(fp); return (L_RECOG *)ERROR_PTR("recog not read", procName, NULL); } fclose(fp); return recog; }
/*! * sarrayRead() * * Input: filename * Return: sarray, or null on error */ SARRAY * sarrayRead(const char *filename) { FILE *fp; SARRAY *sa; PROCNAME("sarrayRead"); if (!filename) return (SARRAY *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL); if ((sa = sarrayReadStream(fp)) == NULL) { fclose(fp); return (SARRAY *)ERROR_PTR("sa not read", procName, NULL); } fclose(fp); return sa; }
/*! * l_dnaRead() * * Input: filename * Return: da, or null on error */ L_DNA * l_dnaRead(const char *filename) { FILE *fp; L_DNA *da; PROCNAME("l_dnaRead"); if (!filename) return (L_DNA *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (L_DNA *)ERROR_PTR("stream not opened", procName, NULL); if ((da = l_dnaReadStream(fp)) == NULL) { fclose(fp); return (L_DNA *)ERROR_PTR("da not read", procName, NULL); } fclose(fp); return da; }
/*! * pixRead() * * Input: filename (with full pathname or in local directory) * Return: pix if OK; null on error * * Notes: * (1) See at top of file for supported formats. */ PIX * pixRead(const char *filename) { FILE *fp; PIX *pix; PROCNAME("pixRead"); if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) { L_ERROR("image file not found: %s\n", procName, filename); return NULL; } if ((pix = pixReadStream(fp, 0)) == NULL) { fclose(fp); return (PIX *)ERROR_PTR("pix not read", procName, NULL); } fclose(fp); return pix; }
/*! * readHeaderPng() * * Input: filename * &width (<return>) * &height (<return>) * &bps (<return>, bits/sample) * &spp (<return>, samples/pixel) * &iscmap (<optional return>; input NULL to ignore) * Return: 0 if OK, 1 on error * * Notes: * (1) If there is a colormap, iscmap is returned as 1; else 0. */ l_int32 readHeaderPng(const char *filename, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap) { l_int32 ret; FILE *fp; PROCNAME("readHeaderPng"); if (!filename) return ERROR_INT("filename not defined", procName, 1); if (!pwidth || !pheight || !pbps || !pspp) return ERROR_INT("input ptr(s) not defined", procName, 1); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); ret = freadHeaderPng(fp, pwidth, pheight, pbps, pspp, piscmap); fclose(fp); return ret; }
/*! * \brief pixReadJpeg() * * \param[in] filename * \param[in] cmapflag 0 for no colormap in returned pix; * 1 to return an 8 bpp cmapped pix if spp = 3 or 4 * \param[in] reduction scaling factor: 1, 2, 4 or 8 * \param[out] pnwarn [optional] number of warnings about * corrupted data * \param[in] hint a bitwise OR of L_JPEG_* values; 0 for default * \return pix, or NULL on error * * <pre> * Notes: * (1) This is a special function for reading jpeg files. * (2) Use this if you want the jpeg library to create * an 8 bpp colormapped image. * (3) Images reduced by factors of 2, 4 or 8 can be returned * significantly faster than full resolution images. * (4) If the jpeg data is bad, the jpeg library will continue * silently, or return warnings, or attempt to exit. Depending * on the severity of the data corruption, there are two possible * outcomes: * (a) a possibly damaged pix can be generated, along with zero * or more warnings, or * (b) the library will attempt to exit (caught by our error * handler) and no pix will be returned. * If a pix is generated with at least one warning of data * corruption, and if L_JPEG_FAIL_ON_BAD_DATA is included in %hint, * no pix will be returned. * (5) The possible hint values are given in the enum in imageio.h: * * L_JPEG_READ_LUMINANCE * * L_JPEG_FAIL_ON_BAD_DATA * Default (0) is to do neither. * </pre> */ PIX * pixReadJpeg(const char *filename, l_int32 cmapflag, l_int32 reduction, l_int32 *pnwarn, l_int32 hint) { l_int32 ret; l_uint8 *comment; FILE *fp; PIX *pix; PROCNAME("pixReadJpeg"); if (pnwarn) *pnwarn = 0; if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); if (cmapflag != 0 && cmapflag != 1) cmapflag = 0; /* default */ if (reduction != 1 && reduction != 2 && reduction != 4 && reduction != 8) return (PIX *)ERROR_PTR("reduction not in {1,2,4,8}", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (PIX *)ERROR_PTR("image file not found", procName, NULL); pix = pixReadStreamJpeg(fp, cmapflag, reduction, pnwarn, hint); if (pix) { ret = fgetJpegComment(fp, &comment); if (!ret && comment) pixSetText(pix, (char *)comment); LEPT_FREE(comment); } fclose(fp); if (!pix) return (PIX *)ERROR_PTR("image not returned", procName, NULL); return pix; }
/*! * pixReadJp2k() * * Input: filename * reduction (scaling factor: 1, 2, 4, 8, 16) * box (<optional> for extracting a subregion), can be null * hint (a bitwise OR of L_JP2K_* values; 0 for default) * debug (output callback messages, etc) * Return: pix (8 or 32 bpp), or null on error * * Notes: * (1) This is a special function for reading jp2k files. * The high-level pixReadStream() uses default values: * @reduction = 1 * @box = NULL * (2) This decodes at either full resolution or at a reduction by * a power of 2. The default value @reduction == 1 gives a full * resolution image. Use @reduction > 1 to get a reduced image. * The actual values of @reduction that can be used on an image * depend on the number of resolution levels chosen when the * image was compressed. Typical values might be 1, 2, 4, 8 and 16. * Using a value representing a reduction level that was not * stored when the file was written will fail with the message: * "failed to read the header". * (3) Use @box to decode only a part of the image. The box is defined * at full resolution. It is reduced internally by @reduction, * and clipping to the right and bottom of the image is automatic. * (4) We presently only handle images with 8 bits/sample (bps). * If the image has 16 bps, the read will fail. * (5) There are 4 possible values of samples/pixel (spp). * The values in brackets give the pixel values in the Pix: * spp = 1 ==> grayscale [8 bpp grayscale] * spp = 2 ==> grayscale + alpha [32 bpp rgba] * spp = 3 ==> rgb [32 bpp rgb] * spp = 4 ==> rgba [32 bpp rgba] * (6) The @hint parameter is reserved for future use. */ PIX * pixReadJp2k(const char *filename, l_uint32 reduction, BOX *box, l_int32 hint, l_int32 debug) { FILE *fp; PIX *pix; PROCNAME("pixReadJp2k"); if (!filename) return (PIX *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (PIX *)ERROR_PTR("image file not found", procName, NULL); pix = pixReadStreamJp2k(fp, reduction, box, hint, debug); fclose(fp); if (!pix) return (PIX *)ERROR_PTR("image not returned", procName, NULL); return pix; }
int main(int argc, char **argv) { l_uint8 *data; l_int32 w, h, n1, n2, n, i, minval, maxval; l_int32 ncolors, rval, gval, bval, equal; l_int32 *rmap, *gmap, *bmap; l_uint32 color; l_float32 gamma; BOX *box; FILE *fp; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; PIX *pixs, *pixb, *pixg, *pixc, *pixd; PIX *pixg2, *pixcs1, *pixcs2, *pixd1, *pixd2; PIXA *pixa, *pixa2, *pixa3; PIXCMAP *cmap, *cmap2; RGBA_QUAD *cta; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ------------------------ (1) ----------------------------*/ /* Blend with a white background */ pix1 = pixRead("books_logo.png"); pixDisplayWithTitle(pix1, 100, 0, NULL, rp->display); pix2 = pixAlphaBlendUniform(pix1, 0xffffff00); pixDisplayWithTitle(pix2, 100, 150, NULL, rp->display); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 0 */ regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 1 */ /* Generate an alpha layer based on the white background */ pix3 = pixSetAlphaOverWhite(pix2); pixSetSpp(pix3, 3); pixWrite("/tmp/alphaops.2.png", pix3, IFF_PNG); /* without alpha */ regTestCheckFile(rp, "/tmp/alphaops.2.png"); /* 2 */ pixSetSpp(pix3, 4); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 3, with alpha */ pixDisplayWithTitle(pix3, 100, 300, NULL, rp->display); /* Render on a light yellow background */ pix4 = pixAlphaBlendUniform(pix3, 0xffffe000); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 4 */ pixDisplayWithTitle(pix4, 100, 450, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); /* ------------------------ (2) ----------------------------*/ lept_rmdir("alpha"); lept_mkdir("alpha"); /* Make the transparency (alpha) layer. * pixs is the mask. We turn it into a transparency (alpha) * layer by converting to 8 bpp. A small convolution fuzzes * the mask edges so that you don't see the pixels. */ pixs = pixRead("feyn-fract.tif"); pixGetDimensions(pixs, &w, &h, NULL); pixg = pixConvert1To8(NULL, pixs, 0, 255); pixg2 = pixBlockconvGray(pixg, NULL, 1, 1); regTestWritePixAndCheck(rp, pixg2, IFF_JFIF_JPEG); /* 5 */ pixDisplayWithTitle(pixg2, 0, 0, "alpha", rp->display); /* Make the viewable image. * pixc is the image that we see where the alpha layer is * opaque -- i.e., greater than 0. Scale it to the same * size as the mask. To visualize what this will look like * when displayed over a black background, create the black * background image, pixb, and do the blending with pixcs1 * explicitly using the alpha layer pixg2. */ pixc = pixRead("tetons.jpg"); pixcs1 = pixScaleToSize(pixc, w, h); regTestWritePixAndCheck(rp, pixcs1, IFF_JFIF_JPEG); /* 6 */ pixDisplayWithTitle(pixcs1, 300, 0, "viewable", rp->display); pixb = pixCreateTemplate(pixcs1); /* black */ pixd1 = pixBlendWithGrayMask(pixb, pixcs1, pixg2, 0, 0); regTestWritePixAndCheck(rp, pixd1, IFF_JFIF_JPEG); /* 7 */ pixDisplayWithTitle(pixd1, 600, 0, "alpha-blended 1", rp->display); /* Embed the alpha layer pixg2 into the color image pixc. * Write it out as is. Then clean pixcs1 (to 0) under the fully * transparent part of the alpha layer, and write that result * out as well. */ pixSetRGBComponent(pixcs1, pixg2, L_ALPHA_CHANNEL); pixWrite("/tmp/alpha/pixcs1.png", pixcs1, IFF_PNG); pixcs2 = pixSetUnderTransparency(pixcs1, 0, 0); pixWrite("/tmp/alpha/pixcs2.png", pixcs2, IFF_PNG); /* What will this look like over a black background? * Do the blending explicitly and display. It should * look identical to the blended result pixd1 before cleaning. */ pixd2 = pixBlendWithGrayMask(pixb, pixcs2, pixg2, 0, 0); regTestWritePixAndCheck(rp, pixd2, IFF_JFIF_JPEG); /* 8 */ pixDisplayWithTitle(pixd2, 0, 400, "alpha blended 2", rp->display); /* Read the two images back, ignoring the transparency layer. * The uncleaned image will come back identical to pixcs1. * However, the cleaned image will be black wherever * the alpha layer was fully transparent. It will * look the same when viewed through the alpha layer, * but have much better compression. */ pix1 = pixRead("/tmp/alpha/pixcs1.png"); /* just pixcs1 */ pix2 = pixRead("/tmp/alpha/pixcs2.png"); /* cleaned under transparent */ n1 = nbytesInFile("/tmp/alpha/pixcs1.png"); n2 = nbytesInFile("/tmp/alpha/pixcs2.png"); fprintf(stderr, " Original: %d bytes\n Cleaned: %d bytes\n", n1, n2); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 9 */ regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 10 */ pixDisplayWithTitle(pix1, 300, 400, "without alpha", rp->display); pixDisplayWithTitle(pix2, 600, 400, "cleaned under transparent", rp->display); pixa = pixaCreate(0); pixSaveTiled(pixg2, pixa, 1.0, 1, 20, 32); pixSaveTiled(pixcs1, pixa, 1.0, 1, 20, 0); pixSaveTiled(pix1, pixa, 1.0, 0, 20, 0); pixSaveTiled(pixd1, pixa, 1.0, 1, 20, 0); pixSaveTiled(pixd2, pixa, 1.0, 0, 20, 0); pixSaveTiled(pix2, pixa, 1.0, 1, 20, 0); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 11 */ pixDisplayWithTitle(pixd, 200, 200, "composite", rp->display); pixWrite("/tmp/alpha/alpha.png", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixb); pixDestroy(&pixg); pixDestroy(&pixg2); pixDestroy(&pixc); pixDestroy(&pixcs1); pixDestroy(&pixcs2); pixDestroy(&pixd); pixDestroy(&pixd1); pixDestroy(&pixd2); pixDestroy(&pix1); pixDestroy(&pix2); /* ------------------------ (3) ----------------------------*/ color = 0xffffa000; gamma = 1.0; minval = 0; maxval = 200; box = boxCreate(0, 85, 600, 100); pixa = pixaCreate(6); pix1 = pixRead("blend-green1.jpg"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-green2.png"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-green3.png"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-orange.jpg"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-yellow.jpg"); pixaAddPix(pixa, pix1, L_INSERT); pix1 = pixRead("blend-red.png"); pixaAddPix(pixa, pix1, L_INSERT); n = pixaGetCount(pixa); pixa2 = pixaCreate(n); pixa3 = pixaCreate(n); for (i = 0; i < n; i++) { pix1 = pixaGetPix(pixa, i, L_CLONE); pix2 = DoBlendTest(pix1, box, color, gamma, minval, maxval, 1); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 12, 14, ... 22 */ pixDisplayWithTitle(pix2, 150 * i, 0, NULL, rp->display); pixaAddPix(pixa2, pix2, L_INSERT); pix2 = DoBlendTest(pix1, box, color, gamma, minval, maxval, 2); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 13, 15, ... 23 */ pixDisplayWithTitle(pix2, 150 * i, 200, NULL, rp->display); pixaAddPix(pixa3, pix2, L_INSERT); pixDestroy(&pix1); } if (rp->display) { pixaConvertToPdf(pixa2, 0, 0.75, L_FLATE_ENCODE, 0, "blend 1 test", "/tmp/alpha/blending1.pdf"); pixaConvertToPdf(pixa3, 0, 0.75, L_FLATE_ENCODE, 0, "blend 2 test", "/tmp/alpha/blending2.pdf"); } pixaDestroy(&pixa); pixaDestroy(&pixa2); pixaDestroy(&pixa3); boxDestroy(&box); /* ------------------------ (4) ----------------------------*/ /* Use one image as the alpha component for a second image */ pix1 = pixRead("test24.jpg"); pix2 = pixRead("marge.jpg"); pix3 = pixScale(pix2, 1.9, 2.2); pix4 = pixConvertTo8(pix3, 0); pixSetRGBComponent(pix1, pix4, L_ALPHA_CHANNEL); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 24 */ pixDisplayWithTitle(pix1, 600, 0, NULL, rp->display); /* Set the alpha value in a colormap to bval */ pix5 = pixOctreeColorQuant(pix1, 128, 0); cmap = pixGetColormap(pix5); pixcmapToArrays(cmap, &rmap, &gmap, &bmap, NULL); n = pixcmapGetCount(cmap); for (i = 0; i < n; i++) { pixcmapGetColor(cmap, i, &rval, &gval, &bval); cta = (RGBA_QUAD *)cmap->array; cta[i].alpha = bval; } /* Test binary serialization/deserialization of colormap with alpha */ pixcmapSerializeToMemory(cmap, 4, &ncolors, &data); cmap2 = pixcmapDeserializeFromMemory(data, 4, ncolors); CmapEqual(cmap, cmap2, &equal); regTestCompareValues(rp, TRUE, equal, 0.0); /* 25 */ pixcmapDestroy(&cmap2); lept_free(data); /* Test ascii serialization/deserialization of colormap with alpha */ fp = fopenWriteStream("/tmp/alpha/cmap.4", "w"); pixcmapWriteStream(fp, cmap); fclose(fp); fp = fopenReadStream("/tmp/alpha/cmap.4"); cmap2 = pixcmapReadStream(fp); fclose(fp); CmapEqual(cmap, cmap2, &equal); regTestCompareValues(rp, TRUE, equal, 0.0); /* 26 */ pixcmapDestroy(&cmap2); /* Test r/w for cmapped pix with non-opaque alpha */ pixDisplayWithTitle(pix5, 900, 0, NULL, rp->display); regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 27 */ pixWrite("/tmp/alpha/fourcomp.png", pix5, IFF_PNG); pix6 = pixRead("/tmp/alpha/fourcomp.png"); regTestComparePix(rp, pix5, pix6); /* 28 */ pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); lept_free(rmap); lept_free(gmap); lept_free(bmap); return regTestCleanup(rp); }
/*! * gplotRead() * * Input: filename * Return: gplot, or NULL on error */ GPLOT * gplotRead(const char *filename) { char buf[L_BUF_SIZE]; char *rootname, *title, *xlabel, *ylabel, *ignores; l_int32 outformat, ret, version, ignore; FILE *fp; GPLOT *gplot; PROCNAME("gplotRead"); if (!filename) return (GPLOT *)ERROR_PTR("filename not defined", procName, NULL); if ((fp = fopenReadStream(filename)) == NULL) return (GPLOT *)ERROR_PTR("stream not opened", procName, NULL); ret = fscanf(fp, "Gplot Version %d\n", &version); if (ret != 1) { fclose(fp); return (GPLOT *)ERROR_PTR("not a gplot file", procName, NULL); } if (version != GPLOT_VERSION_NUMBER) { fclose(fp); return (GPLOT *)ERROR_PTR("invalid gplot version", procName, NULL); } ignore = fscanf(fp, "Rootname: %s\n", buf); rootname = stringNew(buf); ignore = fscanf(fp, "Output format: %d\n", &outformat); ignores = fgets(buf, L_BUF_SIZE, fp); /* Title: ... */ title = stringNew(buf + 7); title[strlen(title) - 1] = '\0'; ignores = fgets(buf, L_BUF_SIZE, fp); /* X axis label: ... */ xlabel = stringNew(buf + 14); xlabel[strlen(xlabel) - 1] = '\0'; ignores = fgets(buf, L_BUF_SIZE, fp); /* Y axis label: ... */ ylabel = stringNew(buf + 14); ylabel[strlen(ylabel) - 1] = '\0'; if (!(gplot = gplotCreate(rootname, outformat, title, xlabel, ylabel))) { fclose(fp); return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL); } FREE(rootname); FREE(title); FREE(xlabel); FREE(ylabel); sarrayDestroy(&gplot->cmddata); sarrayDestroy(&gplot->datanames); sarrayDestroy(&gplot->plotdata); sarrayDestroy(&gplot->plottitles); numaDestroy(&gplot->plotstyles); ignore = fscanf(fp, "Commandfile name: %s\n", buf); stringReplace(&gplot->cmdname, buf); ignore = fscanf(fp, "\nCommandfile data:"); gplot->cmddata = sarrayReadStream(fp); ignore = fscanf(fp, "\nDatafile names:"); gplot->datanames = sarrayReadStream(fp); ignore = fscanf(fp, "\nPlot data:"); gplot->plotdata = sarrayReadStream(fp); ignore = fscanf(fp, "\nPlot titles:"); gplot->plottitles = sarrayReadStream(fp); ignore = fscanf(fp, "\nPlot styles:"); gplot->plotstyles = numaReadStream(fp); ignore = fscanf(fp, "Number of plots: %d\n", &gplot->nplots); ignore = fscanf(fp, "Output file name: %s\n", buf); stringReplace(&gplot->outname, buf); ignore = fscanf(fp, "Axis scaling: %d\n", &gplot->scaling); fclose(fp); return gplot; }
/*! * pixReadHeader() * * Input: filename (with full pathname or in local directory) * &format (<optional return> file format) * &w, &h (<optional returns> width and height) * &bps <optional return> bits/sample * &spp <optional return> samples/pixel (1, 3 or 4) * &iscmap (<optional return> 1 if cmap exists; 0 otherwise) * Return: 0 if OK, 1 on error * * Notes: * (1) This reads the actual headers for jpeg, png, tiff and pnm. * For bmp and gif, we cheat and read the entire file into a pix, * from which we extract the "header" information. */ l_int32 pixReadHeader(const char *filename, l_int32 *pformat, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap) { l_int32 format, ret, w, h, d, bps, spp, iscmap; l_int32 type; /* ignored */ FILE *fp; PIX *pix; PROCNAME("pixReadHeader"); if (pw) *pw = 0; if (ph) *ph = 0; if (pbps) *pbps = 0; if (pspp) *pspp = 0; if (piscmap) *piscmap = 0; if (pformat) *pformat = 0; iscmap = 0; /* init to false */ if (!filename) return ERROR_INT("filename not defined", procName, 1); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); findFileFormatStream(fp, &format); fclose(fp); switch (format) { case IFF_BMP: /* cheating: reading the entire file */ if ((pix = pixRead(filename)) == NULL) return ERROR_INT( "bmp: pix not read", procName, 1); pixGetDimensions(pix, &w, &h, &d); if (pixGetColormap(pix)) iscmap = 1; pixDestroy(&pix); bps = (d == 32) ? 8 : d; spp = (d == 32) ? 3 : 1; break; case IFF_JFIF_JPEG: ret = readHeaderJpeg(filename, &w, &h, &spp, NULL, NULL); bps = 8; if (ret) return ERROR_INT( "jpeg: no header info returned", procName, 1); break; case IFF_PNG: ret = readHeaderPng(filename, &w, &h, &bps, &spp, &iscmap); if (ret) return ERROR_INT( "png: no header info returned", procName, 1); break; case IFF_TIFF: case IFF_TIFF_PACKBITS: case IFF_TIFF_RLE: case IFF_TIFF_G3: case IFF_TIFF_G4: case IFF_TIFF_LZW: case IFF_TIFF_ZIP: /* Reading page 0 by default; possibly redefine format */ ret = readHeaderTiff(filename, 0, &w, &h, &bps, &spp, NULL, &iscmap, &format); if (ret) return ERROR_INT( "tiff: no header info returned", procName, 1); break; case IFF_PNM: ret = readHeaderPnm(filename, &w, &h, &d, &type, &bps, &spp); if (ret) return ERROR_INT( "pnm: no header info returned", procName, 1); break; case IFF_GIF: /* cheating: reading the entire file */ if ((pix = pixRead(filename)) == NULL) return ERROR_INT( "gif: pix not read", procName, 1); pixGetDimensions(pix, &w, &h, &d); pixDestroy(&pix); iscmap = 1; /* always colormapped; max 256 colors */ spp = 1; bps = d; break; case IFF_JP2: ret = readHeaderJp2k(filename, &w, &h, &bps, &spp); break; case IFF_WEBP: if (readHeaderWebP(filename, &w, &h, &spp)) return ERROR_INT( "webp: no header info returned", procName, 1); bps = 8; break; case IFF_SPIX: ret = readHeaderSpix(filename, &w, &h, &bps, &spp, &iscmap); if (ret) return ERROR_INT( "spix: no header info returned", procName, 1); break; case IFF_UNKNOWN: L_ERROR("unknown format in file %s\n", procName, filename); return 1; break; } if (pw) *pw = w; if (ph) *ph = h; if (pbps) *pbps = bps; if (pspp) *pspp = spp; if (piscmap) *piscmap = iscmap; if (pformat) *pformat = format; return 0; }