source: trunk/third/tiff/libtiff/tif_dir.c @ 18174

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