123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: iltiffread.c /main/5 1996/06/19 12:20:39 ageorge $ */
- /**---------------------------------------------------------------------
- ***
- *** (c)Copyright 1991 Hewlett-Packard Co.
- ***
- *** RESTRICTED RIGHTS LEGEND
- *** Use, duplication, or disclosure by the U.S. Government is subject to
- *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
- *** Technical Data and Computer Software clause in DFARS 252.227-7013.
- *** Hewlett-Packard Company
- *** 3000 Hanover Street
- *** Palo Alto, CA 94304 U.S.A.
- *** Rights for non-DOD U.S. Government Departments and Agencies are as set
- *** forth in FAR 52.227-19(c)(1,2).
- ***
- ***-------------------------------------------------------------------*/
- /* /ilc/iltiffread.c : Code for ilReadFileImage(); add a producer to the pipe
- to read from a TIFF file. See also /ilc/iltiff.c and /ilc/iltiffwrite.c .
- */
- #include <stdlib.h>
- #include "iltiffint.h"
- #include "ilpipelem.h"
- #include "ilcodec.h"
- #include "ilerrors.h"
- #include "ilutiljpeg.h"
- typedef struct {
- /* Data set into private when element added */
- ilFilePtr pFile; /* ptr to IL file being read */
- ilFileImagePtr pFileImage; /* ptr to file image being read */
- unsigned int compression; /* compression type of data being read */
- long stripHeight; /* # lines per strip except for last strip */
- unsigned short *pPalette; /* ptr to palette; filled in by Init() */
- ilPtr pCompData; /* ptr to comp data; filled in by Init() */
- ilBool initDone; /* if true, Init() has been called */
- /* Data set into private by ilReadFileInit(). */
- ilPtr pTagAlloc; /* ptr to allocate file tags */
- ilImagePlaneInfo *pDstImagePlane; /* ptr to plane 0 of dst image */
- long nStrips; /* total # of strips to read */
- long nStripsLeft; /* # of strips left to read */
- long lastStripHeight; /* # lines in last strip */
- CARD32 *pOffsetsInit; /* ptr to strip offsets */
- CARD32 *pOffsets; /* ptr to next strip offset to read */
- ilBool shortOffsets; /* offsets are short (else long) */
- CARD32 *pByteCountsInit; /* ptr to strip byte counts or null */
- CARD32 *pByteCounts; /* ptr to next count to read or null */
- ilBool shortByteCounts; /* byte counts short (else long) */
- unsigned long nStripBytes; /* if !pByteCounts: # bytes per strip */
- unsigned long nLastStripBytes; /* if !pByteCounts: # bytes in last strip */
- } ilReadFilePrivRec, *ilReadFilePrivPtr;
- /* --------------------- ilReadJPEGTags -------------------------- */
- /* Called by ilReadFileInit() to read JPEG tag data, for JPEG-compressed file.
- */
- static ilError ilReadJPEGTags (
- ilFilePtr pFile, /* file to read */
- int nComps, /* # of samples/components in this image */
- long *pQOffsets, /* array of nComps file offsets to tables */
- long *pDCOffsets,
- long *pACOffsets,
- ilJPEGData *pCompData /* ptr to structure to fill in */
- )
- {
- int i, c, nBytes;
- ilJPEGSampleData *pSample;
- ilPtr pTable;
- ilByte buffer[16]; /* buffer for DC/AC table prefix (# codes) */
- /* Use sample/component index as table index; load tables based on sample */
- for (c = 0, pSample = pCompData->sample; c < IL_MAX_SAMPLES; c++, pSample++) {
- pSample->QTableIndex = c;
- pSample->DCTableIndex = c;
- pSample->ACTableIndex = c;
- pSample->reserved = 0;
- }
- /* Load "nComps" of each type of table into slot indexed by sample #. */
- for (c = 0; c < nComps; c++, pQOffsets++, pDCOffsets++, pACOffsets++) {
- /* Read Q table into 64 byte malloc'd block and point to it */
- if (!(pTable = (ilPtr)IL_MALLOC (64)))
- return IL_ERROR_MALLOC;
- pCompData->QTables[c] = pTable;
- if (!IL_SEEK (pFile, *pQOffsets) || !IL_READ (pFile, 64, pTable))
- return IL_ERROR_FILE_IO;
- /* Read DC table: first 16 bytes are # of codes for each length (1..16);
- the codes follow in bytes, "size" = sum of values of first 16 bytes.
- Malloc space and read in "size" + 16 bytes.
- */
- if (!IL_SEEK (pFile, *pDCOffsets) || !IL_READ (pFile, 16, buffer))
- return IL_ERROR_FILE_IO;
- for (i = 0, nBytes = 16; i < 16; i++)
- nBytes += buffer[i];
- if (!(pTable = (ilPtr)IL_MALLOC (nBytes)))
- return IL_ERROR_MALLOC;
- pCompData->DCTables[c] = pTable;
- if (!IL_SEEK (pFile, *pDCOffsets) || !IL_READ (pFile, nBytes, pTable))
- return IL_ERROR_FILE_IO;
- /* Read AC table: same as DC table */
- if (!IL_SEEK (pFile, *pACOffsets) || !IL_READ (pFile, 16, buffer))
- return IL_ERROR_FILE_IO;
- for (i = 0, nBytes = 16; i < 16; i++)
- nBytes += buffer[i];
- if (!(pTable = (ilPtr)IL_MALLOC (nBytes)))
- return IL_ERROR_MALLOC;
- pCompData->ACTables[c] = pTable;
- if (!IL_SEEK (pFile, *pACOffsets) || !IL_READ (pFile, nBytes, pTable))
- return IL_ERROR_FILE_IO;
- }
- return IL_OK;
- }
- /* --------------------- ilReadFileInit -------------------------- */
- /* Init() function for ilReadFileImage(). Read the strip offsets (required)
- and strip byte counts (required if compressed) tags.
- */
- static ilError ilReadFileInit (
- ilPtr pPrivate,
- ilImageInfo *pSrcImage,
- ilImageInfo *pDstImage
- )
- {
- ilReadFilePrivPtr pPriv = (ilReadFilePrivPtr)pPrivate;
- ilFileImagePtr pFileImage;
- ilError error;
- ilFileTag *pTag;
- /* Data for tags to read: "numbers" is the array of tag ids, "nTags" in length.
- "?Index" vars are indices into "numbers" and returned data "tags".
- */
- #define MAX_NTAGS 10 /* max # of tags read at once (plus slop) */
- int nTags; /* # of tags to read */
- unsigned short numbers[MAX_NTAGS]; /* tag ids to read */
- ilFileTag *tags [MAX_NTAGS]; /* ptr to returned data */
- int stripOffsetsIndex, stripByteCountsIndex = 0, colorMapIndex,
- QTablesIndex = 0, DCTablesIndex = 0, ACTablesIndex = 0, softwareIndex = 0,
- restartIndex = 0;
- #define ADD_TAG(_index, _tagid) { \
- _index = nTags++; \
- numbers[_index] = _tagid; \
- }
- /* If this function has already been called, exit. All of the tag data is
- read in here and kept around, so if pipe is being re-executed there is no
- need to read it again - merely reset current strip ptrs to start of data.
- */
- if (pPriv->initDone) {
- pPriv->pOffsets = pPriv->pOffsetsInit;
- pPriv->pByteCounts = pPriv->pByteCountsInit;
- pPriv->nStripsLeft = pPriv->nStrips;
- return IL_OK;
- }
- /* Read the strip tags, which reads in the actual strips. Offsets (file offsets
- to strips) are required; read the byte counts only if the image is compressed.
- Read ColorMap tag if a palette image; read JPEG tags if JPEG compressed.
- */
- pFileImage = pPriv->pFileImage;
- nTags = 0;
- ADD_TAG (stripOffsetsIndex, IL_TAG_STRIP_OFFSETS)
- if (pPriv->pPalette)
- ADD_TAG (colorMapIndex, IL_TAG_COLOR_MAP)
- if (pPriv->compression != IL_UNCOMPRESSED)
- ADD_TAG (stripByteCountsIndex, IL_TAG_STRIP_BYTE_COUNTS)
- if (pPriv->compression == IL_JPEG) {
- ADD_TAG (stripByteCountsIndex, IL_TAG_STRIP_BYTE_COUNTS)
- ADD_TAG (QTablesIndex, IL_TAG_JPEG_Q_TABLES)
- ADD_TAG (DCTablesIndex, IL_TAG_JPEG_DC_TABLES)
- ADD_TAG (ACTablesIndex, IL_TAG_JPEG_AC_TABLES)
- ADD_TAG (softwareIndex, IL_TAG_SOFTWARE) /* for bug; see below */
- ADD_TAG (restartIndex, IL_TAG_JPEG_RESTART_INTERVAL)
- }
- pPriv->pTagAlloc = ilReadFileTags ((ilFileImage)pFileImage, nTags, numbers, tags, 0);
- if (pFileImage->context->error)
- return pFileImage->context->error;
- pPriv->pDstImagePlane = pDstImage->plane;
- /* Set pOffsets, ptr to strip offsets (required); determine if short/long. */
- if (!(pTag = tags [stripOffsetsIndex]))
- return IL_ERROR_FILE_STRIP_TAGS;
- pPriv->nStripsLeft = pPriv->nStrips = pTag->nItems;
- pPriv->pOffsets = pPriv->pOffsetsInit = (CARD32 *)pTag->pItems;
- if (pTag->type == IL_TAG_SHORT)
- pPriv->shortOffsets = TRUE;
- else if (pTag->type == IL_TAG_LONG)
- pPriv->shortOffsets = FALSE;
- else return IL_ERROR_FILE_STRIP_TAGS;
- /* Validate nStrips with stripHeight and height of image. */
- if (pPriv->nStrips <= 0)
- return IL_ERROR_FILE_STRIP_TAGS;
- pPriv->lastStripHeight = pFileImage->p.height -
- (pPriv->nStrips-1) * pFileImage->p.stripHeight;
- if ((pPriv->lastStripHeight <= 0)
- || (pPriv->lastStripHeight > pFileImage->p.stripHeight))
- return IL_ERROR_FILE_STRIP_TAGS;
- /* If image is uncompressed, ignore strip byte counts - can calculate them,
- and it is safer (have seen uncompressed files with bad strip byte counts,
- and perhaps they should be rejected, but we can read them, so why not?):
- set nStripBytes based on dst row bytes, nLastStripBytes for last strip.
- If compress: Strip byte counts must exist and have same # items as offsets.
- */
- if (pPriv->compression == IL_UNCOMPRESSED) {
- unsigned long dstRowBytes = pPriv->pDstImagePlane->nBytesPerRow;
- pPriv->pByteCounts = pPriv->pByteCountsInit = (CARD32 *)NULL;
- pPriv->nStripBytes = pPriv->stripHeight * dstRowBytes;
- pPriv->nLastStripBytes = pPriv->lastStripHeight * dstRowBytes;
- }
- else {
- pTag = tags [stripByteCountsIndex];
- if (!pTag)
- return IL_ERROR_FILE_STRIP_TAGS;
- pPriv->pByteCounts = pPriv->pByteCountsInit = (CARD32 *)pTag->pItems;
- if (pTag->nItems != pPriv->nStrips)
- return IL_ERROR_FILE_STRIP_TAGS;
- if (pTag->type == IL_TAG_SHORT)
- pPriv->shortByteCounts = TRUE;
- else if (pTag->type == IL_TAG_LONG)
- pPriv->shortByteCounts = FALSE;
- else return IL_ERROR_FILE_STRIP_TAGS;
- }
- /* ColorMap (palette) must be present if a palette image (pPriv->pPalette).
- Copy TIFF palette (size = 2 ** nBits) to pPriv->pPalette (size = 3 * 256).
- */
- if (pPriv->pPalette) {
- unsigned short *pPalette, *pFilePalette;
- int nPaletteEntries, i;
- pTag = tags [colorMapIndex];
- if (!pTag)
- return IL_ERROR_FILE_MISSING_TAG;
- nPaletteEntries = 1 << pPriv->pFileImage->p.format.nBitsPerSample[0];
- if (pTag->nItems != (3 * nPaletteEntries))
- return IL_ERROR_FILE_MALFORMED_TAG;
- pPalette = pPriv->pPalette;
- pFilePalette = (unsigned short *)pTag->pItems;
- for (i = 0; i < nPaletteEntries; i++, pPalette++, pFilePalette++) {
- pPalette[0] = pFilePalette [0];
- pPalette[256] = pFilePalette [nPaletteEntries];
- pPalette[512] = pFilePalette [nPaletteEntries << 1];
- }
- }
- /* If a JPEG file read JPEG tags and load Q/DC/AC tables into pCompData.
- JPEG table tags must be present and # items = # components/samples.
- */
- if (pPriv->compression == IL_JPEG) {
- int nSamples = pFileImage->p.des.nSamplesPerPixel;
- ilFileTag *pQTag, *pDCTag, *pACTag, *pTag;
- pQTag = tags[QTablesIndex];
- pDCTag = tags[DCTablesIndex];
- pACTag = tags[ACTablesIndex];
- if (!pQTag || !pDCTag || !pACTag)
- return IL_ERROR_FILE_MISSING_TAG;
- if ((pQTag->nItems != nSamples) || (pQTag->type != IL_TAG_LONG)
- || (pDCTag->nItems != nSamples) || (pDCTag->type != IL_TAG_LONG)
- || (pACTag->nItems != nSamples) || (pACTag->type != IL_TAG_LONG))
- return IL_ERROR_FILE_MALFORMED_TAG;
- if ((error = ilReadJPEGTags (pPriv->pFile, nSamples, (long *)pQTag->pItems,
- (long *)pDCTag->pItems, (long *)pACTag->pItems,
- (ilJPEGData *)pPriv->pCompData)))
- return error;
- /* If restartInterval tag present, store value else default to 0 */
- if ((pTag = tags[restartIndex]) && (pTag->type == IL_TAG_SHORT))
- ((ilJPEGData *)pPriv->pCompData)->restartInterval = *((short *)pTag->pItems);
- else ((ilJPEGData *)pPriv->pCompData)->restartInterval = 0;
- /* Handle 2 bugs in older versions of IL (v2.0 and earlier). These versions
- always wrote in "JIF mode", as a single strip. The read code always
- read using the JIF tag instead of the strip offsets/byte counts, because
- the decompression code could only handle JIF data.
- "count" bug: in versions 2.0 and earlier. The (single) strip byte
- count was too small; usually by 8 for a single sample image (gray) or 14
- for multi-sample (RGB or YCbCr); larger for some baselevels.
- Then work around the count bug by reading until the EOI marker is found.
- The data length is then all bytes up but not including the EOI marker.
- "offset" bug: the strip offset is 3 bytes too small. Fix by adding
- 3 to the strip offset.
- The bugs are in files written by IL versions 1.1 (Image Developer's
- Kit release; first to support JPEG) or 2.0 (Image 2).
- So if the first "n" chars of the software tag are:
- "HP IL v1.1" (n = 10) count and offset bugs
- "HP IL v2.0" (n = 10) count bug
- "HP IL v 2.0" (n = 11) count bug
- */
- { ilBool hasCountBug, hasOffsetBug;
- ilFileTag *pSoftwareTag;
- char *pName;
- hasCountBug = FALSE;
- hasOffsetBug = FALSE;
- if ((pSoftwareTag = tags[softwareIndex])) {
- pName = (char *)pSoftwareTag->pItems;
- if ((pSoftwareTag->nItems >= 7) && (pName[0] == 'H') && (pName[1] == 'P')
- && (pName[2] == ' ') && (pName[3] == 'I') && (pName[4] == 'L')
- && (pName[5] == ' ') && (pName[6] == 'v')) {
- if ((pSoftwareTag->nItems >= 10) && (pName[7] == '1')
- && (pName[8] == '.') && (pName[9] == '1'))
- hasCountBug = hasOffsetBug = TRUE;
- else if ((pSoftwareTag->nItems >= 10)
- && (pName[7] == '2') && (pName[8] == '.') && (pName[9] == '0'))
- hasCountBug = TRUE;
- else if ((pSoftwareTag->nItems >= 11) && (pName[7] == ' ')
- && (pName[8] == '2') && (pName[9] == '.') && (pName[10] == '0'))
- hasCountBug = TRUE;
- }
- }
- if (hasOffsetBug)
- *pPriv->pOffsets += 3;
- if (hasCountBug) {
- # define JPEGM_FIRST_BYTE 0xFF /* first byte of all JPEG markers */
- # define JPEGM_EOI 0xD9 /* End Of Image */
- ilByte value;
- long nStripBytes;
- nStripBytes = *pPriv->pByteCounts;
- if (!IL_SEEK (pPriv->pFile, *pPriv->pOffsets + nStripBytes))
- return (IL_ERROR_COMPRESSED_DATA);
- do { /* get a marker */
- do {
- if (!IL_READ (pPriv->pFile, 1, &value))
- return IL_ERROR_COMPRESSED_DATA;
- nStripBytes++;
- } while (value != JPEGM_FIRST_BYTE);
- do {
- if (!IL_READ (pPriv->pFile, 1, &value))
- return IL_ERROR_COMPRESSED_DATA;
- nStripBytes++;
- } while (value == JPEGM_FIRST_BYTE);
- } while (!value); /* skip "0" after ff */
- if (value != JPEGM_EOI)
- return IL_ERROR_COMPRESSED_DATA;
- /* nStripBytes now includes marker; subtract 2 to remove marker */
- nStripBytes -= 2;
- *pPriv->pByteCounts = nStripBytes;
- }
- }
- } /* END JPEG */
- pPriv->initDone = TRUE; /* avoid re-reading; e.g. palette data */
- return IL_OK;
- }
- /* ------------------------ ilReadFileDestroy -------------------------------- */
- /* Destroy() function for ilReadFileImage(). Calls ilDestroyObject() on the
- file, whose refCount was inc'd when element added. This prevents the file
- from being destroyed until the pipe element is destroyed.
- Free the palette space, compression data and tag malloc space if present.
- */
- static ilError ilReadFileDestroy (
- ilPtr pPrivate
- )
- {
- ilReadFilePrivPtr pPriv = (ilReadFilePrivPtr)pPrivate;
- ilDestroyObject ((ilObject)pPriv->pFile);
- if (pPriv->pPalette)
- IL_FREE (pPriv->pPalette);
- if (pPriv->pCompData && (pPriv->compression == IL_JPEG)) {
- _ilJPEGFreeTables ((ilJPEGData *)pPriv->pCompData);
- IL_FREE (pPriv->pCompData);
- }
- if (pPriv->pTagAlloc && pPriv->initDone)
- free (pPriv->pTagAlloc); /* not IL_FREE(); act like client */
- return IL_OK;
- }
- /* --------------------- ilReadFileExecute -------------------------- */
- /* Execute() for ilReadFileImage(). Read one strip (or whole image if no
- strips) out to the dst image. If compressed, special care required.
- This is a producer; signal last strip if no more strips to read.
- */
- static ilError ilReadFileExecute (
- ilExecuteData *pData,
- long dstLine,
- long *pNLines
- )
- {
- ilReadFilePrivPtr pPriv;
- unsigned long nBytes, offset;
- ilPtr pDst;
- ilImagePlaneInfo *pDstImagePlane;
- /* Get "offset", position of strip in file, and "nBytes" to read: from strip
- byte counts if present (must be if compressed), else use calculated values.
- */
- pPriv = (ilReadFilePrivPtr)pData->pPrivate;
- pPriv->nStripsLeft--;
- if (pPriv->shortOffsets) {
- offset = *((unsigned short *)pPriv->pOffsets);
- pPriv->pOffsets = (CARD32 *)((ilPtr)pPriv->pOffsets + 2);
- }
- else offset = *pPriv->pOffsets++;
- if (pPriv->pByteCounts) {
- if (pPriv->shortByteCounts) {
- nBytes = *((unsigned short *)pPriv->pByteCounts);
- pPriv->pByteCounts = (CARD32 *)((ilPtr)pPriv->pByteCounts + 2);
- }
- else nBytes = *pPriv->pByteCounts++;
- }
- else nBytes = (pPriv->nStripsLeft <= 0) ? pPriv->nLastStripBytes : pPriv->nStripBytes;
- /* If reading a compressed image, read into "pPixels + srcOffset" (ignore
- dstLine); make sure room for "nBytes"; (re)alloc buffer if not room.
- Pass "nBytes" written on to next pipe element.
- */
- pDstImagePlane = pPriv->pDstImagePlane;
- if (pPriv->compression != IL_UNCOMPRESSED) {
- long dstOffset;
- dstOffset = *pData->compressed.pDstOffset;
- if ((dstOffset + nBytes) > pDstImagePlane->bufferSize)
- if (!_ilReallocCompressedBuffer (pData->pDstImage, 0, dstOffset + nBytes))
- return IL_ERROR_MALLOC; /* error, EXIT */
- pDst = pDstImagePlane->pPixels + dstOffset;
- *pData->compressed.pNBytesWritten = nBytes;
- }
- else pDst = pDstImagePlane->pPixels + dstLine * pDstImagePlane->nBytesPerRow;
- /* Seek to offset and read nBytes into pDst. */
- if (!IL_SEEK (pPriv->pFile, offset)
- || !IL_READ (pPriv->pFile, nBytes, pDst))
- return (IL_ERROR_FILE_IO);
- /* Set # of lines written - strip height unless last strip (return flag). */
- if (pPriv->nStripsLeft <= 0) {
- *pNLines = pPriv->lastStripHeight;
- return IL_ERROR_LAST_STRIP;
- }
- else {
- *pNLines = pPriv->stripHeight;
- return IL_OK;
- }
- }
- /* ---------------------- ilReadFileImage ---------------------------------- */
- /* Public function: see spec.
- Adds a producer to the given pipe to read the given fileImage.
- */
- ilBool ilReadFileImage (
- ilPipe pipe,
- ilFileImage fileImage,
- ilRect *pSrcRect,
- unsigned long mustBeZero
- )
- {
- ilDstElementData dstData;
- ilFileImagePtr pFileImage;
- ilReadFilePrivPtr pPriv;
- unsigned short *pPalette;
- ilPtr pCompData;
- /* Validate that pipe and file image have the same context. */
- pFileImage = (ilFileImagePtr)fileImage;
- if (mustBeZero != 0)
- return ilDeclarePipeInvalid (pipe, IL_ERROR_PAR_NOT_ZERO);
- if (pFileImage->context != pipe->context)
- return ilDeclarePipeInvalid (pipe, IL_ERROR_CONTEXT_MISMATCH);
- /* Get pipe state - must be IL_PIPE_EMPTY or declare an error. */
- if (ilGetPipeInfo (pipe, FALSE, (ilPipeInfo *)NULL, (ilImageDes *)NULL,
- (ilImageFormat *)NULL) != IL_PIPE_EMPTY) {
- if (!pFileImage->context->error)
- ilDeclarePipeInvalid (pipe, IL_ERROR_PIPE_STATE);
- return FALSE;
- }
- /* Planar sample order not yet supported. */
- if (pFileImage->p.format.sampleOrder != IL_SAMPLE_PIXELS)
- return ilDeclarePipeInvalid (pipe, IL_ERROR_NOT_IMPLEMENTED);
- /* If a palette image, allocate space for it (must pass ptr to it when adding
- pipe element), but don't read it until Init() called.
- */
- if (pFileImage->p.des.type == IL_PALETTE) {
- pPalette = (unsigned short *)IL_MALLOC (sizeof (unsigned short) * 3 * 256);
- if (!pPalette)
- return ilDeclarePipeInvalid (pipe, IL_ERROR_MALLOC);
- }
- else pPalette = (unsigned short *)NULL;
- /* Allocate and zero pCompData if JPEG (similar to pPalette) */
- if (pFileImage->p.des.compression == IL_JPEG) {
- pCompData = (ilPtr)IL_MALLOC_ZERO (sizeof (ilJPEGData));
- if (!pCompData)
- return ilDeclarePipeInvalid (pipe, IL_ERROR_MALLOC);
- }
- else pCompData = (ilPtr)NULL;
- /* Add a producer pipe element: output data is defined in *pFileImage. */
- dstData.producerObject = (ilObject)fileImage;
- dstData.pDes = &pFileImage->p.des;
- dstData.pFormat = &pFileImage->p.format;
- dstData.width = pFileImage->p.width;
- dstData.height = pFileImage->p.height;
- dstData.stripHeight = pFileImage->p.stripHeight;
- dstData.constantStrip = TRUE;
- dstData.pPalette = pPalette;
- dstData.pCompData = pCompData;
- pPriv = (ilReadFilePrivPtr)ilAddPipeElement (pipe, IL_PRODUCER,
- sizeof (ilReadFilePrivRec), 0, (ilSrcElementData *)NULL, &dstData,
- ilReadFileInit, IL_NPF, ilReadFileDestroy, ilReadFileExecute, NULL, 0);
- if (!pPriv) {
- if (pPalette) IL_FREE (pPalette);
- if (pCompData) IL_FREE (pCompData);
- return FALSE;
- }
- /* Init private. Inc refCount for this file - dec'd in ilReadFileDestroy(). */
- pPriv->pFile = (ilFilePtr)pFileImage->p.file;
- pPriv->pFileImage = pFileImage;
- pPriv->compression = pFileImage->p.des.compression;
- pPriv->stripHeight = pFileImage->p.stripHeight;
- pPriv->pPalette = pPalette;
- pPriv->pCompData = pCompData;
- pPriv->initDone = FALSE;
- ((ilObjectPtr)pFileImage->p.file)->refCount++;
- /* If a src rect given, crop to it.
- NOTE: IMPLEMENT PARTIAL FILE READ IN THE FUTURE !!!!!
- */
- if (pSrcRect)
- return ilCrop (pipe, pSrcRect);
- pipe->context->error = IL_OK;
- return TRUE;
- }
|