PageRenderTime 96ms CodeModel.GetById 2ms app.highlight 86ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/LibTIFF/tif_dirinfo.c

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