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
TIFFError(tif->tif_name, "%d: Bad value for \"%s\"", v,
142
_TIFFFieldWithTag(tif, tag)->field_name);
146
TIFFError(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);