~ubuntu-branches/ubuntu/karmic/tiff/karmic-security

« back to all changes in this revision

Viewing changes to contrib/tags/xtif_dir.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-10-14 07:57:59 UTC
  • Revision ID: james.westby@ubuntu.com-20041014075759-a77e7zuaetya8cp0
Tags: upstream-3.6.1
ImportĀ upstreamĀ versionĀ 3.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * xtif_dir.c
 
3
 *
 
4
 * Extended TIFF Directory Tag Support.
 
5
 *
 
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.
 
10
 *
 
11
 *  Author: Niles D. Ritter
 
12
 */
 
13
 
 
14
#include "xtiffiop.h"
 
15
#include <stdio.h>
 
16
 
 
17
/*  Tiff info structure.
 
18
 *
 
19
 *     Entry format:
 
20
 *        { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, 
 
21
 *          OkToChange, PassDirCountOnSet, AsciiName }
 
22
 *
 
23
 *     For ReadCount, WriteCount, -1 = unknown; used for mult-valued
 
24
 *         tags and ASCII.
 
25
 */
 
26
 
 
27
static const TIFFFieldInfo xtiffFieldInfo[] = {
 
28
  
 
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" },
 
36
};
 
37
#define N(a)    (sizeof (a) / sizeof (a[0]))
 
38
 
 
39
 
 
40
static void
 
41
_XTIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
 
42
{
 
43
        xtiff *xt = XTIFFDIR(tif);
 
44
        XTIFFDirectory *xd = &xt->xtif_dir;
 
45
        int i,num;
 
46
 
 
47
        /* call the inherited method */
 
48
        if (PARENT(xt,printdir))
 
49
                (PARENT(xt,printdir))(tif,fd,flags);
 
50
 
 
51
        /* XXX Add field printing here. Replace the three example
 
52
         *    tags implemented below with your own.
 
53
         */
 
54
 
 
55
        fprintf(fd,"--My Example Tags--\n");
 
56
 
 
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.
 
60
         */
 
61
        if (TIFFFieldSet(tif,FIELD_EXAMPLE_MULTI))
 
62
        {
 
63
                fprintf(fd, "  My Multi-Valued Doubles:");
 
64
                if (flags & TIFFPRINT_MYMULTIDOUBLES) 
 
65
                {
 
66
                        double *value = xd->xd_example_multi;
 
67
        
 
68
                        num = xd->xd_num_multi;
 
69
                        fprintf(fd,"(");
 
70
                        for (i=0;i<num;i++) fprintf(fd, " %lg", *value++);
 
71
                        fprintf(fd,")\n");
 
72
                } else
 
73
                        fprintf(fd, "(present)\n");
 
74
        }
 
75
 
 
76
        if (TIFFFieldSet(tif,FIELD_EXAMPLE_SINGLE))
 
77
        {
 
78
                fprintf(fd, "  My Single Long Tag:  %lu\n", xd->xd_example_single);
 
79
        }
 
80
 
 
81
        if (TIFFFieldSet(tif,FIELD_EXAMPLE_ASCII))
 
82
        {
 
83
                _TIFFprintAsciiTag(fd,"My ASCII Tag",
 
84
                         xd->xd_example_ascii);
 
85
        }
 
86
}
 
87
 
 
88
static int
 
89
_XTIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
 
90
{
 
91
        xtiff *xt = XTIFFDIR(tif);
 
92
        XTIFFDirectory* xd = &xt->xtif_dir;
 
93
        int status = 1;
 
94
        uint32 v32=0;
 
95
        int i=0, v=0;
 
96
        va_list ap1 = ap;
 
97
 
 
98
        /* va_start is called by the calling routine */
 
99
        
 
100
        switch (tag) {
 
101
                /* 
 
102
                 * XXX put your extended tags here; replace the implemented
 
103
                 *     example tags with your own. 
 
104
                 */
 
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);
 
110
                break;
 
111
        case TIFFTAG_EXAMPLE_SINGLE:
 
112
                xd->xd_example_single = va_arg(ap, uint32);
 
113
                break;
 
114
        case TIFFTAG_EXAMPLE_ASCII:
 
115
                _TIFFsetString(&xd->xd_example_ascii, va_arg(ap, char*));
 
116
                break;
 
117
        default:
 
118
                /* call the inherited method */
 
119
                return (PARENT(xt,vsetfield))(tif,tag,ap);
 
120
                break;
 
121
        }
 
122
        if (status) {
 
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.
 
128
                 */
 
129
                if (!(xt->xtif_flags & XTIFFP_PRINT))
 
130
                {
 
131
                        PARENT(xt,printdir) =  TIFFMEMBER(tif,printdir);
 
132
                        TIFFMEMBER(tif,printdir) = _XTIFFPrintDirectory;
 
133
                        xt->xtif_flags |= XTIFFP_PRINT;
 
134
                }
 
135
                TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
 
136
                tif->tif_flags |= TIFF_DIRTYDIRECT;
 
137
        }
 
138
        va_end(ap);
 
139
        return (status);
 
140
badvalue:
 
141
        TIFFError(tif->tif_name, "%d: Bad value for \"%s\"", v,
 
142
            _TIFFFieldWithTag(tif, tag)->field_name);
 
143
        va_end(ap);
 
144
        return (0);
 
145
badvalue32:
 
146
        TIFFError(tif->tif_name, "%ld: Bad value for \"%s\"", v32,
 
147
            _TIFFFieldWithTag(tif, tag)->field_name);
 
148
        va_end(ap);
 
149
        return (0);
 
150
}
 
151
 
 
152
 
 
153
static int
 
154
_XTIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
 
155
{
 
156
        xtiff *xt = XTIFFDIR(tif);
 
157
        XTIFFDirectory* xd = &xt->xtif_dir;
 
158
 
 
159
        switch (tag) {
 
160
                /* 
 
161
                 * XXX put your extended tags here; replace the implemented
 
162
                 *     example tags with your own.
 
163
                 */
 
164
        case TIFFTAG_EXAMPLE_MULTI:
 
165
                *va_arg(ap, uint16*) = xd->xd_num_multi;
 
166
                *va_arg(ap, double**) = xd->xd_example_multi;
 
167
                break;
 
168
        case TIFFTAG_EXAMPLE_ASCII:
 
169
                *va_arg(ap, char**) = xd->xd_example_ascii;
 
170
                break;
 
171
        case TIFFTAG_EXAMPLE_SINGLE:
 
172
                *va_arg(ap, uint32*) = xd->xd_example_single;
 
173
                break;
 
174
        default:
 
175
                /* return inherited method */
 
176
                return (PARENT(xt,vgetfield))(tif,tag,ap);
 
177
                break;
 
178
        }
 
179
        return (1);
 
180
}
 
181
 
 
182
#define CleanupField(member) {          \
 
183
    if (xd->member) {                   \
 
184
        _TIFFfree(xd->member);          \
 
185
        xd->member = 0;                 \
 
186
    }                                   \
 
187
}
 
188
/*
 
189
 * Release storage associated with a directory.
 
190
 */
 
191
static void
 
192
_XTIFFFreeDirectory(xtiff* xt)
 
193
{
 
194
        XTIFFDirectory* xd = &xt->xtif_dir;
 
195
 
 
196
        /* 
 
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
 
200
         *  _XTIFFVSetField().
 
201
         */
 
202
        
 
203
        CleanupField(xd_example_multi);
 
204
        CleanupField(xd_example_ascii);
 
205
        
 
206
}
 
207
#undef CleanupField
 
208
 
 
209
static void _XTIFFLocalDefaultDirectory(TIFF *tif)
 
210
{
 
211
        xtiff *xt = XTIFFDIR(tif);
 
212
        XTIFFDirectory* xd = &xt->xtif_dir;
 
213
 
 
214
        /* Install the extended Tag field info */
 
215
        _TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
 
216
 
 
217
        /*
 
218
         *  free up any dynamically allocated arrays
 
219
         *  before the new directory is read in.
 
220
         */
 
221
         
 
222
        _XTIFFFreeDirectory(xt);        
 
223
        _TIFFmemset(xt,0,sizeof(xtiff));
 
224
 
 
225
        /* Override the tag access methods */
 
226
 
 
227
        PARENT(xt,vsetfield) =  TIFFMEMBER(tif,vsetfield);
 
228
        TIFFMEMBER(tif,vsetfield) = _XTIFFVSetField;
 
229
        PARENT(xt,vgetfield) =  TIFFMEMBER(tif,vgetfield);
 
230
        TIFFMEMBER(tif,vgetfield) = _XTIFFVGetField;
 
231
 
 
232
        /* 
 
233
         * XXX Set up any default values here.
 
234
         */
 
235
        
 
236
        xd->xd_example_single = 234;
 
237
}
 
238
 
 
239
 
 
240
 
 
241
/**********************************************************************
 
242
 *    Nothing below this line should need to be changed.
 
243
 **********************************************************************/
 
244
 
 
245
static TIFFExtendProc _ParentExtender;
 
246
 
 
247
/*
 
248
 *  This is the callback procedure, and is
 
249
 *  called by the DefaultDirectory method
 
250
 *  every time a new TIFF directory is opened.
 
251
 */
 
252
 
 
253
static void
 
254
_XTIFFDefaultDirectory(TIFF *tif)
 
255
{
 
256
        xtiff *xt;
 
257
        
 
258
        /* Allocate Directory Structure if first time, and install it */
 
259
        if (!(tif->tif_flags & XTIFF_INITIALIZED))
 
260
        {
 
261
                xt = _TIFFmalloc(sizeof(xtiff));
 
262
                if (!xt)
 
263
                {
 
264
                        /* handle memory allocation failure here ! */
 
265
                        return;
 
266
                }
 
267
                _TIFFmemset(xt,0,sizeof(xtiff));
 
268
                /*
 
269
                 * Install into TIFF structure.
 
270
                 */
 
271
                TIFFMEMBER(tif,clientdir) = (tidata_t)xt;
 
272
                tif->tif_flags |= XTIFF_INITIALIZED; /* dont do this again! */
 
273
        }
 
274
        
 
275
        /* set up our own defaults */
 
276
        _XTIFFLocalDefaultDirectory(tif);
 
277
 
 
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.
 
281
         */
 
282
 
 
283
        if (_ParentExtender) 
 
284
                (*_ParentExtender)(tif);
 
285
 
 
286
}
 
287
 
 
288
/*
 
289
 *  XTIFF Initializer -- sets up the callback
 
290
 *   procedure for the TIFF module.
 
291
 */
 
292
 
 
293
static
 
294
void _XTIFFInitialize(void)
 
295
{
 
296
        static first_time=1;
 
297
        
 
298
        if (! first_time) return; /* Been there. Done that. */
 
299
        first_time = 0;
 
300
        
 
301
        /* Grab the inherited method and install */
 
302
        _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
 
303
}
 
304
 
 
305
 
 
306
/*
 
307
 * Public File I/O Routines.
 
308
 */
 
309
TIFF*
 
310
XTIFFOpen(const char* name, const char* mode)
 
311
{
 
312
        /* Set up the callback */
 
313
        _XTIFFInitialize();     
 
314
        
 
315
        /* Open the file; the callback will set everything up
 
316
         */
 
317
        return TIFFOpen(name, mode);
 
318
}
 
319
 
 
320
TIFF*
 
321
XTIFFFdOpen(int fd, const char* name, const char* mode)
 
322
{
 
323
        /* Set up the callback */
 
324
        _XTIFFInitialize();     
 
325
 
 
326
        /* Open the file; the callback will set everything up
 
327
         */
 
328
        return TIFFFdOpen(fd, name, mode);
 
329
}
 
330
 
 
331
 
 
332
void
 
333
XTIFFClose(TIFF *tif)
 
334
{
 
335
        xtiff *xt = XTIFFDIR(tif);
 
336
        
 
337
        /* call inherited function first */
 
338
        TIFFClose(tif);
 
339
        
 
340
        /* Free up extended allocated memory */
 
341
        _XTIFFFreeDirectory(xt);
 
342
        _TIFFfree(xt);
 
343
}