Example #1
0
/*!
 *  findFileFormatStream()
 *
 *      Input:  fp (file stream)
 *              &format (<return>)
 *      Return: 0 if OK, 1 on error or if format is not recognized
 *
 *  Notes:
 *      (1) Important: Side effect -- this resets fp to BOF.
 */
l_int32
findFileFormatStream(FILE     *fp,
                     l_int32  *pformat)
{
l_uint8  firstbytes[12];
l_int32  format;

    PROCNAME("findFileFormatStream");

    if (!pformat)
        return ERROR_INT("&format not defined", procName, 1);
    *pformat = IFF_UNKNOWN;
    if (!fp)
        return ERROR_INT("stream not defined", procName, 1);

    rewind(fp);
    if (fnbytesInFile(fp) < 12)
        return ERROR_INT("truncated file", procName, 1);

    if (fread((char *)&firstbytes, 1, 12, fp) != 12)
        return ERROR_INT("failed to read first 12 bytes of file", procName, 1);
    rewind(fp);

    findFileFormatBuffer(firstbytes, &format);
    if (format == IFF_TIFF) {
        findTiffCompression(fp, &format);
        rewind(fp);
    }
    *pformat = format;
    if (format == IFF_UNKNOWN)
        return 1;
    else
        return 0;
}
Example #2
0
/*!
 *  sreadHeaderJp2k()
 *
 *      Input:  data
 *              size
 *              &w (<optional return>)
 *              &h (<optional return>)
 *              &spp (<optional return>, samples/pixel)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) The metadata is stored as follows:
 *          h:    4 bytes @ 48
 *          w:    4 bytes @ 52
 *          spp:  2 bytes @ 56
 */
l_int32
sreadHeaderJp2k(const l_uint8  *data,
                size_t          size,
                l_int32        *pw,
                l_int32        *ph,
                l_int32        *pspp)
{
l_int32  format, val, w, h, spp;

    PROCNAME("sreadHeaderJp2k");

    if (pw) *pw = 0;
    if (ph) *ph = 0;
    if (pspp) *pspp = 0;
    if (!data)
        return ERROR_INT("data not defined", procName, 1);
    if (size < 60)
        return ERROR_INT("size < 60", procName, 1);
    findFileFormatBuffer(data, &format);
    if (format != IFF_JP2)
        return ERROR_INT("not jp2 file", procName, 1);

    val = *((l_uint32 *)data + 12);
    h = convertOnLittleEnd32(val);
    val = *((l_uint32 *)data + 13);
    w = convertOnLittleEnd32(val);
    val = *((l_uint16 *)data + 28);
    spp = convertOnLittleEnd16(val);
    if (w > MAX_JP2K_WIDTH || h > MAX_JP2K_HEIGHT)
        return ERROR_INT("unrealistically large sizes", procName, 1);
    if (pw) *pw = w;
    if (ph) *ph = h;
    if (pspp) *pspp = spp;
    return 0;
}
Example #3
0
/*!
 *  readHeaderMemJp2k()
 *
 *      Input:  data
 *              size (at least 80)
 *              &w (<optional return>)
 *              &h (<optional return>)
 *              &bps (<optional return>, bits/sample)
 *              &spp (<optional return>, samples/pixel)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) The ISO/IEC reference for jpeg2000 is
 *               http://www.jpeg.org/public/15444-1annexi.pdf
 *          and the file format syntax begins at page 127.
 *      (2) The Image Header Box begins with 'ihdr' = 0x69686472 in
 *          big-endian order.  This typically, but not always, starts
 *          byte 44, with the big-endian data fields beginning at byte 48:
 *               h:    4 bytes
 *               w:    4 bytes
 *               spp:  2 bytes
 *               bps:  1 byte   (contains bps - 1)
 */
l_int32
readHeaderMemJp2k(const l_uint8  *data,
                  size_t          size,
                  l_int32        *pw,
                  l_int32        *ph,
                  l_int32        *pbps,
                  l_int32        *pspp)
{
l_int32  format, val, w, h, bps, spp, loc, found, windex;
l_uint8  ihdr[4] = {0x69, 0x68, 0x64, 0x72};  /* 'ihdr' */

    PROCNAME("readHeaderMemJp2k");

    if (pw) *pw = 0;
    if (ph) *ph = 0;
    if (pbps) *pbps = 0;
    if (pspp) *pspp = 0;
    if (!data)
        return ERROR_INT("data not defined", procName, 1);
    if (size < 80)
        return ERROR_INT("size < 80", procName, 1);
    findFileFormatBuffer(data, &format);
    if (format != IFF_JP2)
        return ERROR_INT("not jp2 file", procName, 1);

        /* Search for beginning of the Image Header Box: 'ihdr' */
    arrayFindSequence(data, size, ihdr, 4, &loc, &found);
    if (!found)
        return ERROR_INT("image parameters not found", procName, 1);
    if (loc != 44)
        L_INFO("Beginning of ihdr is at byte %d\n", procName, loc);

    windex = loc / 4 + 1;
    val = *((l_uint32 *)data + windex);
    h = convertOnLittleEnd32(val);
    val = *((l_uint32 *)data + windex + 1);
    w = convertOnLittleEnd32(val);
    val = *((l_uint16 *)data + 2 * (windex + 2));
    spp = convertOnLittleEnd16(val);
    bps = *(data + 4 * (windex + 2) + 2) + 1;
    if (w > MAX_JP2K_WIDTH || h > MAX_JP2K_HEIGHT)
        return ERROR_INT("unrealistically large sizes", procName, 1);
    if (pw) *pw = w;
    if (ph) *ph = h;
    if (pbps) *pbps = bps;
    if (pspp) *pspp = spp;
    return 0;
}
Example #4
0
/*!
 *  pixReadHeaderMem()
 *
 *      Input:  data (const; encoded)
 *              datasize (size of data)
 *              &format (<optional returns> image 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, jp2k and pnm.
 *          For bmp and gif, we cheat and read all the data into a pix,
 *          from which we extract the "header" information.
 *      (2) The amount of data required depends on the format.  For
 *          png, it requires less than 30 bytes, but for jpeg it can
 *          require most of the compressed file.  In practice, the data
 *          is typically the entire compressed file in memory.
 *      (3) findFileFormatBuffer() requires up to 8 bytes to decide on
 *          the format, which we require.
 */
l_int32
pixReadHeaderMem(const l_uint8  *data,
                 size_t          size,
                 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;  /* not used */
PIX     *pix;

    PROCNAME("pixReadHeaderMem");

    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 (!data)
        return ERROR_INT("data not defined", procName, 1);
    if (size < 8)
        return ERROR_INT("size < 8", procName, 1);

    findFileFormatBuffer(data, &format);

    switch (format)
    {
    case IFF_BMP:  /* cheating: read the pix */
        if ((pix = pixReadMemBmp(data, size)) == NULL)
            return ERROR_INT( "bmp: pix not read", procName, 1);
        pixGetDimensions(pix, &w, &h, &d);
        pixDestroy(&pix);
        bps = (d == 32) ? 8 : d;
        spp = (d == 32) ? 3 : 1;
        break;

    case IFF_JFIF_JPEG:
        ret = readHeaderMemJpeg(data, size, &w, &h, &spp, NULL, NULL);
        bps = 8;
        if (ret)
            return ERROR_INT( "jpeg: no header info returned", procName, 1);
        break;

    case IFF_PNG:
        ret = readHeaderMemPng(data, size, &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 = readHeaderMemTiff(data, size, 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 = readHeaderMemPnm(data, size, &w, &h, &d, &type, &bps, &spp);
        if (ret)
            return ERROR_INT( "pnm: no header info returned", procName, 1);
        break;

    case IFF_GIF:  /* cheating: read the pix */
        if ((pix = pixReadMemGif(data, size)) == 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 = readHeaderMemJp2k(data, size, &w, &h, &bps, &spp);
        break;

    case IFF_WEBP:
        bps = 8;
        ret = readHeaderMemWebP(data, size, &w, &h, &spp);
        break;

    case IFF_SPIX:
        ret = sreadHeaderSpix((l_uint32 *)data, &w, &h, &bps,
                               &spp, &iscmap);
        if (ret)
            return ERROR_INT( "pnm: no header info returned", procName, 1);
        break;

    case IFF_UNKNOWN:
        return ERROR_INT("unknown format; no data returned", procName, 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;
}
Example #5
0
/*!
 *  pixReadMem()
 *
 *      Input:  data (const; encoded)
 *              datasize (size of data)
 *      Return: pix, or null on error
 *
 *  Notes:
 *      (1) This is a variation of pixReadStream(), where the data is read
 *          from a memory buffer rather than a file.
 *      (2) On windows, this only reads tiff formatted files directly from
 *          memory.  For other formats, it write to a temp file and
 *          decompress from file.
 *      (3) findFileFormatBuffer() requires up to 8 bytes to decide on
 *          the format.  That determines the constraint here.  But in
 *          fact the data must contain the entire compressed string for
 *          the image.
 */
PIX *
pixReadMem(const l_uint8  *data,
           size_t          size)
{
l_int32  format;
PIX     *pix;

    PROCNAME("pixReadMem");

    if (!data)
        return (PIX *)ERROR_PTR("data not defined", procName, NULL);
    if (size < 8)
        return (PIX *)ERROR_PTR("size < 8", procName, NULL);
    pix = NULL;

    findFileFormatBuffer(data, &format);
    switch (format)
    {
    case IFF_BMP:
        if ((pix = pixReadMemBmp(data, size)) == NULL )
            return (PIX *)ERROR_PTR( "bmp: no pix returned", procName, NULL);
        break;

    case IFF_JFIF_JPEG:
        if ((pix = pixReadMemJpeg(data, size, READ_24_BIT_COLOR, 1, NULL, 0))
                == NULL)
            return (PIX *)ERROR_PTR( "jpeg: no pix returned", procName, NULL);
        break;

    case IFF_PNG:
        if ((pix = pixReadMemPng(data, size)) == NULL)
            return (PIX *)ERROR_PTR("png: no pix returned", procName, NULL);
        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 */
        if ((pix = pixReadMemTiff(data, size, 0)) == NULL)
            return (PIX *)ERROR_PTR("tiff: no pix returned", procName, NULL);
        break;

    case IFF_PNM:
        if ((pix = pixReadMemPnm(data, size)) == NULL)
            return (PIX *)ERROR_PTR("pnm: no pix returned", procName, NULL);
        break;

    case IFF_GIF:
        if ((pix = pixReadMemGif(data, size)) == NULL)
            return (PIX *)ERROR_PTR("gif: no pix returned", procName, NULL);
        break;

    case IFF_JP2:
        if ((pix = pixReadMemJp2k(data, size, 1, NULL, 0)) == NULL)
            return (PIX *)ERROR_PTR("jp2k: no pix returned", procName, NULL);
        break;

    case IFF_WEBP:
        if ((pix = pixReadMemWebP(data, size)) == NULL)
            return (PIX *)ERROR_PTR("webp: no pix returned", procName, NULL);
        break;

    case IFF_SPIX:
        if ((pix = pixReadMemSpix(data, size)) == NULL)
            return (PIX *)ERROR_PTR("spix: no pix returned", procName, NULL);
        break;

    case IFF_UNKNOWN:
        return (PIX *)ERROR_PTR("Unknown format: no pix returned",
                procName, NULL);
        break;
    }

        /* Set the input format.  For tiff reading from memory we lose
         * the actual input format; for 1 bpp, default to G4.  */
    if (pix) {
        if (format == IFF_TIFF && pixGetDepth(pix) == 1)
            format = IFF_TIFF_G4;
        pixSetInputFormat(pix, format);
    }

    return pix;
}