2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: iltiff.c /main/6 1996/10/04 11:29:48 rcs $ */
24 /**---------------------------------------------------------------------
26 *** (c)Copyright 1991 Hewlett-Packard Co.
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).
38 ***-------------------------------------------------------------------*/
40 /* /ilc/iltiff.c : General TIFF file access functions, including
41 those exposed in /ilc/iltiffint.h to other /ilc/iltiff*.c code.
46 #include "iltiffint.h"
50 /* Used when this module is compiled by the DtHelp library build */
51 #include "GraphicsP.h"
54 /* Size in bytes of one item (# items = TIFF "length"), for each TIFF tag type.
55 Also, # of entries of that type which fit in one long.
56 Indexed by tag type = 1..IL_MAX_TAG_TYPE (0 entry unused).
58 IL_PRIVATE int _ilTagTypeItemSizes [IL_MAX_TAG_TYPE+1] = {
59 0, /* 0th entry unused; invalid tag type */
64 8 }; /* IL_TAG_RATIONAL */
66 IL_PRIVATE int _ilTagTypeItemsThatFit [IL_MAX_TAG_TYPE+1] = {
67 0, /* 0th entry unused; invalid tag type */
72 0 }; /* IL_TAG_RATIONAL */
74 /* Structure of the first 8 bytes of a TIFF file: see ilConnectFile() */
78 ilByte IFDHeadOffset[4];
82 /* ------------------------- ilFreeFileList -------------------------------- */
83 /* Free the file list in the given file "*pFile".
84 Note: ilFreeFileList() is also the Destroy() function for ilFile object.
87 static void ilFreeFileList (
91 ilFileImagePtr pFileImage, pAltFileImage, pFileImageTemp;
93 /* Run thru the list of file images; for each: if a mask image destroy it
94 (only one); if child images, destroy them - they are linked by pChild.
96 pFileImage = pFile->pFileImageHead;
99 /* Destroy the mask image if present */
100 pAltFileImage = (ilFileImagePtr)pFileImage->p.pMask;
102 IL_FREE (pAltFileImage);
104 /* Destroy the child images if present. They are linked
105 by pNext, and each one can have a mask image.
107 pAltFileImage = (ilFileImagePtr)pFileImage->p.pChild;
108 while (pAltFileImage) {
109 if (pAltFileImage->p.pMask)
110 IL_FREE (pAltFileImage->p.pMask);
111 pFileImageTemp = pAltFileImage;
112 pAltFileImage = (ilFileImagePtr)pAltFileImage->p.pNext;
113 IL_FREE (pFileImageTemp);
116 /* Destroy the main image */
117 pFileImageTemp = pFileImage;
118 pFileImage = (ilFileImagePtr)pFileImage->p.pNext;
119 IL_FREE (pFileImageTemp);
122 /* Make the list empty and declare it invalid.
124 pFile->pFileImageHead = pFile->pFileImageTail = (ilFileImagePtr)NULL;
125 pFile->haveImageList = FALSE;
129 /* ----------------------- ilReadFileTags --------------------------------- */
130 /* Public function: see spec.
132 ilPtr ilReadFileTags (
133 ilFileImage fileImage,
135 unsigned short *pTagNumbers,
137 unsigned long mustBeZero
140 #define RFT_FATAL_ERROR(_error) {error = (_error); goto RFTFatalError; }
141 ilFileImagePtr pFileImage;
142 ilTIFFTagPtr pFileTag, pFileTags;
145 unsigned long readSize, mallocSize;
147 ilPtr pTagData, pTagAlloc;
149 ilFileTag *pTag, **ppTag;
150 int tagNumber, nFileTags, nItems, nTags, tagType, i;
153 pFileImage = (ilFileImagePtr)fileImage;
154 if (mustBeZero != 0) {
155 pFileImage->context->error = IL_ERROR_PAR_NOT_ZERO;
156 return (ilPtr)NULL; /* EXIT */
158 if (nTagsInit <= 0) {
159 pFileImage->context->error = IL_OK;
160 return (ilPtr)NULL; /* no tags; EXIT */
163 pFile = (ilFilePtr)pFileImage->p.file;
164 bigEndian = pFile->bigEndian;
166 /* Allocate space and read in all the file tags to "*pFileTags".
167 Flip the bytes of number, type and length, but not the data/offset.
169 pTagAlloc = (ilPtr)NULL; /* in case of fatal error */
170 readSize = pFileImage->tagCount * IL_TAG_SIZE;
171 pFileTags = (ilTIFFTagPtr)IL_MALLOC (readSize);
173 RFT_FATAL_ERROR (IL_ERROR_MALLOC)
174 if (!IL_SEEK (pFile, pFileImage->tagOffset)
175 || !IL_READ (pFile, readSize, pFileTags))
176 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
178 pFileTag = pFileTags;
179 pTagData = (ilPtr)pFileTag;
180 nFileTags = pFileImage->tagCount;
181 while (nFileTags-- > 0) {
182 IL_FLIP_SHORT (bigEndian, pTagData, pFileTag->number)
184 IL_FLIP_SHORT (bigEndian, pTagData, tagType)
186 /* NOTE: declare fatal error if tag type out of range, BUT TIFF 6.0 says
187 we should ignore these tags; ALSO, there are new tag types for 6.0.
189 if ((tagType == 0) || (tagType > IL_MAX_TAG_TYPE))
190 RFT_FATAL_ERROR (IL_ERROR_FILE_TAG_TYPE)
191 pFileTag->type = tagType;
193 IL_FLIP_LONG (bigEndian, pTagData, pFileTag->length)
194 pTagData += 8; /* skip length and data */
198 /* For each of caller's tags: find *pTagNumber in the pFileTags list.
199 If not found, set corresponding "ppTags" entry to null, else point it
200 at the found entry in pFileTags list, add its data size (rounded up to
201 multiple of 4 - long-align), and the size of one ilFileTag, to "mallocSize".
206 while (nTags-- > 0) {
207 tagNumber = *pTagNumbers++;
209 pFileTag = pFileTags;
210 nFileTags = pFileImage->tagCount;
211 while (nFileTags-- > 0) {
212 if (pFileTag->number == tagNumber) {
219 mallocSize += (sizeof (ilFileTag) +
220 (pFileTag->length * _ilTagTypeItemSizes [pFileTag->type] + 3)) & ~3;
221 *ppTag++ = (ilFileTag *)pFileTag;
223 else *ppTag++ = (ilFileTag *)NULL;
226 /* If no tags found; exit, else allocate "mallocSize" bytes, and for each found
227 tag, point corresponding "ppTags" to spot in pTagAlloc that has the ilFileTag
228 data, followed by the data itself, then long aligned.
229 What is returned will look like:
230 ppTags [0] == null if tag not present, else ->:
231 tag data: byte offset
232 number (same value as corresponding 0
233 entry in pTagsNumbers)
236 pItems (points to <items>, i.e. one 8
237 long past this spot, or null if
238 "nItems" is zero (0).
239 <items> - "nItems" occurrences of data 12
241 ppTags [1]-> <next tag, at offset 12 + ppTag[0]->nItems
242 * size in bytes of one ppTag[0] item,
243 as determined by "type".
245 if (mallocSize == 0) {
247 pFileImage->context->error = IL_OK;
248 return (ilPtr)NULL; /* EXIT */
250 pTagAlloc = (ilPtr)malloc (mallocSize); /* caller uses free() to free this */
252 RFT_FATAL_ERROR (IL_ERROR_MALLOC)
254 pTag = (ilFileTag *)pTagAlloc;
257 while (nTags-- > 0) {
259 ppTag++; /* tag not found, already null, next */
260 else { /* tag found */
261 pFileTag = (ilTIFFTagPtr)*ppTag; /* points to internal tag data */
262 *ppTag++ = pTag; /* point to converted data, next tag */
263 pTag->number = pFileTag->number; /* copy from pFileTags to pTagAlloc */
264 tagType = pTag->type = pFileTag->type;
265 nItems = pTag->nItems = pFileTag->length;
266 pTagData = (ilPtr)pTag + sizeof(ilFileTag);
269 pTag->pItems = (ilPtr)NULL;
270 pTag = (ilFileTag *)pTagData; /* point pTag to spot for next tag */
273 pTag->pItems = pTagData; /* data follows the tag */
274 pTag = (ilFileTag *)(pTagData + /* next spot = past data, long-aligned */
275 ((nItems * _ilTagTypeItemSizes [tagType] + 3) & ~3));
277 /* Byte flip the tag data to the spot pointed to by "pTagData",
278 i.e. right after the 12 bytes for the tag. In TIFF, the data
279 is in the "offset" field tag if it fits in 4 bytes, else offset
280 points to the data in the file - seek and read it in that case.
286 bcopy (pFileTag->data.chars, (char *)pTagData, nItems);
288 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
289 if (!IL_SEEK (pFile, offset)
290 || !IL_READ (pFile, nItems, pTagData))
291 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
297 for (i = 0; nItems > 0; nItems--, i += 2, pTagData += 2)
298 IL_FLIP_SHORT (bigEndian, pFileTag->data.chars + i,
299 *((unsigned short *)pTagData))
302 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
303 if (!IL_SEEK (pFile, offset)
304 || !IL_READ (pFile, nItems<<1, pTagData))
305 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
306 for (; nItems > 0; nItems--, pTagData += 2)
307 IL_FLIP_SHORT (bigEndian, pTagData, *((unsigned short *)pTagData))
313 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, *((INT32 *)pTagData))
315 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
316 if (!IL_SEEK (pFile, offset)
317 || !IL_READ (pFile, nItems<<2, pTagData))
318 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
319 for (; nItems > 0; nItems--, pTagData += 4)
320 IL_FLIP_LONG (bigEndian, pTagData, *((INT32 *)pTagData))
324 case IL_TAG_RATIONAL:
325 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
326 if (!IL_SEEK (pFile, offset) || !IL_READ (pFile, nItems<<3, pTagData))
327 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
328 while (nItems-- > 0) {
329 IL_FLIP_LONG (bigEndian, pTagData, *((INT32 *)pTagData))
331 IL_FLIP_LONG (bigEndian, pTagData, *((INT32 *)pTagData))
336 } /* END nItems > 0 */
337 } /* END tag found */
338 } /* END each caller's tag */
340 /* Tags read successfully: free pFileTags (local buffer); return pTagAlloc.
343 pFileImage->context->error = IL_OK;
344 return pTagAlloc; /* EXIT */
346 /* Fatal error: free pFileTags, pTagAlloc if not null, return error code, null.
353 pFileImage->context->error = error;
354 return (ilPtr)NULL; /* EXIT */
358 /* --------------------- ilAddImageToList --------------------------------- */
359 /* Called when forming file image list. "pPrevFileImage" is a pointer to the
360 previous non-mask image in the file; null if pFileImage first non-mask read.
361 pFileImage->imageType indicates whether image being added is
362 child/mask/mainImage; if child or mask, pPrevFileImage must be non-null.
364 static void ilAddImageToList (
366 ilFileImagePtr pFileImage,
367 ilFileImagePtr pPrevFileImage
370 pFileImage->p.pNext = pFileImage->p.pPrev =
371 pFileImage->p.pChild = pFileImage->p.pMask = (ilFileImage)NULL;
373 switch (pFileImage->imageType) {
375 if (pPrevFileImage->imageType == childImage)
376 pPrevFileImage->p.pNext = (ilFileImage)pFileImage;
377 else pPrevFileImage->p.pChild = (ilFileImage)pFileImage;
381 pPrevFileImage->p.pMask = (ilFileImage)pFileImage;
384 /* Main image: if page # present, add to list in page order, else add to end */
386 if (pFileImage->p.nPages < 0) { /* no page #; add to end of list */
387 if ((pFileImage->p.pPrev = (ilFileImage)pFile->pFileImageTail))
388 pFileImage->p.pPrev->pNext = (ilFileImage)pFileImage;
389 else pFile->pFileImageHead = pFileImage;
392 /* Have page #. If list is empty or page # <= that of first element in
393 list, add pFileImage to front of list; otherwise find place in list
394 based on page # and insert image in that place.
396 pPrevFileImage = pFile->pFileImageHead;
397 if (!pPrevFileImage || (pFileImage->p.page <= pPrevFileImage->p.page)) {
398 pFileImage->p.pNext = (ilFileImage)pPrevFileImage; /* add to front */
399 pFileImage->p.pPrev = (ilFileImage)NULL;
400 pFile->pFileImageHead = pFileImage;
402 else { /* Add after pPrevFileImage w/ highest page # <= image's page # */
403 while (pPrevFileImage->p.pNext
404 && (pPrevFileImage->p.pNext->page <= pFileImage->p.page)) {
405 pPrevFileImage = (ilFileImagePtr)pPrevFileImage->p.pNext;
407 pFileImage->p.pNext = pPrevFileImage->p.pNext;
408 pFileImage->p.pPrev = (ilFileImage)pPrevFileImage;
409 pPrevFileImage->p.pNext = (ilFileImage)pFileImage;
413 /* Point next in list, or tail if this image is last, back to this image */
414 if (pFileImage->p.pNext)
415 pFileImage->p.pNext->pPrev = (ilFileImage)pFileImage;
416 else pFile->pFileImageTail = pFileImage;
422 /* --------------------- ilReadTagsAndAddImageToList ------------------------ */
423 /* Look at the tag values in the given file image "*pFileImage", and if the tags
424 indicate a supported image, add it to the list of file images in "*pFile".
425 If image is not supported (e.g unknown compression type) the image is freed.
426 ppPrevFileImage must point to the ptr to the previous image read from the
427 file, or null if this is the first image; used for child and mask images.
428 Return IL_OK if image valid, even if not supported; an error means
429 the image is malformed (e.g. missing required tag).
431 static ilError ilReadTagsAndAddImageToList (
433 ilFileImagePtr *ppPrevFileImage,
434 ilFileImagePtr pFileImage
437 /* Indexes into "tagNumbers" below. NOTE: order is important, as tags are checked
438 in the below order, and some tags default to values which must be before them.
439 Also NOTE: check for type other than short/long and # items done below!
441 #define NEW_SUBFILE_TYPE 0
442 #define IMAGE_WIDTH 1
443 #define IMAGE_LENGTH 2
444 #define RESOLUTION_UNIT 3
445 #define X_RESOLUTION 4 /* follow RESOLUTION_UNIT */
446 #define Y_RESOLUTION 5 /* follow RESOLUTION_UNIT */
447 #define ROWS_PER_STRIP 6 /* follow IMAGE_WIDTH */
448 #define SAMPLES_PER_PIXEL 7
449 #define PLANAR_CONFIGURATION 8 /* follow SAMPLES_PER_PIXEL */
450 #define BITS_PER_SAMPLE 9 /* follow SAMPLES_PER_PIXEL */
451 #define FILL_ORDER 10
452 #define GROUP_3_OPTIONS 11 /* follow FILL_ORDER */
453 #define GROUP_4_OPTIONS 12 /* follow FILL_ORDER */
454 #define COMPRESSION 13 /* follow GROUP_3/4_OPTIONS, FILL_ORDER */
455 #define PREDICTOR 14 /* follow COMPRESSION */
456 #define PHOTOMETRIC_INTERPRETATION 15 /* follow COMP, BITS_PS, SAMPLES_PP, NEW_SFT */
457 #define PAGE_NUMBER 16 /* follow NEW_SFT */
458 #define JPEG_PROC 17 /* follow COMPRESSION */
459 #define YCBCR_COEFFICIENTS 18 /* follow PHOTO_INT */
460 #define YCBCR_SUBSAMPLING 19 /* follow PHOTO_INT */
461 #define YCBCR_POSITIONING 20 /* follow PHOTO_INT */
462 #define REFERENCE_BLACK_WHITE 21 /* follow PHOTO_INT */
463 #define PRIVATE_0 22 /* follow PHOTO_INT */
465 static unsigned short tagNumbers [] = {
466 IL_TAG_NEW_SUBFILE_TYPE,
469 IL_TAG_RESOLUTION_UNIT,
472 IL_TAG_ROWS_PER_STRIP,
473 IL_TAG_SAMPLES_PER_PIXEL,
474 IL_TAG_PLANAR_CONFIGURATION,
475 IL_TAG_BITS_PER_SAMPLE,
477 IL_TAG_GROUP_3_OPTIONS,
478 IL_TAG_GROUP_4_OPTIONS,
481 IL_TAG_PHOTOMETRIC_INTERPRETATION,
484 IL_TAG_YCBCR_COEFFICIENTS,
485 IL_TAG_YCBCR_SUBSAMPLING,
486 IL_TAG_YCBCR_POSITIONING,
487 IL_TAG_REFERENCE_BLACK_WHITE,
490 #define AI_NTAGS (sizeof(tagNumbers) / sizeof (unsigned short))
491 #define AIL_FATAL_ERROR(_error) {error = (_error); goto AILFatalError; }
493 ilFileImageRelation imageType;
494 ilFileTag *tag [AI_NTAGS];
499 int i, tagIndex, nBits, resolutionUnit, fillOrder;
500 unsigned long group3CompData;
501 unsigned long group4CompData;
503 ilYCbCrInfo *pYCbCr; /* null if not YCbCr ; else -> des...YCbCr */
505 /* Init/zero des and format in *pFileImage.
507 IL_INIT_IMAGE_DES (&pFileImage->p.des)
508 IL_INIT_IMAGE_FORMAT (&pFileImage->p.format)
510 /* Read the above file tags; fatal error if error returned.
512 pTagAlloc = ilReadFileTags ((ilFileImage)pFileImage, AI_NTAGS, tagNumbers, tag, 0);
514 return (pFileImage->context->error) ?
515 pFileImage->context->error : IL_ERROR_FILE_MISSING_TAG;
517 /* Loop thru the tags; set "present" true if tag found, set "value" to integer
518 value of tag (long or short allowed - exceptions checked explicitly - else
520 Fix bug #0169: ignore tags with # items <= 0.
522 for (tagIndex = 0; tagIndex < AI_NTAGS; tagIndex++) {
523 if ((pTag = tag [tagIndex]) && (pTag->nItems > 0)) {
524 if (pTag->type == IL_TAG_SHORT)
525 value = *((unsigned short *)pTag->pItems);
526 else if (pTag->type == IL_TAG_LONG)
527 /* compatibility problem with long and unsigned long data fields */
528 value = *((CARD32 *)pTag->pItems);
529 else if ((tagIndex != X_RESOLUTION)
530 && (tagIndex != Y_RESOLUTION)
531 && (tagIndex != YCBCR_COEFFICIENTS)
532 && (tagIndex != REFERENCE_BLACK_WHITE))
533 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
534 if (pTag->nItems != 1) {
535 if ((tagIndex != BITS_PER_SAMPLE)
536 && (tagIndex != PAGE_NUMBER)
537 && (tagIndex != YCBCR_COEFFICIENTS)
538 && (tagIndex != YCBCR_SUBSAMPLING)
539 && (tagIndex != REFERENCE_BLACK_WHITE)
540 && (tagIndex != PRIVATE_0))
541 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
545 else present = FALSE;
547 /* Parse the tags and fill in pFileImage->format, des. Init des first.
548 See page 8 in the TIFF v5.0 spec for info on each tag type.
551 case NEW_SUBFILE_TYPE:
552 if (present && (value & 4)) imageType = maskImage;
553 else if (present && (value & 1)) imageType = childImage;
554 else imageType = mainImage;
558 if (!present) AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
559 pFileImage->p.width = value;
563 if (!present) AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
564 pFileImage->p.height = value;
567 /* Resolution returned as dpi * 2, or "0" if not present. The TIFF
568 spec says should default to 300 dpi if not present, but we let
569 the caller make that assumption.
571 case RESOLUTION_UNIT:
573 resolutionUnit = 2; /* default to inches */
574 else resolutionUnit = value;
583 if (pTag->type != IL_TAG_RATIONAL)
584 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
585 /* compatibility problem with long and unsigned long data fields */
586 value = *((INT32 *)pTag->pItems);
587 denom = *((INT32 *)pTag->pItems + 1);
588 if (resolutionUnit == 3) /* centimeters */
589 value = (denom == 0) ? 0 : (double)value / 2.54 / (double)denom + 0.5;
590 else /* not centimeters: assume inches */
591 value = (denom == 0) ? 0 : (double)value / (double)denom + 0.5;
593 if (tagIndex == X_RESOLUTION)
594 pFileImage->p.xRes = value;
595 else pFileImage->p.yRes = value;
600 if (!present || (((long)value) < 0) || (value > pFileImage->p.height))
601 pFileImage->p.stripHeight = pFileImage->p.height;
602 else pFileImage->p.stripHeight = value;
605 case SAMPLES_PER_PIXEL:
606 if (!present) value = 1;
608 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
609 if (value > IL_MAX_SAMPLES)
610 goto UnsupportedImage;
611 pFileImage->p.des.nSamplesPerPixel = value;
614 /* Planar configuration: default to pixels unless more than one
615 sample, and value is present and is 2.
617 case PLANAR_CONFIGURATION:
618 pFileImage->p.format.sampleOrder = ((pFileImage->p.des.nSamplesPerPixel != 1)
619 && present && (value == 2)) ? IL_SAMPLE_PLANES : IL_SAMPLE_PIXELS;
622 /* bits per sample: default to 1, or to first item (in "value") if
623 fewer items than samples per pixel.
625 case BITS_PER_SAMPLE:
626 for (i = 0; i < pFileImage->p.des.nSamplesPerPixel; i++)
627 pFileImage->p.format.nBitsPerSample [i] = (!present || (pTag->nItems < 1)) ?
628 1 : ((i > pTag->nItems - 1) ? value : *((unsigned short *)pTag->pItems + i));
631 /* FillOrder: used for class F only (TIFF compression "3")
634 fillOrder = (present && (value == 2)) ? IL_LSB_FIRST : IL_MSB_FIRST;
637 /* Parse group 3 TIFF options, assumed to be 0 if not present.
638 As per TIFF spec, don't support if any unrecognized bits are not 0.
639 Note that "group3CompData" is set to 0 below if comp = 2 (TIFF G3).
641 case GROUP_3_OPTIONS:
642 group3CompData = IL_G3M_EOL_MARKERS; /* EOL present if not "TIFF" G3 */
643 if (fillOrder == IL_LSB_FIRST)
644 group3CompData |= IL_G3M_LSB_FIRST;
647 goto UnsupportedImage; /* non-zero unhandled bits; unsupported */
649 group3CompData |= IL_G3M_2D;
651 group3CompData |= IL_G3M_UNCOMPRESSED;
653 group3CompData |= IL_G3M_EOL_UNALIGNED;
657 /* Group 4: set LSB first if FillOrder tag specifies it. If
658 Group4Options tag defined and any bit other than zero set (bit 0
659 is undefined) than consider image unsupported. Bit one (1) specifies
660 "uncompressed" mode which is not supported.
662 case GROUP_4_OPTIONS:
664 if (fillOrder == IL_LSB_FIRST)
665 group4CompData |= IL_G4M_LSB_FIRST;
668 goto UnsupportedImage; /* non-zero unhandled bits; unsupported */
673 if (!present) value = 1;
675 case 1: pFileImage->p.des.compression = IL_UNCOMPRESSED; break;
677 /* Comp codes 2 and 3 are both Group 3 - the difference is only in
678 what *pCompData describes. For code 2 ("TIFF" group 3), the comp
679 data is 0 - the bits were defined that way. For code 3, use what
680 was deciphered/defaulted by the group 3 options tag.
683 group3CompData = 0; /* "TIFF" G3 - default options, set to 0 */
684 case 3: /* "true" G3 */
685 pFileImage->p.des.compression = IL_G3;
686 pFileImage->p.des.compInfo.g3.flags = group3CompData;
689 case 4: pFileImage->p.des.compression = IL_G4;
690 pFileImage->p.des.compInfo.g4.flags = group4CompData;
692 case 5: pFileImage->p.des.compression = IL_LZW; break;
694 pFileImage->p.des.compression = IL_JPEG;
695 pFileImage->p.des.compInfo.JPEG.reserved = IL_JPEGM_RAW;
696 pFileImage->p.des.compInfo.JPEG.process = 0;
698 case 32773: pFileImage->p.des.compression = IL_PACKBITS; break;
699 default: goto UnsupportedImage;
703 /* NOTE: predictive LZW not supported yet !!!!
706 if (present && (value != 1) && (pFileImage->p.des.compression == IL_LZW))
707 goto UnsupportedImage;
710 /* If no photometric interpration, default based on (assumed) image
711 type: 1 sample: 1 bit/pixel: bitonal, white=0 if fax comp, else 1;
712 > 1 bit/pixel: gray, black=0.
713 3 samples: RGB; else error.
715 case PHOTOMETRIC_INTERPRETATION:
716 pYCbCr = (ilYCbCrInfo *)NULL; /* unless a YCbCr image */
718 if (pFileImage->p.des.nSamplesPerPixel == 1) {
719 if (pFileImage->p.format.nBitsPerSample[0] == 1) {
720 pFileImage->p.des.type = IL_BITONAL;
721 switch (pFileImage->p.des.compression) {
722 case IL_G3: case IL_G4:
723 pFileImage->p.des.blackIsZero = FALSE;
726 pFileImage->p.des.blackIsZero = TRUE;
731 pFileImage->p.des.type = IL_GRAY;
732 pFileImage->p.des.blackIsZero = TRUE;
735 else if (pFileImage->p.des.nSamplesPerPixel == 3)
736 pFileImage->p.des.type = IL_RGB;
737 else AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
739 else switch (value) { /* photo interpretation present; handle it */
741 /* Bitonal or gray; 0 = white is 0, else black is zero. */
744 if (pFileImage->p.des.nSamplesPerPixel != 1)
745 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
746 pFileImage->p.des.blackIsZero = (value == 1);
747 pFileImage->p.des.type = (pFileImage->p.format.nBitsPerSample[0] == 1) ?
748 IL_BITONAL : IL_GRAY;
753 if (pFileImage->p.des.nSamplesPerPixel != 3)
754 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
755 pFileImage->p.des.type = IL_RGB;
758 /* Palette images: max of 8 bits */
760 if (pFileImage->p.des.nSamplesPerPixel != 1)
761 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
762 if (pFileImage->p.format.nBitsPerSample[0] > 8)
763 goto UnsupportedImage;
764 pFileImage->p.des.type = IL_PALETTE;
767 /* Mask image: is bitonal */
769 if (pFileImage->p.des.nSamplesPerPixel != 1)
770 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
771 pFileImage->p.des.type = IL_BITONAL;
772 pFileImage->p.des.blackIsZero = FALSE;
773 imageType = maskImage;
776 /* YCbCr: set pYCbCr to non-null */
778 if (pFileImage->p.des.nSamplesPerPixel != 3)
779 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
780 pFileImage->p.des.type = IL_YCBCR;
781 pYCbCr = &pFileImage->p.des.typeInfo.YCbCr; /* point to YCbCr data */
784 /* Others not supported */
785 default: goto UnsupportedImage;
791 if ((pTag->nItems != 2) || (pTag->type != IL_TAG_SHORT))
792 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
793 pFileImage->p.page = value;
794 pFileImage->p.nPages = *((unsigned short *)pTag->pItems + 1);
796 else pFileImage->p.page = pFileImage->p.nPages = -1;
799 /* JPEG tags: ignore if not JPEG compression */
801 if (pFileImage->p.des.compression == IL_JPEG) {
802 if (!present) AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
803 if (value != 1) /* only baseline sequential supported! */
804 goto UnsupportedImage;
808 /* YCbCr tags: ignored if not YCbCr image */
809 case YCBCR_COEFFICIENTS:
812 pYCbCr->lumaRed = 2990;
813 pYCbCr->lumaGreen = 5870;
814 pYCbCr->lumaBlue = 1140;
817 /* compatibility problem with long or unsigned long data fields */
818 INT32 *pLong = (INT32 *)pTag->pItems;
820 if ((pTag->nItems != 3) || (pTag->type != IL_TAG_RATIONAL))
821 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
822 num = *pLong++; denom = *pLong++;
823 pYCbCr->lumaRed = num/denom * 10000;
824 num = *pLong++; denom = *pLong++;
825 pYCbCr->lumaGreen = num/denom * 10000;
826 num = *pLong++; denom = *pLong++;
827 pYCbCr->lumaBlue = num/denom * 10000;
832 case YCBCR_SUBSAMPLING:
835 pYCbCr->sample[1].subsampleHoriz = pYCbCr->sample[1].subsampleVert = 2;
837 if ((pTag->nItems != 2) || (pTag->type != IL_TAG_SHORT))
838 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
839 pYCbCr->sample[1].subsampleHoriz = *((short *)pTag->pItems);
840 pYCbCr->sample[1].subsampleVert = *((short *)pTag->pItems + 1);
842 /* Set Y subsampling to (1,1); copy Cr to Cb: defined by TIFF */
843 pYCbCr->sample[0].subsampleHoriz = pYCbCr->sample[0].subsampleVert = 1;
844 pYCbCr->sample[2].subsampleHoriz = pYCbCr->sample[1].subsampleHoriz;
845 pYCbCr->sample[2].subsampleVert = pYCbCr->sample[1].subsampleVert;
849 /* Ignore positioning for now; set to zero (0) */
850 case YCBCR_POSITIONING:
852 pYCbCr->positioning = 0;
855 /* ReferenceBlackWhite: if present, allow tag type to be "long" or "rational".
856 "rational" is the correct tag type; "long" was written by Image 1 (the
857 first Developer's Kit that supported JPEG), so support the old files.
859 case REFERENCE_BLACK_WHITE:
861 ilYCbCrSampleInfo *pSample = pYCbCr->sample;
864 pSample->refBlack = 0; pSample->refWhite = 255; pSample++;
865 pSample->refBlack = 0; pSample->refWhite = 255; pSample++;
866 pSample->refBlack = 0; pSample->refWhite = 255; pSample++;
869 /* compatibility problem with long and unsigned long data fields */
870 INT32 *pLong = (INT32 *)pTag->pItems;
871 if (pTag->nItems != 6)
872 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
873 if (pTag->type == IL_TAG_LONG) { /* old type */
874 for (i = 0; i < 3; i++, pSample++) {
875 pSample->refBlack = *pLong++;
876 pSample->refWhite = *pLong++;
879 else if (pTag->type == IL_TAG_RATIONAL) { /* correct TIFF 6.0 type */
881 for (i = 0; i < 3; i++, pSample++) {
884 pSample->refBlack = (denom == 1) ? num :
885 (double)num / (double)denom + 0.5;
888 pSample->refWhite = (denom == 1) ? num :
889 (double)num / (double)denom + 0.5;
892 else AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG); /* bad tag type */
897 /* HP IL private tag. See /ilc/iltiffint.h for definition.
898 If "dithered palette" mask on, set levels and bit in flags in des.
902 if (value & IL_TAG_P0_FLAG_DITHER_LEVELS) {
903 if (pFileImage->p.des.type == IL_PALETTE) {
904 short *pLevel = ((short *)pTag->pItems + 1);
905 if ((pTag->nItems < 4) || (pTag->type != IL_TAG_SHORT))
906 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
907 pFileImage->p.des.flags |= IL_DITHERED_PALETTE;
908 pFileImage->p.des.typeInfo.palette.levels[0] = *pLevel++;
909 pFileImage->p.des.typeInfo.palette.levels[1] = *pLevel++;
910 pFileImage->p.des.typeInfo.palette.levels[2] = *pLevel++;
916 } /* END switch tag index */
919 /* All the tags are parsed and valid so far. Finish filling in *pFileImage;
920 # levels is inferred from # bits; only supporting byte/sample for now.
922 for (i = 0; i < pFileImage->p.des.nSamplesPerPixel; i++) {
923 nBits = pFileImage->p.format.nBitsPerSample [i];
925 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE); /* error; invalid # bits */
927 goto UnsupportedImage; /* not error, not supported */
928 pFileImage->p.des.nLevelsPerSample [i] = 1 << nBits;
930 pFileImage->p.format.byteOrder = IL_MSB_FIRST; /* arbitrary! */
931 pFileImage->p.format.rowBitAlign = 8; /* by TIFF definition */
933 /* If mask image: must be bitonal or discard it. */
934 if (imageType == maskImage) {
935 ilFileImagePtr pPrevFileImage = *ppPrevFileImage;
936 if (!pPrevFileImage /* no image before it */
937 || pPrevFileImage->p.pMask /* already has mask */
938 || (pFileImage->p.des.nSamplesPerPixel != 1)
939 || (pFileImage->p.format.nBitsPerSample[0] != 1))
940 goto UnsupportedImage; /* reject image */
943 /* If a child image and no previous image, make a main image and add it. */
944 if ((imageType == childImage) && !*ppPrevFileImage)
945 imageType = mainImage;
947 /* Add image to list, make previous image unless a mask image */
948 pFileImage->imageType = imageType; /* child/mask/mainImage */
949 ilAddImageToList (pFile, pFileImage, *ppPrevFileImage);
950 if (imageType != maskImage)
951 *ppPrevFileImage = pFileImage;
953 free (pTagAlloc); /* free() as client would */
954 return IL_OK; /* success; EXIT */
956 /* Error: free pTagAlloc, but not pFileImage - caller does that. Return error.
957 Use free(), not IL_FREE(), to free pTagAlloc, just like caller should.
964 /* Image is not supported; not an error, but don't add to list - free image.
967 IL_FREE (pFileImage);
972 /* ------------------------ ilListFileImages ------------------------------- */
973 /* Public function: see spec.
975 ilFileImage ilListFileImages (
977 unsigned long mustBeZero
981 long imageSequenceNumber;
982 ilByte fourBytes [4];
983 ilFileOffset IFDOffset;
984 ilFileImagePtr pFileImage, pPrevFileImage;
989 /* Check if image list already built - if so, return ptr to it.
991 pFile = (ilFilePtr)file;
992 if (mustBeZero != 0) {
993 pFile->o.p.context->error = IL_ERROR_PAR_NOT_ZERO;
994 return (ilFileImage)NULL; /* EXIT */
996 if (pFile->haveImageList) {
997 pFile->o.p.context->error = IL_OK;
998 return (ilFileImage)pFile->pFileImageHead; /* EXIT */
1001 ilFreeFileList (pFile); /* remove potential invalid image list */
1003 /* Don't have image list - read file and build the list. When done,
1004 pFile->IFDTailPtrOffset points to the "next IFD" ptr which is null, i.e.
1005 the next IFD ptr for the last image in the file. For a file with no images
1006 that would be the ptr in the file header.
1007 First read header to get ptr to first image in file.
1010 /* Used when this module is compiled by the DtHelp library build */
1011 if (_DtGrSeek (pFile->stream, pFile->offset, 0)) {
1013 if (fseek (pFile->stream, pFile->offset, 0)) {
1015 pFile->o.p.context->error = IL_ERROR_FILE_IO;
1016 return (ilFileImage)NULL;
1019 /* Used when this module is compiled by the DtHelp library build */
1020 if (!_DtGrRead ((char *)&header, sizeof (header), 1, pFile->stream)) {
1022 if (!fread ((char *)&header, sizeof (header), 1, pFile->stream)) {
1024 pFile->o.p.context->error = IL_ERROR_FILE_IO;
1025 return (ilFileImage)NULL;
1027 IL_FLIP_LONG (pFile->bigEndian, header.IFDHeadOffset, IFDOffset);
1029 pFile->haveImageList = TRUE;
1030 pFile->IFDTailPtrOffset = 4; /* point to first IFD ptr in header */
1031 imageSequenceNumber = 0;
1032 bigEndian = pFile->bigEndian;
1033 pPrevFileImage = (ilFileImagePtr)NULL;
1035 /* Overview: read the tag count, allocate room for tags (pBeginTagBuffer) and
1036 read the unflipped tags into it. Allocate space for converted tags
1037 (pFile->pTags) and copy/flip unflipped tags into it.
1038 After the tags comes the offset to next IFD; read and flip it.
1041 imageSequenceNumber++;
1042 pFileImage = (ilFileImagePtr)IL_MALLOC_ZERO (sizeof (ilFileImageRec));
1044 error = IL_ERROR_MALLOC;
1048 pFileImage->p.file = (ilFile)pFile;
1049 pFileImage->context = pFile->o.p.context;
1051 /* Read and flip the tagCount, @IFDOffset. Point tagOffset at next location.
1053 if (!IL_SEEK (pFile, IFDOffset)
1054 || !IL_READ (pFile, 2, fourBytes)) {
1055 error = IL_ERROR_FILE_IO;
1058 IL_FLIP_SHORT (bigEndian, fourBytes, pFileImage->tagCount);
1059 pFileImage->tagOffset = IFDOffset + 2;
1061 /* Add file image to list, if supported. An error is returned only if
1062 the file image is malformed; not if it is just unsupported.
1064 if ((error = ilReadTagsAndAddImageToList (pFile, &pPrevFileImage, pFileImage)))
1065 goto LFIFatalError; /* fatal error returned; EXIT */
1067 /* Read and flip offset to next IFD, at end of tags; save in pFile. */
1068 IFDOffset += pFileImage->tagCount * IL_TAG_SIZE + 2;
1069 pFile->IFDTailPtrOffset = IFDOffset;
1070 if (!IL_SEEK (pFile, IFDOffset)
1071 || !IL_READ (pFile, 4, fourBytes)) {
1072 error = IL_ERROR_FILE_IO;
1075 IL_FLIP_LONG (bigEndian, fourBytes, IFDOffset);
1078 /* Images accessed successfully; return ok; */
1079 pFile->o.p.context->error = IL_OK;
1080 return (ilFileImage)pFile->pFileImageHead; /* EXIT */
1082 /* Fatal error: dispose file list and pFileImage if non-null, return "error",
1083 and sequence # of image in file that provoked the error.
1087 IL_FREE (pFileImage);
1088 ilFreeFileList (pFile);
1089 pFile->o.p.context->error = error;
1090 pFile->o.p.context->errorInfo = imageSequenceNumber;
1091 return (ilFileImage)NULL;
1095 /* ------------------------ ilConnectFile -------------------------------- */
1096 /* Public function: see spec.
1097 Locate a TIFF file at "offset" within "file", and return a handle used
1098 to access this file, or return null and an error code.
1100 ilFile ilConnectFile (
1103 /* Used when this module is compiled by the DtHelp library build */
1104 _DtGrStream *stream,
1109 unsigned long mustBeZero
1114 ilTIFFHeader header;
1116 if (mustBeZero != 0) {
1117 context->error = IL_ERROR_PAR_NOT_ZERO;
1118 return (ilPipe)NULL;
1121 /* Read what should be a TIFF file header at "offset" within "file".
1122 Verify that byte order is "MM" (bigEndian) or "II" (!bigEndian) or error.
1123 Verify the answer to life, the universe, and everything ...
1126 /* Used when this module is compiled by the DtHelp library build */
1127 if (_DtGrSeek (stream, offset, 0)) { /* nonzero means error for fseek */
1129 if (fseek (stream, offset, 0)) { /* nonzero means error for fseek */
1131 context->error = IL_ERROR_FILE_IO;
1132 return (ilFile)NULL;
1135 /* Used when this module is compiled by the DtHelp library build */
1136 if (!_DtGrRead ((char *)&header, sizeof (header), 1, stream)) {
1138 if (!fread ((char *)&header, sizeof (header), 1, stream)) {
1140 context->error = IL_ERROR_FILE_IO;
1141 return (ilFile)NULL;
1143 if ((header.byteOrder[0] == 'M') && (header.byteOrder[1] == 'M'))
1145 else if ((header.byteOrder[0] == 'I') && (header.byteOrder[1] == 'I'))
1148 context->error = IL_ERROR_FILE_NOT_TIFF;
1149 return (ilFile)NULL;
1151 if (!(bigEndian && (header.version[0] == 0) && (header.version[1] == 42))
1152 && !(!bigEndian && (header.version[0] == 42) && (header.version[1] == 0))) {
1153 context->error = IL_ERROR_FILE_NOT_TIFF;
1154 return (ilFile)NULL;
1157 /* File seems to be a valid TIFF file. Create an ilFileRec object, init it
1158 and return ptr to it.
1160 pFile = (ilFilePtr)_ilCreateObject (context, IL_FILE, ilFreeFileList, sizeof(ilFileRec));
1162 return (ilFile)NULL; /* context->error already set */
1164 pFile->stream = stream;
1165 pFile->offset = offset;
1166 pFile->bigEndian = bigEndian;
1167 pFile->pFileImageHead = pFile->pFileImageTail = (ilFileImagePtr)NULL;
1168 pFile->haveImageList = FALSE;
1170 context->error = IL_OK;
1171 return (ilFile)pFile;