1 /* $Id: tif_dirinfo.c,v 1.62 2006/02/07 10:45:38 dron Exp $ */
2 
3 /*
4  * Copyright (c) 1988-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
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.
14  *
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.
18  *
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
24  * OF THIS SOFTWARE.
25  */
26 
27 /*
28  * TIFF Library.
29  *
30  * Core Directory Tag Support.
31  */
32 #include "tiffiop.h"
33 #include <stdlib.h>
34 
35 /*
36  * NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
37  *       If a tag can have both LONG and SHORT types then the LONG must be
38  *       placed before the SHORT for writing to work properly.
39  *
40  * NOTE: The second field (field_readcount) and third field (field_writecount)
41  *       sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
42  *       and TIFFTAG_SPP (-2). The macros should be used but would throw off
43  *       the formatting of the code, so please interprete the -1, -2 and -3
44  *       values accordingly.
45  */
46 static const TIFFFieldInfo
47 tiffFieldInfo[] = {
48     { TIFFTAG_SUBFILETYPE,	 1, 1,	TIFF_LONG,	FIELD_SUBFILETYPE,
49       1,	0,	"SubfileType" },
50 /* XXX SHORT for compatibility w/ old versions of the library */
51     { TIFFTAG_SUBFILETYPE,	 1, 1,	TIFF_SHORT,	FIELD_SUBFILETYPE,
52       1,	0,	"SubfileType" },
53     { TIFFTAG_OSUBFILETYPE,	 1, 1,	TIFF_SHORT,	FIELD_SUBFILETYPE,
54       1,	0,	"OldSubfileType" },
55     { TIFFTAG_IMAGEWIDTH,	 1, 1,	TIFF_LONG,	FIELD_IMAGEDIMENSIONS,
56       0,	0,	"ImageWidth" },
57     { TIFFTAG_IMAGEWIDTH,	 1, 1,	TIFF_SHORT,	FIELD_IMAGEDIMENSIONS,
58       0,	0,	"ImageWidth" },
59     { TIFFTAG_IMAGELENGTH,	 1, 1,	TIFF_LONG,	FIELD_IMAGEDIMENSIONS,
60       1,	0,	"ImageLength" },
61     { TIFFTAG_IMAGELENGTH,	 1, 1,	TIFF_SHORT,	FIELD_IMAGEDIMENSIONS,
62       1,	0,	"ImageLength" },
63     { TIFFTAG_BITSPERSAMPLE,	-1,-1,	TIFF_SHORT,	FIELD_BITSPERSAMPLE,
64       0,	0,	"BitsPerSample" },
65 /* XXX LONG for compatibility with some broken TIFF writers */
66     { TIFFTAG_BITSPERSAMPLE,	-1,-1,	TIFF_LONG,	FIELD_BITSPERSAMPLE,
67       0,	0,	"BitsPerSample" },
68     { TIFFTAG_COMPRESSION,	-1, 1,	TIFF_SHORT,	FIELD_COMPRESSION,
69       0,	0,	"Compression" },
70 /* XXX LONG for compatibility with some broken TIFF writers */
71     { TIFFTAG_COMPRESSION,	-1, 1,	TIFF_LONG,	FIELD_COMPRESSION,
72       0,	0,	"Compression" },
73     { TIFFTAG_PHOTOMETRIC,	 1, 1,	TIFF_SHORT,	FIELD_PHOTOMETRIC,
74       0,	0,	"PhotometricInterpretation" },
75 /* XXX LONG for compatibility with some broken TIFF writers */
76     { TIFFTAG_PHOTOMETRIC,	 1, 1,	TIFF_LONG,	FIELD_PHOTOMETRIC,
77       0,	0,	"PhotometricInterpretation" },
78     { TIFFTAG_THRESHHOLDING,	 1, 1,	TIFF_SHORT,	FIELD_THRESHHOLDING,
79       1,	0,	"Threshholding" },
80     { TIFFTAG_CELLWIDTH,	 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
81       1,	0,	"CellWidth" },
82     { TIFFTAG_CELLLENGTH,	 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
83       1,	0,	"CellLength" },
84     { TIFFTAG_FILLORDER,	 1, 1,	TIFF_SHORT,	FIELD_FILLORDER,
85       0,	0,	"FillOrder" },
86     { TIFFTAG_DOCUMENTNAME,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
87       1,	0,	"DocumentName" },
88     { TIFFTAG_IMAGEDESCRIPTION,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
89       1,	0,	"ImageDescription" },
90     { TIFFTAG_MAKE,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
91       1,	0,	"Make" },
92     { TIFFTAG_MODEL,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
93       1,	0,	"Model" },
94     { TIFFTAG_STRIPOFFSETS,	-1,-1,	TIFF_LONG,	FIELD_STRIPOFFSETS,
95       0,	0,	"StripOffsets" },
96     { TIFFTAG_STRIPOFFSETS,	-1,-1,	TIFF_SHORT,	FIELD_STRIPOFFSETS,
97       0,	0,	"StripOffsets" },
98     { TIFFTAG_ORIENTATION,	 1, 1,	TIFF_SHORT,	FIELD_ORIENTATION,
99       0,	0,	"Orientation" },
100     { TIFFTAG_SAMPLESPERPIXEL,	 1, 1,	TIFF_SHORT,	FIELD_SAMPLESPERPIXEL,
101       0,	0,	"SamplesPerPixel" },
102     { TIFFTAG_ROWSPERSTRIP,	 1, 1,	TIFF_LONG,	FIELD_ROWSPERSTRIP,
103       0,	0,	"RowsPerStrip" },
104     { TIFFTAG_ROWSPERSTRIP,	 1, 1,	TIFF_SHORT,	FIELD_ROWSPERSTRIP,
105       0,	0,	"RowsPerStrip" },
106     { TIFFTAG_STRIPBYTECOUNTS,	-1,-1,	TIFF_LONG,	FIELD_STRIPBYTECOUNTS,
107       0,	0,	"StripByteCounts" },
108     { TIFFTAG_STRIPBYTECOUNTS,	-1,-1,	TIFF_SHORT,	FIELD_STRIPBYTECOUNTS,
109       0,	0,	"StripByteCounts" },
110     { TIFFTAG_MINSAMPLEVALUE,	-2,-1,	TIFF_SHORT,	FIELD_MINSAMPLEVALUE,
111       1,	0,	"MinSampleValue" },
112     { TIFFTAG_MAXSAMPLEVALUE,	-2,-1,	TIFF_SHORT,	FIELD_MAXSAMPLEVALUE,
113       1,	0,	"MaxSampleValue" },
114     { TIFFTAG_XRESOLUTION,	 1, 1,	TIFF_RATIONAL,	FIELD_RESOLUTION,
115       1,	0,	"XResolution" },
116     { TIFFTAG_YRESOLUTION,	 1, 1,	TIFF_RATIONAL,	FIELD_RESOLUTION,
117       1,	0,	"YResolution" },
118     { TIFFTAG_PLANARCONFIG,	 1, 1,	TIFF_SHORT,	FIELD_PLANARCONFIG,
119       0,	0,	"PlanarConfiguration" },
120     { TIFFTAG_PAGENAME,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
121       1,	0,	"PageName" },
122     { TIFFTAG_XPOSITION,	 1, 1,	TIFF_RATIONAL,	FIELD_POSITION,
123       1,	0,	"XPosition" },
124     { TIFFTAG_YPOSITION,	 1, 1,	TIFF_RATIONAL,	FIELD_POSITION,
125       1,	0,	"YPosition" },
126     { TIFFTAG_FREEOFFSETS,	-1,-1,	TIFF_LONG,	FIELD_IGNORE,
127       0,	0,	"FreeOffsets" },
128     { TIFFTAG_FREEBYTECOUNTS,	-1,-1,	TIFF_LONG,	FIELD_IGNORE,
129       0,	0,	"FreeByteCounts" },
130     { TIFFTAG_GRAYRESPONSEUNIT,	 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
131       1,	0,	"GrayResponseUnit" },
132     { TIFFTAG_GRAYRESPONSECURVE,-1,-1,	TIFF_SHORT,	FIELD_IGNORE,
133       1,	0,	"GrayResponseCurve" },
134     { TIFFTAG_RESOLUTIONUNIT,	 1, 1,	TIFF_SHORT,	FIELD_RESOLUTIONUNIT,
135       1,	0,	"ResolutionUnit" },
136     { TIFFTAG_PAGENUMBER,	 2, 2,	TIFF_SHORT,	FIELD_PAGENUMBER,
137       1,	0,	"PageNumber" },
138     { TIFFTAG_COLORRESPONSEUNIT, 1, 1,	TIFF_SHORT,	FIELD_IGNORE,
139       1,	0,	"ColorResponseUnit" },
140     { TIFFTAG_TRANSFERFUNCTION,	-1,-1,	TIFF_SHORT,	FIELD_TRANSFERFUNCTION,
141       1,	0,	"TransferFunction" },
142     { TIFFTAG_SOFTWARE,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
143       1,	0,	"Software" },
144     { TIFFTAG_DATETIME,		20,20,	TIFF_ASCII,	FIELD_CUSTOM,
145       1,	0,	"DateTime" },
146     { TIFFTAG_ARTIST,		-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
147       1,	0,	"Artist" },
148     { TIFFTAG_HOSTCOMPUTER,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
149       1,	0,	"HostComputer" },
150     { TIFFTAG_WHITEPOINT,	 2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM,
151       1,	0,	"WhitePoint" },
152     { TIFFTAG_PRIMARYCHROMATICITIES,6,6,TIFF_RATIONAL,	FIELD_CUSTOM,
153       1,	0,	"PrimaryChromaticities" },
154     { TIFFTAG_COLORMAP,		-1,-1,	TIFF_SHORT,	FIELD_COLORMAP,
155       1,	0,	"ColorMap" },
156     { TIFFTAG_HALFTONEHINTS,	 2, 2,	TIFF_SHORT,	FIELD_HALFTONEHINTS,
157       1,	0,	"HalftoneHints" },
158     { TIFFTAG_TILEWIDTH,	 1, 1,	TIFF_LONG,	FIELD_TILEDIMENSIONS,
159       0,	0,	"TileWidth" },
160     { TIFFTAG_TILEWIDTH,	 1, 1,	TIFF_SHORT,	FIELD_TILEDIMENSIONS,
161       0,	0,	"TileWidth" },
162     { TIFFTAG_TILELENGTH,	 1, 1,	TIFF_LONG,	FIELD_TILEDIMENSIONS,
163       0,	0,	"TileLength" },
164     { TIFFTAG_TILELENGTH,	 1, 1,	TIFF_SHORT,	FIELD_TILEDIMENSIONS,
165       0,	0,	"TileLength" },
166     { TIFFTAG_TILEOFFSETS,	-1, 1,	TIFF_LONG,	FIELD_STRIPOFFSETS,
167       0,	0,	"TileOffsets" },
168     { TIFFTAG_TILEBYTECOUNTS,	-1, 1,	TIFF_LONG,	FIELD_STRIPBYTECOUNTS,
169       0,	0,	"TileByteCounts" },
170     { TIFFTAG_TILEBYTECOUNTS,	-1, 1,	TIFF_SHORT,	FIELD_STRIPBYTECOUNTS,
171       0,	0,	"TileByteCounts" },
172     { TIFFTAG_SUBIFD,		-1,-1,	TIFF_IFD,	FIELD_SUBIFD,
173       1,	1,	"SubIFD" },
174     { TIFFTAG_SUBIFD,		-1,-1,	TIFF_LONG,	FIELD_SUBIFD,
175       1,	1,	"SubIFD" },
176     { TIFFTAG_INKSET,		 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
177       0,	0,	"InkSet" },
178     { TIFFTAG_INKNAMES,		-1,-1,	TIFF_ASCII,	FIELD_INKNAMES,
179       1,	1,	"InkNames" },
180     { TIFFTAG_NUMBEROFINKS,	 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
181       1,	0,	"NumberOfInks" },
182     { TIFFTAG_DOTRANGE,		 2, 2,	TIFF_SHORT,	FIELD_CUSTOM,
183       0,	0,	"DotRange" },
184     { TIFFTAG_DOTRANGE,		 2, 2,	TIFF_BYTE,	FIELD_CUSTOM,
185       0,	0,	"DotRange" },
186     { TIFFTAG_TARGETPRINTER,	-1,-1,	TIFF_ASCII,	FIELD_CUSTOM,
187       1,	0,	"TargetPrinter" },
188     { TIFFTAG_EXTRASAMPLES,	-1,-1,	TIFF_SHORT,	FIELD_EXTRASAMPLES,
189       0,	1,	"ExtraSamples" },
190 /* XXX for bogus Adobe Photoshop v2.5 files */
191     { TIFFTAG_EXTRASAMPLES,	-1,-1,	TIFF_BYTE,	FIELD_EXTRASAMPLES,
192       0,	1,	"ExtraSamples" },
193     { TIFFTAG_SAMPLEFORMAT,	-1,-1,	TIFF_SHORT,	FIELD_SAMPLEFORMAT,
194       0,	0,	"SampleFormat" },
195     { TIFFTAG_SMINSAMPLEVALUE,	-2,-1,	TIFF_ANY,	FIELD_SMINSAMPLEVALUE,
196       1,	0,	"SMinSampleValue" },
197     { TIFFTAG_SMAXSAMPLEVALUE,	-2,-1,	TIFF_ANY,	FIELD_SMAXSAMPLEVALUE,
198       1,	0,	"SMaxSampleValue" },
199     { TIFFTAG_CLIPPATH,		-1, -3, TIFF_BYTE,	FIELD_CUSTOM,
200       0,	1,	"ClipPath" },
201     { TIFFTAG_XCLIPPATHUNITS,	 1, 1,	TIFF_SLONG,	FIELD_CUSTOM,
202       0,	0,	"XClipPathUnits" },
203     { TIFFTAG_XCLIPPATHUNITS,	 1, 1,	TIFF_SSHORT,	FIELD_CUSTOM,
204       0,	0,	"XClipPathUnits" },
205     { TIFFTAG_XCLIPPATHUNITS,	 1, 1,	TIFF_SBYTE,	FIELD_CUSTOM,
206       0,	0,	"XClipPathUnits" },
207     { TIFFTAG_YCLIPPATHUNITS,	 1, 1,	TIFF_SLONG,	FIELD_CUSTOM,
208       0,	0,	"YClipPathUnits" },
209     { TIFFTAG_YCLIPPATHUNITS,	 1, 1,	TIFF_SSHORT,	FIELD_CUSTOM,
210       0,	0,	"YClipPathUnits" },
211     { TIFFTAG_YCLIPPATHUNITS,	 1, 1,	TIFF_SBYTE,	FIELD_CUSTOM,
212       0,	0,	"YClipPathUnits" },
213     { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3,	TIFF_RATIONAL,	FIELD_CUSTOM,
214       0,	0,	"YCbCrCoefficients" },
215     { TIFFTAG_YCBCRSUBSAMPLING,	 2, 2,	TIFF_SHORT,	FIELD_YCBCRSUBSAMPLING,
216       0,	0,	"YCbCrSubsampling" },
217     { TIFFTAG_YCBCRPOSITIONING,	 1, 1,	TIFF_SHORT,	FIELD_YCBCRPOSITIONING,
218       0,	0,	"YCbCrPositioning" },
219     { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL,	FIELD_CUSTOM,
220       1,	0,	"ReferenceBlackWhite" },
221 /* XXX temporarily accept LONG for backwards compatibility */
222     { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_LONG,	FIELD_CUSTOM,
223       1,	0,	"ReferenceBlackWhite" },
224     { TIFFTAG_XMLPACKET,	-3,-3,	TIFF_BYTE,	FIELD_CUSTOM,
225       0,	1,	"XMLPacket" },
226 /* begin SGI tags */
227     { TIFFTAG_MATTEING,		 1, 1,	TIFF_SHORT,	FIELD_EXTRASAMPLES,
228       0,	0,	"Matteing" },
229     { TIFFTAG_DATATYPE,		-2,-1,	TIFF_SHORT,	FIELD_SAMPLEFORMAT,
230       0,	0,	"DataType" },
231     { TIFFTAG_IMAGEDEPTH,	 1, 1,	TIFF_LONG,	FIELD_IMAGEDEPTH,
232       0,	0,	"ImageDepth" },
233     { TIFFTAG_IMAGEDEPTH,	 1, 1,	TIFF_SHORT,	FIELD_IMAGEDEPTH,
234       0,	0,	"ImageDepth" },
235     { TIFFTAG_TILEDEPTH,	 1, 1,	TIFF_LONG,	FIELD_TILEDEPTH,
236       0,	0,	"TileDepth" },
237     { TIFFTAG_TILEDEPTH,	 1, 1,	TIFF_SHORT,	FIELD_TILEDEPTH,
238       0,	0,	"TileDepth" },
239 /* end SGI tags */
240 /* begin Pixar tags */
241     { TIFFTAG_PIXAR_IMAGEFULLWIDTH,  1, 1, TIFF_LONG,	FIELD_CUSTOM,
242       1,	0,	"ImageFullWidth" },
243     { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG,	FIELD_CUSTOM,
244       1,	0,	"ImageFullLength" },
245     { TIFFTAG_PIXAR_TEXTUREFORMAT,  -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
246       1,	0,	"TextureFormat" },
247     { TIFFTAG_PIXAR_WRAPMODES,	    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
248       1,	0,	"TextureWrapModes" },
249     { TIFFTAG_PIXAR_FOVCOT,	     1, 1, TIFF_FLOAT,	FIELD_CUSTOM,
250       1,	0,	"FieldOfViewCotangent" },
251     { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN,	16,16,	TIFF_FLOAT,
252       FIELD_CUSTOM,	1,	0,	"MatrixWorldToScreen" },
253     { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA,	16,16,	TIFF_FLOAT,
254        FIELD_CUSTOM,	1,	0,	"MatrixWorldToCamera" },
255     { TIFFTAG_COPYRIGHT,	-1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
256       1,	0,	"Copyright" },
257 /* end Pixar tags */
258     { TIFFTAG_RICHTIFFIPTC, -3, -3,	TIFF_LONG,	FIELD_CUSTOM,
259       0,    1,   "RichTIFFIPTC" },
260     { TIFFTAG_PHOTOSHOP,    -3, -3,	TIFF_BYTE,	FIELD_CUSTOM,
261       0,    1,   "Photoshop" },
262     { TIFFTAG_EXIFIFD,		1, 1,	TIFF_LONG,	FIELD_CUSTOM,
263       0,	0,	"EXIFIFDOffset" },
264     { TIFFTAG_ICCPROFILE,	-3, -3,	TIFF_UNDEFINED,	FIELD_CUSTOM,
265       0,	1,	"ICC Profile" },
266     { TIFFTAG_GPSIFD,		1, 1,	TIFF_LONG,	FIELD_CUSTOM,
267       0,	0,	"GPSIFDOffset" },
268     { TIFFTAG_STONITS,		 1, 1,	TIFF_DOUBLE,	FIELD_CUSTOM,
269       0,	0,	"StoNits" },
270     { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_LONG,	FIELD_CUSTOM,
271       0,	0,	"InteroperabilityIFDOffset" },
272 /* begin DNG tags */
273     { TIFFTAG_DNGVERSION,	4, 4,	TIFF_BYTE,	FIELD_CUSTOM,
274       0,	0,	"DNGVersion" },
275     { TIFFTAG_DNGBACKWARDVERSION, 4, 4,	TIFF_BYTE,	FIELD_CUSTOM,
276       0,	0,	"DNGBackwardVersion" },
277     { TIFFTAG_UNIQUECAMERAMODEL,    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
278       1,	0,	"UniqueCameraModel" },
279     { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
280       1,	0,	"LocalizedCameraModel" },
281     { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE,	FIELD_CUSTOM,
282       1,	1,	"LocalizedCameraModel" },
283     { TIFFTAG_CFAPLANECOLOR,	-1, -1,	TIFF_BYTE,	FIELD_CUSTOM,
284       0,	1,	"CFAPlaneColor" },
285     { TIFFTAG_CFALAYOUT,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
286       0,	0,	"CFALayout" },
287     { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT,	FIELD_CUSTOM,
288       0,	1,	"LinearizationTable" },
289     { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT,	FIELD_CUSTOM,
290       0,	0,	"BlackLevelRepeatDim" },
291     { TIFFTAG_BLACKLEVEL,	-1, -1,	TIFF_LONG,	FIELD_CUSTOM,
292       0,	1,	"BlackLevel" },
293     { TIFFTAG_BLACKLEVEL,	-1, -1,	TIFF_SHORT,	FIELD_CUSTOM,
294       0,	1,	"BlackLevel" },
295     { TIFFTAG_BLACKLEVEL,	-1, -1,	TIFF_RATIONAL,	FIELD_CUSTOM,
296       0,	1,	"BlackLevel" },
297     { TIFFTAG_BLACKLEVELDELTAH,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
298       0,	1,	"BlackLevelDeltaH" },
299     { TIFFTAG_BLACKLEVELDELTAV,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
300       0,	1,	"BlackLevelDeltaV" },
301     { TIFFTAG_WHITELEVEL,	-2, -2,	TIFF_LONG,	FIELD_CUSTOM,
302       0,	0,	"WhiteLevel" },
303     { TIFFTAG_WHITELEVEL,	-2, -2,	TIFF_SHORT,	FIELD_CUSTOM,
304       0,	0,	"WhiteLevel" },
305     { TIFFTAG_DEFAULTSCALE,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM,
306       0,	0,	"DefaultScale" },
307     { TIFFTAG_BESTQUALITYSCALE,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
308       0,	0,	"BestQualityScale" },
309     { TIFFTAG_DEFAULTCROPORIGIN,	2, 2,	TIFF_LONG,	FIELD_CUSTOM,
310       0,	0,	"DefaultCropOrigin" },
311     { TIFFTAG_DEFAULTCROPORIGIN,	2, 2,	TIFF_SHORT,	FIELD_CUSTOM,
312       0,	0,	"DefaultCropOrigin" },
313     { TIFFTAG_DEFAULTCROPORIGIN,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM,
314       0,	0,	"DefaultCropOrigin" },
315     { TIFFTAG_DEFAULTCROPSIZE,	2, 2,	TIFF_LONG,	FIELD_CUSTOM,
316       0,	0,	"DefaultCropSize" },
317     { TIFFTAG_DEFAULTCROPSIZE,	2, 2,	TIFF_SHORT,	FIELD_CUSTOM,
318       0,	0,	"DefaultCropSize" },
319     { TIFFTAG_DEFAULTCROPSIZE,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM,
320       0,	0,	"DefaultCropSize" },
321     { TIFFTAG_COLORMATRIX1,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
322       0,	1,	"ColorMatrix1" },
323     { TIFFTAG_COLORMATRIX2,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
324       0,	1,	"ColorMatrix2" },
325     { TIFFTAG_CAMERACALIBRATION1,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
326       0,	1,	"CameraCalibration1" },
327     { TIFFTAG_CAMERACALIBRATION2,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
328       0,	1,	"CameraCalibration2" },
329     { TIFFTAG_REDUCTIONMATRIX1,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
330       0,	1,	"ReductionMatrix1" },
331     { TIFFTAG_REDUCTIONMATRIX2,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
332       0,	1,	"ReductionMatrix2" },
333     { TIFFTAG_ANALOGBALANCE,	-1, -1,	TIFF_RATIONAL,	FIELD_CUSTOM,
334       0,	1,	"AnalogBalance" },
335     { TIFFTAG_ASSHOTNEUTRAL,	-1, -1,	TIFF_SHORT,	FIELD_CUSTOM,
336       0,	1,	"AsShotNeutral" },
337     { TIFFTAG_ASSHOTNEUTRAL,	-1, -1,	TIFF_RATIONAL,	FIELD_CUSTOM,
338       0,	1,	"AsShotNeutral" },
339     { TIFFTAG_ASSHOTWHITEXY,	2, 2,	TIFF_RATIONAL,	FIELD_CUSTOM,
340       0,	0,	"AsShotWhiteXY" },
341     { TIFFTAG_BASELINEEXPOSURE,	1, 1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
342       0,	0,	"BaselineExposure" },
343     { TIFFTAG_BASELINENOISE,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
344       0,	0,	"BaselineNoise" },
345     { TIFFTAG_BASELINESHARPNESS,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
346       0,	0,	"BaselineSharpness" },
347     { TIFFTAG_BAYERGREENSPLIT,	1, 1,	TIFF_LONG,	FIELD_CUSTOM,
348       0,	0,	"BayerGreenSplit" },
349     { TIFFTAG_LINEARRESPONSELIMIT,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
350       0,	0,	"LinearResponseLimit" },
351     { TIFFTAG_CAMERASERIALNUMBER,    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
352       1,	0,	"CameraSerialNumber" },
353     { TIFFTAG_LENSINFO,	4, 4,	TIFF_RATIONAL,	FIELD_CUSTOM,
354       0,	0,	"LensInfo" },
355     { TIFFTAG_CHROMABLURRADIUS,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
356       0,	0,	"ChromaBlurRadius" },
357     { TIFFTAG_ANTIALIASSTRENGTH,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
358       0,	0,	"AntiAliasStrength" },
359     { TIFFTAG_SHADOWSCALE,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
360       0,	0,	"ShadowScale" },
361     { TIFFTAG_DNGPRIVATEDATA,    -1, -1, TIFF_BYTE,	FIELD_CUSTOM,
362       0,	1,	"DNGPrivateData" },
363     { TIFFTAG_MAKERNOTESAFETY,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
364       0,	0,	"MakerNoteSafety" },
365     { TIFFTAG_CALIBRATIONILLUMINANT1,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
366       0,	0,	"CalibrationIlluminant1" },
367     { TIFFTAG_CALIBRATIONILLUMINANT2,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
368       0,	0,	"CalibrationIlluminant2" },
369     { TIFFTAG_RAWDATAUNIQUEID,	16, 16,	TIFF_BYTE,	FIELD_CUSTOM,
370       0,	0,	"RawDataUniqueID" },
371     { TIFFTAG_ORIGINALRAWFILENAME,    -1, -1, TIFF_ASCII,	FIELD_CUSTOM,
372       1,	0,	"OriginalRawFileName" },
373     { TIFFTAG_ORIGINALRAWFILENAME,    -1, -1, TIFF_BYTE,	FIELD_CUSTOM,
374       1,	1,	"OriginalRawFileName" },
375     { TIFFTAG_ORIGINALRAWFILEDATA,    -1, -1, TIFF_UNDEFINED,	FIELD_CUSTOM,
376       0,	1,	"OriginalRawFileData" },
377     { TIFFTAG_ACTIVEAREA,	4, 4,	TIFF_LONG,	FIELD_CUSTOM,
378       0,	0,	"ActiveArea" },
379     { TIFFTAG_ACTIVEAREA,	4, 4,	TIFF_SHORT,	FIELD_CUSTOM,
380       0,	0,	"ActiveArea" },
381     { TIFFTAG_MASKEDAREAS,	-1, -1,	TIFF_LONG,	FIELD_CUSTOM,
382       0,	1,	"MaskedAreas" },
383     { TIFFTAG_ASSHOTICCPROFILE,    -1, -1, TIFF_UNDEFINED,	FIELD_CUSTOM,
384       0,	1,	"AsShotICCProfile" },
385     { TIFFTAG_ASSHOTPREPROFILEMATRIX,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
386       0,	1,	"AsShotPreProfileMatrix" },
387     { TIFFTAG_CURRENTICCPROFILE,    -1, -1, TIFF_UNDEFINED,	FIELD_CUSTOM,
388       0,	1,	"CurrentICCProfile" },
389     { TIFFTAG_CURRENTPREPROFILEMATRIX,	-1, -1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
390       0,	1,	"CurrentPreProfileMatrix" },
391 /* end DNG tags */
392 };
393 
394 static const TIFFFieldInfo
395 exifFieldInfo[] = {
396     { EXIFTAG_EXPOSURETIME,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
397       1,	0,	"ExposureTime" },
398     { EXIFTAG_FNUMBER,		1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
399       1,	0,	"FNumber" },
400     { EXIFTAG_EXPOSUREPROGRAM,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
401       1,	0,	"ExposureProgram" },
402     { EXIFTAG_SPECTRALSENSITIVITY,    -1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
403       1,	0,	"SpectralSensitivity" },
404     { EXIFTAG_ISOSPEEDRATINGS,  -1, -1,		TIFF_SHORT,	FIELD_CUSTOM,
405       1,	1,	"ISOSpeedRatings" },
406     { EXIFTAG_OECF,	-1, -1,			TIFF_UNDEFINED,	FIELD_CUSTOM,
407       1,	1,	"OptoelectricConversionFactor" },
408     { EXIFTAG_EXIFVERSION,	4, 4,		TIFF_UNDEFINED,	FIELD_CUSTOM,
409       1,	0,	"ExifVersion" },
410     { EXIFTAG_DATETIMEORIGINAL,	20, 20,		TIFF_ASCII,	FIELD_CUSTOM,
411       1,	0,	"DateTimeOriginal" },
412     { EXIFTAG_DATETIMEDIGITIZED, 20, 20,	TIFF_ASCII,	FIELD_CUSTOM,
413       1,	0,	"DateTimeDigitized" },
414     { EXIFTAG_COMPONENTSCONFIGURATION,	 4, 4,	TIFF_UNDEFINED,	FIELD_CUSTOM,
415       1,	0,	"ComponentsConfiguration" },
416     { EXIFTAG_COMPRESSEDBITSPERPIXEL,	 1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
417       1,	0,	"CompressedBitsPerPixel" },
418     { EXIFTAG_SHUTTERSPEEDVALUE,	1, 1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
419       1,	0,	"ShutterSpeedValue" },
420     { EXIFTAG_APERTUREVALUE,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
421       1,	0,	"ApertureValue" },
422     { EXIFTAG_BRIGHTNESSVALUE,	1, 1,		TIFF_SRATIONAL,	FIELD_CUSTOM,
423       1,	0,	"BrightnessValue" },
424     { EXIFTAG_EXPOSUREBIASVALUE,	1, 1,	TIFF_SRATIONAL,	FIELD_CUSTOM,
425       1,	0,	"ExposureBiasValue" },
426     { EXIFTAG_MAXAPERTUREVALUE,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
427       1,	0,	"MaxApertureValue" },
428     { EXIFTAG_SUBJECTDISTANCE,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
429       1,	0,	"SubjectDistance" },
430     { EXIFTAG_METERINGMODE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
431       1,	0,	"MeteringMode" },
432     { EXIFTAG_LIGHTSOURCE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
433       1,	0,	"LightSource" },
434     { EXIFTAG_FLASH,	1, 1,			TIFF_SHORT,	FIELD_CUSTOM,
435       1,	0,	"Flash" },
436     { EXIFTAG_FOCALLENGTH,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
437       1,	0,	"FocalLength" },
438     { EXIFTAG_SUBJECTAREA,	-1, -1,		TIFF_SHORT,	FIELD_CUSTOM,
439       1,	1,	"SubjectArea" },
440     { EXIFTAG_MAKERNOTE,	-1, -1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
441       1,	1,	"MakerNote" },
442     { EXIFTAG_USERCOMMENT,	-1, -1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
443       1,	1,	"UserComment" },
444     { EXIFTAG_SUBSECTIME,    -1, -1,		TIFF_ASCII,	FIELD_CUSTOM,
445       1,	0,	"SubSecTime" },
446     { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
447       1,	0,	"SubSecTimeOriginal" },
448     { EXIFTAG_SUBSECTIMEDIGITIZED,-1, -1,	TIFF_ASCII,	FIELD_CUSTOM,
449       1,	0,	"SubSecTimeDigitized" },
450     { EXIFTAG_FLASHPIXVERSION,	4, 4,		TIFF_UNDEFINED,	FIELD_CUSTOM,
451       1,	0,	"FlashpixVersion" },
452     { EXIFTAG_PIXELXDIMENSION,	1, 1,		TIFF_LONG,	FIELD_CUSTOM,
453       1,	0,	"PixelXDimension" },
454     { EXIFTAG_PIXELXDIMENSION,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
455       1,	0,	"PixelXDimension" },
456     { EXIFTAG_PIXELYDIMENSION,	1, 1,		TIFF_LONG,	FIELD_CUSTOM,
457       1,	0,	"PixelYDimension" },
458     { EXIFTAG_PIXELYDIMENSION,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
459       1,	0,	"PixelYDimension" },
460     { EXIFTAG_RELATEDSOUNDFILE,	13, 13,		TIFF_ASCII,	FIELD_CUSTOM,
461       1,	0,	"RelatedSoundFile" },
462     { EXIFTAG_FLASHENERGY,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
463       1,	0,	"FlashEnergy" },
464     { EXIFTAG_SPATIALFREQUENCYRESPONSE,	-1, -1,	TIFF_UNDEFINED,	FIELD_CUSTOM,
465       1,	1,	"SpatialFrequencyResponse" },
466     { EXIFTAG_FOCALPLANEXRESOLUTION,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
467       1,	0,	"FocalPlaneXResolution" },
468     { EXIFTAG_FOCALPLANEYRESOLUTION,	1, 1,	TIFF_RATIONAL,	FIELD_CUSTOM,
469       1,	0,	"FocalPlaneYResolution" },
470     { EXIFTAG_FOCALPLANERESOLUTIONUNIT,	1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
471       1,	0,	"FocalPlaneResolutionUnit" },
472     { EXIFTAG_SUBJECTLOCATION,	2, 2,		TIFF_SHORT,	FIELD_CUSTOM,
473       1,	0,	"SubjectLocation" },
474     { EXIFTAG_EXPOSUREINDEX,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
475       1,	0,	"ExposureIndex" },
476     { EXIFTAG_SENSINGMETHOD,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
477       1,	0,	"SensingMethod" },
478     { EXIFTAG_FILESOURCE,	1, 1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
479       1,	0,	"FileSource" },
480     { EXIFTAG_SCENETYPE,	1, 1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
481       1,	0,	"SceneType" },
482     { EXIFTAG_CFAPATTERN,	-1, -1,		TIFF_UNDEFINED,	FIELD_CUSTOM,
483       1,	1,	"CFAPattern" },
484     { EXIFTAG_CUSTOMRENDERED,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
485       1,	0,	"CustomRendered" },
486     { EXIFTAG_EXPOSUREMODE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
487       1,	0,	"ExposureMode" },
488     { EXIFTAG_WHITEBALANCE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
489       1,	0,	"WhiteBalance" },
490     { EXIFTAG_DIGITALZOOMRATIO,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
491       1,	0,	"DigitalZoomRatio" },
492     { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
493       1,	0,	"FocalLengthIn35mmFilm" },
494     { EXIFTAG_SCENECAPTURETYPE,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
495       1,	0,	"SceneCaptureType" },
496     { EXIFTAG_GAINCONTROL,	1, 1,		TIFF_RATIONAL,	FIELD_CUSTOM,
497       1,	0,	"GainControl" },
498     { EXIFTAG_CONTRAST,		1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
499       1,	0,	"Contrast" },
500     { EXIFTAG_SATURATION,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
501       1,	0,	"Saturation" },
502     { EXIFTAG_SHARPNESS,	1, 1,		TIFF_SHORT,	FIELD_CUSTOM,
503       1,	0,	"Sharpness" },
504     { EXIFTAG_DEVICESETTINGDESCRIPTION,	-1, -1,	TIFF_UNDEFINED,	FIELD_CUSTOM,
505       1,	1,	"DeviceSettingDescription" },
506     { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1,	TIFF_SHORT,	FIELD_CUSTOM,
507       1,	0,	"SubjectDistanceRange" },
508     { EXIFTAG_IMAGEUNIQUEID,	33, 33,		TIFF_ASCII,	FIELD_CUSTOM,
509       1,	0,	"ImageUniqueID" }
510 };
511 
512 const TIFFFieldInfo *
_TIFFGetFieldInfo(size_t * size)513 _TIFFGetFieldInfo(size_t *size)
514 {
515 	*size = TIFFArrayCount(tiffFieldInfo);
516 	return tiffFieldInfo;
517 }
518 
519 const TIFFFieldInfo *
_TIFFGetExifFieldInfo(size_t * size)520 _TIFFGetExifFieldInfo(size_t *size)
521 {
522 	*size = TIFFArrayCount(exifFieldInfo);
523 	return exifFieldInfo;
524 }
525 
526 void
_TIFFSetupFieldInfo(TIFF * tif,const TIFFFieldInfo info[],size_t n)527 _TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n)
528 {
529 	if (tif->tif_fieldinfo) {
530 		size_t  i;
531 
532 		for (i = 0; i < tif->tif_nfields; i++)
533 		{
534 			TIFFFieldInfo *fld = tif->tif_fieldinfo[i];
535 			if (fld->field_bit == FIELD_CUSTOM &&
536 				strncmp("Tag ", fld->field_name, 4) == 0) {
537 					_TIFFfree(fld->field_name);
538 					_TIFFfree(fld);
539 				}
540 		}
541 
542 		_TIFFfree(tif->tif_fieldinfo);
543 		tif->tif_nfields = 0;
544 	}
545 	_TIFFMergeFieldInfo(tif, info, n);
546 }
547 
548 static int
tagCompare(const void * a,const void * b)549 tagCompare(const void* a, const void* b)
550 {
551 	const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
552 	const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
553 	/* NB: be careful of return values for 16-bit platforms */
554 	if (ta->field_tag != tb->field_tag)
555 		return (ta->field_tag < tb->field_tag ? -1 : 1);
556 	else
557 		return ((int)tb->field_type - (int)ta->field_type);
558 }
559 
560 static int
tagNameCompare(const void * a,const void * b)561 tagNameCompare(const void* a, const void* b)
562 {
563 	const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
564 	const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
565 
566         return strcmp(ta->field_name, tb->field_name);
567 }
568 
569 void
_TIFFMergeFieldInfo(TIFF * tif,const TIFFFieldInfo info[],int n)570 _TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
571 {
572 	TIFFFieldInfo** tp;
573 	int i;
574 
575         tif->tif_foundfield = NULL;
576 
577 	if (tif->tif_nfields > 0) {
578 		tif->tif_fieldinfo = (TIFFFieldInfo**)
579 		    _TIFFrealloc(tif->tif_fieldinfo,
580 			(tif->tif_nfields+n) * sizeof (TIFFFieldInfo*));
581 	} else {
582 		tif->tif_fieldinfo = (TIFFFieldInfo**)
583 		    _TIFFmalloc(n * sizeof (TIFFFieldInfo*));
584 	}
585 	assert(tif->tif_fieldinfo != NULL);
586 	tp = tif->tif_fieldinfo + tif->tif_nfields;
587 	for (i = 0; i < n; i++)
588 		*tp++ = (TIFFFieldInfo*) (info + i);	/* XXX */
589 
590         /* Sort the field info by tag number */
591         qsort(tif->tif_fieldinfo, tif->tif_nfields += n,
592 	      sizeof (TIFFFieldInfo*), tagCompare);
593 }
594 
595 void
_TIFFPrintFieldInfo(TIFF * tif,FILE * fd)596 _TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
597 {
598 	size_t i;
599 
600 	fprintf(fd, "%s: \n", tif->tif_name);
601 	for (i = 0; i < tif->tif_nfields; i++) {
602 		const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
603 		fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
604 			, (int)i
605 			, (unsigned long) fip->field_tag
606 			, fip->field_readcount, fip->field_writecount
607 			, fip->field_type
608 			, fip->field_bit
609 			, fip->field_oktochange ? "TRUE" : "FALSE"
610 			, fip->field_passcount ? "TRUE" : "FALSE"
611 			, fip->field_name
612 		);
613 	}
614 }
615 
616 /*
617  * Return size of TIFFDataType in bytes
618  */
619 int
TIFFDataWidth(TIFFDataType type)620 TIFFDataWidth(TIFFDataType type)
621 {
622 	switch(type)
623 	{
624 	case 0:  /* nothing */
625 	case 1:  /* TIFF_BYTE */
626 	case 2:  /* TIFF_ASCII */
627 	case 6:  /* TIFF_SBYTE */
628 	case 7:  /* TIFF_UNDEFINED */
629 		return 1;
630 	case 3:  /* TIFF_SHORT */
631 	case 8:  /* TIFF_SSHORT */
632 		return 2;
633 	case 4:  /* TIFF_LONG */
634 	case 9:  /* TIFF_SLONG */
635 	case 11: /* TIFF_FLOAT */
636         case 13: /* TIFF_IFD */
637 		return 4;
638 	case 5:  /* TIFF_RATIONAL */
639 	case 10: /* TIFF_SRATIONAL */
640 	case 12: /* TIFF_DOUBLE */
641 		return 8;
642 	default:
643 		return 0; /* will return 0 for unknown types */
644 	}
645 }
646 
647 /*
648  * Return size of TIFFDataType in bytes.
649  *
650  * XXX: We need a separate function to determine the space needed
651  * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
652  * but we use 4-byte float to represent rationals.
653  */
654 int
_TIFFDataSize(TIFFDataType type)655 _TIFFDataSize(TIFFDataType type)
656 {
657 	switch (type) {
658 		case TIFF_BYTE:
659 		case TIFF_SBYTE:
660 		case TIFF_ASCII:
661 		case TIFF_UNDEFINED:
662 		    return 1;
663 		case TIFF_SHORT:
664 		case TIFF_SSHORT:
665 		    return 2;
666 		case TIFF_LONG:
667 		case TIFF_SLONG:
668 		case TIFF_FLOAT:
669 		case TIFF_IFD:
670 		case TIFF_RATIONAL:
671 		case TIFF_SRATIONAL:
672 		    return 4;
673 		case TIFF_DOUBLE:
674 		    return 8;
675 		default:
676 		    return 0;
677 	}
678 }
679 
680 /*
681  * Return nearest TIFFDataType to the sample type of an image.
682  */
683 TIFFDataType
_TIFFSampleToTagType(TIFF * tif)684 _TIFFSampleToTagType(TIFF* tif)
685 {
686 	uint32 bps = TIFFhowmany8(tif->tif_dir.td_bitspersample);
687 
688 	switch (tif->tif_dir.td_sampleformat) {
689 	case SAMPLEFORMAT_IEEEFP:
690 		return (bps == 4 ? TIFF_FLOAT : TIFF_DOUBLE);
691 	case SAMPLEFORMAT_INT:
692 		return (bps <= 1 ? TIFF_SBYTE :
693 		    bps <= 2 ? TIFF_SSHORT : TIFF_SLONG);
694 	case SAMPLEFORMAT_UINT:
695 		return (bps <= 1 ? TIFF_BYTE :
696 		    bps <= 2 ? TIFF_SHORT : TIFF_LONG);
697 	case SAMPLEFORMAT_VOID:
698 		return (TIFF_UNDEFINED);
699 	}
700 	/*NOTREACHED*/
701 	return (TIFF_UNDEFINED);
702 }
703 
704 const TIFFFieldInfo*
_TIFFFindFieldInfo(TIFF * tif,ttag_t tag,TIFFDataType dt)705 _TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt)
706 {
707 	int i, n;
708 
709 	if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
710 	    (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
711 		return (tif->tif_foundfield);
712 	/* NB: use sorted search (e.g. binary search) */
713 	if(dt != TIFF_ANY) {
714             TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
715 	    TIFFFieldInfo* pkey = &key;
716 	    const TIFFFieldInfo **ret;
717 
718 	    key.field_tag = tag;
719             key.field_type = dt;
720 
721 	    ret = (const TIFFFieldInfo **) bsearch(&pkey,
722 						   tif->tif_fieldinfo,
723 						   tif->tif_nfields,
724 						   sizeof(TIFFFieldInfo *),
725 						   tagCompare);
726 	    return (ret) ? (*ret) : NULL;
727         } else for (i = 0, n = tif->tif_nfields; i < n; i++) {
728 		const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
729 		if (fip->field_tag == tag &&
730 		    (dt == TIFF_ANY || fip->field_type == dt))
731 			return (tif->tif_foundfield = fip);
732 	}
733 	return ((const TIFFFieldInfo *)0);
734 }
735 
736 const TIFFFieldInfo*
_TIFFFindFieldInfoByName(TIFF * tif,const char * field_name,TIFFDataType dt)737 _TIFFFindFieldInfoByName(TIFF* tif, const char *field_name, TIFFDataType dt)
738 {
739 	int i, n;
740 
741 	if (tif->tif_foundfield
742 	    && streq(tif->tif_foundfield->field_name, field_name)
743 	    && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
744 		return (tif->tif_foundfield);
745 	/* NB: use sorted search (e.g. binary search) */
746 	if(dt != TIFF_ANY) {
747             TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
748 	    TIFFFieldInfo* pkey = &key;
749 	    const TIFFFieldInfo **ret;
750 
751             key.field_name = (char *)field_name;
752             key.field_type = dt;
753 
754             ret = (const TIFFFieldInfo **) lfind(&pkey,
755 						 tif->tif_fieldinfo,
756 						 &tif->tif_nfields,
757 						 sizeof(TIFFFieldInfo *),
758 						 tagNameCompare);
759 	    return (ret) ? (*ret) : NULL;
760         } else
761 		for (i = 0, n = tif->tif_nfields; i < n; i++) {
762 			const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
763 			if (streq(fip->field_name, field_name) &&
764 			    (dt == TIFF_ANY || fip->field_type == dt))
765 				return (tif->tif_foundfield = fip);
766 		}
767 	return ((const TIFFFieldInfo *)0);
768 }
769 
770 const TIFFFieldInfo*
_TIFFFieldWithTag(TIFF * tif,ttag_t tag)771 _TIFFFieldWithTag(TIFF* tif, ttag_t tag)
772 {
773 	const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
774 	if (!fip) {
775 		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
776 			  "Internal error, unknown tag 0x%x",
777                           (unsigned int) tag);
778 		assert(fip != NULL);
779 		/*NOTREACHED*/
780 	}
781 	return (fip);
782 }
783 
784 const TIFFFieldInfo*
_TIFFFieldWithName(TIFF * tif,const char * field_name)785 _TIFFFieldWithName(TIFF* tif, const char *field_name)
786 {
787 	const TIFFFieldInfo* fip =
788 		_TIFFFindFieldInfoByName(tif, field_name, TIFF_ANY);
789 	if (!fip) {
790 		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
791 			  "Internal error, unknown tag %s", field_name);
792 		assert(fip != NULL);
793 		/*NOTREACHED*/
794 	}
795 	return (fip);
796 }
797 
798 const TIFFFieldInfo*
_TIFFFindOrRegisterFieldInfo(TIFF * tif,ttag_t tag,TIFFDataType dt)799 _TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt )
800 
801 {
802     const TIFFFieldInfo *fld;
803 
804     fld = _TIFFFindFieldInfo( tif, tag, dt );
805     if( fld == NULL )
806     {
807         fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
808         _TIFFMergeFieldInfo( tif, fld, 1 );
809     }
810 
811     return fld;
812 }
813 
814 TIFFFieldInfo*
_TIFFCreateAnonFieldInfo(TIFF * tif,ttag_t tag,TIFFDataType field_type)815 _TIFFCreateAnonFieldInfo(TIFF *tif, ttag_t tag, TIFFDataType field_type)
816 {
817 	TIFFFieldInfo *fld;
818 	(void) tif;
819 
820 	fld = (TIFFFieldInfo *) _TIFFmalloc(sizeof (TIFFFieldInfo));
821 	if (fld == NULL)
822 	    return NULL;
823 	_TIFFmemset( fld, 0, sizeof(TIFFFieldInfo) );
824 
825 	fld->field_tag = tag;
826 	fld->field_readcount = TIFF_VARIABLE;
827 	fld->field_writecount = TIFF_VARIABLE;
828 	fld->field_type = field_type;
829 	fld->field_bit = FIELD_CUSTOM;
830 	fld->field_oktochange = TRUE;
831 	fld->field_passcount = TRUE;
832 	fld->field_name = (char *) _TIFFmalloc(32);
833 	if (fld->field_name == NULL) {
834 	    _TIFFfree(fld);
835 	    return NULL;
836 	}
837 
838 	/* note that this name is a special sign to TIFFClose() and
839 	 * _TIFFSetupFieldInfo() to free the field
840 	 */
841 	sprintf(fld->field_name, "Tag %d", (int) tag);
842 
843 	return fld;
844 }
845 
846 /* vim: set ts=8 sts=8 sw=8 noet: */
847