/src/3rdparty/libtiff/html/addingtags.html
https://bitbucket.org/ultra_iter/qt-vtl · HTML · 292 lines · 241 code · 51 blank · 0 comment · 0 complexity · c578567b0dc4e5a61fd6d80f849b00d0 MD5 · raw file
- <HTML>
- <HEAD>
- <TITLE>
- Modifying The TIFF Library
- </TITLE>
- </HEAD>
- <BODY BGCOLOR=white>
- <FONT FACE="Arial, Helvetica, Sans">
- <H1>
- Defining New TIFF Tags
- </H1>
- Libtiff has built-in knowledge of all the standard TIFF tags, as
- well as extentions. The following describes how to add knowledge of
- new tags as builtins to libtiff, or how to application specific tags can
- be used by applications without modifying libtiff.
- <p>
- <h2>TIFFFieldInfo</h2>
- How libtiff manages specific tags is primarily controlled by the
- definition for that tag value stored internally as a TIFFFieldInfo structure.
- This structure looks like this:
- <p>
- <pre>
- typedef struct {
- ttag_t field_tag; /* field's tag */
- short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
- short field_writecount; /* write count/TIFF_VARIABLE */
- TIFFDataType field_type; /* type of associated data */
- unsigned short field_bit; /* bit in fieldsset bit vector */
- unsigned char field_oktochange;/* if true, can change while writing */
- unsigned char field_passcount;/* if true, pass dir count on set */
- char *field_name; /* ASCII name */
- } TIFFFieldInfo;
- </pre>
- <ul>
- <li> <b>field_tag</b>: the tag number. For instance 277 for the
- SamplesPerPixel tag. Builtin tags will generally have a #define in
- tiff.h for each known tag. <p>
- <li> <b>field_readcount</b>: The number of values which should be read.
- The special value TIFF_VARIABLE (-1) indicates that a variable number of
- values may be read. The special value TIFFTAG_SPP (-2) indicates that there
- should be one value for each sample as defined by TIFFTAG_SAMPLESPERPIXEL.
- The special value TIFF_VARIABLE2 (-3) is presumably similar to TIFF_VARIABLE
- though I am not sure what the distinction in behaviour is. This field
- is TIFF_VARIABLE for variable length ascii fields.<p>
- <li> <b>field_writecount</b>: The number of values which should be written.
- Generally the same as field_readcount. A few built-in exceptions exist, but
- I haven't analysed why they differ. <p>
- <li> <b>field_type</b>: Type of the field. One of TIFF_BYTE, TIFF_ASCII,
- TIFF_SHORT, TIFF_LONG, TIFF_RATIONAL, TIFF_SBYTE, TIFF_UNDEFINED,
- TIFF_SSHORT, TIFF_SLONG, TIFF_SRATIONAL, TIFF_FLOAT, TIFF_DOUBLE or
- TIFF_IFD. Note that some fields can support more than one type (for
- instance short and long). These fields should have multiple TIFFFieldInfos.
- <p>
- <li> <b>field_bit</b>: Built-in tags stored in special fields in the
- TIFF structure have assigned field numbers to distinguish them (ie.
- FIELD_SAMPLESPERPIXEL). New tags should generally just use
- FIELD_CUSTOM indicating they are stored in the generic tag list.<p>
- <li> <b>field_oktochange</b>: TRUE if it is OK to change this tag value
- while an image is being written. FALSE for stuff that must be set once
- and then left unchanged (like ImageWidth, or PhotometricInterpretation for
- instance).<p>
- <li> <b>field_passcount</b>: If TRUE, then the count value must be passed
- in TIFFSetField(), and TIFFGetField(), otherwise the count is not required.
- This should generally be TRUE for non-ascii variable count tags unless
- the count is implicit (such as with the colormap).<p>
- <li> <b>field_name</b>: A name for the tag. Normally mixed case (studly caps)
- like "StripByteCounts" and relatively short. <p>
- </ul>
- A TIFFFieldInfo definition exists for each built-in tag in the tif_dirinfo.c
- file. Some tags which support multiple data types have more than one
- definition, one per data type supported. <p>
- Various functions exist for getting the internal TIFFFieldInfo definitions,
- including _TIFFFindFieldInfo(), and _TIFFFindFieldInfoByName(). See
- tif_dirinfo.c for details. There must be some mechanism to get the whole
- list, though I don't see it off hand.<p>
- <h2>Default Tag Auto-registration</h2>
- In libtiff 3.6.0 a new mechanism was introduced allowing libtiff to
- read unrecognised tags automatically. When an unknown tags is encountered,
- it is automatically internally defined with a default name and a type
- derived from the tag value in the file. Applications only need to predefine
- application specific tags if they need to be able to set them in a file, or
- if particular calling conventions are desired for TIFFSetField() and
- TIFFGetField().<p>
- When tags are autodefined like this the <b>field_readcount</b> and
- <b>field_writecount</b> values are always TIFF_VARIABLE. The
- <b>field_passcount</b> is always TRUE, and the <b>field_bit</b> is
- FIELD_CUSTOM. The field name will be "Tag %d" where the %d is the tag
- number.<p>
- <h2>Defining Application Tags</h2>
- For various reasons, it is common for applications to want to define
- their own tags to store information outside the core TIFF specification.
- This is done by calling TIFFMergeFieldInfo() with one or more TIFFFieldInfos.
- <p>
- The libgeotiff library provides geospatial information extentions within
- a TIFF file. First, a set of TIFFFieldInfo's is prepared with information
- on the new tags:<p>
- <pre>
- static const TIFFFieldInfo xtiffFieldInfo[] = {
-
- /* XXX Insert Your tags here */
- { TIFFTAG_GEOPIXELSCALE, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
- TRUE, TRUE, "GeoPixelScale" },
- { TIFFTAG_GEOTRANSMATRIX, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
- TRUE, TRUE, "GeoTransformationMatrix" },
- { TIFFTAG_GEOTIEPOINTS, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
- TRUE, TRUE, "GeoTiePoints" },
- { TIFFTAG_GEOKEYDIRECTORY, -1,-1, TIFF_SHORT, FIELD_CUSTOM,
- TRUE, TRUE, "GeoKeyDirectory" },
- { TIFFTAG_GEODOUBLEPARAMS, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM,
- TRUE, TRUE, "GeoDoubleParams" },
- { TIFFTAG_GEOASCIIPARAMS, -1,-1, TIFF_ASCII, FIELD_CUSTOM,
- TRUE, FALSE, "GeoASCIIParams" }
- };
- </pre>
- In order to define the tags, we call TIFFMergeFieldInfo() on the
- desired TIFF handle with the list of TIFFFieldInfos.<p>
- <pre>
- #define N(a) (sizeof (a) / sizeof (a[0]))
- /* Install the extended Tag field info */
- TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
- </pre>
- The tags need to be defined for each TIFF file opened - and when reading
- they should be defined before the tags of the file are read, yet a valid
- TIFF * is needed to merge the tags against. In order to get them
- registered at the appropriate part of the setup process, it is necessary
- to register our merge function as an extender callback with libtiff.
- This is done with TIFFSetTagExtender(). We also keep track of the
- previous tag extender (if any) so that we can call it from our extender
- allowing a chain of customizations to take effect. <P>
- <pre>
- static TIFFExtendProc _ParentExtender = NULL;
- static
- void _XTIFFInitialize(void)
- {
- static int first_time=1;
-
- if (! first_time) return; /* Been there. Done that. */
- first_time = 0;
-
- /* Grab the inherited method and install */
- _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
- }
- </pre>
- The extender callback is looks like this. It merges in our new fields
- and then calls the next extender if there is one in effect.<p>
- <pre>
- static void
- _XTIFFDefaultDirectory(TIFF *tif)
- {
- /* Install the extended Tag field info */
- TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
- /* Since an XTIFF client module may have overridden
- * the default directory method, we call it now to
- * allow it to set up the rest of its own methods.
- */
- if (_ParentExtender)
- (*_ParentExtender)(tif);
- }
- </pre>
- The above approach ensures that our new definitions are used when reading
- or writing any TIFF file. However, since on reading we already have
- default definitions for tags, it is usually not critical to pre-define them.
- If tag definitions are only required for writing custom tags, you can just
- call TIFFMergeFieldInfo() before setting new tags. The whole extender
- architecture can then be avoided.<p>
- <A NAME=AddingTags><P><H2>Adding New Builtin Tags</H2></A>
- A similar approach is taken to the above. However, the TIFFFieldInfo
- should be added to the tiffFieldInfo[] list in tif_dirinfo.c. Ensure that
- new tags are added in sorted order by the tag number.<p>
- Normally new built-in tags should be defined with FIELD_CUSTOM; however, if
- it is desirable for the tag value to have it's own field in the TIFFDirectory
- structure, then you will need to #define a new FIELD_ value for it, and
- add appropriate handling as follows:
- <OL>
- <LI>Define the tag in <B>tiff.h</B>.
- <LI>Add a field to the directory structure in <B>tif_dir.h</B>
- and define a <TT>FIELD_*</TT> bit (also update the definition of
- <TT>FIELD_CODEC</TT> to reflect your addition).
- <LI>Add an entry in the <TT>TIFFFieldInfo</TT> array defined at the top of
- <B>tif_dirinfo.c</B>.
- Note that you must keep this array sorted by tag
- number and that the widest variant entry for a tag should come
- first (e.g. <TT>LONG</TT> before <TT>SHORT</TT>).
- <LI>Add entries in <TT>_TIFFVSetField()</TT> and <TT>_TIFFVGetField()</TT>
- for the new tag.
- <LI>(<I>optional</I>) If the value associated with the tag is not a scalar value
- (e.g. the array for <TT>TransferFunction</TT>) and requires
- special processing,
- then add the appropriate code to <TT>TIFFReadDirectory()</TT> and
- <TT>TIFFWriteDirectory()</TT>. You're best off finding a similar tag and
- cribbing code.
- <LI>Add support to <TT>TIFFPrintDirectory()</TT> in <B>tif_print.c</B>
- to print the tag's value.
- </OL>
- <P>
- If you want to maintain portability, beware of making assumptions
- about data types. Use the typedefs (<TT>uint16</TT>, etc. when dealing with
- data on disk and <TT>t*_t</TT> when stuff is in memory) and be careful about
- passing items through printf or similar vararg interfaces.
- <A NAME=AddingCODECTags><P><H2>Adding New Codec-private Tags</H2></A>
- To add tags that are meaningful <EM>only when a particular compression
- algorithm is used</EM> follow these steps:
- <OL>
- <LI>Define the tag in <B>tiff.h</B>.
- <LI>Allocate storage for the tag values in the private state block of
- the codec.
- <LI>Insure the state block is created when the codec is initialized.
- <LI>At <TT>TIFFInitfoo</TT> time override the method pointers in the
- TIFF structure
- for getting, setting and printing tag values. For example,
- <PRE>
- sp->vgetparent = tif->tif_vgetfield;
- tif->tif_vgetfield = fooVGetField; /* hook for codec tags */
- sp->vsetparent = tif->tif_vsetfield;
- tif->tif_vsetfield = fooVSetField; /* hook for codec tags */
- tif->tif_printdir = fooPrintDir; /* hook for codec tags */
- </PRE>
- (Actually you may decide not to override the
- <TT>tif_printdir</TT> method, but rather just specify it).
- <LI>Create a private <TT>TIFFFieldInfo</TT> array for your tags and
- merge them into the core tags at initialization time using
- <TT>_TIFFMergeFieldInfo</TT>; e.g.
- <PRE>
- _TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo));
- </PRE>
- (where <TT>N</TT> is a macro used liberaly throughout the distributed code).
- <LI>Fill in the get and set routines. Be sure to call the parent method
- for tags that you are not handled directly. Also be sure to set the
- <TT>FIELD_*</TT> bits for tags that are to be written to the file. Note that
- you can create ``pseudo-tags'' by defining tags that are processed
- exclusively in the get/set routines and never written to file (see
- the handling of <TT>TIFFTAG_FAXMODE</TT> in <B>tif_fax3.c</B>
- for an example of this).
- <LI>Fill in the print routine, if appropriate.
- </OL>
- Note that space has been allocated in the <TT>FIELD_*</TT> bit space for
- codec-private tags. Define your bits as <TT>FIELD_CODEC+<offset></TT> to
- keep them away from the core tags. If you need more tags than there
- is room for, just increase <TT>FIELD_SETLONGS</TT> at the top of
- <B>tiffiop.h</B>.
- <HR>
- Last updated: $Date: 2004/09/10 14:43:18 $
- </BODY>
- </HTML>