4 * Extended TIFF Directory Tag Support.
6 * You may use this file as a template to add your own
7 * extended tags to the library. Only the parts of the code
8 * marked with "XXX" require modification. Three example tags
9 * are shown; you should replace them with your own.
11 * Author: Niles D. Ritter
17 /* Tiff info structure.
20 * { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM,
21 * OkToChange, PassDirCountOnSet, AsciiName }
23 * For ReadCount, WriteCount, -1 = unknown; used for mult-valued
27 static const TIFFFieldInfo xtiffFieldInfo
[] = {
29 /* XXX Replace these example tags with your own extended tags */
30 { TIFFTAG_EXAMPLE_MULTI
, -1,-1, TIFF_DOUBLE
, FIELD_EXAMPLE_MULTI
,
31 TRUE
, TRUE
, "MyMultivaluedTag" },
32 { TIFFTAG_EXAMPLE_SINGLE
, 1, 1, TIFF_LONG
, FIELD_EXAMPLE_SINGLE
,
33 TRUE
, FALSE
, "MySingleLongTag" },
34 { TIFFTAG_EXAMPLE_ASCII
, -1,-1, TIFF_ASCII
, FIELD_EXAMPLE_ASCII
,
35 TRUE
, FALSE
, "MyAsciiTag" },
37 #define N(a) (sizeof (a) / sizeof (a[0]))
41 _XTIFFPrintDirectory(TIFF
* tif
, FILE* fd
, long flags
)
43 xtiff
*xt
= XTIFFDIR(tif
);
44 XTIFFDirectory
*xd
= &xt
->xtif_dir
;
47 /* call the inherited method */
48 if (PARENT(xt
,printdir
))
49 (PARENT(xt
,printdir
))(tif
,fd
,flags
);
51 /* XXX Add field printing here. Replace the three example
52 * tags implemented below with your own.
55 fprintf(fd
,"--My Example Tags--\n");
57 /* Our first example tag may have a lot of values, so we
58 * will only print them out if the TIFFPRINT_MYMULTIDOUBLES
59 * flag is passed into the print method.
61 if (TIFFFieldSet(tif
,FIELD_EXAMPLE_MULTI
))
63 fprintf(fd
, " My Multi-Valued Doubles:");
64 if (flags
& TIFFPRINT_MYMULTIDOUBLES
)
66 double *value
= xd
->xd_example_multi
;
68 num
= xd
->xd_num_multi
;
70 for (i
=0;i
<num
;i
++) fprintf(fd
, " %lg", *value
++);
73 fprintf(fd
, "(present)\n");
76 if (TIFFFieldSet(tif
,FIELD_EXAMPLE_SINGLE
))
78 fprintf(fd
, " My Single Long Tag: %lu\n", xd
->xd_example_single
);
81 if (TIFFFieldSet(tif
,FIELD_EXAMPLE_ASCII
))
83 _TIFFprintAsciiTag(fd
,"My ASCII Tag",
84 xd
->xd_example_ascii
);
89 _XTIFFVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
)
91 xtiff
*xt
= XTIFFDIR(tif
);
92 XTIFFDirectory
* xd
= &xt
->xtif_dir
;
98 /* va_start is called by the calling routine */
102 * XXX put your extended tags here; replace the implemented
103 * example tags with your own.
105 case TIFFTAG_EXAMPLE_MULTI
:
106 /* multi-valued tags need to store the count as well */
107 xd
->xd_num_multi
= (uint16
) va_arg(ap
, int);
108 _TIFFsetDoubleArray(&xd
->xd_example_multi
, va_arg(ap
, double*),
109 (long) xd
->xd_num_multi
);
111 case TIFFTAG_EXAMPLE_SINGLE
:
112 xd
->xd_example_single
= va_arg(ap
, uint32
);
114 case TIFFTAG_EXAMPLE_ASCII
:
115 _TIFFsetString(&xd
->xd_example_ascii
, va_arg(ap
, char*));
118 /* call the inherited method */
119 return (PARENT(xt
,vsetfield
))(tif
,tag
,ap
);
123 /* we have to override the print method here,
124 * after the compression tags have gotten to it.
125 * This makes sense because the only time we would
126 * need the extended print method is if an extended
127 * tag is set by the reader.
129 if (!(xt
->xtif_flags
& XTIFFP_PRINT
))
131 PARENT(xt
,printdir
) = TIFFMEMBER(tif
,printdir
);
132 TIFFMEMBER(tif
,printdir
) = _XTIFFPrintDirectory
;
133 xt
->xtif_flags
|= XTIFFP_PRINT
;
135 TIFFSetFieldBit(tif
, _TIFFFieldWithTag(tif
, tag
)->field_bit
);
136 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
141 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, "%d: Bad value for \"%s\"", v
,
142 _TIFFFieldWithTag(tif
, tag
)->field_name
);
146 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, "%ld: Bad value for \"%s\"", v32
,
147 _TIFFFieldWithTag(tif
, tag
)->field_name
);
154 _XTIFFVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
)
156 xtiff
*xt
= XTIFFDIR(tif
);
157 XTIFFDirectory
* xd
= &xt
->xtif_dir
;
161 * XXX put your extended tags here; replace the implemented
162 * example tags with your own.
164 case TIFFTAG_EXAMPLE_MULTI
:
165 *va_arg(ap
, uint16
*) = xd
->xd_num_multi
;
166 *va_arg(ap
, double**) = xd
->xd_example_multi
;
168 case TIFFTAG_EXAMPLE_ASCII
:
169 *va_arg(ap
, char**) = xd
->xd_example_ascii
;
171 case TIFFTAG_EXAMPLE_SINGLE
:
172 *va_arg(ap
, uint32
*) = xd
->xd_example_single
;
175 /* return inherited method */
176 return (PARENT(xt
,vgetfield
))(tif
,tag
,ap
);
182 #define CleanupField(member) { \
184 _TIFFfree(xd->member); \
189 * Release storage associated with a directory.
192 _XTIFFFreeDirectory(xtiff
* xt
)
194 XTIFFDirectory
* xd
= &xt
->xtif_dir
;
197 * XXX - Purge all Your allocated memory except
198 * for the xtiff directory itself. This includes
199 * all fields that require a _TIFFsetXXX call in
203 CleanupField(xd_example_multi
);
204 CleanupField(xd_example_ascii
);
209 static void _XTIFFLocalDefaultDirectory(TIFF
*tif
)
211 xtiff
*xt
= XTIFFDIR(tif
);
212 XTIFFDirectory
* xd
= &xt
->xtif_dir
;
214 /* Install the extended Tag field info */
215 _TIFFMergeFieldInfo(tif
, xtiffFieldInfo
, N(xtiffFieldInfo
));
218 * free up any dynamically allocated arrays
219 * before the new directory is read in.
222 _XTIFFFreeDirectory(xt
);
223 _TIFFmemset(xt
,0,sizeof(xtiff
));
225 /* Override the tag access methods */
227 PARENT(xt
,vsetfield
) = TIFFMEMBER(tif
,vsetfield
);
228 TIFFMEMBER(tif
,vsetfield
) = _XTIFFVSetField
;
229 PARENT(xt
,vgetfield
) = TIFFMEMBER(tif
,vgetfield
);
230 TIFFMEMBER(tif
,vgetfield
) = _XTIFFVGetField
;
233 * XXX Set up any default values here.
236 xd
->xd_example_single
= 234;
241 /**********************************************************************
242 * Nothing below this line should need to be changed.
243 **********************************************************************/
245 static TIFFExtendProc _ParentExtender
;
248 * This is the callback procedure, and is
249 * called by the DefaultDirectory method
250 * every time a new TIFF directory is opened.
254 _XTIFFDefaultDirectory(TIFF
*tif
)
258 /* Allocate Directory Structure if first time, and install it */
259 if (!(tif
->tif_flags
& XTIFF_INITIALIZED
))
261 xt
= _TIFFmalloc(sizeof(xtiff
));
264 /* handle memory allocation failure here ! */
267 _TIFFmemset(xt
,0,sizeof(xtiff
));
269 * Install into TIFF structure.
271 TIFFMEMBER(tif
,clientdir
) = (tidata_t
)xt
;
272 tif
->tif_flags
|= XTIFF_INITIALIZED
; /* dont do this again! */
275 /* set up our own defaults */
276 _XTIFFLocalDefaultDirectory(tif
);
278 /* Since an XTIFF client module may have overridden
279 * the default directory method, we call it now to
280 * allow it to set up the rest of its own methods.
284 (*_ParentExtender
)(tif
);
289 * XTIFF Initializer -- sets up the callback
290 * procedure for the TIFF module.
294 void _XTIFFInitialize(void)
298 if (! first_time
) return; /* Been there. Done that. */
301 /* Grab the inherited method and install */
302 _ParentExtender
= TIFFSetTagExtender(_XTIFFDefaultDirectory
);
307 * Public File I/O Routines.
310 XTIFFOpen(const char* name
, const char* mode
)
312 /* Set up the callback */
315 /* Open the file; the callback will set everything up
317 return TIFFOpen(name
, mode
);
321 XTIFFFdOpen(int fd
, const char* name
, const char* mode
)
323 /* Set up the callback */
326 /* Open the file; the callback will set everything up
328 return TIFFFdOpen(fd
, name
, mode
);
333 XTIFFClose(TIFF
*tif
)
335 xtiff
*xt
= XTIFFDIR(tif
);
337 /* call inherited function first */
340 /* Free up extended allocated memory */
341 _XTIFFFreeDirectory(xt
);