/*!
 *  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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/*!
 *  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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/*!
 * \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;
}
Beispiel #7
0
/*!
 *  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;
}
Beispiel #8
0
/*!
 * \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;
}
Beispiel #9
0
/*
 *  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;
}
Beispiel #10
0
/* 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;
}
Beispiel #12
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;
}
Beispiel #13
0
/*!
 *  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;
}
Beispiel #14
0
/*!
 * \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;
}
Beispiel #16
0
/*!
 *  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;
}
Beispiel #17
0
/*!
 *  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;
}
Beispiel #19
0
/*!
 *  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;
}
Beispiel #20
0
/*!
 * \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;
}
Beispiel #22
0
/*!
 *  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;
}
Beispiel #23
0
/*!
 *  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;
}
Beispiel #24
0
/*!
 *  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;
}
Beispiel #25
0
/*!
 * \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;
}
Beispiel #26
0
/*!
 *  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;
}
Beispiel #27
0
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);
}
Beispiel #28
0
/*!
 *  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;
}
Beispiel #29
0
/*!
 *  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;
}