4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
30 * Core Directory Tag Support.
36 * NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
37 * If a tag can have both LONG and SHORT types
38 * then the LONG must be placed before the SHORT for
39 * writing to work properly.
41 static const TIFFFieldInfo tiffFieldInfo
[] = {
42 { TIFFTAG_SUBFILETYPE
, 1, 1, TIFF_LONG
, FIELD_SUBFILETYPE
,
43 TRUE
, FALSE
, "SubfileType" },
44 /* XXX SHORT for compatibility w/ old versions of the library */
45 { TIFFTAG_SUBFILETYPE
, 1, 1, TIFF_SHORT
, FIELD_SUBFILETYPE
,
46 TRUE
, FALSE
, "SubfileType" },
47 { TIFFTAG_OSUBFILETYPE
, 1, 1, TIFF_SHORT
, FIELD_SUBFILETYPE
,
48 TRUE
, FALSE
, "OldSubfileType" },
49 { TIFFTAG_IMAGEWIDTH
, 1, 1, TIFF_LONG
, FIELD_IMAGEDIMENSIONS
,
50 FALSE
, FALSE
, "ImageWidth" },
51 { TIFFTAG_IMAGEWIDTH
, 1, 1, TIFF_SHORT
, FIELD_IMAGEDIMENSIONS
,
52 FALSE
, FALSE
, "ImageWidth" },
53 { TIFFTAG_IMAGELENGTH
, 1, 1, TIFF_LONG
, FIELD_IMAGEDIMENSIONS
,
54 TRUE
, FALSE
, "ImageLength" },
55 { TIFFTAG_IMAGELENGTH
, 1, 1, TIFF_SHORT
, FIELD_IMAGEDIMENSIONS
,
56 TRUE
, FALSE
, "ImageLength" },
57 { TIFFTAG_BITSPERSAMPLE
, -1,-1, TIFF_SHORT
, FIELD_BITSPERSAMPLE
,
58 FALSE
, FALSE
, "BitsPerSample" },
59 { TIFFTAG_COMPRESSION
, -1, 1, TIFF_SHORT
, FIELD_COMPRESSION
,
60 FALSE
, FALSE
, "Compression" },
61 { TIFFTAG_PHOTOMETRIC
, 1, 1, TIFF_SHORT
, FIELD_PHOTOMETRIC
,
62 FALSE
, FALSE
, "PhotometricInterpretation" },
63 { TIFFTAG_THRESHHOLDING
, 1, 1, TIFF_SHORT
, FIELD_THRESHHOLDING
,
64 TRUE
, FALSE
, "Threshholding" },
65 { TIFFTAG_CELLWIDTH
, 1, 1, TIFF_SHORT
, FIELD_IGNORE
,
66 TRUE
, FALSE
, "CellWidth" },
67 { TIFFTAG_CELLLENGTH
, 1, 1, TIFF_SHORT
, FIELD_IGNORE
,
68 TRUE
, FALSE
, "CellLength" },
69 { TIFFTAG_FILLORDER
, 1, 1, TIFF_SHORT
, FIELD_FILLORDER
,
70 FALSE
, FALSE
, "FillOrder" },
71 { TIFFTAG_DOCUMENTNAME
, -1,-1, TIFF_ASCII
, FIELD_DOCUMENTNAME
,
72 TRUE
, FALSE
, "DocumentName" },
73 { TIFFTAG_IMAGEDESCRIPTION
, -1,-1, TIFF_ASCII
, FIELD_IMAGEDESCRIPTION
,
74 TRUE
, FALSE
, "ImageDescription" },
75 { TIFFTAG_MAKE
, -1,-1, TIFF_ASCII
, FIELD_MAKE
,
76 TRUE
, FALSE
, "Make" },
77 { TIFFTAG_MODEL
, -1,-1, TIFF_ASCII
, FIELD_MODEL
,
78 TRUE
, FALSE
, "Model" },
79 { TIFFTAG_STRIPOFFSETS
, -1,-1, TIFF_LONG
, FIELD_STRIPOFFSETS
,
80 FALSE
, FALSE
, "StripOffsets" },
81 { TIFFTAG_STRIPOFFSETS
, -1,-1, TIFF_SHORT
, FIELD_STRIPOFFSETS
,
82 FALSE
, FALSE
, "StripOffsets" },
83 { TIFFTAG_ORIENTATION
, 1, 1, TIFF_SHORT
, FIELD_ORIENTATION
,
84 FALSE
, FALSE
, "Orientation" },
85 { TIFFTAG_SAMPLESPERPIXEL
, 1, 1, TIFF_SHORT
, FIELD_SAMPLESPERPIXEL
,
86 FALSE
, FALSE
, "SamplesPerPixel" },
87 { TIFFTAG_ROWSPERSTRIP
, 1, 1, TIFF_LONG
, FIELD_ROWSPERSTRIP
,
88 FALSE
, FALSE
, "RowsPerStrip" },
89 { TIFFTAG_ROWSPERSTRIP
, 1, 1, TIFF_SHORT
, FIELD_ROWSPERSTRIP
,
90 FALSE
, FALSE
, "RowsPerStrip" },
91 { TIFFTAG_STRIPBYTECOUNTS
, -1,-1, TIFF_LONG
, FIELD_STRIPBYTECOUNTS
,
92 FALSE
, FALSE
, "StripByteCounts" },
93 { TIFFTAG_STRIPBYTECOUNTS
, -1,-1, TIFF_SHORT
, FIELD_STRIPBYTECOUNTS
,
94 FALSE
, FALSE
, "StripByteCounts" },
95 { TIFFTAG_MINSAMPLEVALUE
, -2,-1, TIFF_SHORT
, FIELD_MINSAMPLEVALUE
,
96 TRUE
, FALSE
, "MinSampleValue" },
97 { TIFFTAG_MAXSAMPLEVALUE
, -2,-1, TIFF_SHORT
, FIELD_MAXSAMPLEVALUE
,
98 TRUE
, FALSE
, "MaxSampleValue" },
99 { TIFFTAG_XRESOLUTION
, 1, 1, TIFF_RATIONAL
, FIELD_RESOLUTION
,
100 FALSE
, FALSE
, "XResolution" },
101 { TIFFTAG_YRESOLUTION
, 1, 1, TIFF_RATIONAL
, FIELD_RESOLUTION
,
102 FALSE
, FALSE
, "YResolution" },
103 { TIFFTAG_PLANARCONFIG
, 1, 1, TIFF_SHORT
, FIELD_PLANARCONFIG
,
104 FALSE
, FALSE
, "PlanarConfiguration" },
105 { TIFFTAG_PAGENAME
, -1,-1, TIFF_ASCII
, FIELD_PAGENAME
,
106 TRUE
, FALSE
, "PageName" },
107 { TIFFTAG_XPOSITION
, 1, 1, TIFF_RATIONAL
, FIELD_POSITION
,
108 TRUE
, FALSE
, "XPosition" },
109 { TIFFTAG_YPOSITION
, 1, 1, TIFF_RATIONAL
, FIELD_POSITION
,
110 TRUE
, FALSE
, "YPosition" },
111 { TIFFTAG_FREEOFFSETS
, -1,-1, TIFF_LONG
, FIELD_IGNORE
,
112 FALSE
, FALSE
, "FreeOffsets" },
113 { TIFFTAG_FREEBYTECOUNTS
, -1,-1, TIFF_LONG
, FIELD_IGNORE
,
114 FALSE
, FALSE
, "FreeByteCounts" },
115 { TIFFTAG_GRAYRESPONSEUNIT
, 1, 1, TIFF_SHORT
, FIELD_IGNORE
,
116 TRUE
, FALSE
, "GrayResponseUnit" },
117 { TIFFTAG_GRAYRESPONSECURVE
,-1,-1, TIFF_SHORT
, FIELD_IGNORE
,
118 TRUE
, FALSE
, "GrayResponseCurve" },
119 { TIFFTAG_RESOLUTIONUNIT
, 1, 1, TIFF_SHORT
, FIELD_RESOLUTIONUNIT
,
120 FALSE
, FALSE
, "ResolutionUnit" },
121 { TIFFTAG_PAGENUMBER
, 2, 2, TIFF_SHORT
, FIELD_PAGENUMBER
,
122 TRUE
, FALSE
, "PageNumber" },
123 { TIFFTAG_COLORRESPONSEUNIT
, 1, 1, TIFF_SHORT
, FIELD_IGNORE
,
124 TRUE
, FALSE
, "ColorResponseUnit" },
125 #ifdef COLORIMETRY_SUPPORT
126 { TIFFTAG_TRANSFERFUNCTION
, -1,-1, TIFF_SHORT
, FIELD_TRANSFERFUNCTION
,
127 TRUE
, FALSE
, "TransferFunction" },
129 { TIFFTAG_SOFTWARE
, -1,-1, TIFF_ASCII
, FIELD_SOFTWARE
,
130 TRUE
, FALSE
, "Software" },
131 { TIFFTAG_DATETIME
, 20,20, TIFF_ASCII
, FIELD_DATETIME
,
132 TRUE
, FALSE
, "DateTime" },
133 { TIFFTAG_ARTIST
, -1,-1, TIFF_ASCII
, FIELD_ARTIST
,
134 TRUE
, FALSE
, "Artist" },
135 { TIFFTAG_HOSTCOMPUTER
, -1,-1, TIFF_ASCII
, FIELD_HOSTCOMPUTER
,
136 TRUE
, FALSE
, "HostComputer" },
137 #ifdef COLORIMETRY_SUPPORT
138 { TIFFTAG_WHITEPOINT
, 2, 2, TIFF_RATIONAL
,FIELD_WHITEPOINT
,
139 TRUE
, FALSE
, "WhitePoint" },
140 { TIFFTAG_PRIMARYCHROMATICITIES
,6,6,TIFF_RATIONAL
,FIELD_PRIMARYCHROMAS
,
141 TRUE
, FALSE
, "PrimaryChromaticities" },
143 { TIFFTAG_COLORMAP
, -1,-1, TIFF_SHORT
, FIELD_COLORMAP
,
144 TRUE
, FALSE
, "ColorMap" },
145 { TIFFTAG_HALFTONEHINTS
, 2, 2, TIFF_SHORT
, FIELD_HALFTONEHINTS
,
146 TRUE
, FALSE
, "HalftoneHints" },
147 { TIFFTAG_TILEWIDTH
, 1, 1, TIFF_LONG
, FIELD_TILEDIMENSIONS
,
148 FALSE
, FALSE
, "TileWidth" },
149 { TIFFTAG_TILEWIDTH
, 1, 1, TIFF_SHORT
, FIELD_TILEDIMENSIONS
,
150 FALSE
, FALSE
, "TileWidth" },
151 { TIFFTAG_TILELENGTH
, 1, 1, TIFF_LONG
, FIELD_TILEDIMENSIONS
,
152 FALSE
, FALSE
, "TileLength" },
153 { TIFFTAG_TILELENGTH
, 1, 1, TIFF_SHORT
, FIELD_TILEDIMENSIONS
,
154 FALSE
, FALSE
, "TileLength" },
155 { TIFFTAG_TILEOFFSETS
, -1, 1, TIFF_LONG
, FIELD_STRIPOFFSETS
,
156 FALSE
, FALSE
, "TileOffsets" },
157 { TIFFTAG_TILEBYTECOUNTS
, -1, 1, TIFF_LONG
, FIELD_STRIPBYTECOUNTS
,
158 FALSE
, FALSE
, "TileByteCounts" },
159 { TIFFTAG_TILEBYTECOUNTS
, -1, 1, TIFF_SHORT
, FIELD_STRIPBYTECOUNTS
,
160 FALSE
, FALSE
, "TileByteCounts" },
161 #ifdef TIFFTAG_SUBIFD
162 { TIFFTAG_SUBIFD
, -1,-1, TIFF_LONG
, FIELD_SUBIFD
,
163 TRUE
, TRUE
, "SubIFD" },
165 #ifdef CMYK_SUPPORT /* 6.0 CMYK tags */
166 { TIFFTAG_INKSET
, 1, 1, TIFF_SHORT
, FIELD_INKSET
,
167 FALSE
, FALSE
, "InkSet" },
168 { TIFFTAG_INKNAMES
, -1,-1, TIFF_ASCII
, FIELD_INKNAMES
,
169 TRUE
, TRUE
, "InkNames" },
170 { TIFFTAG_NUMBEROFINKS
, 1, 1, TIFF_SHORT
, FIELD_NUMBEROFINKS
,
171 TRUE
, FALSE
, "NumberOfInks" },
172 { TIFFTAG_DOTRANGE
, 2, 2, TIFF_SHORT
, FIELD_DOTRANGE
,
173 FALSE
, FALSE
, "DotRange" },
174 { TIFFTAG_DOTRANGE
, 2, 2, TIFF_BYTE
, FIELD_DOTRANGE
,
175 FALSE
, FALSE
, "DotRange" },
176 { TIFFTAG_TARGETPRINTER
, -1,-1, TIFF_ASCII
, FIELD_TARGETPRINTER
,
177 TRUE
, FALSE
, "TargetPrinter" },
179 { TIFFTAG_EXTRASAMPLES
, -1,-1, TIFF_SHORT
, FIELD_EXTRASAMPLES
,
180 FALSE
, FALSE
, "ExtraSamples" },
181 /* XXX for bogus Adobe Photoshop v2.5 files */
182 { TIFFTAG_EXTRASAMPLES
, -1,-1, TIFF_BYTE
, FIELD_EXTRASAMPLES
,
183 FALSE
, FALSE
, "ExtraSamples" },
184 { TIFFTAG_SAMPLEFORMAT
, -1,-1, TIFF_SHORT
, FIELD_SAMPLEFORMAT
,
185 FALSE
, FALSE
, "SampleFormat" },
186 { TIFFTAG_SMINSAMPLEVALUE
, -2,-1, TIFF_ANY
, FIELD_SMINSAMPLEVALUE
,
187 TRUE
, FALSE
, "SMinSampleValue" },
188 { TIFFTAG_SMAXSAMPLEVALUE
, -2,-1, TIFF_ANY
, FIELD_SMAXSAMPLEVALUE
,
189 TRUE
, FALSE
, "SMaxSampleValue" },
190 #ifdef YCBCR_SUPPORT /* 6.0 YCbCr tags */
191 { TIFFTAG_YCBCRCOEFFICIENTS
, 3, 3, TIFF_RATIONAL
, FIELD_YCBCRCOEFFICIENTS
,
192 FALSE
, FALSE
, "YCbCrCoefficients" },
193 { TIFFTAG_YCBCRSUBSAMPLING
, 2, 2, TIFF_SHORT
, FIELD_YCBCRSUBSAMPLING
,
194 FALSE
, FALSE
, "YCbCrSubsampling" },
195 { TIFFTAG_YCBCRPOSITIONING
, 1, 1, TIFF_SHORT
, FIELD_YCBCRPOSITIONING
,
196 FALSE
, FALSE
, "YCbCrPositioning" },
198 #ifdef COLORIMETRY_SUPPORT
199 { TIFFTAG_REFERENCEBLACKWHITE
,6,6,TIFF_RATIONAL
, FIELD_REFBLACKWHITE
,
200 TRUE
, FALSE
, "ReferenceBlackWhite" },
201 /* XXX temporarily accept LONG for backwards compatibility */
202 { TIFFTAG_REFERENCEBLACKWHITE
,6,6,TIFF_LONG
, FIELD_REFBLACKWHITE
,
203 TRUE
, FALSE
, "ReferenceBlackWhite" },
206 { TIFFTAG_MATTEING
, 1, 1, TIFF_SHORT
, FIELD_EXTRASAMPLES
,
207 FALSE
, FALSE
, "Matteing" },
208 { TIFFTAG_DATATYPE
, -2,-1, TIFF_SHORT
, FIELD_SAMPLEFORMAT
,
209 FALSE
, FALSE
, "DataType" },
210 { TIFFTAG_IMAGEDEPTH
, 1, 1, TIFF_LONG
, FIELD_IMAGEDEPTH
,
211 FALSE
, FALSE
, "ImageDepth" },
212 { TIFFTAG_IMAGEDEPTH
, 1, 1, TIFF_SHORT
, FIELD_IMAGEDEPTH
,
213 FALSE
, FALSE
, "ImageDepth" },
214 { TIFFTAG_TILEDEPTH
, 1, 1, TIFF_LONG
, FIELD_TILEDEPTH
,
215 FALSE
, FALSE
, "TileDepth" },
216 { TIFFTAG_TILEDEPTH
, 1, 1, TIFF_SHORT
, FIELD_TILEDEPTH
,
217 FALSE
, FALSE
, "TileDepth" },
220 #ifdef PHOTOSHOP_SUPPORT
221 { TIFFTAG_RICHTIFFIPTC
, -1,-1, TIFF_LONG
, FIELD_RICHTIFFIPTC
,
222 FALSE
, TRUE
, "RichTIFFIPTC" },
224 { TIFFTAG_RICHTIFFIPTC
, -1,-3, TIFF_UNDEFINED
, FIELD_RICHTIFFIPTC
,
225 FALSE
, TRUE
, "RichTIFFIPTC" },
228 #ifdef PHOTOSHOP_SUPPORT
229 { TIFFTAG_PHOTOSHOP
, -1,-3, TIFF_UNDEFINED
, FIELD_PHOTOSHOP
,
230 FALSE
, TRUE
, "Photoshop" },
231 { TIFFTAG_PHOTOSHOP
, -1,-1, TIFF_BYTE
, FIELD_PHOTOSHOP
,
232 FALSE
, TRUE
, "Photoshop" },
235 { TIFFTAG_ICCPROFILE
, -1,-3, TIFF_UNDEFINED
, FIELD_ICCPROFILE
,
236 FALSE
, TRUE
, "ICC Profile" },
238 { TIFFTAG_STONITS
, 1, 1, TIFF_DOUBLE
, FIELD_STONITS
,
239 FALSE
, FALSE
, "StoNits" },
241 #define N(a) (sizeof (a) / sizeof (a[0]))
244 _TIFFSetupFieldInfo(TIFF
* tif
)
246 if (tif
->tif_fieldinfo
) {
247 _TIFFfree(tif
->tif_fieldinfo
);
248 tif
->tif_nfields
= 0;
250 _TIFFMergeFieldInfo(tif
, tiffFieldInfo
, N(tiffFieldInfo
));
254 tagCompare(const void* a
, const void* b
)
256 const TIFFFieldInfo
* ta
= *(const TIFFFieldInfo
**) a
;
257 const TIFFFieldInfo
* tb
= *(const TIFFFieldInfo
**) b
;
258 /* NB: be careful of return values for 16-bit platforms */
259 if (ta
->field_tag
!= tb
->field_tag
)
260 return (ta
->field_tag
< tb
->field_tag
? -1 : 1);
262 return (tb
->field_type
< ta
->field_type
? -1 : 1);
266 _TIFFMergeFieldInfo(TIFF
* tif
, const TIFFFieldInfo info
[], int n
)
271 if (tif
->tif_nfields
> 0) {
272 tif
->tif_fieldinfo
= (TIFFFieldInfo
**)
273 _TIFFrealloc(tif
->tif_fieldinfo
,
274 (tif
->tif_nfields
+n
) * sizeof (TIFFFieldInfo
*));
276 tif
->tif_fieldinfo
= (TIFFFieldInfo
**)
277 _TIFFmalloc(n
* sizeof (TIFFFieldInfo
*));
279 tp
= &tif
->tif_fieldinfo
[tif
->tif_nfields
];
280 for (i
= 0; i
< n
; i
++)
281 tp
[i
] = (TIFFFieldInfo
*) &info
[i
]; /* XXX */
283 * NB: the core tags are presumed sorted correctly.
285 if (tif
->tif_nfields
> 0)
286 qsort(tif
->tif_fieldinfo
, (size_t) (tif
->tif_nfields
+= n
),
287 sizeof (TIFFFieldInfo
*), tagCompare
);
289 tif
->tif_nfields
+= n
;
293 _TIFFPrintFieldInfo(TIFF
* tif
, FILE* fd
)
297 fprintf(fd
, "%s: \n", tif
->tif_name
);
298 for (i
= 0; i
< tif
->tif_nfields
; i
++) {
299 const TIFFFieldInfo
* fip
= tif
->tif_fieldinfo
[i
];
300 fprintf(fd
, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
302 , (unsigned long) fip
->field_tag
303 , fip
->field_readcount
, fip
->field_writecount
306 , fip
->field_oktochange
? "TRUE" : "FALSE"
307 , fip
->field_passcount
? "TRUE" : "FALSE"
313 const int tiffDataWidth
[] = {
319 8, /* TIFF_RATIONAL */
321 1, /* TIFF_UNDEFINED */
324 8, /* TIFF_SRATIONAL */
330 * Return nearest TIFFDataType to the sample type of an image.
333 _TIFFSampleToTagType(TIFF
* tif
)
335 int bps
= (int) TIFFhowmany(tif
->tif_dir
.td_bitspersample
, 8);
337 switch (tif
->tif_dir
.td_sampleformat
) {
338 case SAMPLEFORMAT_IEEEFP
:
339 return (bps
== 4 ? TIFF_FLOAT
: TIFF_DOUBLE
);
340 case SAMPLEFORMAT_INT
:
341 return (bps
<= 1 ? TIFF_SBYTE
:
342 bps
<= 2 ? TIFF_SSHORT
: TIFF_SLONG
);
343 case SAMPLEFORMAT_UINT
:
344 return (bps
<= 1 ? TIFF_BYTE
:
345 bps
<= 2 ? TIFF_SHORT
: TIFF_LONG
);
346 case SAMPLEFORMAT_VOID
:
347 return (TIFF_UNDEFINED
);
350 return (TIFF_UNDEFINED
);
354 _TIFFFindFieldInfo(TIFF
* tif
, ttag_t tag
, TIFFDataType dt
)
356 static const TIFFFieldInfo
*last
= NULL
;
359 if (last
&& last
->field_tag
== tag
&&
360 (dt
== TIFF_ANY
|| dt
== last
->field_type
))
362 /* NB: if table gets big, use sorted search (e.g. binary search) */
363 for (i
= 0, n
= tif
->tif_nfields
; i
< n
; i
++) {
364 const TIFFFieldInfo
* fip
= tif
->tif_fieldinfo
[i
];
365 if (fip
->field_tag
== tag
&&
366 (dt
== TIFF_ANY
|| fip
->field_type
== dt
))
369 return ((const TIFFFieldInfo
*)0);
376 _TIFFFieldWithTag(TIFF
* tif
, ttag_t tag
)
378 const TIFFFieldInfo
* fip
= _TIFFFindFieldInfo(tif
, tag
, TIFF_ANY
);
380 TIFFError("TIFFFieldWithTag",
381 "Internal error, unknown tag 0x%x", (u_int
) tag
);