iltiffread.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: iltiffread.c /main/5 1996/06/19 12:20:39 ageorge $ */
  24. /**---------------------------------------------------------------------
  25. ***
  26. *** (c)Copyright 1991 Hewlett-Packard Co.
  27. ***
  28. *** RESTRICTED RIGHTS LEGEND
  29. *** Use, duplication, or disclosure by the U.S. Government is subject to
  30. *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
  31. *** Technical Data and Computer Software clause in DFARS 252.227-7013.
  32. *** Hewlett-Packard Company
  33. *** 3000 Hanover Street
  34. *** Palo Alto, CA 94304 U.S.A.
  35. *** Rights for non-DOD U.S. Government Departments and Agencies are as set
  36. *** forth in FAR 52.227-19(c)(1,2).
  37. ***
  38. ***-------------------------------------------------------------------*/
  39. /* /ilc/iltiffread.c : Code for ilReadFileImage(); add a producer to the pipe
  40. to read from a TIFF file. See also /ilc/iltiff.c and /ilc/iltiffwrite.c .
  41. */
  42. #include <stdlib.h>
  43. #include "iltiffint.h"
  44. #include "ilpipelem.h"
  45. #include "ilcodec.h"
  46. #include "ilerrors.h"
  47. #include "ilutiljpeg.h"
  48. typedef struct {
  49. /* Data set into private when element added */
  50. ilFilePtr pFile; /* ptr to IL file being read */
  51. ilFileImagePtr pFileImage; /* ptr to file image being read */
  52. unsigned int compression; /* compression type of data being read */
  53. long stripHeight; /* # lines per strip except for last strip */
  54. unsigned short *pPalette; /* ptr to palette; filled in by Init() */
  55. ilPtr pCompData; /* ptr to comp data; filled in by Init() */
  56. ilBool initDone; /* if true, Init() has been called */
  57. /* Data set into private by ilReadFileInit(). */
  58. ilPtr pTagAlloc; /* ptr to allocate file tags */
  59. ilImagePlaneInfo *pDstImagePlane; /* ptr to plane 0 of dst image */
  60. long nStrips; /* total # of strips to read */
  61. long nStripsLeft; /* # of strips left to read */
  62. long lastStripHeight; /* # lines in last strip */
  63. CARD32 *pOffsetsInit; /* ptr to strip offsets */
  64. CARD32 *pOffsets; /* ptr to next strip offset to read */
  65. ilBool shortOffsets; /* offsets are short (else long) */
  66. CARD32 *pByteCountsInit; /* ptr to strip byte counts or null */
  67. CARD32 *pByteCounts; /* ptr to next count to read or null */
  68. ilBool shortByteCounts; /* byte counts short (else long) */
  69. unsigned long nStripBytes; /* if !pByteCounts: # bytes per strip */
  70. unsigned long nLastStripBytes; /* if !pByteCounts: # bytes in last strip */
  71. } ilReadFilePrivRec, *ilReadFilePrivPtr;
  72. /* --------------------- ilReadJPEGTags -------------------------- */
  73. /* Called by ilReadFileInit() to read JPEG tag data, for JPEG-compressed file.
  74. */
  75. static ilError ilReadJPEGTags (
  76. ilFilePtr pFile, /* file to read */
  77. int nComps, /* # of samples/components in this image */
  78. long *pQOffsets, /* array of nComps file offsets to tables */
  79. long *pDCOffsets,
  80. long *pACOffsets,
  81. ilJPEGData *pCompData /* ptr to structure to fill in */
  82. )
  83. {
  84. int i, c, nBytes;
  85. ilJPEGSampleData *pSample;
  86. ilPtr pTable;
  87. ilByte buffer[16]; /* buffer for DC/AC table prefix (# codes) */
  88. /* Use sample/component index as table index; load tables based on sample */
  89. for (c = 0, pSample = pCompData->sample; c < IL_MAX_SAMPLES; c++, pSample++) {
  90. pSample->QTableIndex = c;
  91. pSample->DCTableIndex = c;
  92. pSample->ACTableIndex = c;
  93. pSample->reserved = 0;
  94. }
  95. /* Load "nComps" of each type of table into slot indexed by sample #. */
  96. for (c = 0; c < nComps; c++, pQOffsets++, pDCOffsets++, pACOffsets++) {
  97. /* Read Q table into 64 byte malloc'd block and point to it */
  98. if (!(pTable = (ilPtr)IL_MALLOC (64)))
  99. return IL_ERROR_MALLOC;
  100. pCompData->QTables[c] = pTable;
  101. if (!IL_SEEK (pFile, *pQOffsets) || !IL_READ (pFile, 64, pTable))
  102. return IL_ERROR_FILE_IO;
  103. /* Read DC table: first 16 bytes are # of codes for each length (1..16);
  104. the codes follow in bytes, "size" = sum of values of first 16 bytes.
  105. Malloc space and read in "size" + 16 bytes.
  106. */
  107. if (!IL_SEEK (pFile, *pDCOffsets) || !IL_READ (pFile, 16, buffer))
  108. return IL_ERROR_FILE_IO;
  109. for (i = 0, nBytes = 16; i < 16; i++)
  110. nBytes += buffer[i];
  111. if (!(pTable = (ilPtr)IL_MALLOC (nBytes)))
  112. return IL_ERROR_MALLOC;
  113. pCompData->DCTables[c] = pTable;
  114. if (!IL_SEEK (pFile, *pDCOffsets) || !IL_READ (pFile, nBytes, pTable))
  115. return IL_ERROR_FILE_IO;
  116. /* Read AC table: same as DC table */
  117. if (!IL_SEEK (pFile, *pACOffsets) || !IL_READ (pFile, 16, buffer))
  118. return IL_ERROR_FILE_IO;
  119. for (i = 0, nBytes = 16; i < 16; i++)
  120. nBytes += buffer[i];
  121. if (!(pTable = (ilPtr)IL_MALLOC (nBytes)))
  122. return IL_ERROR_MALLOC;
  123. pCompData->ACTables[c] = pTable;
  124. if (!IL_SEEK (pFile, *pACOffsets) || !IL_READ (pFile, nBytes, pTable))
  125. return IL_ERROR_FILE_IO;
  126. }
  127. return IL_OK;
  128. }
  129. /* --------------------- ilReadFileInit -------------------------- */
  130. /* Init() function for ilReadFileImage(). Read the strip offsets (required)
  131. and strip byte counts (required if compressed) tags.
  132. */
  133. static ilError ilReadFileInit (
  134. ilPtr pPrivate,
  135. ilImageInfo *pSrcImage,
  136. ilImageInfo *pDstImage
  137. )
  138. {
  139. ilReadFilePrivPtr pPriv = (ilReadFilePrivPtr)pPrivate;
  140. ilFileImagePtr pFileImage;
  141. ilError error;
  142. ilFileTag *pTag;
  143. /* Data for tags to read: "numbers" is the array of tag ids, "nTags" in length.
  144. "?Index" vars are indices into "numbers" and returned data "tags".
  145. */
  146. #define MAX_NTAGS 10 /* max # of tags read at once (plus slop) */
  147. int nTags; /* # of tags to read */
  148. unsigned short numbers[MAX_NTAGS]; /* tag ids to read */
  149. ilFileTag *tags [MAX_NTAGS]; /* ptr to returned data */
  150. int stripOffsetsIndex, stripByteCountsIndex = 0, colorMapIndex,
  151. QTablesIndex = 0, DCTablesIndex = 0, ACTablesIndex = 0, softwareIndex = 0,
  152. restartIndex = 0;
  153. #define ADD_TAG(_index, _tagid) { \
  154. _index = nTags++; \
  155. numbers[_index] = _tagid; \
  156. }
  157. /* If this function has already been called, exit. All of the tag data is
  158. read in here and kept around, so if pipe is being re-executed there is no
  159. need to read it again - merely reset current strip ptrs to start of data.
  160. */
  161. if (pPriv->initDone) {
  162. pPriv->pOffsets = pPriv->pOffsetsInit;
  163. pPriv->pByteCounts = pPriv->pByteCountsInit;
  164. pPriv->nStripsLeft = pPriv->nStrips;
  165. return IL_OK;
  166. }
  167. /* Read the strip tags, which reads in the actual strips. Offsets (file offsets
  168. to strips) are required; read the byte counts only if the image is compressed.
  169. Read ColorMap tag if a palette image; read JPEG tags if JPEG compressed.
  170. */
  171. pFileImage = pPriv->pFileImage;
  172. nTags = 0;
  173. ADD_TAG (stripOffsetsIndex, IL_TAG_STRIP_OFFSETS)
  174. if (pPriv->pPalette)
  175. ADD_TAG (colorMapIndex, IL_TAG_COLOR_MAP)
  176. if (pPriv->compression != IL_UNCOMPRESSED)
  177. ADD_TAG (stripByteCountsIndex, IL_TAG_STRIP_BYTE_COUNTS)
  178. if (pPriv->compression == IL_JPEG) {
  179. ADD_TAG (stripByteCountsIndex, IL_TAG_STRIP_BYTE_COUNTS)
  180. ADD_TAG (QTablesIndex, IL_TAG_JPEG_Q_TABLES)
  181. ADD_TAG (DCTablesIndex, IL_TAG_JPEG_DC_TABLES)
  182. ADD_TAG (ACTablesIndex, IL_TAG_JPEG_AC_TABLES)
  183. ADD_TAG (softwareIndex, IL_TAG_SOFTWARE) /* for bug; see below */
  184. ADD_TAG (restartIndex, IL_TAG_JPEG_RESTART_INTERVAL)
  185. }
  186. pPriv->pTagAlloc = ilReadFileTags ((ilFileImage)pFileImage, nTags, numbers, tags, 0);
  187. if (pFileImage->context->error)
  188. return pFileImage->context->error;
  189. pPriv->pDstImagePlane = pDstImage->plane;
  190. /* Set pOffsets, ptr to strip offsets (required); determine if short/long. */
  191. if (!(pTag = tags [stripOffsetsIndex]))
  192. return IL_ERROR_FILE_STRIP_TAGS;
  193. pPriv->nStripsLeft = pPriv->nStrips = pTag->nItems;
  194. pPriv->pOffsets = pPriv->pOffsetsInit = (CARD32 *)pTag->pItems;
  195. if (pTag->type == IL_TAG_SHORT)
  196. pPriv->shortOffsets = TRUE;
  197. else if (pTag->type == IL_TAG_LONG)
  198. pPriv->shortOffsets = FALSE;
  199. else return IL_ERROR_FILE_STRIP_TAGS;
  200. /* Validate nStrips with stripHeight and height of image. */
  201. if (pPriv->nStrips <= 0)
  202. return IL_ERROR_FILE_STRIP_TAGS;
  203. pPriv->lastStripHeight = pFileImage->p.height -
  204. (pPriv->nStrips-1) * pFileImage->p.stripHeight;
  205. if ((pPriv->lastStripHeight <= 0)
  206. || (pPriv->lastStripHeight > pFileImage->p.stripHeight))
  207. return IL_ERROR_FILE_STRIP_TAGS;
  208. /* If image is uncompressed, ignore strip byte counts - can calculate them,
  209. and it is safer (have seen uncompressed files with bad strip byte counts,
  210. and perhaps they should be rejected, but we can read them, so why not?):
  211. set nStripBytes based on dst row bytes, nLastStripBytes for last strip.
  212. If compress: Strip byte counts must exist and have same # items as offsets.
  213. */
  214. if (pPriv->compression == IL_UNCOMPRESSED) {
  215. unsigned long dstRowBytes = pPriv->pDstImagePlane->nBytesPerRow;
  216. pPriv->pByteCounts = pPriv->pByteCountsInit = (CARD32 *)NULL;
  217. pPriv->nStripBytes = pPriv->stripHeight * dstRowBytes;
  218. pPriv->nLastStripBytes = pPriv->lastStripHeight * dstRowBytes;
  219. }
  220. else {
  221. pTag = tags [stripByteCountsIndex];
  222. if (!pTag)
  223. return IL_ERROR_FILE_STRIP_TAGS;
  224. pPriv->pByteCounts = pPriv->pByteCountsInit = (CARD32 *)pTag->pItems;
  225. if (pTag->nItems != pPriv->nStrips)
  226. return IL_ERROR_FILE_STRIP_TAGS;
  227. if (pTag->type == IL_TAG_SHORT)
  228. pPriv->shortByteCounts = TRUE;
  229. else if (pTag->type == IL_TAG_LONG)
  230. pPriv->shortByteCounts = FALSE;
  231. else return IL_ERROR_FILE_STRIP_TAGS;
  232. }
  233. /* ColorMap (palette) must be present if a palette image (pPriv->pPalette).
  234. Copy TIFF palette (size = 2 ** nBits) to pPriv->pPalette (size = 3 * 256).
  235. */
  236. if (pPriv->pPalette) {
  237. unsigned short *pPalette, *pFilePalette;
  238. int nPaletteEntries, i;
  239. pTag = tags [colorMapIndex];
  240. if (!pTag)
  241. return IL_ERROR_FILE_MISSING_TAG;
  242. nPaletteEntries = 1 << pPriv->pFileImage->p.format.nBitsPerSample[0];
  243. if (pTag->nItems != (3 * nPaletteEntries))
  244. return IL_ERROR_FILE_MALFORMED_TAG;
  245. pPalette = pPriv->pPalette;
  246. pFilePalette = (unsigned short *)pTag->pItems;
  247. for (i = 0; i < nPaletteEntries; i++, pPalette++, pFilePalette++) {
  248. pPalette[0] = pFilePalette [0];
  249. pPalette[256] = pFilePalette [nPaletteEntries];
  250. pPalette[512] = pFilePalette [nPaletteEntries << 1];
  251. }
  252. }
  253. /* If a JPEG file read JPEG tags and load Q/DC/AC tables into pCompData.
  254. JPEG table tags must be present and # items = # components/samples.
  255. */
  256. if (pPriv->compression == IL_JPEG) {
  257. int nSamples = pFileImage->p.des.nSamplesPerPixel;
  258. ilFileTag *pQTag, *pDCTag, *pACTag, *pTag;
  259. pQTag = tags[QTablesIndex];
  260. pDCTag = tags[DCTablesIndex];
  261. pACTag = tags[ACTablesIndex];
  262. if (!pQTag || !pDCTag || !pACTag)
  263. return IL_ERROR_FILE_MISSING_TAG;
  264. if ((pQTag->nItems != nSamples) || (pQTag->type != IL_TAG_LONG)
  265. || (pDCTag->nItems != nSamples) || (pDCTag->type != IL_TAG_LONG)
  266. || (pACTag->nItems != nSamples) || (pACTag->type != IL_TAG_LONG))
  267. return IL_ERROR_FILE_MALFORMED_TAG;
  268. if ((error = ilReadJPEGTags (pPriv->pFile, nSamples, (long *)pQTag->pItems,
  269. (long *)pDCTag->pItems, (long *)pACTag->pItems,
  270. (ilJPEGData *)pPriv->pCompData)))
  271. return error;
  272. /* If restartInterval tag present, store value else default to 0 */
  273. if ((pTag = tags[restartIndex]) && (pTag->type == IL_TAG_SHORT))
  274. ((ilJPEGData *)pPriv->pCompData)->restartInterval = *((short *)pTag->pItems);
  275. else ((ilJPEGData *)pPriv->pCompData)->restartInterval = 0;
  276. /* Handle 2 bugs in older versions of IL (v2.0 and earlier). These versions
  277. always wrote in "JIF mode", as a single strip. The read code always
  278. read using the JIF tag instead of the strip offsets/byte counts, because
  279. the decompression code could only handle JIF data.
  280. "count" bug: in versions 2.0 and earlier. The (single) strip byte
  281. count was too small; usually by 8 for a single sample image (gray) or 14
  282. for multi-sample (RGB or YCbCr); larger for some baselevels.
  283. Then work around the count bug by reading until the EOI marker is found.
  284. The data length is then all bytes up but not including the EOI marker.
  285. "offset" bug: the strip offset is 3 bytes too small. Fix by adding
  286. 3 to the strip offset.
  287. The bugs are in files written by IL versions 1.1 (Image Developer's
  288. Kit release; first to support JPEG) or 2.0 (Image 2).
  289. So if the first "n" chars of the software tag are:
  290. "HP IL v1.1" (n = 10) count and offset bugs
  291. "HP IL v2.0" (n = 10) count bug
  292. "HP IL v 2.0" (n = 11) count bug
  293. */
  294. { ilBool hasCountBug, hasOffsetBug;
  295. ilFileTag *pSoftwareTag;
  296. char *pName;
  297. hasCountBug = FALSE;
  298. hasOffsetBug = FALSE;
  299. if ((pSoftwareTag = tags[softwareIndex])) {
  300. pName = (char *)pSoftwareTag->pItems;
  301. if ((pSoftwareTag->nItems >= 7) && (pName[0] == 'H') && (pName[1] == 'P')
  302. && (pName[2] == ' ') && (pName[3] == 'I') && (pName[4] == 'L')
  303. && (pName[5] == ' ') && (pName[6] == 'v')) {
  304. if ((pSoftwareTag->nItems >= 10) && (pName[7] == '1')
  305. && (pName[8] == '.') && (pName[9] == '1'))
  306. hasCountBug = hasOffsetBug = TRUE;
  307. else if ((pSoftwareTag->nItems >= 10)
  308. && (pName[7] == '2') && (pName[8] == '.') && (pName[9] == '0'))
  309. hasCountBug = TRUE;
  310. else if ((pSoftwareTag->nItems >= 11) && (pName[7] == ' ')
  311. && (pName[8] == '2') && (pName[9] == '.') && (pName[10] == '0'))
  312. hasCountBug = TRUE;
  313. }
  314. }
  315. if (hasOffsetBug)
  316. *pPriv->pOffsets += 3;
  317. if (hasCountBug) {
  318. # define JPEGM_FIRST_BYTE 0xFF /* first byte of all JPEG markers */
  319. # define JPEGM_EOI 0xD9 /* End Of Image */
  320. ilByte value;
  321. long nStripBytes;
  322. nStripBytes = *pPriv->pByteCounts;
  323. if (!IL_SEEK (pPriv->pFile, *pPriv->pOffsets + nStripBytes))
  324. return (IL_ERROR_COMPRESSED_DATA);
  325. do { /* get a marker */
  326. do {
  327. if (!IL_READ (pPriv->pFile, 1, &value))
  328. return IL_ERROR_COMPRESSED_DATA;
  329. nStripBytes++;
  330. } while (value != JPEGM_FIRST_BYTE);
  331. do {
  332. if (!IL_READ (pPriv->pFile, 1, &value))
  333. return IL_ERROR_COMPRESSED_DATA;
  334. nStripBytes++;
  335. } while (value == JPEGM_FIRST_BYTE);
  336. } while (!value); /* skip "0" after ff */
  337. if (value != JPEGM_EOI)
  338. return IL_ERROR_COMPRESSED_DATA;
  339. /* nStripBytes now includes marker; subtract 2 to remove marker */
  340. nStripBytes -= 2;
  341. *pPriv->pByteCounts = nStripBytes;
  342. }
  343. }
  344. } /* END JPEG */
  345. pPriv->initDone = TRUE; /* avoid re-reading; e.g. palette data */
  346. return IL_OK;
  347. }
  348. /* ------------------------ ilReadFileDestroy -------------------------------- */
  349. /* Destroy() function for ilReadFileImage(). Calls ilDestroyObject() on the
  350. file, whose refCount was inc'd when element added. This prevents the file
  351. from being destroyed until the pipe element is destroyed.
  352. Free the palette space, compression data and tag malloc space if present.
  353. */
  354. static ilError ilReadFileDestroy (
  355. ilPtr pPrivate
  356. )
  357. {
  358. ilReadFilePrivPtr pPriv = (ilReadFilePrivPtr)pPrivate;
  359. ilDestroyObject ((ilObject)pPriv->pFile);
  360. if (pPriv->pPalette)
  361. IL_FREE (pPriv->pPalette);
  362. if (pPriv->pCompData && (pPriv->compression == IL_JPEG)) {
  363. _ilJPEGFreeTables ((ilJPEGData *)pPriv->pCompData);
  364. IL_FREE (pPriv->pCompData);
  365. }
  366. if (pPriv->pTagAlloc && pPriv->initDone)
  367. free (pPriv->pTagAlloc); /* not IL_FREE(); act like client */
  368. return IL_OK;
  369. }
  370. /* --------------------- ilReadFileExecute -------------------------- */
  371. /* Execute() for ilReadFileImage(). Read one strip (or whole image if no
  372. strips) out to the dst image. If compressed, special care required.
  373. This is a producer; signal last strip if no more strips to read.
  374. */
  375. static ilError ilReadFileExecute (
  376. ilExecuteData *pData,
  377. long dstLine,
  378. long *pNLines
  379. )
  380. {
  381. ilReadFilePrivPtr pPriv;
  382. unsigned long nBytes, offset;
  383. ilPtr pDst;
  384. ilImagePlaneInfo *pDstImagePlane;
  385. /* Get "offset", position of strip in file, and "nBytes" to read: from strip
  386. byte counts if present (must be if compressed), else use calculated values.
  387. */
  388. pPriv = (ilReadFilePrivPtr)pData->pPrivate;
  389. pPriv->nStripsLeft--;
  390. if (pPriv->shortOffsets) {
  391. offset = *((unsigned short *)pPriv->pOffsets);
  392. pPriv->pOffsets = (CARD32 *)((ilPtr)pPriv->pOffsets + 2);
  393. }
  394. else offset = *pPriv->pOffsets++;
  395. if (pPriv->pByteCounts) {
  396. if (pPriv->shortByteCounts) {
  397. nBytes = *((unsigned short *)pPriv->pByteCounts);
  398. pPriv->pByteCounts = (CARD32 *)((ilPtr)pPriv->pByteCounts + 2);
  399. }
  400. else nBytes = *pPriv->pByteCounts++;
  401. }
  402. else nBytes = (pPriv->nStripsLeft <= 0) ? pPriv->nLastStripBytes : pPriv->nStripBytes;
  403. /* If reading a compressed image, read into "pPixels + srcOffset" (ignore
  404. dstLine); make sure room for "nBytes"; (re)alloc buffer if not room.
  405. Pass "nBytes" written on to next pipe element.
  406. */
  407. pDstImagePlane = pPriv->pDstImagePlane;
  408. if (pPriv->compression != IL_UNCOMPRESSED) {
  409. long dstOffset;
  410. dstOffset = *pData->compressed.pDstOffset;
  411. if ((dstOffset + nBytes) > pDstImagePlane->bufferSize)
  412. if (!_ilReallocCompressedBuffer (pData->pDstImage, 0, dstOffset + nBytes))
  413. return IL_ERROR_MALLOC; /* error, EXIT */
  414. pDst = pDstImagePlane->pPixels + dstOffset;
  415. *pData->compressed.pNBytesWritten = nBytes;
  416. }
  417. else pDst = pDstImagePlane->pPixels + dstLine * pDstImagePlane->nBytesPerRow;
  418. /* Seek to offset and read nBytes into pDst. */
  419. if (!IL_SEEK (pPriv->pFile, offset)
  420. || !IL_READ (pPriv->pFile, nBytes, pDst))
  421. return (IL_ERROR_FILE_IO);
  422. /* Set # of lines written - strip height unless last strip (return flag). */
  423. if (pPriv->nStripsLeft <= 0) {
  424. *pNLines = pPriv->lastStripHeight;
  425. return IL_ERROR_LAST_STRIP;
  426. }
  427. else {
  428. *pNLines = pPriv->stripHeight;
  429. return IL_OK;
  430. }
  431. }
  432. /* ---------------------- ilReadFileImage ---------------------------------- */
  433. /* Public function: see spec.
  434. Adds a producer to the given pipe to read the given fileImage.
  435. */
  436. ilBool ilReadFileImage (
  437. ilPipe pipe,
  438. ilFileImage fileImage,
  439. ilRect *pSrcRect,
  440. unsigned long mustBeZero
  441. )
  442. {
  443. ilDstElementData dstData;
  444. ilFileImagePtr pFileImage;
  445. ilReadFilePrivPtr pPriv;
  446. unsigned short *pPalette;
  447. ilPtr pCompData;
  448. /* Validate that pipe and file image have the same context. */
  449. pFileImage = (ilFileImagePtr)fileImage;
  450. if (mustBeZero != 0)
  451. return ilDeclarePipeInvalid (pipe, IL_ERROR_PAR_NOT_ZERO);
  452. if (pFileImage->context != pipe->context)
  453. return ilDeclarePipeInvalid (pipe, IL_ERROR_CONTEXT_MISMATCH);
  454. /* Get pipe state - must be IL_PIPE_EMPTY or declare an error. */
  455. if (ilGetPipeInfo (pipe, FALSE, (ilPipeInfo *)NULL, (ilImageDes *)NULL,
  456. (ilImageFormat *)NULL) != IL_PIPE_EMPTY) {
  457. if (!pFileImage->context->error)
  458. ilDeclarePipeInvalid (pipe, IL_ERROR_PIPE_STATE);
  459. return FALSE;
  460. }
  461. /* Planar sample order not yet supported. */
  462. if (pFileImage->p.format.sampleOrder != IL_SAMPLE_PIXELS)
  463. return ilDeclarePipeInvalid (pipe, IL_ERROR_NOT_IMPLEMENTED);
  464. /* If a palette image, allocate space for it (must pass ptr to it when adding
  465. pipe element), but don't read it until Init() called.
  466. */
  467. if (pFileImage->p.des.type == IL_PALETTE) {
  468. pPalette = (unsigned short *)IL_MALLOC (sizeof (unsigned short) * 3 * 256);
  469. if (!pPalette)
  470. return ilDeclarePipeInvalid (pipe, IL_ERROR_MALLOC);
  471. }
  472. else pPalette = (unsigned short *)NULL;
  473. /* Allocate and zero pCompData if JPEG (similar to pPalette) */
  474. if (pFileImage->p.des.compression == IL_JPEG) {
  475. pCompData = (ilPtr)IL_MALLOC_ZERO (sizeof (ilJPEGData));
  476. if (!pCompData)
  477. return ilDeclarePipeInvalid (pipe, IL_ERROR_MALLOC);
  478. }
  479. else pCompData = (ilPtr)NULL;
  480. /* Add a producer pipe element: output data is defined in *pFileImage. */
  481. dstData.producerObject = (ilObject)fileImage;
  482. dstData.pDes = &pFileImage->p.des;
  483. dstData.pFormat = &pFileImage->p.format;
  484. dstData.width = pFileImage->p.width;
  485. dstData.height = pFileImage->p.height;
  486. dstData.stripHeight = pFileImage->p.stripHeight;
  487. dstData.constantStrip = TRUE;
  488. dstData.pPalette = pPalette;
  489. dstData.pCompData = pCompData;
  490. pPriv = (ilReadFilePrivPtr)ilAddPipeElement (pipe, IL_PRODUCER,
  491. sizeof (ilReadFilePrivRec), 0, (ilSrcElementData *)NULL, &dstData,
  492. ilReadFileInit, IL_NPF, ilReadFileDestroy, ilReadFileExecute, NULL, 0);
  493. if (!pPriv) {
  494. if (pPalette) IL_FREE (pPalette);
  495. if (pCompData) IL_FREE (pCompData);
  496. return FALSE;
  497. }
  498. /* Init private. Inc refCount for this file - dec'd in ilReadFileDestroy(). */
  499. pPriv->pFile = (ilFilePtr)pFileImage->p.file;
  500. pPriv->pFileImage = pFileImage;
  501. pPriv->compression = pFileImage->p.des.compression;
  502. pPriv->stripHeight = pFileImage->p.stripHeight;
  503. pPriv->pPalette = pPalette;
  504. pPriv->pCompData = pCompData;
  505. pPriv->initDone = FALSE;
  506. ((ilObjectPtr)pFileImage->p.file)->refCount++;
  507. /* If a src rect given, crop to it.
  508. NOTE: IMPLEMENT PARTIAL FILE READ IN THE FUTURE !!!!!
  509. */
  510. if (pSrcRect)
  511. return ilCrop (pipe, pSrcRect);
  512. pipe->context->error = IL_OK;
  513. return TRUE;
  514. }