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 librararies 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.
44 #include "iltiffint.h"
48 /* Used when this module is compiled by the DtHelp library build */
49 #include "GraphicsP.h"
52 /* Size in bytes of one item (# items = TIFF "length"), for each TIFF tag type.
53 Also, # of entries of that type which fit in one long.
54 Indexed by tag type = 1..IL_MAX_TAG_TYPE (0 entry unused).
56 IL_PRIVATE int _ilTagTypeItemSizes [IL_MAX_TAG_TYPE+1] = {
57 0, /* 0th entry unused; invalid tag type */
62 8 }; /* IL_TAG_RATIONAL */
64 IL_PRIVATE int _ilTagTypeItemsThatFit [IL_MAX_TAG_TYPE+1] = {
65 0, /* 0th entry unused; invalid tag type */
70 0 }; /* IL_TAG_RATIONAL */
72 /* Structure of the first 8 bytes of a TIFF file: see ilConnectFile() */
76 ilByte IFDHeadOffset[4];
80 /* ------------------------- ilFreeFileList -------------------------------- */
81 /* Free the file list in the given file "*pFile".
82 Note: ilFreeFileList() is also the Destroy() function for ilFile object.
85 static void ilFreeFileList (
89 register ilFileImagePtr pFileImage, pAltFileImage, pFileImageTemp;
91 /* Run thru the list of file images; for each: if a mask image destroy it
92 (only one); if child images, destroy them - they are linked by pChild.
94 pFileImage = pFile->pFileImageHead;
97 /* Destroy the mask image if present */
98 pAltFileImage = (ilFileImagePtr)pFileImage->p.pMask;
100 IL_FREE (pAltFileImage);
102 /* Destroy the child images if present. They are linked
103 by pNext, and each one can have a mask image.
105 pAltFileImage = (ilFileImagePtr)pFileImage->p.pChild;
106 while (pAltFileImage) {
107 if (pAltFileImage->p.pMask)
108 IL_FREE (pAltFileImage->p.pMask);
109 pFileImageTemp = pAltFileImage;
110 pAltFileImage = (ilFileImagePtr)pAltFileImage->p.pNext;
111 IL_FREE (pFileImageTemp);
114 /* Destroy the main image */
115 pFileImageTemp = pFileImage;
116 pFileImage = (ilFileImagePtr)pFileImage->p.pNext;
117 IL_FREE (pFileImageTemp);
120 /* Make the list empty and declare it invalid.
122 pFile->pFileImageHead = pFile->pFileImageTail = (ilFileImagePtr)NULL;
123 pFile->haveImageList = FALSE;
127 /* ----------------------- ilReadFileTags --------------------------------- */
128 /* Public function: see spec.
130 ilPtr ilReadFileTags (
131 ilFileImage fileImage,
133 unsigned short *pTagNumbers,
135 unsigned long mustBeZero
138 #define RFT_FATAL_ERROR(_error) {error = (_error); goto RFTFatalError; }
139 ilFileImagePtr pFileImage;
140 ilTIFFTagPtr pFileTag, pFileTags;
143 unsigned long readSize, mallocSize;
145 ilPtr pTagData, pTagAlloc;
147 ilFileTag *pTag, **ppTag;
148 int tagNumber, nFileTags, nItems, nTags, tagType, i;
149 register ilBool bigEndian;
151 pFileImage = (ilFileImagePtr)fileImage;
152 if (mustBeZero != 0) {
153 pFileImage->context->error = IL_ERROR_PAR_NOT_ZERO;
154 return (ilPtr)NULL; /* EXIT */
156 if (nTagsInit <= 0) {
157 pFileImage->context->error = IL_OK;
158 return (ilPtr)NULL; /* no tags; EXIT */
161 pFile = (ilFilePtr)pFileImage->p.file;
162 bigEndian = pFile->bigEndian;
164 /* Allocate space and read in all the file tags to "*pFileTags".
165 Flip the bytes of number, type and length, but not the data/offset.
167 pTagAlloc = (ilPtr)NULL; /* in case of fatal error */
168 readSize = pFileImage->tagCount * IL_TAG_SIZE;
169 pFileTags = (ilTIFFTagPtr)IL_MALLOC (readSize);
171 RFT_FATAL_ERROR (IL_ERROR_MALLOC)
172 if (!IL_SEEK (pFile, pFileImage->tagOffset)
173 || !IL_READ (pFile, readSize, pFileTags))
174 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
176 pFileTag = pFileTags;
177 pTagData = (ilPtr)pFileTag;
178 nFileTags = pFileImage->tagCount;
179 while (nFileTags-- > 0) {
180 IL_FLIP_SHORT (bigEndian, pTagData, pFileTag->number)
182 IL_FLIP_SHORT (bigEndian, pTagData, tagType)
184 /* NOTE: declare fatal error if tag type out of range, BUT TIFF 6.0 says
185 we should ignore these tags; ALSO, there are new tag types for 6.0.
187 if ((tagType == 0) || (tagType > IL_MAX_TAG_TYPE))
188 RFT_FATAL_ERROR (IL_ERROR_FILE_TAG_TYPE)
189 pFileTag->type = tagType;
191 IL_FLIP_LONG (bigEndian, pTagData, pFileTag->length)
192 pTagData += 8; /* skip length and data */
196 /* For each of caller's tags: find *pTagNumber in the pFileTags list.
197 If not found, set corresponding "ppTags" entry to null, else point it
198 at the found entry in pFileTags list, add its data size (rounded up to
199 multiple of 4 - long-align), and the size of one ilFileTag, to "mallocSize".
204 while (nTags-- > 0) {
205 tagNumber = *pTagNumbers++;
207 pFileTag = pFileTags;
208 nFileTags = pFileImage->tagCount;
209 while (nFileTags-- > 0) {
210 if (pFileTag->number == tagNumber) {
217 mallocSize += sizeof (ilFileTag) +
218 (pFileTag->length * _ilTagTypeItemSizes [pFileTag->type] + 3) & ~3;
219 *ppTag++ = (ilFileTag *)pFileTag;
221 else *ppTag++ = (ilFileTag *)NULL;
224 /* If no tags found; exit, else allocate "mallocSize" bytes, and for each found
225 tag, point corresponding "ppTags" to spot in pTagAlloc that has the ilFileTag
226 data, followed by the data itself, then long aligned.
227 What is returned will look like:
228 ppTags [0] == null if tag not present, else ->:
229 tag data: byte offset
230 number (same value as corresponding 0
231 entry in pTagsNumbers)
234 pItems (points to <items>, i.e. one 8
235 long past this spot, or null if
236 "nItems" is zero (0).
237 <items> - "nItems" occurrences of data 12
239 ppTags [1]-> <next tag, at offset 12 + ppTag[0]->nItems
240 * size in bytes of one ppTag[0] item,
241 as determined by "type".
243 if (mallocSize == 0) {
245 pFileImage->context->error = IL_OK;
246 return (ilPtr)NULL; /* EXIT */
248 pTagAlloc = (ilPtr)malloc (mallocSize); /* caller uses free() to free this */
250 RFT_FATAL_ERROR (IL_ERROR_MALLOC)
252 pTag = (ilFileTag *)pTagAlloc;
255 while (nTags-- > 0) {
257 ppTag++; /* tag not found, already null, next */
258 else { /* tag found */
259 pFileTag = (ilTIFFTagPtr)*ppTag; /* points to internal tag data */
260 *ppTag++ = pTag; /* point to converted data, next tag */
261 pTag->number = pFileTag->number; /* copy from pFileTags to pTagAlloc */
262 tagType = pTag->type = pFileTag->type;
263 nItems = pTag->nItems = pFileTag->length;
264 pTagData = (ilPtr)pTag + sizeof(ilFileTag);
267 pTag->pItems = (ilPtr)NULL;
268 pTag = (ilFileTag *)pTagData; /* point pTag to spot for next tag */
271 pTag->pItems = pTagData; /* data follows the tag */
272 pTag = (ilFileTag *)(pTagData + /* next spot = past data, long-aligned */
273 ((nItems * _ilTagTypeItemSizes [tagType] + 3) & ~3));
275 /* Byte flip the tag data to the spot pointed to by "pTagData",
276 i.e. right after the 12 bytes for the tag. In TIFF, the data
277 is in the "offset" field tag if it fits in 4 bytes, else offset
278 points to the data in the file - seek and read it in that case.
284 bcopy (pFileTag->data.chars, (char *)pTagData, nItems);
286 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
287 if (!IL_SEEK (pFile, offset)
288 || !IL_READ (pFile, nItems, pTagData))
289 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
295 for (i = 0; nItems > 0; nItems--, i += 2, pTagData += 2)
296 IL_FLIP_SHORT (bigEndian, pFileTag->data.chars + i,
297 *((unsigned short *)pTagData))
300 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
301 if (!IL_SEEK (pFile, offset)
302 || !IL_READ (pFile, nItems<<1, pTagData))
303 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
304 for (; nItems > 0; nItems--, pTagData += 2)
305 IL_FLIP_SHORT (bigEndian, pTagData, *((unsigned short *)pTagData))
311 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, *((INT32 *)pTagData))
313 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
314 if (!IL_SEEK (pFile, offset)
315 || !IL_READ (pFile, nItems<<2, pTagData))
316 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
317 for (; nItems > 0; nItems--, pTagData += 4)
318 IL_FLIP_LONG (bigEndian, pTagData, *((INT32 *)pTagData))
322 case IL_TAG_RATIONAL:
323 IL_FLIP_LONG (bigEndian, pFileTag->data.chars, offset)
324 if (!IL_SEEK (pFile, offset) || !IL_READ (pFile, nItems<<3, pTagData))
325 RFT_FATAL_ERROR (IL_ERROR_FILE_IO)
326 while (nItems-- > 0) {
327 IL_FLIP_LONG (bigEndian, pTagData, *((INT32 *)pTagData))
329 IL_FLIP_LONG (bigEndian, pTagData, *((INT32 *)pTagData))
334 } /* END nItems > 0 */
335 } /* END tag found */
336 } /* END each caller's tag */
338 /* Tags read succesfully: free pFileTags (local buffer); return pTagAlloc.
341 pFileImage->context->error = IL_OK;
342 return pTagAlloc; /* EXIT */
344 /* Fatal error: free pFileTags, pTagAlloc if not null, return error code, null.
351 pFileImage->context->error = error;
352 return (ilPtr)NULL; /* EXIT */
356 /* --------------------- ilAddImageToList --------------------------------- */
357 /* Called when forming file image list. "pPrevFileImage" is a pointer to the
358 previous non-mask image in the file; null if pFileImage first non-mask read.
359 pFileImage->imageType indicates whether image being added is
360 child/mask/mainImage; if child or mask, pPrevFileImage must be non-null.
362 static void ilAddImageToList (
364 register ilFileImagePtr pFileImage,
365 ilFileImagePtr pPrevFileImage
368 pFileImage->p.pNext = pFileImage->p.pPrev =
369 pFileImage->p.pChild = pFileImage->p.pMask = (ilFileImage)NULL;
371 switch (pFileImage->imageType) {
373 if (pPrevFileImage->imageType == childImage)
374 pPrevFileImage->p.pNext = (ilFileImage)pFileImage;
375 else pPrevFileImage->p.pChild = (ilFileImage)pFileImage;
379 pPrevFileImage->p.pMask = (ilFileImage)pFileImage;
382 /* Main image: if page # present, add to list in page order, else add to end */
384 if (pFileImage->p.nPages < 0) { /* no page #; add to end of list */
385 if (pFileImage->p.pPrev = (ilFileImage)pFile->pFileImageTail)
386 pFileImage->p.pPrev->pNext = (ilFileImage)pFileImage;
387 else pFile->pFileImageHead = pFileImage;
390 /* Have page #. If list is empty or page # <= that of first element in
391 list, add pFileImage to front of list; otherwise find place in list
392 based on page # and insert image in that place.
394 pPrevFileImage = pFile->pFileImageHead;
395 if (!pPrevFileImage || (pFileImage->p.page <= pPrevFileImage->p.page)) {
396 pFileImage->p.pNext = (ilFileImage)pPrevFileImage; /* add to front */
397 pFileImage->p.pPrev = (ilFileImage)NULL;
398 pFile->pFileImageHead = pFileImage;
400 else { /* Add after pPrevFileImage w/ highest page # <= image's page # */
401 while (pPrevFileImage->p.pNext
402 && (pPrevFileImage->p.pNext->page <= pFileImage->p.page)) {
403 pPrevFileImage = (ilFileImagePtr)pPrevFileImage->p.pNext;
405 pFileImage->p.pNext = pPrevFileImage->p.pNext;
406 pFileImage->p.pPrev = (ilFileImage)pPrevFileImage;
407 pPrevFileImage->p.pNext = (ilFileImage)pFileImage;
411 /* Point next in list, or tail if this image is last, back to this image */
412 if (pFileImage->p.pNext)
413 pFileImage->p.pNext->pPrev = (ilFileImage)pFileImage;
414 else pFile->pFileImageTail = pFileImage;
420 /* --------------------- ilReadTagsAndAddImageToList ------------------------ */
421 /* Look at the tag values in the given file image "*pFileImage", and if the tags
422 indicate a supported image, add it to the list of file images in "*pFile".
423 If image is not supported (e.g unknown compression type) the image is freed.
424 ppPrevFileImage must point to the ptr to the previous image read from the
425 file, or null if this is the first image; used for child and mask images.
426 Return IL_OK if image valid, even if not supported; an error means
427 the image is malformed (e.g. missing required tag).
429 static ilError ilReadTagsAndAddImageToList (
431 ilFileImagePtr *ppPrevFileImage,
432 register ilFileImagePtr pFileImage
435 /* Indexes into "tagNumbers" below. NOTE: order is important, as tags are checked
436 in the below order, and some tags default to values which must be before them.
437 Also NOTE: check for type other than short/long and # items done below!
439 #define NEW_SUBFILE_TYPE 0
440 #define IMAGE_WIDTH 1
441 #define IMAGE_LENGTH 2
442 #define RESOLUTION_UNIT 3
443 #define X_RESOLUTION 4 /* follow RESOLUTION_UNIT */
444 #define Y_RESOLUTION 5 /* follow RESOLUTION_UNIT */
445 #define ROWS_PER_STRIP 6 /* follow IMAGE_WIDTH */
446 #define SAMPLES_PER_PIXEL 7
447 #define PLANAR_CONFIGURATION 8 /* follow SAMPLES_PER_PIXEL */
448 #define BITS_PER_SAMPLE 9 /* follow SAMPLES_PER_PIXEL */
449 #define FILL_ORDER 10
450 #define GROUP_3_OPTIONS 11 /* follow FILL_ORDER */
451 #define GROUP_4_OPTIONS 12 /* follow FILL_ORDER */
452 #define COMPRESSION 13 /* follow GROUP_3/4_OPTIONS, FILL_ORDER */
453 #define PREDICTOR 14 /* follow COMPRESSION */
454 #define PHOTOMETRIC_INTERPRETATION 15 /* follow COMP, BITS_PS, SAMPLES_PP, NEW_SFT */
455 #define PAGE_NUMBER 16 /* follow NEW_SFT */
456 #define JPEG_PROC 17 /* follow COMPRESSION */
457 #define YCBCR_COEFFICIENTS 18 /* follow PHOTO_INT */
458 #define YCBCR_SUBSAMPLING 19 /* follow PHOTO_INT */
459 #define YCBCR_POSITIONING 20 /* follow PHOTO_INT */
460 #define REFERENCE_BLACK_WHITE 21 /* follow PHOTO_INT */
461 #define PRIVATE_0 22 /* follow PHOTO_INT */
463 static unsigned short tagNumbers [] = {
464 IL_TAG_NEW_SUBFILE_TYPE,
467 IL_TAG_RESOLUTION_UNIT,
470 IL_TAG_ROWS_PER_STRIP,
471 IL_TAG_SAMPLES_PER_PIXEL,
472 IL_TAG_PLANAR_CONFIGURATION,
473 IL_TAG_BITS_PER_SAMPLE,
475 IL_TAG_GROUP_3_OPTIONS,
476 IL_TAG_GROUP_4_OPTIONS,
479 IL_TAG_PHOTOMETRIC_INTERPRETATION,
482 IL_TAG_YCBCR_COEFFICIENTS,
483 IL_TAG_YCBCR_SUBSAMPLING,
484 IL_TAG_YCBCR_POSITIONING,
485 IL_TAG_REFERENCE_BLACK_WHITE,
488 #define AI_NTAGS (sizeof(tagNumbers) / sizeof (unsigned short))
489 #define AIL_FATAL_ERROR(_error) {error = (_error); goto AILFatalError; }
491 ilFileImageRelation imageType;
492 ilFileTag *tag [AI_NTAGS];
496 register unsigned long value;
497 int i, tagIndex, nBits, resolutionUnit, fillOrder;
498 unsigned long group3CompData;
499 unsigned long group4CompData;
500 register ilFileTag *pTag;
501 ilYCbCrInfo *pYCbCr; /* null if not YCbCr ; else -> des...YCbCr */
503 /* Init/zero des and format in *pFileImage.
505 IL_INIT_IMAGE_DES (&pFileImage->p.des)
506 IL_INIT_IMAGE_FORMAT (&pFileImage->p.format)
508 /* Read the above file tags; fatal error if error returned.
510 pTagAlloc = ilReadFileTags ((ilFileImage)pFileImage, AI_NTAGS, tagNumbers, tag, 0);
512 return (pFileImage->context->error) ?
513 pFileImage->context->error : IL_ERROR_FILE_MISSING_TAG;
515 /* Loop thru the tags; set "present" true if tag found, set "value" to integer
516 value of tag (long or short allowed - exceptions checked explicitly - else
518 Fix bug #0169: ignore tags with # items <= 0.
520 for (tagIndex = 0; tagIndex < AI_NTAGS; tagIndex++) {
521 if ((pTag = tag [tagIndex]) && (pTag->nItems > 0)) {
522 if (pTag->type == IL_TAG_SHORT)
523 value = *((unsigned short *)pTag->pItems);
524 else if (pTag->type == IL_TAG_LONG)
525 /* compatibility problem with long and unsigned long data fields */
526 value = *((CARD32 *)pTag->pItems);
527 else if ((tagIndex != X_RESOLUTION)
528 && (tagIndex != Y_RESOLUTION)
529 && (tagIndex != YCBCR_COEFFICIENTS)
530 && (tagIndex != REFERENCE_BLACK_WHITE))
531 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
532 if (pTag->nItems != 1) {
533 if ((tagIndex != BITS_PER_SAMPLE)
534 && (tagIndex != PAGE_NUMBER)
535 && (tagIndex != YCBCR_COEFFICIENTS)
536 && (tagIndex != YCBCR_SUBSAMPLING)
537 && (tagIndex != REFERENCE_BLACK_WHITE)
538 && (tagIndex != PRIVATE_0))
539 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
543 else present = FALSE;
545 /* Parse the tags and fill in pFileImage->format, des. Init des first.
546 See page 8 in the TIFF v5.0 spec for info on each tag type.
549 case NEW_SUBFILE_TYPE:
550 if (present && (value & 4)) imageType = maskImage;
551 else if (present && (value & 1)) imageType = childImage;
552 else imageType = mainImage;
556 if (!present) AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
557 pFileImage->p.width = value;
561 if (!present) AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
562 pFileImage->p.height = value;
565 /* Resolution returned as dpi * 2, or "0" if not present. The TIFF
566 spec says should default to 300 dpi if not present, but we let
567 the caller make that assumption.
569 case RESOLUTION_UNIT:
571 resolutionUnit = 2; /* default to inches */
572 else resolutionUnit = value;
581 if (pTag->type != IL_TAG_RATIONAL)
582 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
583 /* compatibility problem with long and unsigned long data fields */
584 value = *((INT32 *)pTag->pItems);
585 denom = *((INT32 *)pTag->pItems + 1);
586 if (resolutionUnit == 3) /* centimeters */
587 value = (denom == 0) ? 0 : (double)value / 2.54 / (double)denom + 0.5;
588 else /* not centimeters: assume inches */
589 value = (denom == 0) ? 0 : (double)value / (double)denom + 0.5;
591 if (tagIndex == X_RESOLUTION)
592 pFileImage->p.xRes = value;
593 else pFileImage->p.yRes = value;
598 if (!present || (((long)value) < 0) || (value > pFileImage->p.height))
599 pFileImage->p.stripHeight = pFileImage->p.height;
600 else pFileImage->p.stripHeight = value;
603 case SAMPLES_PER_PIXEL:
604 if (!present) value = 1;
606 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
607 if (value > IL_MAX_SAMPLES)
608 goto UnsupportedImage;
609 pFileImage->p.des.nSamplesPerPixel = value;
612 /* Planar configuration: default to pixels unless more than one
613 sample, and value is present and is 2.
615 case PLANAR_CONFIGURATION:
616 pFileImage->p.format.sampleOrder = ((pFileImage->p.des.nSamplesPerPixel != 1)
617 && present && (value == 2)) ? IL_SAMPLE_PLANES : IL_SAMPLE_PIXELS;
620 /* bits per sample: default to 1, or to first item (in "value") if
621 fewer items than samples per pixel.
623 case BITS_PER_SAMPLE:
624 for (i = 0; i < pFileImage->p.des.nSamplesPerPixel; i++)
625 pFileImage->p.format.nBitsPerSample [i] = (!present || (pTag->nItems < 1)) ?
626 1 : ((i > pTag->nItems - 1) ? value : *((unsigned short *)pTag->pItems + i));
629 /* FillOrder: used for class F only (TIFF compression "3")
632 fillOrder = (present && (value == 2)) ? IL_LSB_FIRST : IL_MSB_FIRST;
635 /* Parse group 3 TIFF options, assumed to be 0 if not present.
636 As per TIFF spec, dont support if any unrecognized bits are not 0.
637 Note that "group3CompData" is set to 0 below if comp = 2 (TIFF G3).
639 case GROUP_3_OPTIONS:
640 group3CompData = IL_G3M_EOL_MARKERS; /* EOL present if not "TIFF" G3 */
641 if (fillOrder == IL_LSB_FIRST)
642 group3CompData |= IL_G3M_LSB_FIRST;
645 goto UnsupportedImage; /* non-zero unhandled bits; unsupported */
647 group3CompData |= IL_G3M_2D;
649 group3CompData |= IL_G3M_UNCOMPRESSED;
651 group3CompData |= IL_G3M_EOL_UNALIGNED;
655 /* Group 4: set LSB first if FillOrder tag specifies it. If
656 Group4Options tag defined and any bit other than zero set (bit 0
657 is undefined) than consider image unsupported. Bit one (1) specifies
658 "uncompressed" mode which is not supported.
660 case GROUP_4_OPTIONS:
662 if (fillOrder == IL_LSB_FIRST)
663 group4CompData |= IL_G4M_LSB_FIRST;
666 goto UnsupportedImage; /* non-zero unhandled bits; unsupported */
671 if (!present) value = 1;
673 case 1: pFileImage->p.des.compression = IL_UNCOMPRESSED; break;
675 /* Comp codes 2 and 3 are both Group 3 - the difference is only in
676 what *pCompData describes. For code 2 ("TIFF" group 3), the comp
677 data is 0 - the bits were defined that way. For code 3, use what
678 was deciphered/defaulted by the group 3 options tag.
681 group3CompData = 0; /* "TIFF" G3 - default options, set to 0 */
682 case 3: /* "true" G3 */
683 pFileImage->p.des.compression = IL_G3;
684 pFileImage->p.des.compInfo.g3.flags = group3CompData;
687 case 4: pFileImage->p.des.compression = IL_G4;
688 pFileImage->p.des.compInfo.g4.flags = group4CompData;
690 case 5: pFileImage->p.des.compression = IL_LZW; break;
692 pFileImage->p.des.compression = IL_JPEG;
693 pFileImage->p.des.compInfo.JPEG.reserved = IL_JPEGM_RAW;
694 pFileImage->p.des.compInfo.JPEG.process = 0;
696 case 32773: pFileImage->p.des.compression = IL_PACKBITS; break;
697 default: goto UnsupportedImage;
701 /* NOTE: predictive LZW not supported yet !!!!
704 if (present && (value != 1) && (pFileImage->p.des.compression == IL_LZW))
705 goto UnsupportedImage;
708 /* If no photometric interpration, default based on (assumed) image
709 type: 1 sample: 1 bit/pixel: bitonal, white=0 if fax comp, else 1;
710 > 1 bit/pixel: gray, black=0.
711 3 samples: RGB; else error.
713 case PHOTOMETRIC_INTERPRETATION:
714 pYCbCr = (ilYCbCrInfo *)NULL; /* unless a YCbCr image */
716 if (pFileImage->p.des.nSamplesPerPixel == 1) {
717 if (pFileImage->p.format.nBitsPerSample[0] == 1) {
718 pFileImage->p.des.type = IL_BITONAL;
719 switch (pFileImage->p.des.compression) {
720 case IL_G3: case IL_G4:
721 pFileImage->p.des.blackIsZero = FALSE;
724 pFileImage->p.des.blackIsZero = TRUE;
729 pFileImage->p.des.type = IL_GRAY;
730 pFileImage->p.des.blackIsZero = TRUE;
733 else if (pFileImage->p.des.nSamplesPerPixel == 3)
734 pFileImage->p.des.type = IL_RGB;
735 else AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
737 else switch (value) { /* photo interpretation present; handle it */
739 /* Bitonal or gray; 0 = white is 0, else black is zero. */
742 if (pFileImage->p.des.nSamplesPerPixel != 1)
743 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
744 pFileImage->p.des.blackIsZero = (value == 1);
745 pFileImage->p.des.type = (pFileImage->p.format.nBitsPerSample[0] == 1) ?
746 IL_BITONAL : IL_GRAY;
751 if (pFileImage->p.des.nSamplesPerPixel != 3)
752 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
753 pFileImage->p.des.type = IL_RGB;
756 /* Palette images: max of 8 bits */
758 if (pFileImage->p.des.nSamplesPerPixel != 1)
759 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
760 if (pFileImage->p.format.nBitsPerSample[0] > 8)
761 goto UnsupportedImage;
762 pFileImage->p.des.type = IL_PALETTE;
765 /* Mask image: is bitonal */
767 if (pFileImage->p.des.nSamplesPerPixel != 1)
768 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
769 pFileImage->p.des.type = IL_BITONAL;
770 pFileImage->p.des.blackIsZero = FALSE;
771 imageType = maskImage;
774 /* YCbCr: set pYCbCr to non-null */
776 if (pFileImage->p.des.nSamplesPerPixel != 3)
777 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE);
778 pFileImage->p.des.type = IL_YCBCR;
779 pYCbCr = &pFileImage->p.des.typeInfo.YCbCr; /* point to YCbCr data */
782 /* Others not supported */
783 default: goto UnsupportedImage;
789 if ((pTag->nItems != 2) || (pTag->type != IL_TAG_SHORT))
790 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
791 pFileImage->p.page = value;
792 pFileImage->p.nPages = *((unsigned short *)pTag->pItems + 1);
794 else pFileImage->p.page = pFileImage->p.nPages = -1;
797 /* JPEG tags: ignore if not JPEG compression */
799 if (pFileImage->p.des.compression == IL_JPEG) {
800 if (!present) AIL_FATAL_ERROR (IL_ERROR_FILE_MISSING_TAG);
801 if (value != 1) /* only baseline sequential supported! */
802 goto UnsupportedImage;
806 /* YCbCr tags: ignored if not YCbCr image */
807 case YCBCR_COEFFICIENTS:
810 pYCbCr->lumaRed = 2990;
811 pYCbCr->lumaGreen = 5870;
812 pYCbCr->lumaBlue = 1140;
815 /* compatibility problem with long or unsigned long data fields */
816 register INT32 *pLong = (INT32 *)pTag->pItems;
818 if ((pTag->nItems != 3) || (pTag->type != IL_TAG_RATIONAL))
819 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
820 num = *pLong++; denom = *pLong++;
821 pYCbCr->lumaRed = num/denom * 10000;
822 num = *pLong++; denom = *pLong++;
823 pYCbCr->lumaGreen = num/denom * 10000;
824 num = *pLong++; denom = *pLong++;
825 pYCbCr->lumaBlue = num/denom * 10000;
830 case YCBCR_SUBSAMPLING:
833 pYCbCr->sample[1].subsampleHoriz = pYCbCr->sample[1].subsampleVert = 2;
835 if ((pTag->nItems != 2) || (pTag->type != IL_TAG_SHORT))
836 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
837 pYCbCr->sample[1].subsampleHoriz = *((short *)pTag->pItems);
838 pYCbCr->sample[1].subsampleVert = *((short *)pTag->pItems + 1);
840 /* Set Y subsampling to (1,1); copy Cr to Cb: defined by TIFF */
841 pYCbCr->sample[0].subsampleHoriz = pYCbCr->sample[0].subsampleVert = 1;
842 pYCbCr->sample[2].subsampleHoriz = pYCbCr->sample[1].subsampleHoriz;
843 pYCbCr->sample[2].subsampleVert = pYCbCr->sample[1].subsampleVert;
847 /* Ignore positioning for now; set to zero (0) */
848 case YCBCR_POSITIONING:
850 pYCbCr->positioning = 0;
853 /* ReferenceBlackWhite: if present, allow tag type to be "long" or "rational".
854 "rational" is the correct tag type; "long" was written by Image 1 (the
855 first Developer's Kit that supported JPEG), so support the old files.
857 case REFERENCE_BLACK_WHITE:
859 register ilYCbCrSampleInfo *pSample = pYCbCr->sample;
862 pSample->refBlack = 0; pSample->refWhite = 255; pSample++;
863 pSample->refBlack = 0; pSample->refWhite = 255; pSample++;
864 pSample->refBlack = 0; pSample->refWhite = 255; pSample++;
867 /* compatibility problem with long and unsigned long data fields */
868 register INT32 *pLong = (INT32 *)pTag->pItems;
869 if (pTag->nItems != 6)
870 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
871 if (pTag->type == IL_TAG_LONG) { /* old type */
872 for (i = 0; i < 3; i++, pSample++) {
873 pSample->refBlack = *pLong++;
874 pSample->refWhite = *pLong++;
877 else if (pTag->type == IL_TAG_RATIONAL) { /* correct TIFF 6.0 type */
879 for (i = 0; i < 3; i++, pSample++) {
882 pSample->refBlack = (denom == 1) ? num :
883 (double)num / (double)denom + 0.5;
886 pSample->refWhite = (denom == 1) ? num :
887 (double)num / (double)denom + 0.5;
890 else AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG); /* bad tag type */
895 /* HP IL private tag. See /ilc/iltiffint.h for definition.
896 If "dithered palette" mask on, set levels and bit in flags in des.
900 if (value & IL_TAG_P0_FLAG_DITHER_LEVELS) {
901 if (pFileImage->p.des.type == IL_PALETTE) {
902 register short *pLevel = ((short *)pTag->pItems + 1);
903 if ((pTag->nItems < 4) || (pTag->type != IL_TAG_SHORT))
904 AIL_FATAL_ERROR (IL_ERROR_FILE_MALFORMED_TAG);
905 pFileImage->p.des.flags |= IL_DITHERED_PALETTE;
906 pFileImage->p.des.typeInfo.palette.levels[0] = *pLevel++;
907 pFileImage->p.des.typeInfo.palette.levels[1] = *pLevel++;
908 pFileImage->p.des.typeInfo.palette.levels[2] = *pLevel++;
914 } /* END switch tag index */
917 /* All the tags are parsed and valid so far. Finish filling in *pFileImage;
918 # levels is inferred from # bits; only supporting byte/sample for now.
920 for (i = 0; i < pFileImage->p.des.nSamplesPerPixel; i++) {
921 nBits = pFileImage->p.format.nBitsPerSample [i];
923 AIL_FATAL_ERROR (IL_ERROR_FILE_TAG_VALUE); /* error; invalid # bits */
925 goto UnsupportedImage; /* not error, not supported */
926 pFileImage->p.des.nLevelsPerSample [i] = 1 << nBits;
928 pFileImage->p.format.byteOrder = IL_MSB_FIRST; /* arbitrary! */
929 pFileImage->p.format.rowBitAlign = 8; /* by TIFF definition */
931 /* If mask image: must be bitonal or discard it. */
932 if (imageType == maskImage) {
933 register ilFileImagePtr pPrevFileImage = *ppPrevFileImage;
934 if (!pPrevFileImage /* no image before it */
935 || pPrevFileImage->p.pMask /* already has mask */
936 || (pFileImage->p.des.nSamplesPerPixel != 1)
937 || (pFileImage->p.format.nBitsPerSample[0] != 1))
938 goto UnsupportedImage; /* reject image */
941 /* If a child image and no previous image, make a main image and add it. */
942 if ((imageType == childImage) && !*ppPrevFileImage)
943 imageType = mainImage;
945 /* Add image to list, make previous image unless a mask image */
946 pFileImage->imageType = imageType; /* child/mask/mainImage */
947 ilAddImageToList (pFile, pFileImage, *ppPrevFileImage);
948 if (imageType != maskImage)
949 *ppPrevFileImage = pFileImage;
951 free (pTagAlloc); /* free() as client would */
952 return IL_OK; /* success; EXIT */
954 /* Error: free pTagAlloc, but not pFileImage - caller does that. Return error.
955 Use free(), not IL_FREE(), to free pTagAlloc, just like caller should.
962 /* Image is not supported; not an error, but don't add to list - free image.
965 IL_FREE (pFileImage);
970 /* ------------------------ ilListFileImages ------------------------------- */
971 /* Public function: see spec.
973 ilFileImage ilListFileImages (
975 unsigned long mustBeZero
979 long imageSequenceNumber;
980 ilByte fourBytes [4];
981 ilFileOffset IFDOffset;
982 ilFileImagePtr pFileImage, pFileImageHead, pPrevFileImage;
984 register ilFilePtr pFile;
985 register ilBool bigEndian;
987 /* Check if image list already built - if so, return ptr to it.
989 pFile = (ilFilePtr)file;
990 if (mustBeZero != 0) {
991 pFile->o.p.context->error = IL_ERROR_PAR_NOT_ZERO;
992 return (ilFileImage)NULL; /* EXIT */
994 if (pFile->haveImageList) {
995 pFile->o.p.context->error = IL_OK;
996 return (ilFileImage)pFile->pFileImageHead; /* EXIT */
999 ilFreeFileList (pFile); /* remove potential invalid image list */
1001 /* Dont have image list - read file and build the list. When done,
1002 pFile->IFDTailPtrOffset points to the "next IFD" ptr which is null, i.e.
1003 the next IFD ptr for the last image in the file. For a file with no images
1004 that would be the ptr in the file header.
1005 First read header to get ptr to first image in file.
1008 /* Used when this module is compiled by the DtHelp library build */
1009 if (_DtGrSeek (pFile->stream, pFile->offset, 0)) {
1011 if (fseek (pFile->stream, pFile->offset, 0)) {
1013 pFile->o.p.context->error = IL_ERROR_FILE_IO;
1014 return (ilFileImage)NULL;
1017 /* Used when this module is compiled by the DtHelp library build */
1018 if (!_DtGrRead ((char *)&header, sizeof (header), 1, pFile->stream)) {
1020 if (!fread ((char *)&header, sizeof (header), 1, pFile->stream)) {
1022 pFile->o.p.context->error = IL_ERROR_FILE_IO;
1023 return (ilFileImage)NULL;
1025 IL_FLIP_LONG (pFile->bigEndian, header.IFDHeadOffset, IFDOffset);
1027 pFile->haveImageList = TRUE;
1028 pFile->IFDTailPtrOffset = 4; /* point to first IFD ptr in header */
1029 imageSequenceNumber = 0;
1030 bigEndian = pFile->bigEndian;
1031 pPrevFileImage = (ilFileImagePtr)NULL;
1033 /* Overview: read the tag count, allocate room for tags (pBeginTagBuffer) and
1034 read the unflipped tags into it. Allocate space for converted tags
1035 (pFile->pTags) and copy/flip unflipped tags into it.
1036 After the tags comes the offset to next IFD; read and flip it.
1039 imageSequenceNumber++;
1040 pFileImage = (ilFileImagePtr)IL_MALLOC_ZERO (sizeof (ilFileImageRec));
1042 error = IL_ERROR_MALLOC;
1046 pFileImage->p.file = (ilFile)pFile;
1047 pFileImage->context = pFile->o.p.context;
1049 /* Read and flip the tagCount, @IFDOffset. Point tagOffset at next location.
1051 if (!IL_SEEK (pFile, IFDOffset)
1052 || !IL_READ (pFile, 2, fourBytes)) {
1053 error = IL_ERROR_FILE_IO;
1056 IL_FLIP_SHORT (bigEndian, fourBytes, pFileImage->tagCount);
1057 pFileImage->tagOffset = IFDOffset + 2;
1059 /* Add file image to list, if supported. An error is returned only if
1060 the file image is malformed; not if it is just unsupported.
1062 if (error = ilReadTagsAndAddImageToList (pFile, &pPrevFileImage, pFileImage))
1063 goto LFIFatalError; /* fatal error returned; EXIT */
1065 /* Read and flip offset to next IFD, at end of tags; save in pFile. */
1066 IFDOffset += pFileImage->tagCount * IL_TAG_SIZE + 2;
1067 pFile->IFDTailPtrOffset = IFDOffset;
1068 if (!IL_SEEK (pFile, IFDOffset)
1069 || !IL_READ (pFile, 4, fourBytes)) {
1070 error = IL_ERROR_FILE_IO;
1073 IL_FLIP_LONG (bigEndian, fourBytes, IFDOffset);
1076 /* Images accessed successfully; return ok; */
1077 pFile->o.p.context->error = IL_OK;
1078 return (ilFileImage)pFile->pFileImageHead; /* EXIT */
1080 /* Fatal error: dispose file list and pFileImage if non-null, return "error",
1081 and sequence # of image in file that provoked the error.
1085 IL_FREE (pFileImage);
1086 ilFreeFileList (pFile);
1087 pFile->o.p.context->error = error;
1088 pFile->o.p.context->errorInfo = imageSequenceNumber;
1089 return (ilFileImage)NULL;
1093 /* ------------------------ ilConnectFile -------------------------------- */
1094 /* Public function: see spec.
1095 Locate a TIFF file at "offset" within "file", and return a handle used
1096 to access this file, or return null and an error code.
1098 ilFile ilConnectFile (
1101 /* Used when this module is compiled by the DtHelp library build */
1102 _DtGrStream *stream,
1107 unsigned long mustBeZero
1112 ilTIFFHeader header;
1114 if (mustBeZero != 0) {
1115 context->error = IL_ERROR_PAR_NOT_ZERO;
1116 return (ilPipe)NULL;
1119 /* Read what should be a TIFF file header at "offset" within "file".
1120 Verify that byte order is "MM" (bigEndian) or "II" (!bigEndian) or error.
1121 Verify the answer to life, the universe, and everything ...
1124 /* Used when this module is compiled by the DtHelp library build */
1125 if (_DtGrSeek (stream, offset, 0)) { /* nonzero means error for fseek */
1127 if (fseek (stream, offset, 0)) { /* nonzero means error for fseek */
1129 context->error = IL_ERROR_FILE_IO;
1130 return (ilFile)NULL;
1133 /* Used when this module is compiled by the DtHelp library build */
1134 if (!_DtGrRead ((char *)&header, sizeof (header), 1, stream)) {
1136 if (!fread ((char *)&header, sizeof (header), 1, stream)) {
1138 context->error = IL_ERROR_FILE_IO;
1139 return (ilFile)NULL;
1141 if ((header.byteOrder[0] == 'M') && (header.byteOrder[1] == 'M'))
1143 else if ((header.byteOrder[0] == 'I') && (header.byteOrder[1] == 'I'))
1146 context->error = IL_ERROR_FILE_NOT_TIFF;
1147 return (ilFile)NULL;
1149 if (!(bigEndian && (header.version[0] == 0) && (header.version[1] == 42))
1150 && !(!bigEndian && (header.version[0] == 42) && (header.version[1] == 0))) {
1151 context->error = IL_ERROR_FILE_NOT_TIFF;
1152 return (ilFile)NULL;
1155 /* File seems to be a valid TIFF file. Create an ilFileRec object, init it
1156 and return ptr to it.
1158 pFile = (ilFilePtr)_ilCreateObject (context, IL_FILE, ilFreeFileList, sizeof(ilFileRec));
1160 return (ilFile)NULL; /* context->error already set */
1162 pFile->stream = stream;
1163 pFile->offset = offset;
1164 pFile->bigEndian = bigEndian;
1165 pFile->pFileImageHead = pFile->pFileImageTail = (ilFileImagePtr)NULL;
1166 pFile->haveImageList = FALSE;
1168 context->error = IL_OK;
1169 return (ilFile)pFile;