~ubuntu-branches/ubuntu/oneiric/tiff/oneiric-updates

« back to all changes in this revision

Viewing changes to .pc/ycbcr-read-scanline.patch/libtiff/tif_dir.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2010-06-14 13:19:59 UTC
  • Revision ID: james.westby@ubuntu.com-20100614131959-op2496hcyylejsxt
Tags: 3.9.2-3ubuntu1
* SECURITY UPDATE: arbitrary code execution via multiple integer
  overflows.  Backported upstream fixes:
  - debian/patches/CVE-2010-1411.patch
  - debian/patches/CVE-2010-2065.patch
  - debian/patches/CVE-2010-2067.patch
  - debian/patches/fix-64bit-flip.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tif_dir.c,v 1.75.2.2 2009-01-01 00:10:43 bfriesen Exp $ */
 
2
 
 
3
/*
 
4
 * Copyright (c) 1988-1997 Sam Leffler
 
5
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 
6
 *
 
7
 * Permission to use, copy, modify, distribute, and sell this software and 
 
8
 * its documentation for any purpose is hereby granted without fee, provided
 
9
 * that (i) the above copyright notices and this permission notice appear in
 
10
 * all copies of the software and related documentation, and (ii) the names of
 
11
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 
12
 * publicity relating to the software without the specific, prior written
 
13
 * permission of Sam Leffler and Silicon Graphics.
 
14
 * 
 
15
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 
16
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 
17
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 
18
 * 
 
19
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 
20
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 
21
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
22
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 
23
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 
24
 * OF THIS SOFTWARE.
 
25
 */
 
26
 
 
27
/*
 
28
 * TIFF Library.
 
29
 *
 
30
 * Directory Tag Get & Set Routines.
 
31
 * (and also some miscellaneous stuff)
 
32
 */
 
33
#include "tiffiop.h"
 
34
 
 
35
/*
 
36
 * These are used in the backwards compatibility code...
 
37
 */
 
38
#define DATATYPE_VOID           0       /* !untyped data */
 
39
#define DATATYPE_INT            1       /* !signed integer data */
 
40
#define DATATYPE_UINT           2       /* !unsigned integer data */
 
41
#define DATATYPE_IEEEFP         3       /* !IEEE floating point data */
 
42
 
 
43
static void
 
44
setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
 
45
{
 
46
        if (*vpp)
 
47
                _TIFFfree(*vpp), *vpp = 0;
 
48
        if (vp) {
 
49
                tsize_t bytes = nmemb * elem_size;
 
50
                if (elem_size && bytes / elem_size == nmemb)
 
51
                        *vpp = (void*) _TIFFmalloc(bytes);
 
52
                if (*vpp)
 
53
                        _TIFFmemcpy(*vpp, vp, bytes);
 
54
        }
 
55
}
 
56
void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
 
57
    { setByteArray(vpp, vp, n, 1); }
 
58
void _TIFFsetString(char** cpp, char* cp)
 
59
    { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
 
60
void _TIFFsetNString(char** cpp, char* cp, uint32 n)
 
61
    { setByteArray((void**) cpp, (void*) cp, n, 1); }
 
62
void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
 
63
    { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
 
64
void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
 
65
    { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
 
66
void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
 
67
    { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
 
68
void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
 
69
    { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
 
70
 
 
71
/*
 
72
 * Install extra samples information.
 
73
 */
 
74
static int
 
75
setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
 
76
{
 
77
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
 
78
#define EXTRASAMPLE_COREL_UNASSALPHA 999 
 
79
 
 
80
        uint16* va;
 
81
        uint32 i;
 
82
 
 
83
        *v = va_arg(ap, uint32);
 
84
        if ((uint16) *v > td->td_samplesperpixel)
 
85
                return 0;
 
86
        va = va_arg(ap, uint16*);
 
87
        if (*v > 0 && va == NULL)               /* typically missing param */
 
88
                return 0;
 
89
        for (i = 0; i < *v; i++) {
 
90
                if (va[i] > EXTRASAMPLE_UNASSALPHA) {
 
91
                        /*
 
92
                         * XXX: Corel Draw is known to produce incorrect
 
93
                         * ExtraSamples tags which must be patched here if we
 
94
                         * want to be able to open some of the damaged TIFF
 
95
                         * files: 
 
96
                         */
 
97
                        if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
 
98
                                va[i] = EXTRASAMPLE_UNASSALPHA;
 
99
                        else
 
100
                                return 0;
 
101
                }
 
102
        }
 
103
        td->td_extrasamples = (uint16) *v;
 
104
        _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
 
105
        return 1;
 
106
 
 
107
#undef EXTRASAMPLE_COREL_UNASSALPHA
 
108
}
 
109
 
 
110
static uint32
 
111
checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
 
112
{
 
113
        TIFFDirectory* td = &tif->tif_dir;
 
114
        uint16 i = td->td_samplesperpixel;
 
115
 
 
116
        if (slen > 0) {
 
117
                const char* ep = s+slen;
 
118
                const char* cp = s;
 
119
                for (; i > 0; i--) {
 
120
                        for (; *cp != '\0'; cp++)
 
121
                                if (cp >= ep)
 
122
                                        goto bad;
 
123
                        cp++;                           /* skip \0 */
 
124
                }
 
125
                return (cp-s);
 
126
        }
 
127
bad:
 
128
        TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
 
129
            "%s: Invalid InkNames value; expecting %d names, found %d",
 
130
            tif->tif_name,
 
131
            td->td_samplesperpixel,
 
132
            td->td_samplesperpixel-i);
 
133
        return (0);
 
134
}
 
135
 
 
136
static int
 
137
_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
 
138
{
 
139
        static const char module[] = "_TIFFVSetField";
 
140
 
 
141
        TIFFDirectory* td = &tif->tif_dir;
 
142
        int status = 1;
 
143
        uint32 v32, i, v;
 
144
        char* s;
 
145
 
 
146
        switch (tag) {
 
147
        case TIFFTAG_SUBFILETYPE:
 
148
                td->td_subfiletype = va_arg(ap, uint32);
 
149
                break;
 
150
        case TIFFTAG_IMAGEWIDTH:
 
151
                td->td_imagewidth = va_arg(ap, uint32);
 
152
                break;
 
153
        case TIFFTAG_IMAGELENGTH:
 
154
                td->td_imagelength = va_arg(ap, uint32);
 
155
                break;
 
156
        case TIFFTAG_BITSPERSAMPLE:
 
157
                td->td_bitspersample = (uint16) va_arg(ap, int);
 
158
                /*
 
159
                 * If the data require post-decoding processing to byte-swap
 
160
                 * samples, set it up here.  Note that since tags are required
 
161
                 * to be ordered, compression code can override this behaviour
 
162
                 * in the setup method if it wants to roll the post decoding
 
163
                 * work in with its normal work.
 
164
                 */
 
165
                if (tif->tif_flags & TIFF_SWAB) {
 
166
                        if (td->td_bitspersample == 16)
 
167
                                tif->tif_postdecode = _TIFFSwab16BitData;
 
168
                        else if (td->td_bitspersample == 24)
 
169
                                tif->tif_postdecode = _TIFFSwab24BitData;
 
170
                        else if (td->td_bitspersample == 32)
 
171
                                tif->tif_postdecode = _TIFFSwab32BitData;
 
172
                        else if (td->td_bitspersample == 64)
 
173
                                tif->tif_postdecode = _TIFFSwab64BitData;
 
174
                        else if (td->td_bitspersample == 128) /* two 64's */
 
175
                                tif->tif_postdecode = _TIFFSwab64BitData;
 
176
                }
 
177
                break;
 
178
        case TIFFTAG_COMPRESSION:
 
179
                v = va_arg(ap, uint32) & 0xffff;
 
180
                /*
 
181
                 * If we're changing the compression scheme, the notify the
 
182
                 * previous module so that it can cleanup any state it's
 
183
                 * setup.
 
184
                 */
 
185
                if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
 
186
                        if (td->td_compression == v)
 
187
                                break;
 
188
                        (*tif->tif_cleanup)(tif);
 
189
                        tif->tif_flags &= ~TIFF_CODERSETUP;
 
190
                }
 
191
                /*
 
192
                 * Setup new compression routine state.
 
193
                 */
 
194
                if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
 
195
                    td->td_compression = (uint16) v;
 
196
                else
 
197
                    status = 0;
 
198
                break;
 
199
        case TIFFTAG_PHOTOMETRIC:
 
200
                td->td_photometric = (uint16) va_arg(ap, int);
 
201
                break;
 
202
        case TIFFTAG_THRESHHOLDING:
 
203
                td->td_threshholding = (uint16) va_arg(ap, int);
 
204
                break;
 
205
        case TIFFTAG_FILLORDER:
 
206
                v = va_arg(ap, uint32);
 
207
                if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
 
208
                        goto badvalue;
 
209
                td->td_fillorder = (uint16) v;
 
210
                break;
 
211
        case TIFFTAG_ORIENTATION:
 
212
                v = va_arg(ap, uint32);
 
213
                if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
 
214
                        goto badvalue;
 
215
                else
 
216
                        td->td_orientation = (uint16) v;
 
217
                break;
 
218
        case TIFFTAG_SAMPLESPERPIXEL:
 
219
                /* XXX should cross check -- e.g. if pallette, then 1 */
 
220
                v = va_arg(ap, uint32);
 
221
                if (v == 0)
 
222
                        goto badvalue;
 
223
                td->td_samplesperpixel = (uint16) v;
 
224
                break;
 
225
        case TIFFTAG_ROWSPERSTRIP:
 
226
                v32 = va_arg(ap, uint32);
 
227
                if (v32 == 0)
 
228
                        goto badvalue32;
 
229
                td->td_rowsperstrip = v32;
 
230
                if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
 
231
                        td->td_tilelength = v32;
 
232
                        td->td_tilewidth = td->td_imagewidth;
 
233
                }
 
234
                break;
 
235
        case TIFFTAG_MINSAMPLEVALUE:
 
236
                td->td_minsamplevalue = (uint16) va_arg(ap, int);
 
237
                break;
 
238
        case TIFFTAG_MAXSAMPLEVALUE:
 
239
                td->td_maxsamplevalue = (uint16) va_arg(ap, int);
 
240
                break;
 
241
        case TIFFTAG_SMINSAMPLEVALUE:
 
242
                td->td_sminsamplevalue = va_arg(ap, double);
 
243
                break;
 
244
        case TIFFTAG_SMAXSAMPLEVALUE:
 
245
                td->td_smaxsamplevalue = va_arg(ap, double);
 
246
                break;
 
247
        case TIFFTAG_XRESOLUTION:
 
248
                td->td_xresolution = (float) va_arg(ap, double);
 
249
                break;
 
250
        case TIFFTAG_YRESOLUTION:
 
251
                td->td_yresolution = (float) va_arg(ap, double);
 
252
                break;
 
253
        case TIFFTAG_PLANARCONFIG:
 
254
                v = va_arg(ap, uint32);
 
255
                if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
 
256
                        goto badvalue;
 
257
                td->td_planarconfig = (uint16) v;
 
258
                break;
 
259
        case TIFFTAG_XPOSITION:
 
260
                td->td_xposition = (float) va_arg(ap, double);
 
261
                break;
 
262
        case TIFFTAG_YPOSITION:
 
263
                td->td_yposition = (float) va_arg(ap, double);
 
264
                break;
 
265
        case TIFFTAG_RESOLUTIONUNIT:
 
266
                v = va_arg(ap, uint32);
 
267
                if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
 
268
                        goto badvalue;
 
269
                td->td_resolutionunit = (uint16) v;
 
270
                break;
 
271
        case TIFFTAG_PAGENUMBER:
 
272
                td->td_pagenumber[0] = (uint16) va_arg(ap, int);
 
273
                td->td_pagenumber[1] = (uint16) va_arg(ap, int);
 
274
                break;
 
275
        case TIFFTAG_HALFTONEHINTS:
 
276
                td->td_halftonehints[0] = (uint16) va_arg(ap, int);
 
277
                td->td_halftonehints[1] = (uint16) va_arg(ap, int);
 
278
                break;
 
279
        case TIFFTAG_COLORMAP:
 
280
                v32 = (uint32)(1L<<td->td_bitspersample);
 
281
                _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
 
282
                _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
 
283
                _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
 
284
                break;
 
285
        case TIFFTAG_EXTRASAMPLES:
 
286
                if (!setExtraSamples(td, ap, &v))
 
287
                        goto badvalue;
 
288
                break;
 
289
        case TIFFTAG_MATTEING:
 
290
                td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
 
291
                if (td->td_extrasamples) {
 
292
                        uint16 sv = EXTRASAMPLE_ASSOCALPHA;
 
293
                        _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
 
294
                }
 
295
                break;
 
296
        case TIFFTAG_TILEWIDTH:
 
297
                v32 = va_arg(ap, uint32);
 
298
                if (v32 % 16) {
 
299
                        if (tif->tif_mode != O_RDONLY)
 
300
                                goto badvalue32;
 
301
                        TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
 
302
                                "Nonstandard tile width %d, convert file", v32);
 
303
                }
 
304
                td->td_tilewidth = v32;
 
305
                tif->tif_flags |= TIFF_ISTILED;
 
306
                break;
 
307
        case TIFFTAG_TILELENGTH:
 
308
                v32 = va_arg(ap, uint32);
 
309
                if (v32 % 16) {
 
310
                        if (tif->tif_mode != O_RDONLY)
 
311
                                goto badvalue32;
 
312
                        TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
 
313
                            "Nonstandard tile length %d, convert file", v32);
 
314
                }
 
315
                td->td_tilelength = v32;
 
316
                tif->tif_flags |= TIFF_ISTILED;
 
317
                break;
 
318
        case TIFFTAG_TILEDEPTH:
 
319
                v32 = va_arg(ap, uint32);
 
320
                if (v32 == 0)
 
321
                        goto badvalue32;
 
322
                td->td_tiledepth = v32;
 
323
                break;
 
324
        case TIFFTAG_DATATYPE:
 
325
                v = va_arg(ap, uint32);
 
326
                switch (v) {
 
327
                case DATATYPE_VOID:     v = SAMPLEFORMAT_VOID;  break;
 
328
                case DATATYPE_INT:      v = SAMPLEFORMAT_INT;   break;
 
329
                case DATATYPE_UINT:     v = SAMPLEFORMAT_UINT;  break;
 
330
                case DATATYPE_IEEEFP:   v = SAMPLEFORMAT_IEEEFP;break;
 
331
                default:                goto badvalue;
 
332
                }
 
333
                td->td_sampleformat = (uint16) v;
 
334
                break;
 
335
        case TIFFTAG_SAMPLEFORMAT:
 
336
                v = va_arg(ap, uint32);
 
337
                if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
 
338
                        goto badvalue;
 
339
                td->td_sampleformat = (uint16) v;
 
340
 
 
341
                /*  Try to fix up the SWAB function for complex data. */
 
342
                if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
 
343
                    && td->td_bitspersample == 32
 
344
                    && tif->tif_postdecode == _TIFFSwab32BitData )
 
345
                    tif->tif_postdecode = _TIFFSwab16BitData;
 
346
                else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
 
347
                          || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
 
348
                         && td->td_bitspersample == 64
 
349
                         && tif->tif_postdecode == _TIFFSwab64BitData )
 
350
                    tif->tif_postdecode = _TIFFSwab32BitData;
 
351
                break;
 
352
        case TIFFTAG_IMAGEDEPTH:
 
353
                td->td_imagedepth = va_arg(ap, uint32);
 
354
                break;
 
355
        case TIFFTAG_SUBIFD:
 
356
                if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
 
357
                        td->td_nsubifd = (uint16) va_arg(ap, int);
 
358
                        _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
 
359
                            (long) td->td_nsubifd);
 
360
                } else {
 
361
                        TIFFErrorExt(tif->tif_clientdata, module,
 
362
                                     "%s: Sorry, cannot nest SubIFDs",
 
363
                                     tif->tif_name);
 
364
                        status = 0;
 
365
                }
 
366
                break;
 
367
        case TIFFTAG_YCBCRPOSITIONING:
 
368
                td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
 
369
                break;
 
370
        case TIFFTAG_YCBCRSUBSAMPLING:
 
371
                td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
 
372
                td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
 
373
                break;
 
374
        case TIFFTAG_TRANSFERFUNCTION:
 
375
                v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
 
376
                for (i = 0; i < v; i++)
 
377
                        _TIFFsetShortArray(&td->td_transferfunction[i],
 
378
                            va_arg(ap, uint16*), 1L<<td->td_bitspersample);
 
379
                break;
 
380
        case TIFFTAG_INKNAMES:
 
381
                v = va_arg(ap, uint32);
 
382
                s = va_arg(ap, char*);
 
383
                v = checkInkNamesString(tif, v, s);
 
384
                status = v > 0;
 
385
                if( v > 0 ) {
 
386
                        _TIFFsetNString(&td->td_inknames, s, v);
 
387
                        td->td_inknameslen = v;
 
388
                }
 
389
                break;
 
390
        default: {
 
391
            TIFFTagValue *tv;
 
392
            int tv_size, iCustom;
 
393
            const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 
394
 
 
395
            /*
 
396
             * This can happen if multiple images are open with different
 
397
             * codecs which have private tags.  The global tag information
 
398
             * table may then have tags that are valid for one file but not
 
399
             * the other. If the client tries to set a tag that is not valid
 
400
             * for the image's codec then we'll arrive here.  This
 
401
             * happens, for example, when tiffcp is used to convert between
 
402
             * compression schemes and codec-specific tags are blindly copied.
 
403
             */
 
404
            if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
 
405
                TIFFErrorExt(tif->tif_clientdata, module,
 
406
                             "%s: Invalid %stag \"%s\" (not supported by codec)",
 
407
                             tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
 
408
                             fip ? fip->field_name : "Unknown");
 
409
                status = 0;
 
410
                break;
 
411
            }
 
412
 
 
413
            /*
 
414
             * Find the existing entry for this custom value.
 
415
             */
 
416
            tv = NULL;
 
417
            for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
 
418
                    if (td->td_customValues[iCustom].info->field_tag == tag) {
 
419
                            tv = td->td_customValues + iCustom;
 
420
                            if (tv->value != NULL) {
 
421
                                    _TIFFfree(tv->value);
 
422
                                    tv->value = NULL;
 
423
                            }
 
424
                            break;
 
425
                    }
 
426
            }
 
427
 
 
428
            /*
 
429
             * Grow the custom list if the entry was not found.
 
430
             */
 
431
            if(tv == NULL) {
 
432
                TIFFTagValue    *new_customValues;
 
433
                
 
434
                td->td_customValueCount++;
 
435
                new_customValues = (TIFFTagValue *)
 
436
                        _TIFFrealloc(td->td_customValues,
 
437
                                     sizeof(TIFFTagValue) * td->td_customValueCount);
 
438
                if (!new_customValues) {
 
439
                        TIFFErrorExt(tif->tif_clientdata, module,
 
440
                "%s: Failed to allocate space for list of custom values",
 
441
                                  tif->tif_name);
 
442
                        status = 0;
 
443
                        goto end;
 
444
                }
 
445
 
 
446
                td->td_customValues = new_customValues;
 
447
 
 
448
                tv = td->td_customValues + (td->td_customValueCount - 1);
 
449
                tv->info = fip;
 
450
                tv->value = NULL;
 
451
                tv->count = 0;
 
452
            }
 
453
 
 
454
            /*
 
455
             * Set custom value ... save a copy of the custom tag value.
 
456
             */
 
457
            tv_size = _TIFFDataSize(fip->field_type);
 
458
            if (tv_size == 0) {
 
459
                    status = 0;
 
460
                    TIFFErrorExt(tif->tif_clientdata, module,
 
461
                                 "%s: Bad field type %d for \"%s\"",
 
462
                                 tif->tif_name, fip->field_type,
 
463
                                 fip->field_name);
 
464
                    goto end;
 
465
            }
 
466
           
 
467
            if(fip->field_passcount) {
 
468
                    if (fip->field_writecount == TIFF_VARIABLE2)
 
469
                        tv->count = (uint32) va_arg(ap, uint32);
 
470
                    else
 
471
                        tv->count = (int) va_arg(ap, int);
 
472
            } else if (fip->field_writecount == TIFF_VARIABLE
 
473
                       || fip->field_writecount == TIFF_VARIABLE2)
 
474
                tv->count = 1;
 
475
            else if (fip->field_writecount == TIFF_SPP)
 
476
                tv->count = td->td_samplesperpixel;
 
477
            else
 
478
                tv->count = fip->field_writecount;
 
479
            
 
480
    
 
481
            if (fip->field_type == TIFF_ASCII)
 
482
                    _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
 
483
            else {
 
484
                tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count,
 
485
                                             "Tag Value");
 
486
                if (!tv->value) {
 
487
                    status = 0;
 
488
                    goto end;
 
489
                }
 
490
 
 
491
                if ((fip->field_passcount
 
492
                    || fip->field_writecount == TIFF_VARIABLE
 
493
                    || fip->field_writecount == TIFF_VARIABLE2
 
494
                    || fip->field_writecount == TIFF_SPP
 
495
                    || tv->count > 1)
 
496
                    && fip->field_tag != TIFFTAG_PAGENUMBER
 
497
                    && fip->field_tag != TIFFTAG_HALFTONEHINTS
 
498
                    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
 
499
                    && fip->field_tag != TIFFTAG_DOTRANGE) {
 
500
                    _TIFFmemcpy(tv->value, va_arg(ap, void *),
 
501
                                tv->count * tv_size);
 
502
                } else {
 
503
                    /*
 
504
                     * XXX: The following loop required to handle
 
505
                     * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
 
506
                     * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
 
507
                     * These tags are actually arrays and should be passed as
 
508
                     * array pointers to TIFFSetField() function, but actually
 
509
                     * passed as a list of separate values. This behaviour
 
510
                     * must be changed in the future!
 
511
                     */
 
512
                    int i;
 
513
                    char *val = (char *)tv->value;
 
514
 
 
515
                    for (i = 0; i < tv->count; i++, val += tv_size) {
 
516
                            switch (fip->field_type) {
 
517
                                case TIFF_BYTE:
 
518
                                case TIFF_UNDEFINED:
 
519
                                    {
 
520
                                        uint8 v = (uint8)va_arg(ap, int);
 
521
                                        _TIFFmemcpy(val, &v, tv_size);
 
522
                                    }
 
523
                                    break;
 
524
                                case TIFF_SBYTE:
 
525
                                    {
 
526
                                        int8 v = (int8)va_arg(ap, int);
 
527
                                        _TIFFmemcpy(val, &v, tv_size);
 
528
                                    }
 
529
                                    break;
 
530
                                case TIFF_SHORT:
 
531
                                    {
 
532
                                        uint16 v = (uint16)va_arg(ap, int);
 
533
                                        _TIFFmemcpy(val, &v, tv_size);
 
534
                                    }
 
535
                                    break;
 
536
                                case TIFF_SSHORT:
 
537
                                    {
 
538
                                        int16 v = (int16)va_arg(ap, int);
 
539
                                        _TIFFmemcpy(val, &v, tv_size);
 
540
                                    }
 
541
                                    break;
 
542
                                case TIFF_LONG:
 
543
                                case TIFF_IFD:
 
544
                                    {
 
545
                                        uint32 v = va_arg(ap, uint32);
 
546
                                        _TIFFmemcpy(val, &v, tv_size);
 
547
                                    }
 
548
                                    break;
 
549
                                case TIFF_SLONG:
 
550
                                    {
 
551
                                        int32 v = va_arg(ap, int32);
 
552
                                        _TIFFmemcpy(val, &v, tv_size);
 
553
                                    }
 
554
                                    break;
 
555
                                case TIFF_RATIONAL:
 
556
                                case TIFF_SRATIONAL:
 
557
                                case TIFF_FLOAT:
 
558
                                    {
 
559
                                        float v = (float)va_arg(ap, double);
 
560
                                        _TIFFmemcpy(val, &v, tv_size);
 
561
                                    }
 
562
                                    break;
 
563
                                case TIFF_DOUBLE:
 
564
                                    {
 
565
                                        double v = va_arg(ap, double);
 
566
                                        _TIFFmemcpy(val, &v, tv_size);
 
567
                                    }
 
568
                                    break;
 
569
                                default:
 
570
                                    _TIFFmemset(val, 0, tv_size);
 
571
                                    status = 0;
 
572
                                    break;
 
573
                            }
 
574
                    }
 
575
                }
 
576
            }
 
577
          }
 
578
        }
 
579
        if (status) {
 
580
                TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
 
581
                tif->tif_flags |= TIFF_DIRTYDIRECT;
 
582
        }
 
583
 
 
584
end:
 
585
        va_end(ap);
 
586
        return (status);
 
587
badvalue:
 
588
        TIFFErrorExt(tif->tif_clientdata, module,
 
589
                     "%s: Bad value %d for \"%s\" tag",
 
590
                     tif->tif_name, v,
 
591
                     _TIFFFieldWithTag(tif, tag)->field_name);
 
592
        va_end(ap);
 
593
        return (0);
 
594
badvalue32:
 
595
        TIFFErrorExt(tif->tif_clientdata, module,
 
596
                     "%s: Bad value %u for \"%s\" tag",
 
597
                     tif->tif_name, v32,
 
598
                     _TIFFFieldWithTag(tif, tag)->field_name);
 
599
        va_end(ap);
 
600
        return (0);
 
601
}
 
602
 
 
603
/*
 
604
 * Return 1/0 according to whether or not
 
605
 * it is permissible to set the tag's value.
 
606
 * Note that we allow ImageLength to be changed
 
607
 * so that we can append and extend to images.
 
608
 * Any other tag may not be altered once writing
 
609
 * has commenced, unless its value has no effect
 
610
 * on the format of the data that is written.
 
611
 */
 
612
static int
 
613
OkToChangeTag(TIFF* tif, ttag_t tag)
 
614
{
 
615
        const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 
616
        if (!fip) {                     /* unknown tag */
 
617
                TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
 
618
                    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
 
619
                return (0);
 
620
        }
 
621
        if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
 
622
            !fip->field_oktochange) {
 
623
                /*
 
624
                 * Consult info table to see if tag can be changed
 
625
                 * after we've started writing.  We only allow changes
 
626
                 * to those tags that don't/shouldn't affect the
 
627
                 * compression and/or format of the data.
 
628
                 */
 
629
                TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
 
630
                    "%s: Cannot modify tag \"%s\" while writing",
 
631
                    tif->tif_name, fip->field_name);
 
632
                return (0);
 
633
        }
 
634
        return (1);
 
635
}
 
636
 
 
637
/*
 
638
 * Record the value of a field in the
 
639
 * internal directory structure.  The
 
640
 * field will be written to the file
 
641
 * when/if the directory structure is
 
642
 * updated.
 
643
 */
 
644
int
 
645
TIFFSetField(TIFF* tif, ttag_t tag, ...)
 
646
{
 
647
        va_list ap;
 
648
        int status;
 
649
 
 
650
        va_start(ap, tag);
 
651
        status = TIFFVSetField(tif, tag, ap);
 
652
        va_end(ap);
 
653
        return (status);
 
654
}
 
655
 
 
656
/*
 
657
 * Like TIFFSetField, but taking a varargs
 
658
 * parameter list.  This routine is useful
 
659
 * for building higher-level interfaces on
 
660
 * top of the library.
 
661
 */
 
662
int
 
663
TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
 
664
{
 
665
        return OkToChangeTag(tif, tag) ?
 
666
            (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
 
667
}
 
668
 
 
669
static int
 
670
_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
 
671
{
 
672
    TIFFDirectory* td = &tif->tif_dir;
 
673
    int            ret_val = 1;
 
674
 
 
675
    switch (tag) {
 
676
        case TIFFTAG_SUBFILETYPE:
 
677
            *va_arg(ap, uint32*) = td->td_subfiletype;
 
678
            break;
 
679
        case TIFFTAG_IMAGEWIDTH:
 
680
            *va_arg(ap, uint32*) = td->td_imagewidth;
 
681
            break;
 
682
        case TIFFTAG_IMAGELENGTH:
 
683
            *va_arg(ap, uint32*) = td->td_imagelength;
 
684
            break;
 
685
        case TIFFTAG_BITSPERSAMPLE:
 
686
            *va_arg(ap, uint16*) = td->td_bitspersample;
 
687
            break;
 
688
        case TIFFTAG_COMPRESSION:
 
689
            *va_arg(ap, uint16*) = td->td_compression;
 
690
            break;
 
691
        case TIFFTAG_PHOTOMETRIC:
 
692
            *va_arg(ap, uint16*) = td->td_photometric;
 
693
            break;
 
694
        case TIFFTAG_THRESHHOLDING:
 
695
            *va_arg(ap, uint16*) = td->td_threshholding;
 
696
            break;
 
697
        case TIFFTAG_FILLORDER:
 
698
            *va_arg(ap, uint16*) = td->td_fillorder;
 
699
            break;
 
700
        case TIFFTAG_ORIENTATION:
 
701
            *va_arg(ap, uint16*) = td->td_orientation;
 
702
            break;
 
703
        case TIFFTAG_SAMPLESPERPIXEL:
 
704
            *va_arg(ap, uint16*) = td->td_samplesperpixel;
 
705
            break;
 
706
        case TIFFTAG_ROWSPERSTRIP:
 
707
            *va_arg(ap, uint32*) = td->td_rowsperstrip;
 
708
            break;
 
709
        case TIFFTAG_MINSAMPLEVALUE:
 
710
            *va_arg(ap, uint16*) = td->td_minsamplevalue;
 
711
            break;
 
712
        case TIFFTAG_MAXSAMPLEVALUE:
 
713
            *va_arg(ap, uint16*) = td->td_maxsamplevalue;
 
714
            break;
 
715
        case TIFFTAG_SMINSAMPLEVALUE:
 
716
            *va_arg(ap, double*) = td->td_sminsamplevalue;
 
717
            break;
 
718
        case TIFFTAG_SMAXSAMPLEVALUE:
 
719
            *va_arg(ap, double*) = td->td_smaxsamplevalue;
 
720
            break;
 
721
        case TIFFTAG_XRESOLUTION:
 
722
            *va_arg(ap, float*) = td->td_xresolution;
 
723
            break;
 
724
        case TIFFTAG_YRESOLUTION:
 
725
            *va_arg(ap, float*) = td->td_yresolution;
 
726
            break;
 
727
        case TIFFTAG_PLANARCONFIG:
 
728
            *va_arg(ap, uint16*) = td->td_planarconfig;
 
729
            break;
 
730
        case TIFFTAG_XPOSITION:
 
731
            *va_arg(ap, float*) = td->td_xposition;
 
732
            break;
 
733
        case TIFFTAG_YPOSITION:
 
734
            *va_arg(ap, float*) = td->td_yposition;
 
735
            break;
 
736
        case TIFFTAG_RESOLUTIONUNIT:
 
737
            *va_arg(ap, uint16*) = td->td_resolutionunit;
 
738
            break;
 
739
        case TIFFTAG_PAGENUMBER:
 
740
            *va_arg(ap, uint16*) = td->td_pagenumber[0];
 
741
            *va_arg(ap, uint16*) = td->td_pagenumber[1];
 
742
            break;
 
743
        case TIFFTAG_HALFTONEHINTS:
 
744
            *va_arg(ap, uint16*) = td->td_halftonehints[0];
 
745
            *va_arg(ap, uint16*) = td->td_halftonehints[1];
 
746
            break;
 
747
        case TIFFTAG_COLORMAP:
 
748
            *va_arg(ap, uint16**) = td->td_colormap[0];
 
749
            *va_arg(ap, uint16**) = td->td_colormap[1];
 
750
            *va_arg(ap, uint16**) = td->td_colormap[2];
 
751
            break;
 
752
        case TIFFTAG_STRIPOFFSETS:
 
753
        case TIFFTAG_TILEOFFSETS:
 
754
            *va_arg(ap, uint32**) = td->td_stripoffset;
 
755
            break;
 
756
        case TIFFTAG_STRIPBYTECOUNTS:
 
757
        case TIFFTAG_TILEBYTECOUNTS:
 
758
            *va_arg(ap, uint32**) = td->td_stripbytecount;
 
759
            break;
 
760
        case TIFFTAG_MATTEING:
 
761
            *va_arg(ap, uint16*) =
 
762
                (td->td_extrasamples == 1 &&
 
763
                 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
 
764
            break;
 
765
        case TIFFTAG_EXTRASAMPLES:
 
766
            *va_arg(ap, uint16*) = td->td_extrasamples;
 
767
            *va_arg(ap, uint16**) = td->td_sampleinfo;
 
768
            break;
 
769
        case TIFFTAG_TILEWIDTH:
 
770
            *va_arg(ap, uint32*) = td->td_tilewidth;
 
771
            break;
 
772
        case TIFFTAG_TILELENGTH:
 
773
            *va_arg(ap, uint32*) = td->td_tilelength;
 
774
            break;
 
775
        case TIFFTAG_TILEDEPTH:
 
776
            *va_arg(ap, uint32*) = td->td_tiledepth;
 
777
            break;
 
778
        case TIFFTAG_DATATYPE:
 
779
            switch (td->td_sampleformat) {
 
780
                case SAMPLEFORMAT_UINT:
 
781
                    *va_arg(ap, uint16*) = DATATYPE_UINT;
 
782
                    break;
 
783
                case SAMPLEFORMAT_INT:
 
784
                    *va_arg(ap, uint16*) = DATATYPE_INT;
 
785
                    break;
 
786
                case SAMPLEFORMAT_IEEEFP:
 
787
                    *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
 
788
                    break;
 
789
                case SAMPLEFORMAT_VOID:
 
790
                    *va_arg(ap, uint16*) = DATATYPE_VOID;
 
791
                    break;
 
792
            }
 
793
            break;
 
794
        case TIFFTAG_SAMPLEFORMAT:
 
795
            *va_arg(ap, uint16*) = td->td_sampleformat;
 
796
            break;
 
797
        case TIFFTAG_IMAGEDEPTH:
 
798
            *va_arg(ap, uint32*) = td->td_imagedepth;
 
799
            break;
 
800
        case TIFFTAG_SUBIFD:
 
801
            *va_arg(ap, uint16*) = td->td_nsubifd;
 
802
            *va_arg(ap, uint32**) = td->td_subifd;
 
803
            break;
 
804
        case TIFFTAG_YCBCRPOSITIONING:
 
805
            *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
 
806
            break;
 
807
        case TIFFTAG_YCBCRSUBSAMPLING:
 
808
            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
 
809
            *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
 
810
            break;
 
811
        case TIFFTAG_TRANSFERFUNCTION:
 
812
            *va_arg(ap, uint16**) = td->td_transferfunction[0];
 
813
            if (td->td_samplesperpixel - td->td_extrasamples > 1) {
 
814
                *va_arg(ap, uint16**) = td->td_transferfunction[1];
 
815
                *va_arg(ap, uint16**) = td->td_transferfunction[2];
 
816
            }
 
817
            break;
 
818
        case TIFFTAG_INKNAMES:
 
819
            *va_arg(ap, char**) = td->td_inknames;
 
820
            break;
 
821
        default:
 
822
        {
 
823
            const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 
824
            int           i;
 
825
            
 
826
            /*
 
827
             * This can happen if multiple images are open with different
 
828
             * codecs which have private tags.  The global tag information
 
829
             * table may then have tags that are valid for one file but not
 
830
             * the other. If the client tries to get a tag that is not valid
 
831
             * for the image's codec then we'll arrive here.
 
832
             */
 
833
            if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
 
834
            {
 
835
                    TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
 
836
                                 "%s: Invalid %stag \"%s\" "
 
837
                                 "(not supported by codec)",
 
838
                                 tif->tif_name,
 
839
                                 isPseudoTag(tag) ? "pseudo-" : "",
 
840
                                 fip ? fip->field_name : "Unknown");
 
841
                    ret_val = 0;
 
842
                    break;
 
843
            }
 
844
 
 
845
            /*
 
846
             * Do we have a custom value?
 
847
             */
 
848
            ret_val = 0;
 
849
            for (i = 0; i < td->td_customValueCount; i++) {
 
850
                TIFFTagValue *tv = td->td_customValues + i;
 
851
 
 
852
                if (tv->info->field_tag != tag)
 
853
                        continue;
 
854
                
 
855
                if (fip->field_passcount) {
 
856
                        if (fip->field_readcount == TIFF_VARIABLE2) 
 
857
                                *va_arg(ap, uint32*) = (uint32)tv->count;
 
858
                        else    /* Assume TIFF_VARIABLE */
 
859
                                *va_arg(ap, uint16*) = (uint16)tv->count;
 
860
                        *va_arg(ap, void **) = tv->value;
 
861
                        ret_val = 1;
 
862
                } else {
 
863
                        if ((fip->field_type == TIFF_ASCII
 
864
                            || fip->field_readcount == TIFF_VARIABLE
 
865
                            || fip->field_readcount == TIFF_VARIABLE2
 
866
                            || fip->field_readcount == TIFF_SPP
 
867
                            || tv->count > 1)
 
868
                            && fip->field_tag != TIFFTAG_PAGENUMBER
 
869
                            && fip->field_tag != TIFFTAG_HALFTONEHINTS
 
870
                            && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
 
871
                            && fip->field_tag != TIFFTAG_DOTRANGE) {
 
872
                                *va_arg(ap, void **) = tv->value;
 
873
                                ret_val = 1;
 
874
                        } else {
 
875
                            int j;
 
876
                            char *val = (char *)tv->value;
 
877
 
 
878
                            for (j = 0; j < tv->count;
 
879
                                 j++, val += _TIFFDataSize(tv->info->field_type)) {
 
880
                                switch (fip->field_type) {
 
881
                                        case TIFF_BYTE:
 
882
                                        case TIFF_UNDEFINED:
 
883
                                                *va_arg(ap, uint8*) =
 
884
                                                        *(uint8 *)val;
 
885
                                                ret_val = 1;
 
886
                                                break;
 
887
                                        case TIFF_SBYTE:
 
888
                                                *va_arg(ap, int8*) =
 
889
                                                        *(int8 *)val;
 
890
                                                ret_val = 1;
 
891
                                                break;
 
892
                                        case TIFF_SHORT:
 
893
                                                *va_arg(ap, uint16*) =
 
894
                                                        *(uint16 *)val;
 
895
                                                ret_val = 1;
 
896
                                                break;
 
897
                                        case TIFF_SSHORT:
 
898
                                                *va_arg(ap, int16*) =
 
899
                                                        *(int16 *)val;
 
900
                                                ret_val = 1;
 
901
                                                break;
 
902
                                        case TIFF_LONG:
 
903
                                        case TIFF_IFD:
 
904
                                                *va_arg(ap, uint32*) =
 
905
                                                        *(uint32 *)val;
 
906
                                                ret_val = 1;
 
907
                                                break;
 
908
                                        case TIFF_SLONG:
 
909
                                                *va_arg(ap, int32*) =
 
910
                                                        *(int32 *)val;
 
911
                                                ret_val = 1;
 
912
                                                break;
 
913
                                        case TIFF_RATIONAL:
 
914
                                        case TIFF_SRATIONAL:
 
915
                                        case TIFF_FLOAT:
 
916
                                                *va_arg(ap, float*) =
 
917
                                                        *(float *)val;
 
918
                                                ret_val = 1;
 
919
                                                break;
 
920
                                        case TIFF_DOUBLE:
 
921
                                                *va_arg(ap, double*) =
 
922
                                                        *(double *)val;
 
923
                                                ret_val = 1;
 
924
                                                break;
 
925
                                        default:
 
926
                                                ret_val = 0;
 
927
                                                break;
 
928
                                }
 
929
                            }
 
930
                        }
 
931
                }
 
932
                break;
 
933
            }
 
934
        }
 
935
    }
 
936
    return(ret_val);
 
937
}
 
938
 
 
939
/*
 
940
 * Return the value of a field in the
 
941
 * internal directory structure.
 
942
 */
 
943
int
 
944
TIFFGetField(TIFF* tif, ttag_t tag, ...)
 
945
{
 
946
        int status;
 
947
        va_list ap;
 
948
 
 
949
        va_start(ap, tag);
 
950
        status = TIFFVGetField(tif, tag, ap);
 
951
        va_end(ap);
 
952
        return (status);
 
953
}
 
954
 
 
955
/*
 
956
 * Like TIFFGetField, but taking a varargs
 
957
 * parameter list.  This routine is useful
 
958
 * for building higher-level interfaces on
 
959
 * top of the library.
 
960
 */
 
961
int
 
962
TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
 
963
{
 
964
        const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
 
965
        return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
 
966
            (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
 
967
}
 
968
 
 
969
#define CleanupField(member) {          \
 
970
    if (td->member) {                   \
 
971
        _TIFFfree(td->member);          \
 
972
        td->member = 0;                 \
 
973
    }                                   \
 
974
}
 
975
 
 
976
/*
 
977
 * Release storage associated with a directory.
 
978
 */
 
979
void
 
980
TIFFFreeDirectory(TIFF* tif)
 
981
{
 
982
        TIFFDirectory *td = &tif->tif_dir;
 
983
        int            i;
 
984
 
 
985
        _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
 
986
        CleanupField(td_colormap[0]);
 
987
        CleanupField(td_colormap[1]);
 
988
        CleanupField(td_colormap[2]);
 
989
        CleanupField(td_sampleinfo);
 
990
        CleanupField(td_subifd);
 
991
        CleanupField(td_inknames);
 
992
        CleanupField(td_transferfunction[0]);
 
993
        CleanupField(td_transferfunction[1]);
 
994
        CleanupField(td_transferfunction[2]);
 
995
        CleanupField(td_stripoffset);
 
996
        CleanupField(td_stripbytecount);
 
997
        TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
 
998
        TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
 
999
 
 
1000
        /* Cleanup custom tag values */
 
1001
        for( i = 0; i < td->td_customValueCount; i++ ) {
 
1002
                if (td->td_customValues[i].value)
 
1003
                        _TIFFfree(td->td_customValues[i].value);
 
1004
        }
 
1005
 
 
1006
        td->td_customValueCount = 0;
 
1007
        CleanupField(td_customValues);
 
1008
}
 
1009
#undef CleanupField
 
1010
 
 
1011
/*
 
1012
 * Client Tag extension support (from Niles Ritter).
 
1013
 */
 
1014
static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
 
1015
 
 
1016
TIFFExtendProc
 
1017
TIFFSetTagExtender(TIFFExtendProc extender)
 
1018
{
 
1019
        TIFFExtendProc prev = _TIFFextender;
 
1020
        _TIFFextender = extender;
 
1021
        return (prev);
 
1022
}
 
1023
 
 
1024
/*
 
1025
 * Setup for a new directory.  Should we automatically call
 
1026
 * TIFFWriteDirectory() if the current one is dirty?
 
1027
 *
 
1028
 * The newly created directory will not exist on the file till
 
1029
 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
 
1030
 */
 
1031
int
 
1032
TIFFCreateDirectory(TIFF* tif)
 
1033
{
 
1034
    TIFFDefaultDirectory(tif);
 
1035
    tif->tif_diroff = 0;
 
1036
    tif->tif_nextdiroff = 0;
 
1037
    tif->tif_curoff = 0;
 
1038
    tif->tif_row = (uint32) -1;
 
1039
    tif->tif_curstrip = (tstrip_t) -1;
 
1040
 
 
1041
    return 0;
 
1042
}
 
1043
 
 
1044
/*
 
1045
 * Setup a default directory structure.
 
1046
 */
 
1047
int
 
1048
TIFFDefaultDirectory(TIFF* tif)
 
1049
{
 
1050
        register TIFFDirectory* td = &tif->tif_dir;
 
1051
 
 
1052
        size_t tiffFieldInfoCount;
 
1053
        const TIFFFieldInfo *tiffFieldInfo =
 
1054
            _TIFFGetFieldInfo(&tiffFieldInfoCount);
 
1055
        _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
 
1056
 
 
1057
        _TIFFmemset(td, 0, sizeof (*td));
 
1058
        td->td_fillorder = FILLORDER_MSB2LSB;
 
1059
        td->td_bitspersample = 1;
 
1060
        td->td_threshholding = THRESHHOLD_BILEVEL;
 
1061
        td->td_orientation = ORIENTATION_TOPLEFT;
 
1062
        td->td_samplesperpixel = 1;
 
1063
        td->td_rowsperstrip = (uint32) -1;
 
1064
        td->td_tilewidth = 0;
 
1065
        td->td_tilelength = 0;
 
1066
        td->td_tiledepth = 1;
 
1067
        td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
 
1068
        td->td_resolutionunit = RESUNIT_INCH;
 
1069
        td->td_sampleformat = SAMPLEFORMAT_UINT;
 
1070
        td->td_imagedepth = 1;
 
1071
        td->td_ycbcrsubsampling[0] = 2;
 
1072
        td->td_ycbcrsubsampling[1] = 2;
 
1073
        td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
 
1074
        tif->tif_postdecode = _TIFFNoPostDecode;
 
1075
        tif->tif_foundfield = NULL;
 
1076
        tif->tif_tagmethods.vsetfield = _TIFFVSetField;
 
1077
        tif->tif_tagmethods.vgetfield = _TIFFVGetField;
 
1078
        tif->tif_tagmethods.printdir = NULL;
 
1079
        /*
 
1080
         *  Give client code a chance to install their own
 
1081
         *  tag extensions & methods, prior to compression overloads.
 
1082
         */
 
1083
        if (_TIFFextender)
 
1084
                (*_TIFFextender)(tif);
 
1085
        (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
 
1086
        /*
 
1087
         * NB: The directory is marked dirty as a result of setting
 
1088
         * up the default compression scheme.  However, this really
 
1089
         * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
 
1090
         * if the user does something.  We could just do the setup
 
1091
         * by hand, but it seems better to use the normal mechanism
 
1092
         * (i.e. TIFFSetField).
 
1093
         */
 
1094
        tif->tif_flags &= ~TIFF_DIRTYDIRECT;
 
1095
 
 
1096
        /*
 
1097
         * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
 
1098
         * we clear the ISTILED flag when setting up a new directory.
 
1099
         * Should we also be clearing stuff like INSUBIFD?
 
1100
         */
 
1101
        tif->tif_flags &= ~TIFF_ISTILED;
 
1102
 
 
1103
        return (1);
 
1104
}
 
1105
 
 
1106
static int
 
1107
TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
 
1108
{
 
1109
        static const char module[] = "TIFFAdvanceDirectory";
 
1110
        uint16 dircount;
 
1111
        if (isMapped(tif))
 
1112
        {
 
1113
                toff_t poff=*nextdir;
 
1114
                if (poff+sizeof(uint16) > tif->tif_size)
 
1115
                {
 
1116
                        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
 
1117
                            tif->tif_name);
 
1118
                        return (0);
 
1119
                }
 
1120
                _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
 
1121
                if (tif->tif_flags & TIFF_SWAB)
 
1122
                        TIFFSwabShort(&dircount);
 
1123
                poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
 
1124
                if (off != NULL)
 
1125
                        *off = poff;
 
1126
                if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
 
1127
                {
 
1128
                        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
 
1129
                            tif->tif_name);
 
1130
                        return (0);
 
1131
                }
 
1132
                _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
 
1133
                if (tif->tif_flags & TIFF_SWAB)
 
1134
                        TIFFSwabLong(nextdir);
 
1135
                return (1);
 
1136
        }
 
1137
        else
 
1138
        {
 
1139
                if (!SeekOK(tif, *nextdir) ||
 
1140
                    !ReadOK(tif, &dircount, sizeof (uint16))) {
 
1141
                        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
 
1142
                            tif->tif_name);
 
1143
                        return (0);
 
1144
                }
 
1145
                if (tif->tif_flags & TIFF_SWAB)
 
1146
                        TIFFSwabShort(&dircount);
 
1147
                if (off != NULL)
 
1148
                        *off = TIFFSeekFile(tif,
 
1149
                            dircount*sizeof (TIFFDirEntry), SEEK_CUR);
 
1150
                else
 
1151
                        (void) TIFFSeekFile(tif,
 
1152
                            dircount*sizeof (TIFFDirEntry), SEEK_CUR);
 
1153
                if (!ReadOK(tif, nextdir, sizeof (uint32))) {
 
1154
                        TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
 
1155
                            tif->tif_name);
 
1156
                        return (0);
 
1157
                }
 
1158
                if (tif->tif_flags & TIFF_SWAB)
 
1159
                        TIFFSwabLong(nextdir);
 
1160
                return (1);
 
1161
        }
 
1162
}
 
1163
 
 
1164
/*
 
1165
 * Count the number of directories in a file.
 
1166
 */
 
1167
tdir_t
 
1168
TIFFNumberOfDirectories(TIFF* tif)
 
1169
{
 
1170
    toff_t nextdir = tif->tif_header.tiff_diroff;
 
1171
    tdir_t n = 0;
 
1172
    
 
1173
    while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
 
1174
        n++;
 
1175
    return (n);
 
1176
}
 
1177
 
 
1178
/*
 
1179
 * Set the n-th directory as the current directory.
 
1180
 * NB: Directories are numbered starting at 0.
 
1181
 */
 
1182
int
 
1183
TIFFSetDirectory(TIFF* tif, tdir_t dirn)
 
1184
{
 
1185
        toff_t nextdir;
 
1186
        tdir_t n;
 
1187
 
 
1188
        nextdir = tif->tif_header.tiff_diroff;
 
1189
        for (n = dirn; n > 0 && nextdir != 0; n--)
 
1190
                if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
 
1191
                        return (0);
 
1192
        tif->tif_nextdiroff = nextdir;
 
1193
        /*
 
1194
         * Set curdir to the actual directory index.  The
 
1195
         * -1 is because TIFFReadDirectory will increment
 
1196
         * tif_curdir after successfully reading the directory.
 
1197
         */
 
1198
        tif->tif_curdir = (dirn - n) - 1;
 
1199
        /*
 
1200
         * Reset tif_dirnumber counter and start new list of seen directories.
 
1201
         * We need this to prevent IFD loops.
 
1202
         */
 
1203
        tif->tif_dirnumber = 0;
 
1204
        return (TIFFReadDirectory(tif));
 
1205
}
 
1206
 
 
1207
/*
 
1208
 * Set the current directory to be the directory
 
1209
 * located at the specified file offset.  This interface
 
1210
 * is used mainly to access directories linked with
 
1211
 * the SubIFD tag (e.g. thumbnail images).
 
1212
 */
 
1213
int
 
1214
TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
 
1215
{
 
1216
        tif->tif_nextdiroff = diroff;
 
1217
        /*
 
1218
         * Reset tif_dirnumber counter and start new list of seen directories.
 
1219
         * We need this to prevent IFD loops.
 
1220
         */
 
1221
        tif->tif_dirnumber = 0;
 
1222
        return (TIFFReadDirectory(tif));
 
1223
}
 
1224
 
 
1225
/*
 
1226
 * Return file offset of the current directory.
 
1227
 */
 
1228
uint32
 
1229
TIFFCurrentDirOffset(TIFF* tif)
 
1230
{
 
1231
        return (tif->tif_diroff);
 
1232
}
 
1233
 
 
1234
/*
 
1235
 * Return an indication of whether or not we are
 
1236
 * at the last directory in the file.
 
1237
 */
 
1238
int
 
1239
TIFFLastDirectory(TIFF* tif)
 
1240
{
 
1241
        return (tif->tif_nextdiroff == 0);
 
1242
}
 
1243
 
 
1244
/*
 
1245
 * Unlink the specified directory from the directory chain.
 
1246
 */
 
1247
int
 
1248
TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
 
1249
{
 
1250
        static const char module[] = "TIFFUnlinkDirectory";
 
1251
        toff_t nextdir;
 
1252
        toff_t off;
 
1253
        tdir_t n;
 
1254
 
 
1255
        if (tif->tif_mode == O_RDONLY) {
 
1256
                TIFFErrorExt(tif->tif_clientdata, module,
 
1257
                             "Can not unlink directory in read-only file");
 
1258
                return (0);
 
1259
        }
 
1260
        /*
 
1261
         * Go to the directory before the one we want
 
1262
         * to unlink and nab the offset of the link
 
1263
         * field we'll need to patch.
 
1264
         */
 
1265
        nextdir = tif->tif_header.tiff_diroff;
 
1266
        off = sizeof (uint16) + sizeof (uint16);
 
1267
        for (n = dirn-1; n > 0; n--) {
 
1268
                if (nextdir == 0) {
 
1269
                        TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
 
1270
                        return (0);
 
1271
                }
 
1272
                if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
 
1273
                        return (0);
 
1274
        }
 
1275
        /*
 
1276
         * Advance to the directory to be unlinked and fetch
 
1277
         * the offset of the directory that follows.
 
1278
         */
 
1279
        if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
 
1280
                return (0);
 
1281
        /*
 
1282
         * Go back and patch the link field of the preceding
 
1283
         * directory to point to the offset of the directory
 
1284
         * that follows.
 
1285
         */
 
1286
        (void) TIFFSeekFile(tif, off, SEEK_SET);
 
1287
        if (tif->tif_flags & TIFF_SWAB)
 
1288
                TIFFSwabLong(&nextdir);
 
1289
        if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
 
1290
                TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
 
1291
                return (0);
 
1292
        }
 
1293
        /*
 
1294
         * Leave directory state setup safely.  We don't have
 
1295
         * facilities for doing inserting and removing directories,
 
1296
         * so it's safest to just invalidate everything.  This
 
1297
         * means that the caller can only append to the directory
 
1298
         * chain.
 
1299
         */
 
1300
        (*tif->tif_cleanup)(tif);
 
1301
        if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
 
1302
                _TIFFfree(tif->tif_rawdata);
 
1303
                tif->tif_rawdata = NULL;
 
1304
                tif->tif_rawcc = 0;
 
1305
        }
 
1306
        tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
 
1307
        TIFFFreeDirectory(tif);
 
1308
        TIFFDefaultDirectory(tif);
 
1309
        tif->tif_diroff = 0;                    /* force link on next write */
 
1310
        tif->tif_nextdiroff = 0;                /* next write must be at end */
 
1311
        tif->tif_curoff = 0;
 
1312
        tif->tif_row = (uint32) -1;
 
1313
        tif->tif_curstrip = (tstrip_t) -1;
 
1314
        return (1);
 
1315
}
 
1316
 
 
1317
/*                      [BFC]
 
1318
 *
 
1319
 * Author: Bruce Cameron <cameron@petris.com>
 
1320
 *
 
1321
 * Set a table of tags that are to be replaced during directory process by the
 
1322
 * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
 
1323
 * 'ReadDirectory' can use the stored information.
 
1324
 *
 
1325
 * FIXME: this is never used properly. Should be removed in the future.
 
1326
 */
 
1327
int
 
1328
TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
 
1329
{
 
1330
    static int TIFFignoretags [FIELD_LAST];
 
1331
    static int tagcount = 0 ;
 
1332
    int         i;                                      /* Loop index */
 
1333
    int         j;                                      /* Loop index */
 
1334
 
 
1335
    switch (task)
 
1336
    {
 
1337
      case TIS_STORE:
 
1338
        if ( tagcount < (FIELD_LAST - 1) )
 
1339
        {
 
1340
            for ( j = 0 ; j < tagcount ; ++j )
 
1341
            {                                   /* Do not add duplicate tag */
 
1342
                if ( TIFFignoretags [j] == TIFFtagID )
 
1343
                    return (TRUE) ;
 
1344
            }
 
1345
            TIFFignoretags [tagcount++] = TIFFtagID ;
 
1346
            return (TRUE) ;
 
1347
        }
 
1348
        break ;
 
1349
        
 
1350
      case TIS_EXTRACT:
 
1351
        for ( i = 0 ; i < tagcount ; ++i )
 
1352
        {
 
1353
            if ( TIFFignoretags [i] == TIFFtagID )
 
1354
                return (TRUE) ;
 
1355
        }
 
1356
        break;
 
1357
        
 
1358
      case TIS_EMPTY:
 
1359
        tagcount = 0 ;                  /* Clear the list */
 
1360
        return (TRUE) ;
 
1361
        
 
1362
      default:
 
1363
        break;
 
1364
    }
 
1365
    
 
1366
    return (FALSE);
 
1367
}
 
1368
 
 
1369
/* vim: set ts=8 sts=8 sw=8 noet: */