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