xref: /libtiff-4.0.7/html/addingtags.html (revision d4dd6ccc)
1fbc93321SFrank Warmerdam<HTML>
2fbc93321SFrank Warmerdam<HEAD>
3fbc93321SFrank Warmerdam<TITLE>
4fbc93321SFrank WarmerdamModifying The TIFF Library
5fbc93321SFrank Warmerdam</TITLE>
6fbc93321SFrank Warmerdam</HEAD>
7fbc93321SFrank Warmerdam<BODY BGCOLOR=white>
8fbc93321SFrank Warmerdam<FONT FACE="Arial, Helvetica, Sans">
9fbc93321SFrank Warmerdam
10fbc93321SFrank Warmerdam<H1>
11fbc93321SFrank WarmerdamDefining New TIFF Tags
12fbc93321SFrank Warmerdam</H1>
13fbc93321SFrank Warmerdam
14fbc93321SFrank WarmerdamLibtiff has built-in knowledge of all the standard TIFF tags, as
15fbc93321SFrank Warmerdamwell as extentions.  The following describes how to add knowledge of
16fbc93321SFrank Warmerdamnew tags as builtins to libtiff, or how to application specific tags can
17fbc93321SFrank Warmerdambe used by applications without modifying libtiff.
18fbc93321SFrank Warmerdam<p>
19fbc93321SFrank Warmerdam
20fbc93321SFrank Warmerdam<h2>TIFFFieldInfo</h2>
21fbc93321SFrank Warmerdam
22fbc93321SFrank WarmerdamHow libtiff manages specific tags is primarily controlled by the
23fbc93321SFrank Warmerdamdefinition for that tag value stored internally as a TIFFFieldInfo structure.
24fbc93321SFrank WarmerdamThis structure looks like this:
25fbc93321SFrank Warmerdam<p>
26fbc93321SFrank Warmerdam
27fbc93321SFrank Warmerdam<pre>
28fbc93321SFrank Warmerdamtypedef	struct {
29fbc93321SFrank Warmerdam  ttag_t    field_tag;          /* field's tag */
30fbc93321SFrank Warmerdam  short	    field_readcount;    /* read count/TIFF_VARIABLE/TIFF_SPP */
31fbc93321SFrank Warmerdam  short	    field_writecount;   /* write count/TIFF_VARIABLE */
32fbc93321SFrank Warmerdam  TIFFDataType field_type;      /* type of associated data */
33fbc93321SFrank Warmerdam  unsigned short field_bit;     /* bit in fieldsset bit vector */
34fbc93321SFrank Warmerdam  unsigned char field_oktochange;/* if true, can change while writing */
35fbc93321SFrank Warmerdam  unsigned char field_passcount;/* if true, pass dir count on set */
36fbc93321SFrank Warmerdam  char	*field_name;		/* ASCII name */
37fbc93321SFrank Warmerdam} TIFFFieldInfo;
38fbc93321SFrank Warmerdam</pre>
39fbc93321SFrank Warmerdam
40fbc93321SFrank Warmerdam<ul>
41fbc93321SFrank Warmerdam<li> <b>field_tag</b>: the tag number.  For instance 277 for the
42fbc93321SFrank WarmerdamSamplesPerPixel tag.  Builtin tags will generally have a #define in
43fbc93321SFrank Warmerdamtiff.h for each known tag. <p>
44fbc93321SFrank Warmerdam
45fbc93321SFrank Warmerdam<li> <b>field_readcount</b>: The number of values which should be read.
46fbc93321SFrank WarmerdamThe special value TIFF_VARIABLE (-1) indicates that a variable number of
47fbc93321SFrank Warmerdamvalues may be read.  The special value TIFFTAG_SPP (-2) indicates that there
48fbc93321SFrank Warmerdamshould be one value for each sample as defined by TIFFTAG_SAMPLESPERPIXEL.
49fbc93321SFrank WarmerdamThe special value TIFF_VARIABLE2 (-3) is presumably similar to TIFF_VARIABLE
50fbc93321SFrank Warmerdamthough I am not sure what the distinction in behaviour is.  This field
51fbc93321SFrank Warmerdamis TIFF_VARIABLE for variable length ascii fields.<p>
52fbc93321SFrank Warmerdam
53fbc93321SFrank Warmerdam<li> <b>field_writecount</b>: The number of values which should be written.
54fbc93321SFrank WarmerdamGenerally the same as field_readcount.  A few built-in exceptions exist, but
55fbc93321SFrank WarmerdamI haven't analysed why they differ. <p>
56fbc93321SFrank Warmerdam
57fbc93321SFrank Warmerdam<li> <b>field_type</b>: Type of the field.  One of TIFF_BYTE, TIFF_ASCII,
58fbc93321SFrank WarmerdamTIFF_SHORT, TIFF_LONG, TIFF_RATIONAL, TIFF_SBYTE, TIFF_UNDEFINED,
59fbc93321SFrank WarmerdamTIFF_SSHORT, TIFF_SLONG, TIFF_SRATIONAL, TIFF_FLOAT, TIFF_DOUBLE or
60fbc93321SFrank WarmerdamTIFF_IFD.  Note that some fields can support more than one type (for
61fbc93321SFrank Warmerdaminstance short and long).  These fields should have multiple TIFFFieldInfos.
62fbc93321SFrank Warmerdam<p>
63fbc93321SFrank Warmerdam
64fbc93321SFrank Warmerdam<li> <b>field_bit</b>: Built-in tags stored in special fields in the
65fbc93321SFrank WarmerdamTIFF structure have assigned field numbers to distinguish them (ie.
66fbc93321SFrank WarmerdamFIELD_SAMPLESPERPIXEL).  New tags should generally just use
67fbc93321SFrank WarmerdamFIELD_CUSTOM indicating they are stored in the generic tag list.<p>
68fbc93321SFrank Warmerdam
69fbc93321SFrank Warmerdam<li> <b>field_oktochange</b>: TRUE if it is OK to change this tag value
70fbc93321SFrank Warmerdamwhile an image is being written.  FALSE for stuff that must be set once
71fbc93321SFrank Warmerdamand then left unchanged (like ImageWidth, or PhotometricInterpretation for
72fbc93321SFrank Warmerdaminstance).<p>
73fbc93321SFrank Warmerdam
74fbc93321SFrank Warmerdam<li> <b>field_passcount</b>: If TRUE, then the count value must be passed
75fbc93321SFrank Warmerdamin TIFFSetField(), and TIFFGetField(), otherwise the count is not required.
76fbc93321SFrank WarmerdamThis should generally be TRUE for non-ascii variable count tags unless
77fbc93321SFrank Warmerdamthe count is implicit (such as with the colormap).<p>
78fbc93321SFrank Warmerdam
79fbc93321SFrank Warmerdam<li> <b>field_name</b>: A name for the tag.  Normally mixed case (studly caps)
80fbc93321SFrank Warmerdamlike "StripByteCounts" and relatively short. <p>
81fbc93321SFrank Warmerdam
82fbc93321SFrank Warmerdam</ul>
83fbc93321SFrank Warmerdam
84fbc93321SFrank WarmerdamA TIFFFieldInfo definition exists for each built-in tag in the tif_dirinfo.c
85fbc93321SFrank Warmerdamfile.  Some tags which support multiple data types have more than one
86fbc93321SFrank Warmerdamdefinition, one per data type supported. <p>
87fbc93321SFrank Warmerdam
88fbc93321SFrank WarmerdamVarious functions exist for getting the internal TIFFFieldInfo definitions,
89fbc93321SFrank Warmerdamincluding _TIFFFindFieldInfo(), and _TIFFFindFieldInfoByName().  See
90fbc93321SFrank Warmerdamtif_dirinfo.c for details.  There must be some mechanism to get the whole
91fbc93321SFrank Warmerdamlist, though I don't see it off hand.<p>
92fbc93321SFrank Warmerdam
93fbc93321SFrank Warmerdam<h2>Default Tag Auto-registration</h2>
94fbc93321SFrank Warmerdam
95fbc93321SFrank WarmerdamIn libtiff 3.6.0 a new mechanism was introduced allowing libtiff to
96fbc93321SFrank Warmerdamread unrecognised tags automatically.  When an unknown tags is encountered,
97fbc93321SFrank Warmerdamit is automatically internally defined with a default name and a type
98fbc93321SFrank Warmerdamderived from the tag value in the file.  Applications only need to predefine
99fbc93321SFrank Warmerdamapplication specific tags if they need to be able to set them in a file, or
100fbc93321SFrank Warmerdamif particular calling conventions are desired for TIFFSetField() and
101fbc93321SFrank WarmerdamTIFFGetField().<p>
102fbc93321SFrank Warmerdam
103fbc93321SFrank WarmerdamWhen tags are autodefined like this the <b>field_readcount</b> and
104fbc93321SFrank Warmerdam<b>field_writecount</b> values are always TIFF_VARIABLE.  The
105fbc93321SFrank Warmerdam<b>field_passcount</b> is always TRUE, and the <b>field_bit</b> is
106fbc93321SFrank WarmerdamFIELD_CUSTOM.  The field name will be "Tag %d" where the %d is the tag
107fbc93321SFrank Warmerdamnumber.<p>
108fbc93321SFrank Warmerdam
109fbc93321SFrank Warmerdam<h2>Defining Application Tags</h2>
110fbc93321SFrank Warmerdam
111fbc93321SFrank WarmerdamFor various reasons, it is common for applications to want to define
112fbc93321SFrank Warmerdamtheir own tags to store information outside the core TIFF specification.
113fbc93321SFrank WarmerdamThis is done by calling TIFFMergeFieldInfo() with one or more TIFFFieldInfos.
114fbc93321SFrank Warmerdam<p>
115fbc93321SFrank Warmerdam
116fbc93321SFrank WarmerdamThe libgeotiff library provides geospatial information extentions within
117fbc93321SFrank Warmerdama TIFF file.  First, a set of TIFFFieldInfo's is prepared with information
118fbc93321SFrank Warmerdamon the new tags:<p>
119fbc93321SFrank Warmerdam
120fbc93321SFrank Warmerdam<pre>
121fbc93321SFrank Warmerdamstatic const TIFFFieldInfo xtiffFieldInfo[] = {
122fbc93321SFrank Warmerdam
123fbc93321SFrank Warmerdam  /* XXX Insert Your tags here */
124fbc93321SFrank Warmerdam    { TIFFTAG_GEOPIXELSCALE,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
125fbc93321SFrank Warmerdam      TRUE,	TRUE,	"GeoPixelScale" },
126fbc93321SFrank Warmerdam    { TIFFTAG_GEOTRANSMATRIX,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
127fbc93321SFrank Warmerdam      TRUE,	TRUE,	"GeoTransformationMatrix" },
128fbc93321SFrank Warmerdam    { TIFFTAG_GEOTIEPOINTS,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
129fbc93321SFrank Warmerdam      TRUE,	TRUE,	"GeoTiePoints" },
130fbc93321SFrank Warmerdam    { TIFFTAG_GEOKEYDIRECTORY, -1,-1, TIFF_SHORT,	FIELD_CUSTOM,
131fbc93321SFrank Warmerdam      TRUE,	TRUE,	"GeoKeyDirectory" },
132fbc93321SFrank Warmerdam    { TIFFTAG_GEODOUBLEPARAMS,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
133fbc93321SFrank Warmerdam      TRUE,	TRUE,	"GeoDoubleParams" },
134fbc93321SFrank Warmerdam    { TIFFTAG_GEOASCIIPARAMS,	-1,-1, TIFF_ASCII,	FIELD_CUSTOM,
135fbc93321SFrank Warmerdam      TRUE,	FALSE,	"GeoASCIIParams" }
136fbc93321SFrank Warmerdam};
137fbc93321SFrank Warmerdam</pre>
138fbc93321SFrank Warmerdam
139fbc93321SFrank WarmerdamIn order to define the tags, we call TIFFMergeFieldInfo() on the
140fbc93321SFrank Warmerdamdesired TIFF handle with the list of TIFFFieldInfos.<p>
141fbc93321SFrank Warmerdam
142fbc93321SFrank Warmerdam<pre>
143fbc93321SFrank Warmerdam#define	N(a)	(sizeof (a) / sizeof (a[0]))
144fbc93321SFrank Warmerdam
145fbc93321SFrank Warmerdam    /* Install the extended Tag field info */
146fbc93321SFrank Warmerdam    TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
147fbc93321SFrank Warmerdam</pre>
148fbc93321SFrank Warmerdam
149fbc93321SFrank WarmerdamThe tags need to be defined for each TIFF file opened - and when reading
150fbc93321SFrank Warmerdamthey should be defined before the tags of the file are read, yet a valid
151fbc93321SFrank WarmerdamTIFF * is needed to merge the tags against.   In order to get them
152fbc93321SFrank Warmerdamregistered at the appropriate part of the setup process, it is necessary
153fbc93321SFrank Warmerdamto register our merge function as an extender callback with libtiff.
154fbc93321SFrank WarmerdamThis is done with TIFFSetTagExtender().  We also keep track of the
155fbc93321SFrank Warmerdamprevious tag extender (if any) so that we can call it from our extender
156fbc93321SFrank Warmerdamallowing a chain of customizations to take effect. <P>
157fbc93321SFrank Warmerdam
158fbc93321SFrank Warmerdam<pre>
159fbc93321SFrank Warmerdamstatic TIFFExtendProc _ParentExtender = NULL;
160fbc93321SFrank Warmerdam
161fbc93321SFrank Warmerdamstatic
162fbc93321SFrank Warmerdamvoid _XTIFFInitialize(void)
163fbc93321SFrank Warmerdam{
164fbc93321SFrank Warmerdam    static int first_time=1;
165fbc93321SFrank Warmerdam
166fbc93321SFrank Warmerdam    if (! first_time) return; /* Been there. Done that. */
167fbc93321SFrank Warmerdam    first_time = 0;
168fbc93321SFrank Warmerdam
169fbc93321SFrank Warmerdam    /* Grab the inherited method and install */
170fbc93321SFrank Warmerdam    _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
171fbc93321SFrank Warmerdam}
172fbc93321SFrank Warmerdam</pre>
173fbc93321SFrank Warmerdam
174fbc93321SFrank WarmerdamThe extender callback is looks like this.  It merges in our new fields
175fbc93321SFrank Warmerdamand then calls the next extender if there is one in effect.<p>
176fbc93321SFrank Warmerdam
177fbc93321SFrank Warmerdam<pre>
178fbc93321SFrank Warmerdamstatic void
179fbc93321SFrank Warmerdam_XTIFFDefaultDirectory(TIFF *tif)
180fbc93321SFrank Warmerdam{
181fbc93321SFrank Warmerdam    /* Install the extended Tag field info */
182fbc93321SFrank Warmerdam    TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
183fbc93321SFrank Warmerdam
184fbc93321SFrank Warmerdam    /* Since an XTIFF client module may have overridden
185fbc93321SFrank Warmerdam     * the default directory method, we call it now to
186fbc93321SFrank Warmerdam     * allow it to set up the rest of its own methods.
187fbc93321SFrank Warmerdam     */
188fbc93321SFrank Warmerdam
189fbc93321SFrank Warmerdam    if (_ParentExtender)
190fbc93321SFrank Warmerdam        (*_ParentExtender)(tif);
191fbc93321SFrank Warmerdam}
192fbc93321SFrank Warmerdam</pre>
193fbc93321SFrank Warmerdam
194fbc93321SFrank WarmerdamThe above approach ensures that our new definitions are used when reading
195fbc93321SFrank Warmerdamor writing any TIFF file.  However, since on reading we already have
196fbc93321SFrank Warmerdamdefault definitions for tags, it is usually not critical to pre-define them.
197fbc93321SFrank WarmerdamIf tag definitions are only required for writing custom tags, you can just
198fbc93321SFrank Warmerdamcall TIFFMergeFieldInfo() before setting new tags.  The whole extender
199fbc93321SFrank Warmerdamarchitecture can then be avoided.<p>
200fbc93321SFrank Warmerdam
201fbc93321SFrank Warmerdam<A NAME=AddingTags><P><H2>Adding New Builtin Tags</H2></A>
202fbc93321SFrank Warmerdam
203fbc93321SFrank WarmerdamA similar approach is taken to the above.  However, the TIFFFieldInfo
204fbc93321SFrank Warmerdamshould be added to the tiffFieldInfo[] list in tif_dirinfo.c.  Ensure that
205fbc93321SFrank Warmerdamnew tags are added in sorted order by the tag number.<p>
206fbc93321SFrank Warmerdam
207fbc93321SFrank WarmerdamNormally new built-in tags should be defined with FIELD_CUSTOM; however, if
208fbc93321SFrank Warmerdamit is desirable for the tag value to have it's own field in the TIFFDirectory
209fbc93321SFrank Warmerdamstructure, then you will need to #define a new FIELD_ value for it, and
210fbc93321SFrank Warmerdamadd appropriate handling as follows:
211fbc93321SFrank Warmerdam
212fbc93321SFrank Warmerdam
213fbc93321SFrank Warmerdam<OL>
214fbc93321SFrank Warmerdam<LI>Define the tag in <B>tiff.h</B>.
215fbc93321SFrank Warmerdam<LI>Add a field to the directory structure in <B>tif_dir.h</B>
216fbc93321SFrank Warmerdam   and define a <TT>FIELD_*</TT> bit (also update the definition of
217fbc93321SFrank Warmerdam   <TT>FIELD_CODEC</TT> to reflect your addition).
218fbc93321SFrank Warmerdam<LI>Add an entry in the <TT>TIFFFieldInfo</TT> array defined at the top of
219fbc93321SFrank Warmerdam   <B>tif_dirinfo.c</B>.
220fbc93321SFrank Warmerdam   Note that you must keep this array sorted by tag
221fbc93321SFrank Warmerdam   number and that the widest variant entry for a tag should come
222fbc93321SFrank Warmerdam   first (e.g. <TT>LONG</TT> before <TT>SHORT</TT>).
223fbc93321SFrank Warmerdam<LI>Add entries in <TT>_TIFFVSetField()</TT> and <TT>_TIFFVGetField()</TT>
224fbc93321SFrank Warmerdam   for the new tag.
225fbc93321SFrank Warmerdam<LI>(<I>optional</I>) If the value associated with the tag is not a scalar value
226fbc93321SFrank Warmerdam   (e.g. the array for <TT>TransferFunction</TT>) and requires
227fbc93321SFrank Warmerdam   special processing,
228fbc93321SFrank Warmerdam   then add the appropriate code to <TT>TIFFReadDirectory()</TT> and
229fbc93321SFrank Warmerdam   <TT>TIFFWriteDirectory()</TT>.  You're best off finding a similar tag and
230fbc93321SFrank Warmerdam   cribbing code.
231fbc93321SFrank Warmerdam<LI>Add support to <TT>TIFFPrintDirectory()</TT> in <B>tif_print.c</B>
232fbc93321SFrank Warmerdam    to print the tag's value.
233fbc93321SFrank Warmerdam</OL>
234fbc93321SFrank Warmerdam
235fbc93321SFrank Warmerdam<P>
236fbc93321SFrank WarmerdamIf you want to maintain portability, beware of making assumptions
237fbc93321SFrank Warmerdamabout data types.  Use the typedefs (<TT>uint16</TT>, etc. when dealing with
238fbc93321SFrank Warmerdamdata on disk and <TT>t*_t</TT> when stuff is in memory) and be careful about
239fbc93321SFrank Warmerdampassing items through printf or similar vararg interfaces.
240fbc93321SFrank Warmerdam
241fbc93321SFrank Warmerdam<A NAME=AddingCODECTags><P><H2>Adding New Codec-private Tags</H2></A>
242fbc93321SFrank Warmerdam
243fbc93321SFrank WarmerdamTo add tags that are meaningful <EM>only when a particular compression
244fbc93321SFrank Warmerdamalgorithm is used</EM> follow these steps:
245fbc93321SFrank Warmerdam
246fbc93321SFrank Warmerdam<OL>
247fbc93321SFrank Warmerdam<LI>Define the tag in <B>tiff.h</B>.
248fbc93321SFrank Warmerdam<LI>Allocate storage for the tag values in the private state block of
249fbc93321SFrank Warmerdam   the codec.
250fbc93321SFrank Warmerdam<LI>Insure the state block is created when the codec is initialized.
251fbc93321SFrank Warmerdam<LI>At <TT>TIFFInitfoo</TT> time override the method pointers in the
252fbc93321SFrank Warmerdam    TIFF structure
253fbc93321SFrank Warmerdam   for getting, setting and printing tag values.  For example,
254fbc93321SFrank Warmerdam<PRE>
255fbc93321SFrank Warmerdam    sp->vgetparent = tif->tif_vgetfield;
256fbc93321SFrank Warmerdam    tif->tif_vgetfield = fooVGetField;	/* hook for codec tags */
257fbc93321SFrank Warmerdam    sp->vsetparent = tif->tif_vsetfield;
258fbc93321SFrank Warmerdam    tif->tif_vsetfield = fooVSetField;	/* hook for codec tags */
259fbc93321SFrank Warmerdam    tif->tif_printdir = fooPrintDir;	/* hook for codec tags */
260fbc93321SFrank Warmerdam</PRE>
261fbc93321SFrank Warmerdam   (Actually you may decide not to override the
262fbc93321SFrank Warmerdam   <TT>tif_printdir</TT> method, but rather just specify it).
263fbc93321SFrank Warmerdam<LI>Create a private <TT>TIFFFieldInfo</TT> array for your tags and
264fbc93321SFrank Warmerdam    merge them into the core tags at initialization time using
265fbc93321SFrank Warmerdam    <TT>_TIFFMergeFieldInfo</TT>; e.g.
266fbc93321SFrank Warmerdam<PRE>
267fbc93321SFrank Warmerdam    _TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo));
268fbc93321SFrank Warmerdam</PRE>
269fbc93321SFrank Warmerdam   (where <TT>N</TT> is a macro used liberaly throughout the distributed code).
270fbc93321SFrank Warmerdam<LI>Fill in the get and set routines.  Be sure to call the parent method
271fbc93321SFrank Warmerdam   for tags that you are not handled directly.  Also be sure to set the
272fbc93321SFrank Warmerdam   <TT>FIELD_*</TT> bits for tags that are to be written to the file.  Note that
273fbc93321SFrank Warmerdam   you can create ``pseudo-tags'' by defining tags that are processed
274fbc93321SFrank Warmerdam   exclusively in the get/set routines and never written to file (see
275fbc93321SFrank Warmerdam   the handling of <TT>TIFFTAG_FAXMODE</TT> in <B>tif_fax3.c</B>
276fbc93321SFrank Warmerdam   for an example of this).
277fbc93321SFrank Warmerdam<LI>Fill in the print routine, if appropriate.
278fbc93321SFrank Warmerdam</OL>
279fbc93321SFrank Warmerdam
280fbc93321SFrank WarmerdamNote that space has been allocated in the <TT>FIELD_*</TT> bit space for
281fbc93321SFrank Warmerdamcodec-private tags.  Define your bits as <TT>FIELD_CODEC+&lt;offset&gt;</TT> to
282fbc93321SFrank Warmerdamkeep them away from the core tags.  If you need more tags than there
283fbc93321SFrank Warmerdamis room for, just increase <TT>FIELD_SETLONGS</TT> at the top of
284fbc93321SFrank Warmerdam<B>tiffiop.h</B>.
285fbc93321SFrank Warmerdam
286fbc93321SFrank Warmerdam<HR>
287fbc93321SFrank Warmerdam
288*d4dd6cccSBob FriesenhahnLast updated: $Date: 2016-09-25 20:05:44 $
289fbc93321SFrank Warmerdam
290fbc93321SFrank Warmerdam</BODY>
291fbc93321SFrank Warmerdam
292fbc93321SFrank Warmerdam</HTML>
293