Blame html/addingtags.html

Packit Service 2594b8
<HTML>
Packit Service 2594b8
<HEAD>
Packit Service 2594b8
<TITLE>
Packit Service 2594b8
Modifying The TIFF Library
Packit Service 2594b8
</TITLE>
Packit Service 2594b8
</HEAD>
Packit Service 2594b8
<BODY BGCOLOR=white> 
Packit Service 2594b8
<FONT FACE="Arial, Helvetica, Sans">
Packit Service 2594b8
Packit Service 2594b8

Packit Service 2594b8
Defining New TIFF Tags
Packit Service 2594b8
Packit Service 2594b8
Packit Service 2594b8
Libtiff has built-in knowledge of all the standard TIFF tags, as
Packit Service 2594b8
well as extentions.  The following describes how to add knowledge of
Packit Service 2594b8
new tags as builtins to libtiff, or how to application specific tags can
Packit Service 2594b8
be used by applications without modifying libtiff. 
Packit Service 2594b8

Packit Service 2594b8
Packit Service 2594b8

TIFFFieldInfo

Packit Service 2594b8
Packit Service 2594b8
How libtiff manages specific tags is primarily controlled by the 
Packit Service 2594b8
definition for that tag value stored internally as a TIFFFieldInfo structure. 
Packit Service 2594b8
This structure looks like this:
Packit Service 2594b8

Packit Service 2594b8
Packit Service 2594b8
Packit Service 2594b8
typedef	struct {
Packit Service 2594b8
  ttag_t    field_tag;          /* field's tag */
Packit Service 2594b8
  short	    field_readcount;    /* read count/TIFF_VARIABLE/TIFF_SPP */
Packit Service 2594b8
  short	    field_writecount;   /* write count/TIFF_VARIABLE */
Packit Service 2594b8
  TIFFDataType field_type;      /* type of associated data */
Packit Service 2594b8
  unsigned short field_bit;     /* bit in fieldsset bit vector */
Packit Service 2594b8
  unsigned char field_oktochange;/* if true, can change while writing */
Packit Service 2594b8
  unsigned char field_passcount;/* if true, pass dir count on set */
Packit Service 2594b8
  char	*field_name;		/* ASCII name */
Packit Service 2594b8
} TIFFFieldInfo;
Packit Service 2594b8
Packit Service 2594b8
Packit Service 2594b8
    Packit Service 2594b8
  • field_tag: the tag number. For instance 277 for the
  • Packit Service 2594b8
    SamplesPerPixel tag.  Builtin tags will generally have a #define in
    Packit Service 2594b8
    tiff.h for each known tag. 

    Packit Service 2594b8
    Packit Service 2594b8
  • field_readcount: The number of values which should be read.
  • Packit Service 2594b8
    The special value TIFF_VARIABLE (-1) indicates that a variable number of
    Packit Service 2594b8
    values may be read.  The special value TIFFTAG_SPP (-2) indicates that there
    Packit Service 2594b8
    should be one value for each sample as defined by TIFFTAG_SAMPLESPERPIXEL.  
    Packit Service 2594b8
    The special value TIFF_VARIABLE2 (-3) is presumably similar to TIFF_VARIABLE
    Packit Service 2594b8
    though I am not sure what the distinction in behaviour is.  This field
    Packit Service 2594b8
    is TIFF_VARIABLE for variable length ascii fields.

    Packit Service 2594b8
    Packit Service 2594b8
  • field_writecount: The number of values which should be written.
  • Packit Service 2594b8
    Generally the same as field_readcount.  A few built-in exceptions exist, but
    Packit Service 2594b8
    I haven't analysed why they differ. 

    Packit Service 2594b8
    Packit Service 2594b8
  • field_type: Type of the field. One of TIFF_BYTE, TIFF_ASCII,
  • Packit Service 2594b8
    TIFF_SHORT, TIFF_LONG, TIFF_RATIONAL, TIFF_SBYTE, TIFF_UNDEFINED, 
    Packit Service 2594b8
    TIFF_SSHORT, TIFF_SLONG, TIFF_SRATIONAL, TIFF_FLOAT, TIFF_DOUBLE or
    Packit Service 2594b8
    TIFF_IFD.  Note that some fields can support more than one type (for 
    Packit Service 2594b8
    instance short and long).  These fields should have multiple TIFFFieldInfos. 
    Packit Service 2594b8

    Packit Service 2594b8
    Packit Service 2594b8
  • field_bit: Built-in tags stored in special fields in the
  • Packit Service 2594b8
    TIFF structure have assigned field numbers to distinguish them (ie. 
    Packit Service 2594b8
    FIELD_SAMPLESPERPIXEL).  New tags should generally just use 
    Packit Service 2594b8
    FIELD_CUSTOM indicating they are stored in the generic tag list.

    Packit Service 2594b8
    Packit Service 2594b8
  • field_oktochange: TRUE if it is OK to change this tag value
  • Packit Service 2594b8
    while an image is being written.  FALSE for stuff that must be set once
    Packit Service 2594b8
    and then left unchanged (like ImageWidth, or PhotometricInterpretation for
    Packit Service 2594b8
    instance).

    Packit Service 2594b8
    Packit Service 2594b8
  • field_passcount: If TRUE, then the count value must be passed
  • Packit Service 2594b8
    in TIFFSetField(), and TIFFGetField(), otherwise the count is not required.
    Packit Service 2594b8
    This should generally be TRUE for non-ascii variable count tags unless
    Packit Service 2594b8
    the count is implicit (such as with the colormap).

    Packit Service 2594b8
    Packit Service 2594b8
  • field_name: A name for the tag. Normally mixed case (studly caps)
  • Packit Service 2594b8
    like "StripByteCounts" and relatively short. 

    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    A TIFFFieldInfo definition exists for each built-in tag in the tif_dirinfo.c
    Packit Service 2594b8
    file.  Some tags which support multiple data types have more than one
    Packit Service 2594b8
    definition, one per data type supported. 

    Packit Service 2594b8
    Packit Service 2594b8
    Various functions exist for getting the internal TIFFFieldInfo definitions,
    Packit Service 2594b8
    including _TIFFFindFieldInfo(), and _TIFFFindFieldInfoByName().  See
    Packit Service 2594b8
    tif_dirinfo.c for details.  There must be some mechanism to get the whole
    Packit Service 2594b8
    list, though I don't see it off hand.

    Packit Service 2594b8
    Packit Service 2594b8

    Default Tag Auto-registration

    Packit Service 2594b8
    Packit Service 2594b8
    In libtiff 3.6.0 a new mechanism was introduced allowing libtiff to 
    Packit Service 2594b8
    read unrecognised tags automatically.  When an unknown tags is encountered, 
    Packit Service 2594b8
    it is automatically internally defined with a default name and a type 
    Packit Service 2594b8
    derived from the tag value in the file.  Applications only need to predefine
    Packit Service 2594b8
    application specific tags if they need to be able to set them in a file, or
    Packit Service 2594b8
    if particular calling conventions are desired for TIFFSetField() and 
    Packit Service 2594b8
    TIFFGetField().

    Packit Service 2594b8
    Packit Service 2594b8
    When tags are autodefined like this the field_readcount and
    Packit Service 2594b8
    field_writecount values are always TIFF_VARIABLE.  The 
    Packit Service 2594b8
    field_passcount is always TRUE, and the field_bit is 
    Packit Service 2594b8
    FIELD_CUSTOM.  The field name will be "Tag %d" where the %d is the tag 
    Packit Service 2594b8
    number.

    Packit Service 2594b8
    Packit Service 2594b8

    Defining Application Tags

    Packit Service 2594b8
    Packit Service 2594b8
    For various reasons, it is common for applications to want to define
    Packit Service 2594b8
    their own tags to store information outside the core TIFF specification. 
    Packit Service 2594b8
    This is done by calling TIFFMergeFieldInfo() with one or more TIFFFieldInfos. 
    Packit Service 2594b8

    Packit Service 2594b8
    Packit Service 2594b8
    The libgeotiff library provides geospatial information extentions within
    Packit Service 2594b8
    a TIFF file.  First, a set of TIFFFieldInfo's is prepared with information
    Packit Service 2594b8
    on the new tags:

    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    static const TIFFFieldInfo xtiffFieldInfo[] = {
    Packit Service 2594b8
      
    Packit Service 2594b8
      /* XXX Insert Your tags here */
    Packit Service 2594b8
        { TIFFTAG_GEOPIXELSCALE,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
    Packit Service 2594b8
          TRUE,	TRUE,	"GeoPixelScale" },
    Packit Service 2594b8
        { TIFFTAG_GEOTRANSMATRIX,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
    Packit Service 2594b8
          TRUE,	TRUE,	"GeoTransformationMatrix" },
    Packit Service 2594b8
        { TIFFTAG_GEOTIEPOINTS,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
    Packit Service 2594b8
          TRUE,	TRUE,	"GeoTiePoints" },
    Packit Service 2594b8
        { TIFFTAG_GEOKEYDIRECTORY, -1,-1, TIFF_SHORT,	FIELD_CUSTOM,
    Packit Service 2594b8
          TRUE,	TRUE,	"GeoKeyDirectory" },
    Packit Service 2594b8
        { TIFFTAG_GEODOUBLEPARAMS,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
    Packit Service 2594b8
          TRUE,	TRUE,	"GeoDoubleParams" },
    Packit Service 2594b8
        { TIFFTAG_GEOASCIIPARAMS,	-1,-1, TIFF_ASCII,	FIELD_CUSTOM,
    Packit Service 2594b8
          TRUE,	FALSE,	"GeoASCIIParams" }
    Packit Service 2594b8
    };
    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    In order to define the tags, we call TIFFMergeFieldInfo() on the
    Packit Service 2594b8
    desired TIFF handle with the list of TIFFFieldInfos.

    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    #define	N(a)	(sizeof (a) / sizeof (a[0]))
    Packit Service 2594b8
    Packit Service 2594b8
        /* Install the extended Tag field info */
    Packit Service 2594b8
        TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    The tags need to be defined for each TIFF file opened - and when reading
    Packit Service 2594b8
    they should be defined before the tags of the file are read, yet a valid
    Packit Service 2594b8
    TIFF * is needed to merge the tags against.   In order to get them 
    Packit Service 2594b8
    registered at the appropriate part of the setup process, it is necessary
    Packit Service 2594b8
    to register our merge function as an extender callback with libtiff. 
    Packit Service 2594b8
    This is done with TIFFSetTagExtender().  We also keep track of the 
    Packit Service 2594b8
    previous tag extender (if any) so that we can call it from our extender
    Packit Service 2594b8
    allowing a chain of customizations to take effect. 

    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    static TIFFExtendProc _ParentExtender = NULL;
    Packit Service 2594b8
    Packit Service 2594b8
    static
    Packit Service 2594b8
    void _XTIFFInitialize(void)
    Packit Service 2594b8
    {
    Packit Service 2594b8
        static int first_time=1;
    Packit Service 2594b8
    	
    Packit Service 2594b8
        if (! first_time) return; /* Been there. Done that. */
    Packit Service 2594b8
        first_time = 0;
    Packit Service 2594b8
    	
    Packit Service 2594b8
        /* Grab the inherited method and install */
    Packit Service 2594b8
        _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
    Packit Service 2594b8
    }
    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    The extender callback is looks like this.  It merges in our new fields
    Packit Service 2594b8
    and then calls the next extender if there is one in effect.

    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    static void
    Packit Service 2594b8
    _XTIFFDefaultDirectory(TIFF *tif)
    Packit Service 2594b8
    {
    Packit Service 2594b8
        /* Install the extended Tag field info */
    Packit Service 2594b8
        TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
    Packit Service 2594b8
    Packit Service 2594b8
        /* Since an XTIFF client module may have overridden
    Packit Service 2594b8
         * the default directory method, we call it now to
    Packit Service 2594b8
         * allow it to set up the rest of its own methods.
    Packit Service 2594b8
         */
    Packit Service 2594b8
    Packit Service 2594b8
        if (_ParentExtender) 
    Packit Service 2594b8
            (*_ParentExtender)(tif);
    Packit Service 2594b8
    }
    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
    The above approach ensures that our new definitions are used when reading
    Packit Service 2594b8
    or writing any TIFF file.  However, since on reading we already have 
    Packit Service 2594b8
    default definitions for tags, it is usually not critical to pre-define them.
    Packit Service 2594b8
    If tag definitions are only required for writing custom tags, you can just
    Packit Service 2594b8
    call TIFFMergeFieldInfo() before setting new tags.  The whole extender
    Packit Service 2594b8
    architecture can then be avoided.

    Packit Service 2594b8
    Packit Service 2594b8

    Adding New Builtin Tags

    Packit Service 2594b8
    Packit Service 2594b8
    A similar approach is taken to the above.  However, the TIFFFieldInfo 
    Packit Service 2594b8
    should be added to the tiffFieldInfo[] list in tif_dirinfo.c.  Ensure that
    Packit Service 2594b8
    new tags are added in sorted order by the tag number.

    Packit Service 2594b8
    Packit Service 2594b8
    Normally new built-in tags should be defined with FIELD_CUSTOM; however, if
    Packit Service 2594b8
    it is desirable for the tag value to have it's own field in the TIFFDirectory
    Packit Service 2594b8
    structure, then you will need to #define a new FIELD_ value for it, and
    Packit Service 2594b8
    add appropriate handling as follows:
    Packit Service 2594b8
    Packit Service 2594b8
    Packit Service 2594b8
      Packit Service 2594b8
    1. Define the tag in tiff.h.
    2. Packit Service 2594b8
    3. Add a field to the directory structure in tif_dir.h
    4. Packit Service 2594b8
         and define a <TT>FIELD_*</TT> bit (also update the definition of
      Packit Service 2594b8
         <TT>FIELD_CODEC</TT> to reflect your addition).
      Packit Service 2594b8
    5. Add an entry in the <TT>TIFFFieldInfo</TT> array defined at the top of
    6. Packit Service 2594b8
         tif_dirinfo.c. 
      Packit Service 2594b8
         Note that you must keep this array sorted by tag
      Packit Service 2594b8
         number and that the widest variant entry for a tag should come
      Packit Service 2594b8
         first (e.g. <TT>LONG</TT> before <TT>SHORT</TT>).
      Packit Service 2594b8
    7. Add entries in <TT>_TIFFVSetField()</TT> and <TT>_TIFFVGetField()</TT>
    8. Packit Service 2594b8
         for the new tag.
      Packit Service 2594b8
    9. (optional) If the value associated with the tag is not a scalar value
    10. Packit Service 2594b8
         (e.g. the array for <TT>TransferFunction</TT>) and requires
      Packit Service 2594b8
         special processing,
      Packit Service 2594b8
         then add the appropriate code to <TT>TIFFReadDirectory()</TT> and
      Packit Service 2594b8
         <TT>TIFFWriteDirectory()</TT>.  You're best off finding a similar tag and
      Packit Service 2594b8
         cribbing code.
      Packit Service 2594b8
    11. Add support to <TT>TIFFPrintDirectory()</TT> in tif_print.c
    12. Packit Service 2594b8
          to print the tag's value.
      Packit Service 2594b8
      Packit Service 2594b8
      Packit Service 2594b8

      Packit Service 2594b8
      If you want to maintain portability, beware of making assumptions
      Packit Service 2594b8
      about data types.  Use the typedefs (<TT>uint16</TT>, etc. when dealing with
      Packit Service 2594b8
      data on disk and <TT>t*_t</TT> when stuff is in memory) and be careful about
      Packit Service 2594b8
      passing items through printf or similar vararg interfaces.
      Packit Service 2594b8
      Packit Service 2594b8

      Adding New Codec-private Tags

      Packit Service 2594b8
      Packit Service 2594b8
      To add tags that are meaningful only when a particular compression
      Packit Service 2594b8
      algorithm is used follow these steps:
      Packit Service 2594b8
      Packit Service 2594b8
        Packit Service 2594b8
      1. Define the tag in tiff.h.
      2. Packit Service 2594b8
      3. Allocate storage for the tag values in the private state block of
      4. Packit Service 2594b8
           the codec.
        Packit Service 2594b8
      5. Insure the state block is created when the codec is initialized.
      6. Packit Service 2594b8
      7. At <TT>TIFFInitfoo</TT> time override the method pointers in the
      8. Packit Service 2594b8
            TIFF structure
        Packit Service 2594b8
           for getting, setting and printing tag values.  For example,
        Packit Service 2594b8
        Packit Service 2594b8
            sp->vgetparent = tif->tif_vgetfield;
        Packit Service 2594b8
            tif->tif_vgetfield = fooVGetField;	/* hook for codec tags */
        Packit Service 2594b8
            sp->vsetparent = tif->tif_vsetfield;
        Packit Service 2594b8
            tif->tif_vsetfield = fooVSetField;	/* hook for codec tags */
        Packit Service 2594b8
            tif->tif_printdir = fooPrintDir;	/* hook for codec tags */
        Packit Service 2594b8
        Packit Service 2594b8
           (Actually you may decide not to override the
        Packit Service 2594b8
           <TT>tif_printdir</TT> method, but rather just specify it).
        Packit Service 2594b8
      9. Create a private <TT>TIFFFieldInfo</TT> array for your tags and
      10. Packit Service 2594b8
            merge them into the core tags at initialization time using
        Packit Service 2594b8
            <TT>_TIFFMergeFieldInfo</TT>; e.g.
        Packit Service 2594b8
        Packit Service 2594b8
            _TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo));
        Packit Service 2594b8
        Packit Service 2594b8
           (where <TT>N</TT> is a macro used liberaly throughout the distributed code).
        Packit Service 2594b8
      11. Fill in the get and set routines. Be sure to call the parent method
      12. Packit Service 2594b8
           for tags that you are not handled directly.  Also be sure to set the
        Packit Service 2594b8
           <TT>FIELD_*</TT> bits for tags that are to be written to the file.  Note that
        Packit Service 2594b8
           you can create ``pseudo-tags'' by defining tags that are processed
        Packit Service 2594b8
           exclusively in the get/set routines and never written to file (see
        Packit Service 2594b8
           the handling of <TT>TIFFTAG_FAXMODE</TT> in tif_fax3.c
        Packit Service 2594b8
           for an example of this).
        Packit Service 2594b8
      13. Fill in the print routine, if appropriate.
      14. Packit Service 2594b8
        Packit Service 2594b8
        Packit Service 2594b8
        Note that space has been allocated in the <TT>FIELD_*</TT> bit space for
        Packit Service 2594b8
        codec-private tags.  Define your bits as <TT>FIELD_CODEC+<offset></TT> to
        Packit Service 2594b8
        keep them away from the core tags.  If you need more tags than there
        Packit Service 2594b8
        is room for, just increase <TT>FIELD_SETLONGS</TT> at the top of
        Packit Service 2594b8
        tiffiop.h.
        Packit Service 2594b8
        Packit Service 2594b8

        Packit Service 2594b8
        Packit Service 2594b8
        Last updated: $Date: 2016-09-25 20:05:44 $
        Packit Service 2594b8
        Packit Service 2594b8
        </BODY>
        Packit Service 2594b8
        Packit Service 2594b8
        </HTML>