~ubuntu-branches/ubuntu/trusty/freeimage/trusty-proposed

« back to all changes in this revision

Viewing changes to Source/LibTIFF/tif_dirwrite.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2010-10-29 14:46:46 UTC
  • Revision ID: james.westby@ubuntu.com-20101029144646-7bq2g444s3ip34p6
Tags: 3.10.0-3
* Don't use embedded copies of various libraries, add build-deps on their
  packaged versions (closes: #595560):
  - libjpeg 6b
  - libmng 1.0.9
  - libopenjpeg 1.2.0
  - libpng 1.2.23
    + CVE-2010-2249, CVE-2010-1205, CVE-2010-0205, CVE-2009-2042,
      CVE-2008-6218, CVE-2008-5907, CVE-2009-0040, CVE-2008-3964,
      CVE-2008-1382
  - openexr 1.6.1
    + CVE-2009-1720, CVE-2009-1721
  - zlib 1.2.3
* The embedded libtiff copy is still used, because freeimage uses its
  internals and I couldn't figure out how to unentangle this.  Update the
  tiff copy to 3.9.4-5, though:
  CVE-2010-3087, CVE-2010-2483, CVE-2010-2482, CVE-2010-2481, CVE-2010-2443,
  CVE-2010-2233, CVE-2010-2067, CVE-2010-2065, CVE-2010-1411, CVE-2009-2347,
  CVE-2008-2327.
* Add tiff copyright and license to debian/copyright (closes: #601002)
* Link with -lm (closes: #558857).
* Try to avoid arch-specific values in our copy of tif_config.h and
  tiffconf.h (closes: #601762)
* Set LFS CFLAGS in Makefile.gnu.
* Orphan package (closes: #595559).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: tif_dirwrite.c,v 1.20 2007/11/10 18:41:03 drolon 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 Write Support Routines.
31
 
 */
32
 
#include "tiffiop.h"
33
 
 
34
 
#ifdef HAVE_IEEEFP
35
 
# define        TIFFCvtNativeToIEEEFloat(tif, n, fp)
36
 
# define        TIFFCvtNativeToIEEEDouble(tif, n, dp)
37
 
#else
38
 
extern  void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
39
 
extern  void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
40
 
#endif
41
 
 
42
 
static  int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
43
 
static  void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
44
 
static  void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
45
 
static  int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
46
 
static  int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
47
 
static  int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
48
 
static  int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
49
 
static  int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
50
 
static  int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
51
 
static  int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
52
 
static  int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
53
 
static  int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
54
 
static  int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
55
 
static  int TIFFWriteAnyArray(TIFF*,
56
 
            TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
57
 
static  int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
58
 
static  int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
59
 
static  int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
60
 
static  int TIFFLinkDirectory(TIFF*);
61
 
 
62
 
#define WriteRationalPair(type, tag1, v1, tag2, v2) {           \
63
 
        TIFFWriteRational((tif), (type), (tag1), (dir), (v1))   \
64
 
        TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \
65
 
        (dir)++;                                                \
66
 
}
67
 
#define TIFFWriteRational(tif, type, tag, dir, v)               \
68
 
        (dir)->tdir_tag = (tag);                                \
69
 
        (dir)->tdir_type = (type);                              \
70
 
        (dir)->tdir_count = 1;                                  \
71
 
        if (!TIFFWriteRationalArray((tif), (dir), &(v)))        \
72
 
                goto bad;
73
 
 
74
 
/*
75
 
 * Write the contents of the current directory
76
 
 * to the specified file.  This routine doesn't
77
 
 * handle overwriting a directory with auxiliary
78
 
 * storage that's been changed.
79
 
 */
80
 
static int
81
 
_TIFFWriteDirectory(TIFF* tif, int done)
82
 
{
83
 
        uint16 dircount;
84
 
        toff_t diroff;
85
 
        ttag_t tag;
86
 
        uint32 nfields;
87
 
        tsize_t dirsize;
88
 
        char* data;
89
 
        TIFFDirEntry* dir;
90
 
        TIFFDirectory* td;
91
 
        unsigned long b, fields[FIELD_SETLONGS];
92
 
        int fi, nfi;
93
 
 
94
 
        if (tif->tif_mode == O_RDONLY)
95
 
                return (1);
96
 
        /*
97
 
         * Clear write state so that subsequent images with
98
 
         * different characteristics get the right buffers
99
 
         * setup for them.
100
 
         */
101
 
        if (done)
102
 
        {
103
 
                if (tif->tif_flags & TIFF_POSTENCODE) {
104
 
                        tif->tif_flags &= ~TIFF_POSTENCODE;
105
 
                        if (!(*tif->tif_postencode)(tif)) {
106
 
                                TIFFErrorExt(tif->tif_clientdata,
107
 
                                             tif->tif_name,
108
 
                                "Error post-encoding before directory write");
109
 
                                return (0);
110
 
                        }
111
 
                }
112
 
                (*tif->tif_close)(tif);         /* shutdown encoder */
113
 
                /*
114
 
                 * Flush any data that might have been written
115
 
                 * by the compression close+cleanup routines.
116
 
                 */
117
 
                if (tif->tif_rawcc > 0 
118
 
                    && (tif->tif_flags & TIFF_BEENWRITING) != 0
119
 
                    && !TIFFFlushData1(tif)) {
120
 
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
121
 
                            "Error flushing data before directory write");
122
 
                        return (0);
123
 
                }
124
 
                if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
125
 
                        _TIFFfree(tif->tif_rawdata);
126
 
                        tif->tif_rawdata = NULL;
127
 
                        tif->tif_rawcc = 0;
128
 
                        tif->tif_rawdatasize = 0;
129
 
                }
130
 
                tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
131
 
        }
132
 
 
133
 
        td = &tif->tif_dir;
134
 
        /*
135
 
         * Size the directory so that we can calculate
136
 
         * offsets for the data items that aren't kept
137
 
         * in-place in each field.
138
 
         */
139
 
        nfields = 0;
140
 
        for (b = 0; b <= FIELD_LAST; b++)
141
 
                if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
142
 
                        nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
143
 
        nfields += td->td_customValueCount;
144
 
        dirsize = nfields * sizeof (TIFFDirEntry);
145
 
        data = (char*) _TIFFmalloc(dirsize);
146
 
        if (data == NULL) {
147
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
148
 
                             "Cannot write directory, out of space");
149
 
                return (0);
150
 
        }
151
 
        /*
152
 
         * Directory hasn't been placed yet, put
153
 
         * it at the end of the file and link it
154
 
         * into the existing directory structure.
155
 
         */
156
 
        if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
157
 
                goto bad;
158
 
        tif->tif_dataoff = (toff_t)(
159
 
            tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
160
 
        if (tif->tif_dataoff & 1)
161
 
                tif->tif_dataoff++;
162
 
        (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
163
 
        tif->tif_curdir++;
164
 
        dir = (TIFFDirEntry*) data;
165
 
        /*
166
 
         * Setup external form of directory
167
 
         * entries and write data items.
168
 
         */
169
 
        _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
170
 
        /*
171
 
         * Write out ExtraSamples tag only if
172
 
         * extra samples are present in the data.
173
 
         */
174
 
        if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
175
 
                ResetFieldBit(fields, FIELD_EXTRASAMPLES);
176
 
                nfields--;
177
 
                dirsize -= sizeof (TIFFDirEntry);
178
 
        }                                                               /*XXX*/
179
 
        for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
180
 
                const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
181
 
 
182
 
                /*
183
 
                 * For custom fields, we test to see if the custom field
184
 
                 * is set or not.  For normal fields, we just use the
185
 
                 * FieldSet test.
186
 
                */
187
 
                if( fip->field_bit == FIELD_CUSTOM )
188
 
                {
189
 
                        int ci, is_set = FALSE;
190
 
 
191
 
                        for( ci = 0; ci < td->td_customValueCount; ci++ )
192
 
                                is_set |= (td->td_customValues[ci].info == fip);
193
 
 
194
 
                        if( !is_set )
195
 
                                continue;
196
 
                }
197
 
                else if (!FieldSet(fields, fip->field_bit))
198
 
                        continue;
199
 
 
200
 
                /*
201
 
                 * Handle other fields.
202
 
                 */
203
 
                switch (fip->field_bit)
204
 
                {
205
 
                case FIELD_STRIPOFFSETS:
206
 
                        /*
207
 
                         * We use one field bit for both strip and tile
208
 
 
209
 
                         * offsets, and so must be careful in selecting
210
 
                         * the appropriate field descriptor (so that tags
211
 
                         * are written in sorted order).
212
 
                         */
213
 
                        tag = isTiled(tif) ?
214
 
                            TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
215
 
                        if (tag != fip->field_tag)
216
 
                                continue;
217
 
                        
218
 
                        dir->tdir_tag = (uint16) tag;
219
 
                        dir->tdir_type = (uint16) TIFF_LONG;
220
 
                        dir->tdir_count = (uint32) td->td_nstrips;
221
 
                        if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
222
 
                                goto bad;
223
 
                        break;
224
 
                case FIELD_STRIPBYTECOUNTS:
225
 
                        /*
226
 
                         * We use one field bit for both strip and tile
227
 
                         * byte counts, and so must be careful in selecting
228
 
                         * the appropriate field descriptor (so that tags
229
 
                         * are written in sorted order).
230
 
                         */
231
 
                        tag = isTiled(tif) ?
232
 
                            TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
233
 
                        if (tag != fip->field_tag)
234
 
                                continue;
235
 
                        
236
 
                        dir->tdir_tag = (uint16) tag;
237
 
                        dir->tdir_type = (uint16) TIFF_LONG;
238
 
                        dir->tdir_count = (uint32) td->td_nstrips;
239
 
                        if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount))
240
 
                                goto bad;
241
 
                        break;
242
 
                case FIELD_ROWSPERSTRIP:
243
 
                        TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
244
 
                            dir, td->td_rowsperstrip);
245
 
                        break;
246
 
                case FIELD_COLORMAP:
247
 
                        if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
248
 
                            3, td->td_colormap))
249
 
                                goto bad;
250
 
                        break;
251
 
                case FIELD_IMAGEDIMENSIONS:
252
 
                        TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
253
 
                            dir++, td->td_imagewidth);
254
 
                        TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
255
 
                            dir, td->td_imagelength);
256
 
                        break;
257
 
                case FIELD_TILEDIMENSIONS:
258
 
                        TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
259
 
                            dir++, td->td_tilewidth);
260
 
                        TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
261
 
                            dir, td->td_tilelength);
262
 
                        break;
263
 
                case FIELD_COMPRESSION:
264
 
                        TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
265
 
                            dir, td->td_compression);
266
 
                        break;
267
 
                case FIELD_PHOTOMETRIC:
268
 
                        TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
269
 
                            dir, td->td_photometric);
270
 
                        break;
271
 
                case FIELD_POSITION:
272
 
                        WriteRationalPair(TIFF_RATIONAL,
273
 
                            TIFFTAG_XPOSITION, td->td_xposition,
274
 
                            TIFFTAG_YPOSITION, td->td_yposition);
275
 
                        break;
276
 
                case FIELD_RESOLUTION:
277
 
                        WriteRationalPair(TIFF_RATIONAL,
278
 
                            TIFFTAG_XRESOLUTION, td->td_xresolution,
279
 
                            TIFFTAG_YRESOLUTION, td->td_yresolution);
280
 
                        break;
281
 
                case FIELD_BITSPERSAMPLE:
282
 
                case FIELD_MINSAMPLEVALUE:
283
 
                case FIELD_MAXSAMPLEVALUE:
284
 
                case FIELD_SAMPLEFORMAT:
285
 
                        if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
286
 
                                goto bad;
287
 
                        break;
288
 
                case FIELD_SMINSAMPLEVALUE:
289
 
                case FIELD_SMAXSAMPLEVALUE:
290
 
                        if (!TIFFWritePerSampleAnys(tif,
291
 
                            _TIFFSampleToTagType(tif), fip->field_tag, dir))
292
 
                                goto bad;
293
 
                        break;
294
 
                case FIELD_PAGENUMBER:
295
 
                case FIELD_HALFTONEHINTS:
296
 
                case FIELD_YCBCRSUBSAMPLING:
297
 
                        if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
298
 
                                goto bad;
299
 
                        break;
300
 
                case FIELD_INKNAMES:
301
 
                        if (!TIFFWriteInkNames(tif, dir))
302
 
                                goto bad;
303
 
                        break;
304
 
                case FIELD_TRANSFERFUNCTION:
305
 
                        if (!TIFFWriteTransferFunction(tif, dir))
306
 
                                goto bad;
307
 
                        break;
308
 
                case FIELD_SUBIFD:
309
 
                        /*
310
 
                         * XXX: Always write this field using LONG type
311
 
                         * for backward compatibility.
312
 
                         */
313
 
                        dir->tdir_tag = (uint16) fip->field_tag;
314
 
                        dir->tdir_type = (uint16) TIFF_LONG;
315
 
                        dir->tdir_count = (uint32) td->td_nsubifd;
316
 
                        if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
317
 
                                goto bad;
318
 
                        /*
319
 
                         * Total hack: if this directory includes a SubIFD
320
 
                         * tag then force the next <n> directories to be
321
 
                         * written as ``sub directories'' of this one.  This
322
 
                         * is used to write things like thumbnails and
323
 
                         * image masks that one wants to keep out of the
324
 
                         * normal directory linkage access mechanism.
325
 
                         */
326
 
                        if (dir->tdir_count > 0) {
327
 
                                tif->tif_flags |= TIFF_INSUBIFD;
328
 
                                tif->tif_nsubifd = (uint16) dir->tdir_count;
329
 
                                if (dir->tdir_count > 1)
330
 
                                        tif->tif_subifdoff = dir->tdir_offset;
331
 
                                else
332
 
                                        tif->tif_subifdoff = (uint32)(
333
 
                                              tif->tif_diroff
334
 
                                            + sizeof (uint16)
335
 
                                            + ((char*)&dir->tdir_offset-data));
336
 
                        }
337
 
                        break;
338
 
                default:
339
 
                        /* XXX: Should be fixed and removed. */
340
 
                        if (fip->field_tag == TIFFTAG_DOTRANGE) {
341
 
                                if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
342
 
                                        goto bad;
343
 
                        }
344
 
                        else if (!TIFFWriteNormalTag(tif, dir, fip))
345
 
                                goto bad;
346
 
                        break;
347
 
                }
348
 
                dir++;
349
 
                
350
 
                if( fip->field_bit != FIELD_CUSTOM )
351
 
                        ResetFieldBit(fields, fip->field_bit);
352
 
        }
353
 
 
354
 
        /*
355
 
         * Write directory.
356
 
         */
357
 
        dircount = (uint16) nfields;
358
 
        diroff = (uint32) tif->tif_nextdiroff;
359
 
        if (tif->tif_flags & TIFF_SWAB) {
360
 
                /*
361
 
                 * The file's byte order is opposite to the
362
 
                 * native machine architecture.  We overwrite
363
 
                 * the directory information with impunity
364
 
                 * because it'll be released below after we
365
 
                 * write it to the file.  Note that all the
366
 
                 * other tag construction routines assume that
367
 
                 * we do this byte-swapping; i.e. they only
368
 
                 * byte-swap indirect data.
369
 
                 */
370
 
                for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
371
 
                        TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
372
 
                        TIFFSwabArrayOfLong(&dir->tdir_count, 2);
373
 
                }
374
 
                dircount = (uint16) nfields;
375
 
                TIFFSwabShort(&dircount);
376
 
                TIFFSwabLong(&diroff);
377
 
        }
378
 
        (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
379
 
        if (!WriteOK(tif, &dircount, sizeof (dircount))) {
380
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
381
 
                             "Error writing directory count");
382
 
                goto bad;
383
 
        }
384
 
        if (!WriteOK(tif, data, dirsize)) {
385
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
386
 
                             "Error writing directory contents");
387
 
                goto bad;
388
 
        }
389
 
        if (!WriteOK(tif, &diroff, sizeof (uint32))) {
390
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
391
 
                             "Error writing directory link");
392
 
                goto bad;
393
 
        }
394
 
        if (done) {
395
 
                TIFFFreeDirectory(tif);
396
 
                tif->tif_flags &= ~TIFF_DIRTYDIRECT;
397
 
                (*tif->tif_cleanup)(tif);
398
 
 
399
 
                /*
400
 
                * Reset directory-related state for subsequent
401
 
                * directories.
402
 
                */
403
 
                TIFFCreateDirectory(tif);
404
 
        }
405
 
        _TIFFfree(data);
406
 
        return (1);
407
 
bad:
408
 
        _TIFFfree(data);
409
 
        return (0);
410
 
}
411
 
#undef WriteRationalPair
412
 
 
413
 
int
414
 
TIFFWriteDirectory(TIFF* tif)
415
 
{
416
 
        return _TIFFWriteDirectory(tif, TRUE);
417
 
}
418
 
 
419
 
/*
420
 
 * Similar to TIFFWriteDirectory(), writes the directory out
421
 
 * but leaves all data structures in memory so that it can be
422
 
 * written again.  This will make a partially written TIFF file
423
 
 * readable before it is successfully completed/closed.
424
 
 */ 
425
 
int
426
 
TIFFCheckpointDirectory(TIFF* tif)
427
 
{
428
 
        int rc;
429
 
        /* Setup the strips arrays, if they haven't already been. */
430
 
        if (tif->tif_dir.td_stripoffset == NULL)
431
 
            (void) TIFFSetupStrips(tif);
432
 
        rc = _TIFFWriteDirectory(tif, FALSE);
433
 
        (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
434
 
        return rc;
435
 
}
436
 
 
437
 
static int
438
 
_TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
439
 
{
440
 
        uint16 dircount;
441
 
        uint32 nfields;
442
 
        tsize_t dirsize;
443
 
        char* data;
444
 
        TIFFDirEntry* dir;
445
 
        TIFFDirectory* td;
446
 
        unsigned long b, fields[FIELD_SETLONGS];
447
 
        int fi, nfi;
448
 
 
449
 
        if (tif->tif_mode == O_RDONLY)
450
 
                return (1);
451
 
 
452
 
        td = &tif->tif_dir;
453
 
        /*
454
 
         * Size the directory so that we can calculate
455
 
         * offsets for the data items that aren't kept
456
 
         * in-place in each field.
457
 
         */
458
 
        nfields = 0;
459
 
        for (b = 0; b <= FIELD_LAST; b++)
460
 
                if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
461
 
                        nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
462
 
        nfields += td->td_customValueCount;
463
 
        dirsize = nfields * sizeof (TIFFDirEntry);
464
 
        data = (char*) _TIFFmalloc(dirsize);
465
 
        if (data == NULL) {
466
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
467
 
                             "Cannot write directory, out of space");
468
 
                return (0);
469
 
        }
470
 
        /*
471
 
         * Put the directory  at the end of the file.
472
 
         */
473
 
        tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
474
 
        tif->tif_dataoff = (toff_t)(
475
 
            tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
476
 
        if (tif->tif_dataoff & 1)
477
 
                tif->tif_dataoff++;
478
 
        (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
479
 
        dir = (TIFFDirEntry*) data;
480
 
        /*
481
 
         * Setup external form of directory
482
 
         * entries and write data items.
483
 
         */
484
 
        _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
485
 
 
486
 
        for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
487
 
                const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
488
 
 
489
 
                /*
490
 
                 * For custom fields, we test to see if the custom field
491
 
                 * is set or not.  For normal fields, we just use the
492
 
                 * FieldSet test.
493
 
                */
494
 
                if( fip->field_bit == FIELD_CUSTOM )
495
 
                {
496
 
                        int ci, is_set = FALSE;
497
 
 
498
 
                        for( ci = 0; ci < td->td_customValueCount; ci++ )
499
 
                                is_set |= (td->td_customValues[ci].info == fip);
500
 
 
501
 
                        if( !is_set )
502
 
                                continue;
503
 
                }
504
 
                else if (!FieldSet(fields, fip->field_bit))
505
 
                        continue;
506
 
                
507
 
                if( fip->field_bit != FIELD_CUSTOM )
508
 
                        ResetFieldBit(fields, fip->field_bit);
509
 
        }
510
 
 
511
 
        /*
512
 
         * Write directory.
513
 
         */
514
 
        dircount = (uint16) nfields;
515
 
        *pdiroff = (uint32) tif->tif_nextdiroff;
516
 
        if (tif->tif_flags & TIFF_SWAB) {
517
 
                /*
518
 
                 * The file's byte order is opposite to the
519
 
                 * native machine architecture.  We overwrite
520
 
                 * the directory information with impunity
521
 
                 * because it'll be released below after we
522
 
                 * write it to the file.  Note that all the
523
 
                 * other tag construction routines assume that
524
 
                 * we do this byte-swapping; i.e. they only
525
 
                 * byte-swap indirect data.
526
 
                 */
527
 
                for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
528
 
                        TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
529
 
                        TIFFSwabArrayOfLong(&dir->tdir_count, 2);
530
 
                }
531
 
                dircount = (uint16) nfields;
532
 
                TIFFSwabShort(&dircount);
533
 
                TIFFSwabLong(pdiroff);
534
 
        }
535
 
        (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
536
 
        if (!WriteOK(tif, &dircount, sizeof (dircount))) {
537
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
538
 
                             "Error writing directory count");
539
 
                goto bad;
540
 
        }
541
 
        if (!WriteOK(tif, data, dirsize)) {
542
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
543
 
                             "Error writing directory contents");
544
 
                goto bad;
545
 
        }
546
 
        if (!WriteOK(tif, pdiroff, sizeof (uint32))) {
547
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
548
 
                             "Error writing directory link");
549
 
                goto bad;
550
 
        }
551
 
        _TIFFfree(data);
552
 
        return (1);
553
 
bad:
554
 
        _TIFFfree(data);
555
 
        return (0);
556
 
}
557
 
 
558
 
int
559
 
TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
560
 
{
561
 
        return _TIFFWriteCustomDirectory(tif, pdiroff);
562
 
}
563
 
 
564
 
/*
565
 
 * Process tags that are not special cased.
566
 
 */
567
 
static int
568
 
TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
569
 
{
570
 
        uint16 wc = (uint16) fip->field_writecount;
571
 
        uint32 wc2;
572
 
 
573
 
        dir->tdir_tag = (uint16) fip->field_tag;
574
 
        dir->tdir_type = (uint16) fip->field_type;
575
 
        dir->tdir_count = wc;
576
 
        
577
 
        switch (fip->field_type) {
578
 
        case TIFF_SHORT:
579
 
        case TIFF_SSHORT:
580
 
                if (fip->field_passcount) {
581
 
                        uint16* wp;
582
 
                        if (wc == (uint16) TIFF_VARIABLE2) {
583
 
                                TIFFGetField(tif, fip->field_tag, &wc2, &wp);
584
 
                                dir->tdir_count = wc2;
585
 
                        } else {        /* Assume TIFF_VARIABLE */
586
 
                                TIFFGetField(tif, fip->field_tag, &wc, &wp);
587
 
                                dir->tdir_count = wc;
588
 
                        }
589
 
                        if (!TIFFWriteShortArray(tif, dir, wp))
590
 
                                return 0;
591
 
                } else {
592
 
                        if (wc == 1) {
593
 
                                uint16 sv;
594
 
                                TIFFGetField(tif, fip->field_tag, &sv);
595
 
                                dir->tdir_offset =
596
 
                                        TIFFInsertData(tif, dir->tdir_type, sv);
597
 
                        } else {
598
 
                                uint16* wp;
599
 
                                TIFFGetField(tif, fip->field_tag, &wp);
600
 
                                if (!TIFFWriteShortArray(tif, dir, wp))
601
 
                                        return 0;
602
 
                        }
603
 
                }
604
 
                break;
605
 
        case TIFF_LONG:
606
 
        case TIFF_SLONG:
607
 
        case TIFF_IFD:
608
 
                if (fip->field_passcount) {
609
 
                        uint32* lp;
610
 
                        if (wc == (uint16) TIFF_VARIABLE2) {
611
 
                                TIFFGetField(tif, fip->field_tag, &wc2, &lp);
612
 
                                dir->tdir_count = wc2;
613
 
                        } else {        /* Assume TIFF_VARIABLE */
614
 
                                TIFFGetField(tif, fip->field_tag, &wc, &lp);
615
 
                                dir->tdir_count = wc;
616
 
                        }
617
 
                        if (!TIFFWriteLongArray(tif, dir, lp))
618
 
                                return 0;
619
 
                } else {
620
 
                        if (wc == 1) {
621
 
                                /* XXX handle LONG->SHORT conversion */
622
 
                                TIFFGetField(tif, fip->field_tag,
623
 
                                             &dir->tdir_offset);
624
 
                        } else {
625
 
                                uint32* lp;
626
 
                                TIFFGetField(tif, fip->field_tag, &lp);
627
 
                                if (!TIFFWriteLongArray(tif, dir, lp))
628
 
                                        return 0;
629
 
                        }
630
 
                }
631
 
                break;
632
 
        case TIFF_RATIONAL:
633
 
        case TIFF_SRATIONAL:
634
 
                if (fip->field_passcount) {
635
 
                        float* fp;
636
 
                        if (wc == (uint16) TIFF_VARIABLE2) {
637
 
                                TIFFGetField(tif, fip->field_tag, &wc2, &fp);
638
 
                                dir->tdir_count = wc2;
639
 
                        } else {        /* Assume TIFF_VARIABLE */
640
 
                                TIFFGetField(tif, fip->field_tag, &wc, &fp);
641
 
                                dir->tdir_count = wc;
642
 
                        }
643
 
                        if (!TIFFWriteRationalArray(tif, dir, fp))
644
 
                                return 0;
645
 
                } else {
646
 
                        if (wc == 1) {
647
 
                                float fv;
648
 
                                TIFFGetField(tif, fip->field_tag, &fv);
649
 
                                if (!TIFFWriteRationalArray(tif, dir, &fv))
650
 
                                        return 0;
651
 
                        } else {
652
 
                                float* fp;
653
 
                                TIFFGetField(tif, fip->field_tag, &fp);
654
 
                                if (!TIFFWriteRationalArray(tif, dir, fp))
655
 
                                        return 0;
656
 
                        }
657
 
                }
658
 
                break;
659
 
        case TIFF_FLOAT:
660
 
                if (fip->field_passcount) {
661
 
                        float* fp;
662
 
                        if (wc == (uint16) TIFF_VARIABLE2) {
663
 
                                TIFFGetField(tif, fip->field_tag, &wc2, &fp);
664
 
                                dir->tdir_count = wc2;
665
 
                        } else {        /* Assume TIFF_VARIABLE */
666
 
                                TIFFGetField(tif, fip->field_tag, &wc, &fp);
667
 
                                dir->tdir_count = wc;
668
 
                        }
669
 
                        if (!TIFFWriteFloatArray(tif, dir, fp))
670
 
                                return 0;
671
 
                } else {
672
 
                        if (wc == 1) {
673
 
                                float fv;
674
 
                                TIFFGetField(tif, fip->field_tag, &fv);
675
 
                                if (!TIFFWriteFloatArray(tif, dir, &fv))
676
 
                                        return 0;
677
 
                        } else {
678
 
                                float* fp;
679
 
                                TIFFGetField(tif, fip->field_tag, &fp);
680
 
                                if (!TIFFWriteFloatArray(tif, dir, fp))
681
 
                                        return 0;
682
 
                        }
683
 
                }
684
 
                break;
685
 
        case TIFF_DOUBLE:
686
 
                if (fip->field_passcount) {
687
 
                        double* dp;
688
 
                        if (wc == (uint16) TIFF_VARIABLE2) {
689
 
                                TIFFGetField(tif, fip->field_tag, &wc2, &dp);
690
 
                                dir->tdir_count = wc2;
691
 
                        } else {        /* Assume TIFF_VARIABLE */
692
 
                                TIFFGetField(tif, fip->field_tag, &wc, &dp);
693
 
                                dir->tdir_count = wc;
694
 
                        }
695
 
                        if (!TIFFWriteDoubleArray(tif, dir, dp))
696
 
                                return 0;
697
 
                } else {
698
 
                        if (wc == 1) {
699
 
                                double dv;
700
 
                                TIFFGetField(tif, fip->field_tag, &dv);
701
 
                                if (!TIFFWriteDoubleArray(tif, dir, &dv))
702
 
                                        return 0;
703
 
                        } else {
704
 
                                double* dp;
705
 
                                TIFFGetField(tif, fip->field_tag, &dp);
706
 
                                if (!TIFFWriteDoubleArray(tif, dir, dp))
707
 
                                        return 0;
708
 
                        }
709
 
                }
710
 
                break;
711
 
        case TIFF_ASCII:
712
 
                { 
713
 
                    char* cp;
714
 
                    if (fip->field_passcount)
715
 
                    {
716
 
                        if( wc == (uint16) TIFF_VARIABLE2 )
717
 
                            TIFFGetField(tif, fip->field_tag, &wc2, &cp);
718
 
                        else
719
 
                            TIFFGetField(tif, fip->field_tag, &wc, &cp);
720
 
                    }
721
 
                    else
722
 
                        TIFFGetField(tif, fip->field_tag, &cp);
723
 
 
724
 
                    dir->tdir_count = (uint32) (strlen(cp) + 1);
725
 
                    if (!TIFFWriteByteArray(tif, dir, cp))
726
 
                        return (0);
727
 
                }
728
 
                break;
729
 
 
730
 
        case TIFF_BYTE:
731
 
        case TIFF_SBYTE:          
732
 
                if (fip->field_passcount) {
733
 
                        char* cp;
734
 
                        if (wc == (uint16) TIFF_VARIABLE2) {
735
 
                                TIFFGetField(tif, fip->field_tag, &wc2, &cp);
736
 
                                dir->tdir_count = wc2;
737
 
                        } else {        /* Assume TIFF_VARIABLE */
738
 
                                TIFFGetField(tif, fip->field_tag, &wc, &cp);
739
 
                                dir->tdir_count = wc;
740
 
                        }
741
 
                        if (!TIFFWriteByteArray(tif, dir, cp))
742
 
                                return 0;
743
 
                } else {
744
 
                        if (wc == 1) {
745
 
                                char cv;
746
 
                                TIFFGetField(tif, fip->field_tag, &cv);
747
 
                                if (!TIFFWriteByteArray(tif, dir, &cv))
748
 
                                        return 0;
749
 
                        } else {
750
 
                                char* cp;
751
 
                                TIFFGetField(tif, fip->field_tag, &cp);
752
 
                                if (!TIFFWriteByteArray(tif, dir, cp))
753
 
                                        return 0;
754
 
                        }
755
 
                }
756
 
                break;
757
 
 
758
 
        case TIFF_UNDEFINED:
759
 
                { char* cp;
760
 
                  if (wc == (unsigned short) TIFF_VARIABLE) {
761
 
                        TIFFGetField(tif, fip->field_tag, &wc, &cp);
762
 
                        dir->tdir_count = wc;
763
 
                  } else if (wc == (unsigned short) TIFF_VARIABLE2) {
764
 
                        TIFFGetField(tif, fip->field_tag, &wc2, &cp);
765
 
                        dir->tdir_count = wc2;
766
 
                  } else 
767
 
                        TIFFGetField(tif, fip->field_tag, &cp);
768
 
                  if (!TIFFWriteByteArray(tif, dir, cp))
769
 
                        return (0);
770
 
                }
771
 
                break;
772
 
 
773
 
        case TIFF_NOTYPE:
774
 
                break;
775
 
        }
776
 
        return (1);
777
 
}
778
 
 
779
 
/*
780
 
 * Setup a directory entry with either a SHORT
781
 
 * or LONG type according to the value.
782
 
 */
783
 
static void
784
 
TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
785
 
{
786
 
        dir->tdir_tag = (uint16) tag;
787
 
        dir->tdir_count = 1;
788
 
        if (v > 0xffffL) {
789
 
                dir->tdir_type = (short) TIFF_LONG;
790
 
                dir->tdir_offset = v;
791
 
        } else {
792
 
                dir->tdir_type = (short) TIFF_SHORT;
793
 
                dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
794
 
        }
795
 
}
796
 
 
797
 
/*
798
 
 * Setup a SHORT directory entry
799
 
 */
800
 
static void
801
 
TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
802
 
{
803
 
        dir->tdir_tag = (uint16) tag;
804
 
        dir->tdir_count = 1;
805
 
        dir->tdir_type = (short) TIFF_SHORT;
806
 
        dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
807
 
}
808
 
#undef MakeShortDirent
809
 
 
810
 
#define NITEMS(x)       (sizeof (x) / sizeof (x[0]))
811
 
/*
812
 
 * Setup a directory entry that references a
813
 
 * samples/pixel array of SHORT values and
814
 
 * (potentially) write the associated indirect
815
 
 * values.
816
 
 */
817
 
static int
818
 
TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
819
 
{
820
 
        uint16 buf[10], v;
821
 
        uint16* w = buf;
822
 
        uint16 i, samples = tif->tif_dir.td_samplesperpixel;
823
 
        int status;
824
 
 
825
 
        if (samples > NITEMS(buf)) {
826
 
                w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
827
 
                if (w == NULL) {
828
 
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
829
 
                            "No space to write per-sample shorts");
830
 
                        return (0);
831
 
                }
832
 
        }
833
 
        TIFFGetField(tif, tag, &v);
834
 
        for (i = 0; i < samples; i++)
835
 
                w[i] = v;
836
 
        
837
 
        dir->tdir_tag = (uint16) tag;
838
 
        dir->tdir_type = (uint16) TIFF_SHORT;
839
 
        dir->tdir_count = samples;
840
 
        status = TIFFWriteShortArray(tif, dir, w);
841
 
        if (w != buf)
842
 
                _TIFFfree((char*) w);
843
 
        return (status);
844
 
}
845
 
 
846
 
/*
847
 
 * Setup a directory entry that references a samples/pixel array of ``type''
848
 
 * values and (potentially) write the associated indirect values.  The source
849
 
 * data from TIFFGetField() for the specified tag must be returned as double.
850
 
 */
851
 
static int
852
 
TIFFWritePerSampleAnys(TIFF* tif,
853
 
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
854
 
{
855
 
        double buf[10], v;
856
 
        double* w = buf;
857
 
        uint16 i, samples = tif->tif_dir.td_samplesperpixel;
858
 
        int status;
859
 
 
860
 
        if (samples > NITEMS(buf)) {
861
 
                w = (double*) _TIFFmalloc(samples * sizeof (double));
862
 
                if (w == NULL) {
863
 
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
864
 
                            "No space to write per-sample values");
865
 
                        return (0);
866
 
                }
867
 
        }
868
 
        TIFFGetField(tif, tag, &v);
869
 
        for (i = 0; i < samples; i++)
870
 
                w[i] = v;
871
 
        status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
872
 
        if (w != buf)
873
 
                _TIFFfree(w);
874
 
        return (status);
875
 
}
876
 
#undef NITEMS
877
 
 
878
 
/*
879
 
 * Setup a pair of shorts that are returned by
880
 
 * value, rather than as a reference to an array.
881
 
 */
882
 
static int
883
 
TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
884
 
{
885
 
        uint16 v[2];
886
 
 
887
 
        TIFFGetField(tif, tag, &v[0], &v[1]);
888
 
 
889
 
        dir->tdir_tag = (uint16) tag;
890
 
        dir->tdir_type = (uint16) TIFF_SHORT;
891
 
        dir->tdir_count = 2;
892
 
        return (TIFFWriteShortArray(tif, dir, v));
893
 
}
894
 
 
895
 
/*
896
 
 * Setup a directory entry for an NxM table of shorts,
897
 
 * where M is known to be 2**bitspersample, and write
898
 
 * the associated indirect data.
899
 
 */
900
 
static int
901
 
TIFFWriteShortTable(TIFF* tif,
902
 
    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
903
 
{
904
 
        uint32 i, off;
905
 
 
906
 
        dir->tdir_tag = (uint16) tag;
907
 
        dir->tdir_type = (short) TIFF_SHORT;
908
 
        /* XXX -- yech, fool TIFFWriteData */
909
 
        dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
910
 
        off = tif->tif_dataoff;
911
 
        for (i = 0; i < n; i++)
912
 
                if (!TIFFWriteData(tif, dir, (char *)table[i]))
913
 
                        return (0);
914
 
        dir->tdir_count *= n;
915
 
        dir->tdir_offset = off;
916
 
        return (1);
917
 
}
918
 
 
919
 
/*
920
 
 * Write/copy data associated with an ASCII or opaque tag value.
921
 
 */
922
 
static int
923
 
TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
924
 
{
925
 
        if (dir->tdir_count <= 4) {
926
 
                if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
927
 
                        dir->tdir_offset = (uint32)cp[0] << 24;
928
 
                        if (dir->tdir_count >= 2)
929
 
                                dir->tdir_offset |= (uint32)cp[1] << 16;
930
 
                        if (dir->tdir_count >= 3)
931
 
                                dir->tdir_offset |= (uint32)cp[2] << 8;
932
 
                        if (dir->tdir_count == 4)
933
 
                                dir->tdir_offset |= cp[3];
934
 
                } else {
935
 
                        dir->tdir_offset = cp[0];
936
 
                        if (dir->tdir_count >= 2)
937
 
                                dir->tdir_offset |= (uint32) cp[1] << 8;
938
 
                        if (dir->tdir_count >= 3)
939
 
                                dir->tdir_offset |= (uint32) cp[2] << 16;
940
 
                        if (dir->tdir_count == 4)
941
 
                                dir->tdir_offset |= (uint32) cp[3] << 24;
942
 
                }
943
 
                return 1;
944
 
        } else
945
 
                return TIFFWriteData(tif, dir, cp);
946
 
}
947
 
 
948
 
/*
949
 
 * Setup a directory entry of an array of SHORT
950
 
 * or SSHORT and write the associated indirect values.
951
 
 */
952
 
static int
953
 
TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
954
 
{
955
 
        if (dir->tdir_count <= 2) {
956
 
                if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
957
 
                        dir->tdir_offset = (uint32) v[0] << 16;
958
 
                        if (dir->tdir_count == 2)
959
 
                                dir->tdir_offset |= v[1] & 0xffff;
960
 
                } else {
961
 
                        dir->tdir_offset = v[0] & 0xffff;
962
 
                        if (dir->tdir_count == 2)
963
 
                                dir->tdir_offset |= (uint32) v[1] << 16;
964
 
                }
965
 
                return (1);
966
 
        } else
967
 
                return (TIFFWriteData(tif, dir, (char*) v));
968
 
}
969
 
 
970
 
/*
971
 
 * Setup a directory entry of an array of LONG
972
 
 * or SLONG and write the associated indirect values.
973
 
 */
974
 
static int
975
 
TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
976
 
{
977
 
        if (dir->tdir_count == 1) {
978
 
                dir->tdir_offset = v[0];
979
 
                return (1);
980
 
        } else
981
 
                return (TIFFWriteData(tif, dir, (char*) v));
982
 
}
983
 
 
984
 
/*
985
 
 * Setup a directory entry of an array of RATIONAL
986
 
 * or SRATIONAL and write the associated indirect values.
987
 
 */
988
 
static int
989
 
TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
990
 
{
991
 
        uint32 i;
992
 
        uint32* t;
993
 
        int status;
994
 
 
995
 
        t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
996
 
        if (t == NULL) {
997
 
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
998
 
                    "No space to write RATIONAL array");
999
 
                return (0);
1000
 
        }
1001
 
        for (i = 0; i < dir->tdir_count; i++) {
1002
 
                float fv = v[i];
1003
 
                int sign = 1;
1004
 
                uint32 den;
1005
 
 
1006
 
                if (fv < 0) {
1007
 
                        if (dir->tdir_type == TIFF_RATIONAL) {
1008
 
                                TIFFWarningExt(tif->tif_clientdata,
1009
 
                                               tif->tif_name,
1010
 
        "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
1011
 
                                _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
1012
 
                                                fv);
1013
 
                                fv = 0;
1014
 
                        } else
1015
 
                                fv = -fv, sign = -1;
1016
 
                }
1017
 
                den = 1L;
1018
 
                if (fv > 0) {
1019
 
                        while (fv < 1L<<(31-3) && den < 1L<<(31-3))
1020
 
                                fv *= 1<<3, den *= 1L<<3;
1021
 
                }
1022
 
                t[2*i+0] = (uint32) (sign * (fv + 0.5));
1023
 
                t[2*i+1] = den;
1024
 
        }
1025
 
        status = TIFFWriteData(tif, dir, (char *)t);
1026
 
        _TIFFfree((char*) t);
1027
 
        return (status);
1028
 
}
1029
 
 
1030
 
static int
1031
 
TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
1032
 
{
1033
 
        TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
1034
 
        if (dir->tdir_count == 1) {
1035
 
                dir->tdir_offset = *(uint32*) &v[0];
1036
 
                return (1);
1037
 
        } else
1038
 
                return (TIFFWriteData(tif, dir, (char*) v));
1039
 
}
1040
 
 
1041
 
static int
1042
 
TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
1043
 
{
1044
 
        TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
1045
 
        return (TIFFWriteData(tif, dir, (char*) v));
1046
 
}
1047
 
 
1048
 
/*
1049
 
 * Write an array of ``type'' values for a specified tag (i.e. this is a tag
1050
 
 * which is allowed to have different types, e.g. SMaxSampleType).
1051
 
 * Internally the data values are represented as double since a double can
1052
 
 * hold any of the TIFF tag types (yes, this should really be an abstract
1053
 
 * type tany_t for portability).  The data is converted into the specified
1054
 
 * type in a temporary buffer and then handed off to the appropriate array
1055
 
 * writer.
1056
 
 */
1057
 
static int
1058
 
TIFFWriteAnyArray(TIFF* tif,
1059
 
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
1060
 
{
1061
 
        char buf[10 * sizeof(double)];
1062
 
        char* w = buf;
1063
 
        int i, status = 0;
1064
 
 
1065
 
        if (n * TIFFDataWidth(type) > sizeof buf) {
1066
 
                w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
1067
 
                if (w == NULL) {
1068
 
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1069
 
                                     "No space to write array");
1070
 
                        return (0);
1071
 
                }
1072
 
        }
1073
 
 
1074
 
        dir->tdir_tag = (uint16) tag;
1075
 
        dir->tdir_type = (uint16) type;
1076
 
        dir->tdir_count = n;
1077
 
 
1078
 
        switch (type) {
1079
 
        case TIFF_BYTE:
1080
 
                { 
1081
 
                        uint8* bp = (uint8*) w;
1082
 
                        for (i = 0; i < (int) n; i++)
1083
 
                                bp[i] = (uint8) v[i];
1084
 
                        if (!TIFFWriteByteArray(tif, dir, (char*) bp))
1085
 
                                goto out;
1086
 
                }
1087
 
                break;
1088
 
        case TIFF_SBYTE:
1089
 
                { 
1090
 
                        int8* bp = (int8*) w;
1091
 
                        for (i = 0; i < (int) n; i++)
1092
 
                                bp[i] = (int8) v[i];
1093
 
                        if (!TIFFWriteByteArray(tif, dir, (char*) bp))
1094
 
                                goto out;
1095
 
                }
1096
 
                break;
1097
 
        case TIFF_SHORT:
1098
 
                {
1099
 
                        uint16* bp = (uint16*) w;
1100
 
                        for (i = 0; i < (int) n; i++)
1101
 
                                bp[i] = (uint16) v[i];
1102
 
                        if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
1103
 
                                goto out;
1104
 
                }
1105
 
                break;
1106
 
        case TIFF_SSHORT:
1107
 
                { 
1108
 
                        int16* bp = (int16*) w;
1109
 
                        for (i = 0; i < (int) n; i++)
1110
 
                                bp[i] = (int16) v[i];
1111
 
                        if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
1112
 
                                goto out;
1113
 
                }
1114
 
                break;
1115
 
        case TIFF_LONG:
1116
 
                {
1117
 
                        uint32* bp = (uint32*) w;
1118
 
                        for (i = 0; i < (int) n; i++)
1119
 
                                bp[i] = (uint32) v[i];
1120
 
                        if (!TIFFWriteLongArray(tif, dir, bp))
1121
 
                                goto out;
1122
 
                }
1123
 
                break;
1124
 
        case TIFF_SLONG:
1125
 
                {
1126
 
                        int32* bp = (int32*) w;
1127
 
                        for (i = 0; i < (int) n; i++)
1128
 
                                bp[i] = (int32) v[i];
1129
 
                        if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
1130
 
                                goto out;
1131
 
                }
1132
 
                break;
1133
 
        case TIFF_FLOAT:
1134
 
                { 
1135
 
                        float* bp = (float*) w;
1136
 
                        for (i = 0; i < (int) n; i++)
1137
 
                                bp[i] = (float) v[i];
1138
 
                        if (!TIFFWriteFloatArray(tif, dir, bp))
1139
 
                                goto out;
1140
 
                }
1141
 
                break;
1142
 
        case TIFF_DOUBLE:
1143
 
                return (TIFFWriteDoubleArray(tif, dir, v));
1144
 
        default:
1145
 
                /* TIFF_NOTYPE */
1146
 
                /* TIFF_ASCII */
1147
 
                /* TIFF_UNDEFINED */
1148
 
                /* TIFF_RATIONAL */
1149
 
                /* TIFF_SRATIONAL */
1150
 
                goto out;
1151
 
        }
1152
 
        status = 1;
1153
 
 out:
1154
 
        if (w != buf)
1155
 
                _TIFFfree(w);
1156
 
        return (status);
1157
 
}
1158
 
 
1159
 
static int
1160
 
TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1161
 
{
1162
 
        TIFFDirectory* td = &tif->tif_dir;
1163
 
        tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1164
 
        uint16** tf = td->td_transferfunction;
1165
 
        int ncols;
1166
 
 
1167
 
        /*
1168
 
         * Check if the table can be written as a single column,
1169
 
         * or if it must be written as 3 columns.  Note that we
1170
 
         * write a 3-column tag if there are 2 samples/pixel and
1171
 
         * a single column of data won't suffice--hmm.
1172
 
         */
1173
 
        switch (td->td_samplesperpixel - td->td_extrasamples) {
1174
 
        default:        if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
1175
 
        case 2:         if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
1176
 
        case 1: case 0: ncols = 1;
1177
 
        }
1178
 
        return (TIFFWriteShortTable(tif,
1179
 
            TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1180
 
}
1181
 
 
1182
 
static int
1183
 
TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1184
 
{
1185
 
        TIFFDirectory* td = &tif->tif_dir;
1186
 
 
1187
 
        dir->tdir_tag = TIFFTAG_INKNAMES;
1188
 
        dir->tdir_type = (short) TIFF_ASCII;
1189
 
        dir->tdir_count = td->td_inknameslen;
1190
 
        return (TIFFWriteByteArray(tif, dir, td->td_inknames));
1191
 
}
1192
 
 
1193
 
/*
1194
 
 * Write a contiguous directory item.
1195
 
 */
1196
 
static int
1197
 
TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1198
 
{
1199
 
        tsize_t cc;
1200
 
 
1201
 
        if (tif->tif_flags & TIFF_SWAB) {
1202
 
                switch (dir->tdir_type) {
1203
 
                case TIFF_SHORT:
1204
 
                case TIFF_SSHORT:
1205
 
                        TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1206
 
                        break;
1207
 
                case TIFF_LONG:
1208
 
                case TIFF_SLONG:
1209
 
                case TIFF_FLOAT:
1210
 
                        TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1211
 
                        break;
1212
 
                case TIFF_RATIONAL:
1213
 
                case TIFF_SRATIONAL:
1214
 
                        TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1215
 
                        break;
1216
 
                case TIFF_DOUBLE:
1217
 
                        TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1218
 
                        break;
1219
 
                }
1220
 
        }
1221
 
        dir->tdir_offset = tif->tif_dataoff;
1222
 
        cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
1223
 
        if (SeekOK(tif, dir->tdir_offset) &&
1224
 
            WriteOK(tif, cp, cc)) {
1225
 
                tif->tif_dataoff += (cc + 1) & ~1;
1226
 
                return (1);
1227
 
        }
1228
 
        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1229
 
                     "Error writing data for field \"%s\"",
1230
 
        _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1231
 
        return (0);
1232
 
}
1233
 
 
1234
 
/*
1235
 
 * Similar to TIFFWriteDirectory(), but if the directory has already
1236
 
 * been written once, it is relocated to the end of the file, in case it
1237
 
 * has changed in size.  Note that this will result in the loss of the 
1238
 
 * previously used directory space. 
1239
 
 */ 
1240
 
 
1241
 
int 
1242
 
TIFFRewriteDirectory( TIFF *tif )
1243
 
{
1244
 
    static const char module[] = "TIFFRewriteDirectory";
1245
 
 
1246
 
    /* We don't need to do anything special if it hasn't been written. */
1247
 
    if( tif->tif_diroff == 0 )
1248
 
        return TIFFWriteDirectory( tif );
1249
 
 
1250
 
    /*
1251
 
    ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
1252
 
    ** will cause it to be added after this directories current pre-link.
1253
 
    */
1254
 
    
1255
 
    /* Is it the first directory in the file? */
1256
 
    if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
1257
 
    {
1258
 
        tif->tif_header.tiff_diroff = 0;
1259
 
        tif->tif_diroff = 0;
1260
 
 
1261
 
        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1262
 
                     SEEK_SET);
1263
 
        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
1264
 
                     sizeof (tif->tif_diroff))) 
1265
 
        {
1266
 
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1267
 
                                     "Error updating TIFF header");
1268
 
            return (0);
1269
 
        }
1270
 
    }
1271
 
    else
1272
 
    {
1273
 
        toff_t  nextdir, off;
1274
 
 
1275
 
        nextdir = tif->tif_header.tiff_diroff;
1276
 
        do {
1277
 
                uint16 dircount;
1278
 
 
1279
 
                if (!SeekOK(tif, nextdir) ||
1280
 
                    !ReadOK(tif, &dircount, sizeof (dircount))) {
1281
 
                        TIFFErrorExt(tif->tif_clientdata, module,
1282
 
                                     "Error fetching directory count");
1283
 
                        return (0);
1284
 
                }
1285
 
                if (tif->tif_flags & TIFF_SWAB)
1286
 
                        TIFFSwabShort(&dircount);
1287
 
                (void) TIFFSeekFile(tif,
1288
 
                    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1289
 
                if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1290
 
                        TIFFErrorExt(tif->tif_clientdata, module,
1291
 
                                     "Error fetching directory link");
1292
 
                        return (0);
1293
 
                }
1294
 
                if (tif->tif_flags & TIFF_SWAB)
1295
 
                        TIFFSwabLong(&nextdir);
1296
 
        } while (nextdir != tif->tif_diroff && nextdir != 0);
1297
 
        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1298
 
        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1299
 
        tif->tif_diroff = 0;
1300
 
        if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
1301
 
                TIFFErrorExt(tif->tif_clientdata, module,
1302
 
                             "Error writing directory link");
1303
 
                return (0);
1304
 
        }
1305
 
    }
1306
 
 
1307
 
    /*
1308
 
    ** Now use TIFFWriteDirectory() normally.
1309
 
    */
1310
 
 
1311
 
    return TIFFWriteDirectory( tif );
1312
 
}
1313
 
 
1314
 
 
1315
 
/*
1316
 
 * Link the current directory into the directory chain for the file.
1317
 
 */
1318
 
static int
1319
 
TIFFLinkDirectory(TIFF* tif)
1320
 
{
1321
 
        static const char module[] = "TIFFLinkDirectory";
1322
 
        toff_t nextdir;
1323
 
        toff_t diroff, off;
1324
 
 
1325
 
        tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
1326
 
        diroff = tif->tif_diroff;
1327
 
        if (tif->tif_flags & TIFF_SWAB)
1328
 
                TIFFSwabLong(&diroff);
1329
 
 
1330
 
        /*
1331
 
         * Handle SubIFDs
1332
 
         */
1333
 
        if (tif->tif_flags & TIFF_INSUBIFD) {
1334
 
                (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
1335
 
                if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1336
 
                        TIFFErrorExt(tif->tif_clientdata, module,
1337
 
                                     "%s: Error writing SubIFD directory link",
1338
 
                                     tif->tif_name);
1339
 
                        return (0);
1340
 
                }
1341
 
                /*
1342
 
                 * Advance to the next SubIFD or, if this is
1343
 
                 * the last one configured, revert back to the
1344
 
                 * normal directory linkage.
1345
 
                 */
1346
 
                if (--tif->tif_nsubifd)
1347
 
                        tif->tif_subifdoff += sizeof (diroff);
1348
 
                else
1349
 
                        tif->tif_flags &= ~TIFF_INSUBIFD;
1350
 
                return (1);
1351
 
        }
1352
 
 
1353
 
        if (tif->tif_header.tiff_diroff == 0) {
1354
 
                /*
1355
 
                 * First directory, overwrite offset in header.
1356
 
                 */
1357
 
                tif->tif_header.tiff_diroff = tif->tif_diroff;
1358
 
                (void) TIFFSeekFile(tif,
1359
 
                                    (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1360
 
                                    SEEK_SET);
1361
 
                if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1362
 
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1363
 
                                     "Error writing TIFF header");
1364
 
                        return (0);
1365
 
                }
1366
 
                return (1);
1367
 
        }
1368
 
        /*
1369
 
         * Not the first directory, search to the last and append.
1370
 
         */
1371
 
        nextdir = tif->tif_header.tiff_diroff;
1372
 
        do {
1373
 
                uint16 dircount;
1374
 
 
1375
 
                if (!SeekOK(tif, nextdir) ||
1376
 
                    !ReadOK(tif, &dircount, sizeof (dircount))) {
1377
 
                        TIFFErrorExt(tif->tif_clientdata, module,
1378
 
                                     "Error fetching directory count");
1379
 
                        return (0);
1380
 
                }
1381
 
                if (tif->tif_flags & TIFF_SWAB)
1382
 
                        TIFFSwabShort(&dircount);
1383
 
                (void) TIFFSeekFile(tif,
1384
 
                    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1385
 
                if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1386
 
                        TIFFErrorExt(tif->tif_clientdata, module,
1387
 
                                     "Error fetching directory link");
1388
 
                        return (0);
1389
 
                }
1390
 
                if (tif->tif_flags & TIFF_SWAB)
1391
 
                        TIFFSwabLong(&nextdir);
1392
 
        } while (nextdir != 0);
1393
 
        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1394
 
        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1395
 
        if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1396
 
                TIFFErrorExt(tif->tif_clientdata, module,
1397
 
                             "Error writing directory link");
1398
 
                return (0);
1399
 
        }
1400
 
        return (1);
1401
 
}
1402
 
 
1403
 
/* vim: set ts=8 sts=8 sw=8 noet: */
 
1
/* $Id: tif_dirwrite.c,v 1.37.2.7 2010-06-08 18:50:42 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 Write Support Routines.
 
31
 */
 
32
#include "tiffiop.h"
 
33
 
 
34
#ifdef HAVE_IEEEFP
 
35
# define        TIFFCvtNativeToIEEEFloat(tif, n, fp)
 
36
# define        TIFFCvtNativeToIEEEDouble(tif, n, dp)
 
37
#else
 
38
extern  void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
 
39
extern  void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
 
40
#endif
 
41
 
 
42
static  int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
 
43
static  void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
 
44
static  void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
 
45
static  int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
 
46
static  int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
 
47
static  int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
 
48
static  int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
 
49
static  int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
 
50
static  int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
 
51
static  int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
 
52
static  int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
 
53
static  int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
 
54
static  int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
 
55
static  int TIFFWriteAnyArray(TIFF*,
 
56
            TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
 
57
static  int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
 
58
static  int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
 
59
static  int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
 
60
static  int TIFFLinkDirectory(TIFF*);
 
61
 
 
62
#define WriteRationalPair(type, tag1, v1, tag2, v2) {           \
 
63
        TIFFWriteRational((tif), (type), (tag1), (dir), (v1))   \
 
64
        TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \
 
65
        (dir)++;                                                \
 
66
}
 
67
#define TIFFWriteRational(tif, type, tag, dir, v)               \
 
68
        (dir)->tdir_tag = (tag);                                \
 
69
        (dir)->tdir_type = (type);                              \
 
70
        (dir)->tdir_count = 1;                                  \
 
71
        if (!TIFFWriteRationalArray((tif), (dir), &(v)))        \
 
72
                goto bad;
 
73
 
 
74
/*
 
75
 * Write the contents of the current directory
 
76
 * to the specified file.  This routine doesn't
 
77
 * handle overwriting a directory with auxiliary
 
78
 * storage that's been changed.
 
79
 */
 
80
static int
 
81
_TIFFWriteDirectory(TIFF* tif, int done)
 
82
{
 
83
        uint16 dircount;
 
84
        toff_t diroff;
 
85
        ttag_t tag;
 
86
        uint32 nfields;
 
87
        tsize_t dirsize;
 
88
        char* data;
 
89
        TIFFDirEntry* dir;
 
90
        TIFFDirectory* td;
 
91
        unsigned long b, fields[FIELD_SETLONGS];
 
92
        int fi, nfi;
 
93
 
 
94
        if (tif->tif_mode == O_RDONLY)
 
95
                return (1);
 
96
        /*
 
97
         * Clear write state so that subsequent images with
 
98
         * different characteristics get the right buffers
 
99
         * setup for them.
 
100
         */
 
101
        if (done)
 
102
        {
 
103
                if (tif->tif_flags & TIFF_POSTENCODE) {
 
104
                        tif->tif_flags &= ~TIFF_POSTENCODE;
 
105
                        if (!(*tif->tif_postencode)(tif)) {
 
106
                                TIFFErrorExt(tif->tif_clientdata,
 
107
                                             tif->tif_name,
 
108
                                "Error post-encoding before directory write");
 
109
                                return (0);
 
110
                        }
 
111
                }
 
112
                (*tif->tif_close)(tif);         /* shutdown encoder */
 
113
                /*
 
114
                 * Flush any data that might have been written
 
115
                 * by the compression close+cleanup routines.
 
116
                 */
 
117
                if (tif->tif_rawcc > 0
 
118
                    && (tif->tif_flags & TIFF_BEENWRITING) != 0
 
119
                    && !TIFFFlushData1(tif)) {
 
120
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
121
                            "Error flushing data before directory write");
 
122
                        return (0);
 
123
                }
 
124
                if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
 
125
                        _TIFFfree(tif->tif_rawdata);
 
126
                        tif->tif_rawdata = NULL;
 
127
                        tif->tif_rawcc = 0;
 
128
                        tif->tif_rawdatasize = 0;
 
129
                }
 
130
                tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
 
131
        }
 
132
 
 
133
        td = &tif->tif_dir;
 
134
        /*
 
135
         * Size the directory so that we can calculate
 
136
         * offsets for the data items that aren't kept
 
137
         * in-place in each field.
 
138
         */
 
139
        nfields = 0;
 
140
        for (b = 0; b <= FIELD_LAST; b++)
 
141
                if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
 
142
                        nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
 
143
        nfields += td->td_customValueCount;
 
144
        dirsize = nfields * sizeof (TIFFDirEntry);
 
145
        data = (char*) _TIFFmalloc(dirsize);
 
146
        if (data == NULL) {
 
147
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
148
                             "Cannot write directory, out of space");
 
149
                return (0);
 
150
        }
 
151
        /*
 
152
         * Directory hasn't been placed yet, put
 
153
         * it at the end of the file and link it
 
154
         * into the existing directory structure.
 
155
         */
 
156
        if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
 
157
                goto bad;
 
158
        tif->tif_dataoff = (toff_t)(
 
159
            tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
 
160
        if (tif->tif_dataoff & 1)
 
161
                tif->tif_dataoff++;
 
162
        (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
 
163
        tif->tif_curdir++;
 
164
        dir = (TIFFDirEntry*) data;
 
165
        /*
 
166
         * Setup external form of directory
 
167
         * entries and write data items.
 
168
         */
 
169
        _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
 
170
        /*
 
171
         * Write out ExtraSamples tag only if
 
172
         * extra samples are present in the data.
 
173
         */
 
174
        if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
 
175
                ResetFieldBit(fields, FIELD_EXTRASAMPLES);
 
176
                nfields--;
 
177
                dirsize -= sizeof (TIFFDirEntry);
 
178
        }                                                               /*XXX*/
 
179
        for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
 
180
                const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
 
181
 
 
182
                /*
 
183
                 * For custom fields, we test to see if the custom field
 
184
                 * is set or not.  For normal fields, we just use the
 
185
                 * FieldSet test.
 
186
                */
 
187
                if( fip->field_bit == FIELD_CUSTOM )
 
188
                {
 
189
                        int ci, is_set = FALSE;
 
190
 
 
191
                        for( ci = 0; ci < td->td_customValueCount; ci++ )
 
192
                                is_set |= (td->td_customValues[ci].info == fip);
 
193
 
 
194
                        if( !is_set )
 
195
                                continue;
 
196
                }
 
197
                else if (!FieldSet(fields, fip->field_bit))
 
198
                        continue;
 
199
 
 
200
                /*
 
201
                 * Handle other fields.
 
202
                 */
 
203
                switch (fip->field_bit)
 
204
                {
 
205
                case FIELD_STRIPOFFSETS:
 
206
                        /*
 
207
                         * We use one field bit for both strip and tile
 
208
 
 
209
                         * offsets, and so must be careful in selecting
 
210
                         * the appropriate field descriptor (so that tags
 
211
                         * are written in sorted order).
 
212
                         */
 
213
                        tag = isTiled(tif) ?
 
214
                            TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
 
215
                        if (tag != fip->field_tag)
 
216
                                continue;
 
217
                        
 
218
                        dir->tdir_tag = (uint16) tag;
 
219
                        dir->tdir_type = (uint16) TIFF_LONG;
 
220
                        dir->tdir_count = (uint32) td->td_nstrips;
 
221
                        if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
 
222
                                goto bad;
 
223
                        break;
 
224
                case FIELD_STRIPBYTECOUNTS:
 
225
                        /*
 
226
                         * We use one field bit for both strip and tile
 
227
                         * byte counts, and so must be careful in selecting
 
228
                         * the appropriate field descriptor (so that tags
 
229
                         * are written in sorted order).
 
230
                         */
 
231
                        tag = isTiled(tif) ?
 
232
                            TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
 
233
                        if (tag != fip->field_tag)
 
234
                                continue;
 
235
                        
 
236
                        dir->tdir_tag = (uint16) tag;
 
237
                        dir->tdir_type = (uint16) TIFF_LONG;
 
238
                        dir->tdir_count = (uint32) td->td_nstrips;
 
239
                        if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount))
 
240
                                goto bad;
 
241
                        break;
 
242
                case FIELD_ROWSPERSTRIP:
 
243
                        TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
 
244
                            dir, td->td_rowsperstrip);
 
245
                        break;
 
246
                case FIELD_COLORMAP:
 
247
                        if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
 
248
                            3, td->td_colormap))
 
249
                                goto bad;
 
250
                        break;
 
251
                case FIELD_IMAGEDIMENSIONS:
 
252
                        TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
 
253
                            dir++, td->td_imagewidth);
 
254
                        TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
 
255
                            dir, td->td_imagelength);
 
256
                        break;
 
257
                case FIELD_TILEDIMENSIONS:
 
258
                        TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
 
259
                            dir++, td->td_tilewidth);
 
260
                        TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
 
261
                            dir, td->td_tilelength);
 
262
                        break;
 
263
                case FIELD_COMPRESSION:
 
264
                        TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
 
265
                            dir, td->td_compression);
 
266
                        break;
 
267
                case FIELD_PHOTOMETRIC:
 
268
                        TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
 
269
                            dir, td->td_photometric);
 
270
                        break;
 
271
                case FIELD_POSITION:
 
272
                        WriteRationalPair(TIFF_RATIONAL,
 
273
                            TIFFTAG_XPOSITION, td->td_xposition,
 
274
                            TIFFTAG_YPOSITION, td->td_yposition);
 
275
                        break;
 
276
                case FIELD_RESOLUTION:
 
277
                        WriteRationalPair(TIFF_RATIONAL,
 
278
                            TIFFTAG_XRESOLUTION, td->td_xresolution,
 
279
                            TIFFTAG_YRESOLUTION, td->td_yresolution);
 
280
                        break;
 
281
                case FIELD_BITSPERSAMPLE:
 
282
                case FIELD_MINSAMPLEVALUE:
 
283
                case FIELD_MAXSAMPLEVALUE:
 
284
                case FIELD_SAMPLEFORMAT:
 
285
                        if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
 
286
                                goto bad;
 
287
                        break;
 
288
                case FIELD_SMINSAMPLEVALUE:
 
289
                case FIELD_SMAXSAMPLEVALUE:
 
290
                        if (!TIFFWritePerSampleAnys(tif,
 
291
                            _TIFFSampleToTagType(tif), fip->field_tag, dir))
 
292
                                goto bad;
 
293
                        break;
 
294
                case FIELD_PAGENUMBER:
 
295
                case FIELD_HALFTONEHINTS:
 
296
                case FIELD_YCBCRSUBSAMPLING:
 
297
                        if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
 
298
                                goto bad;
 
299
                        break;
 
300
                case FIELD_INKNAMES:
 
301
                        if (!TIFFWriteInkNames(tif, dir))
 
302
                                goto bad;
 
303
                        break;
 
304
                case FIELD_TRANSFERFUNCTION:
 
305
                        if (!TIFFWriteTransferFunction(tif, dir))
 
306
                                goto bad;
 
307
                        break;
 
308
                case FIELD_SUBIFD:
 
309
                        /*
 
310
                         * XXX: Always write this field using LONG type
 
311
                         * for backward compatibility.
 
312
                         */
 
313
                        dir->tdir_tag = (uint16) fip->field_tag;
 
314
                        dir->tdir_type = (uint16) TIFF_LONG;
 
315
                        dir->tdir_count = (uint32) td->td_nsubifd;
 
316
                        if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
 
317
                                goto bad;
 
318
                        /*
 
319
                         * Total hack: if this directory includes a SubIFD
 
320
                         * tag then force the next <n> directories to be
 
321
                         * written as ``sub directories'' of this one.  This
 
322
                         * is used to write things like thumbnails and
 
323
                         * image masks that one wants to keep out of the
 
324
                         * normal directory linkage access mechanism.
 
325
                         */
 
326
                        if (dir->tdir_count > 0) {
 
327
                                tif->tif_flags |= TIFF_INSUBIFD;
 
328
                                tif->tif_nsubifd = (uint16) dir->tdir_count;
 
329
                                if (dir->tdir_count > 1)
 
330
                                        tif->tif_subifdoff = dir->tdir_offset;
 
331
                                else
 
332
                                        tif->tif_subifdoff = (uint32)(
 
333
                                              tif->tif_diroff
 
334
                                            + sizeof (uint16)
 
335
                                            + ((char*)&dir->tdir_offset-data));
 
336
                        }
 
337
                        break;
 
338
                default:
 
339
                        /* XXX: Should be fixed and removed. */
 
340
                        if (fip->field_tag == TIFFTAG_DOTRANGE) {
 
341
                                if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
 
342
                                        goto bad;
 
343
                        }
 
344
                        else if (!TIFFWriteNormalTag(tif, dir, fip))
 
345
                                goto bad;
 
346
                        break;
 
347
                }
 
348
                dir++;
 
349
                
 
350
                if( fip->field_bit != FIELD_CUSTOM )
 
351
                        ResetFieldBit(fields, fip->field_bit);
 
352
        }
 
353
 
 
354
        /*
 
355
         * Write directory.
 
356
         */
 
357
        dircount = (uint16) nfields;
 
358
        diroff = (uint32) tif->tif_nextdiroff;
 
359
        if (tif->tif_flags & TIFF_SWAB) {
 
360
                /*
 
361
                 * The file's byte order is opposite to the
 
362
                 * native machine architecture.  We overwrite
 
363
                 * the directory information with impunity
 
364
                 * because it'll be released below after we
 
365
                 * write it to the file.  Note that all the
 
366
                 * other tag construction routines assume that
 
367
                 * we do this byte-swapping; i.e. they only
 
368
                 * byte-swap indirect data.
 
369
                 */
 
370
                for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
 
371
                        TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
 
372
                        TIFFSwabArrayOfLong(&dir->tdir_count, 2);
 
373
                }
 
374
                dircount = (uint16) nfields;
 
375
                TIFFSwabShort(&dircount);
 
376
                TIFFSwabLong(&diroff);
 
377
        }
 
378
        (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
 
379
        if (!WriteOK(tif, &dircount, sizeof (dircount))) {
 
380
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
381
                             "Error writing directory count");
 
382
                goto bad;
 
383
        }
 
384
        if (!WriteOK(tif, data, dirsize)) {
 
385
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
386
                             "Error writing directory contents");
 
387
                goto bad;
 
388
        }
 
389
        if (!WriteOK(tif, &diroff, sizeof (uint32))) {
 
390
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
391
                             "Error writing directory link");
 
392
                goto bad;
 
393
        }
 
394
        if (done) {
 
395
                TIFFFreeDirectory(tif);
 
396
                tif->tif_flags &= ~TIFF_DIRTYDIRECT;
 
397
                (*tif->tif_cleanup)(tif);
 
398
 
 
399
                /*
 
400
                * Reset directory-related state for subsequent
 
401
                * directories.
 
402
                */
 
403
                TIFFCreateDirectory(tif);
 
404
        }
 
405
        _TIFFfree(data);
 
406
        return (1);
 
407
bad:
 
408
        _TIFFfree(data);
 
409
        return (0);
 
410
}
 
411
#undef WriteRationalPair
 
412
 
 
413
int
 
414
TIFFWriteDirectory(TIFF* tif)
 
415
{
 
416
        return _TIFFWriteDirectory(tif, TRUE);
 
417
}
 
418
 
 
419
/*
 
420
 * Similar to TIFFWriteDirectory(), writes the directory out
 
421
 * but leaves all data structures in memory so that it can be
 
422
 * written again.  This will make a partially written TIFF file
 
423
 * readable before it is successfully completed/closed.
 
424
 */ 
 
425
int
 
426
TIFFCheckpointDirectory(TIFF* tif)
 
427
{
 
428
        int rc;
 
429
        /* Setup the strips arrays, if they haven't already been. */
 
430
        if (tif->tif_dir.td_stripoffset == NULL)
 
431
            (void) TIFFSetupStrips(tif);
 
432
        rc = _TIFFWriteDirectory(tif, FALSE);
 
433
        (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
 
434
        return rc;
 
435
}
 
436
 
 
437
static int
 
438
_TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
 
439
{
 
440
        uint16 dircount;
 
441
        uint32 nfields;
 
442
        tsize_t dirsize;
 
443
        char* data;
 
444
        TIFFDirEntry* dir;
 
445
        TIFFDirectory* td;
 
446
        unsigned long b, fields[FIELD_SETLONGS];
 
447
        int fi, nfi;
 
448
 
 
449
        if (tif->tif_mode == O_RDONLY)
 
450
                return (1);
 
451
 
 
452
        td = &tif->tif_dir;
 
453
        /*
 
454
         * Size the directory so that we can calculate
 
455
         * offsets for the data items that aren't kept
 
456
         * in-place in each field.
 
457
         */
 
458
        nfields = 0;
 
459
        for (b = 0; b <= FIELD_LAST; b++)
 
460
                if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
 
461
                        nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
 
462
        nfields += td->td_customValueCount;
 
463
        dirsize = nfields * sizeof (TIFFDirEntry);
 
464
        data = (char*) _TIFFmalloc(dirsize);
 
465
        if (data == NULL) {
 
466
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
467
                             "Cannot write directory, out of space");
 
468
                return (0);
 
469
        }
 
470
        /*
 
471
         * Put the directory  at the end of the file.
 
472
         */
 
473
        tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
 
474
        tif->tif_dataoff = (toff_t)(
 
475
            tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
 
476
        if (tif->tif_dataoff & 1)
 
477
                tif->tif_dataoff++;
 
478
        (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
 
479
        dir = (TIFFDirEntry*) data;
 
480
        /*
 
481
         * Setup external form of directory
 
482
         * entries and write data items.
 
483
         */
 
484
        _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
 
485
 
 
486
        for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
 
487
                const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
 
488
 
 
489
                /*
 
490
                 * For custom fields, we test to see if the custom field
 
491
                 * is set or not.  For normal fields, we just use the
 
492
                 * FieldSet test.
 
493
                */
 
494
                if( fip->field_bit == FIELD_CUSTOM )
 
495
                {
 
496
                        int ci, is_set = FALSE;
 
497
 
 
498
                        for( ci = 0; ci < td->td_customValueCount; ci++ )
 
499
                                is_set |= (td->td_customValues[ci].info == fip);
 
500
 
 
501
                        if( !is_set )
 
502
                                continue;
 
503
                }
 
504
                else if (!FieldSet(fields, fip->field_bit))
 
505
                        continue;
 
506
                
 
507
                if( fip->field_bit != FIELD_CUSTOM )
 
508
                        ResetFieldBit(fields, fip->field_bit);
 
509
        }
 
510
 
 
511
        /*
 
512
         * Write directory.
 
513
         */
 
514
        dircount = (uint16) nfields;
 
515
        *pdiroff = (uint32) tif->tif_nextdiroff;
 
516
        if (tif->tif_flags & TIFF_SWAB) {
 
517
                /*
 
518
                 * The file's byte order is opposite to the
 
519
                 * native machine architecture.  We overwrite
 
520
                 * the directory information with impunity
 
521
                 * because it'll be released below after we
 
522
                 * write it to the file.  Note that all the
 
523
                 * other tag construction routines assume that
 
524
                 * we do this byte-swapping; i.e. they only
 
525
                 * byte-swap indirect data.
 
526
                 */
 
527
                for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
 
528
                        TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
 
529
                        TIFFSwabArrayOfLong(&dir->tdir_count, 2);
 
530
                }
 
531
                dircount = (uint16) nfields;
 
532
                TIFFSwabShort(&dircount);
 
533
                TIFFSwabLong(pdiroff);
 
534
        }
 
535
        (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
 
536
        if (!WriteOK(tif, &dircount, sizeof (dircount))) {
 
537
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
538
                             "Error writing directory count");
 
539
                goto bad;
 
540
        }
 
541
        if (!WriteOK(tif, data, dirsize)) {
 
542
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
543
                             "Error writing directory contents");
 
544
                goto bad;
 
545
        }
 
546
        if (!WriteOK(tif, pdiroff, sizeof (uint32))) {
 
547
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
548
                             "Error writing directory link");
 
549
                goto bad;
 
550
        }
 
551
        _TIFFfree(data);
 
552
        return (1);
 
553
bad:
 
554
        _TIFFfree(data);
 
555
        return (0);
 
556
}
 
557
 
 
558
int
 
559
TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
 
560
{
 
561
        return _TIFFWriteCustomDirectory(tif, pdiroff);
 
562
}
 
563
 
 
564
/*
 
565
 * Process tags that are not special cased.
 
566
 */
 
567
static int
 
568
TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
 
569
{
 
570
        uint16 wc = (uint16) fip->field_writecount;
 
571
        uint32 wc2;
 
572
 
 
573
        dir->tdir_tag = (uint16) fip->field_tag;
 
574
        dir->tdir_type = (uint16) fip->field_type;
 
575
        dir->tdir_count = wc;
 
576
        
 
577
        switch (fip->field_type) {
 
578
        case TIFF_SHORT:
 
579
        case TIFF_SSHORT:
 
580
                if (fip->field_passcount) {
 
581
                        uint16* wp;
 
582
                        if (wc == (uint16) TIFF_VARIABLE2) {
 
583
                                TIFFGetField(tif, fip->field_tag, &wc2, &wp);
 
584
                                dir->tdir_count = wc2;
 
585
                        } else {        /* Assume TIFF_VARIABLE */
 
586
                                TIFFGetField(tif, fip->field_tag, &wc, &wp);
 
587
                                dir->tdir_count = wc;
 
588
                        }
 
589
                        if (!TIFFWriteShortArray(tif, dir, wp))
 
590
                                return 0;
 
591
                } else {
 
592
                        if (wc == 1) {
 
593
                                uint16 sv;
 
594
                                TIFFGetField(tif, fip->field_tag, &sv);
 
595
                                dir->tdir_offset =
 
596
                                        TIFFInsertData(tif, dir->tdir_type, sv);
 
597
                        } else {
 
598
                                uint16* wp;
 
599
                                TIFFGetField(tif, fip->field_tag, &wp);
 
600
                                if (!TIFFWriteShortArray(tif, dir, wp))
 
601
                                        return 0;
 
602
                        }
 
603
                }
 
604
                break;
 
605
        case TIFF_LONG:
 
606
        case TIFF_SLONG:
 
607
        case TIFF_IFD:
 
608
                if (fip->field_passcount) {
 
609
                        uint32* lp;
 
610
                        if (wc == (uint16) TIFF_VARIABLE2) {
 
611
                                TIFFGetField(tif, fip->field_tag, &wc2, &lp);
 
612
                                dir->tdir_count = wc2;
 
613
                        } else {        /* Assume TIFF_VARIABLE */
 
614
                                TIFFGetField(tif, fip->field_tag, &wc, &lp);
 
615
                                dir->tdir_count = wc;
 
616
                        }
 
617
                        if (!TIFFWriteLongArray(tif, dir, lp))
 
618
                                return 0;
 
619
                } else {
 
620
                        if (wc == 1) {
 
621
                                /* XXX handle LONG->SHORT conversion */
 
622
                                TIFFGetField(tif, fip->field_tag,
 
623
                                             &dir->tdir_offset);
 
624
                        } else {
 
625
                                uint32* lp;
 
626
                                TIFFGetField(tif, fip->field_tag, &lp);
 
627
                                if (!TIFFWriteLongArray(tif, dir, lp))
 
628
                                        return 0;
 
629
                        }
 
630
                }
 
631
                break;
 
632
        case TIFF_RATIONAL:
 
633
        case TIFF_SRATIONAL:
 
634
                if (fip->field_passcount) {
 
635
                        float* fp;
 
636
                        if (wc == (uint16) TIFF_VARIABLE2) {
 
637
                                TIFFGetField(tif, fip->field_tag, &wc2, &fp);
 
638
                                dir->tdir_count = wc2;
 
639
                        } else {        /* Assume TIFF_VARIABLE */
 
640
                                TIFFGetField(tif, fip->field_tag, &wc, &fp);
 
641
                                dir->tdir_count = wc;
 
642
                        }
 
643
                        if (!TIFFWriteRationalArray(tif, dir, fp))
 
644
                                return 0;
 
645
                } else {
 
646
                        if (wc == 1) {
 
647
                                float fv;
 
648
                                TIFFGetField(tif, fip->field_tag, &fv);
 
649
                                if (!TIFFWriteRationalArray(tif, dir, &fv))
 
650
                                        return 0;
 
651
                        } else {
 
652
                                float* fp;
 
653
                                TIFFGetField(tif, fip->field_tag, &fp);
 
654
                                if (!TIFFWriteRationalArray(tif, dir, fp))
 
655
                                        return 0;
 
656
                        }
 
657
                }
 
658
                break;
 
659
        case TIFF_FLOAT:
 
660
                if (fip->field_passcount) {
 
661
                        float* fp;
 
662
                        if (wc == (uint16) TIFF_VARIABLE2) {
 
663
                                TIFFGetField(tif, fip->field_tag, &wc2, &fp);
 
664
                                dir->tdir_count = wc2;
 
665
                        } else {        /* Assume TIFF_VARIABLE */
 
666
                                TIFFGetField(tif, fip->field_tag, &wc, &fp);
 
667
                                dir->tdir_count = wc;
 
668
                        }
 
669
                        if (!TIFFWriteFloatArray(tif, dir, fp))
 
670
                                return 0;
 
671
                } else {
 
672
                        if (wc == 1) {
 
673
                                float fv;
 
674
                                TIFFGetField(tif, fip->field_tag, &fv);
 
675
                                if (!TIFFWriteFloatArray(tif, dir, &fv))
 
676
                                        return 0;
 
677
                        } else {
 
678
                                float* fp;
 
679
                                TIFFGetField(tif, fip->field_tag, &fp);
 
680
                                if (!TIFFWriteFloatArray(tif, dir, fp))
 
681
                                        return 0;
 
682
                        }
 
683
                }
 
684
                break;
 
685
        case TIFF_DOUBLE:
 
686
                if (fip->field_passcount) {
 
687
                        double* dp;
 
688
                        if (wc == (uint16) TIFF_VARIABLE2) {
 
689
                                TIFFGetField(tif, fip->field_tag, &wc2, &dp);
 
690
                                dir->tdir_count = wc2;
 
691
                        } else {        /* Assume TIFF_VARIABLE */
 
692
                                TIFFGetField(tif, fip->field_tag, &wc, &dp);
 
693
                                dir->tdir_count = wc;
 
694
                        }
 
695
                        if (!TIFFWriteDoubleArray(tif, dir, dp))
 
696
                                return 0;
 
697
                } else {
 
698
                        if (wc == 1) {
 
699
                                double dv;
 
700
                                TIFFGetField(tif, fip->field_tag, &dv);
 
701
                                if (!TIFFWriteDoubleArray(tif, dir, &dv))
 
702
                                        return 0;
 
703
                        } else {
 
704
                                double* dp;
 
705
                                TIFFGetField(tif, fip->field_tag, &dp);
 
706
                                if (!TIFFWriteDoubleArray(tif, dir, dp))
 
707
                                        return 0;
 
708
                        }
 
709
                }
 
710
                break;
 
711
        case TIFF_ASCII:
 
712
                { 
 
713
                    char* cp;
 
714
                    if (fip->field_passcount)
 
715
                    {
 
716
                        if( wc == (uint16) TIFF_VARIABLE2 )
 
717
                            TIFFGetField(tif, fip->field_tag, &wc2, &cp);
 
718
                        else
 
719
                            TIFFGetField(tif, fip->field_tag, &wc, &cp);
 
720
                    }
 
721
                    else
 
722
                        TIFFGetField(tif, fip->field_tag, &cp);
 
723
 
 
724
                    dir->tdir_count = (uint32) (strlen(cp) + 1);
 
725
                    if (!TIFFWriteByteArray(tif, dir, cp))
 
726
                        return (0);
 
727
                }
 
728
                break;
 
729
 
 
730
        case TIFF_BYTE:
 
731
        case TIFF_SBYTE:          
 
732
                if (fip->field_passcount) {
 
733
                        char* cp;
 
734
                        if (wc == (uint16) TIFF_VARIABLE2) {
 
735
                                TIFFGetField(tif, fip->field_tag, &wc2, &cp);
 
736
                                dir->tdir_count = wc2;
 
737
                        } else {        /* Assume TIFF_VARIABLE */
 
738
                                TIFFGetField(tif, fip->field_tag, &wc, &cp);
 
739
                                dir->tdir_count = wc;
 
740
                        }
 
741
                        if (!TIFFWriteByteArray(tif, dir, cp))
 
742
                                return 0;
 
743
                } else {
 
744
                        if (wc == 1) {
 
745
                                char cv;
 
746
                                TIFFGetField(tif, fip->field_tag, &cv);
 
747
                                if (!TIFFWriteByteArray(tif, dir, &cv))
 
748
                                        return 0;
 
749
                        } else {
 
750
                                char* cp;
 
751
                                TIFFGetField(tif, fip->field_tag, &cp);
 
752
                                if (!TIFFWriteByteArray(tif, dir, cp))
 
753
                                        return 0;
 
754
                        }
 
755
                }
 
756
                break;
 
757
 
 
758
        case TIFF_UNDEFINED:
 
759
                { char* cp;
 
760
                  if (wc == (unsigned short) TIFF_VARIABLE) {
 
761
                        TIFFGetField(tif, fip->field_tag, &wc, &cp);
 
762
                        dir->tdir_count = wc;
 
763
                  } else if (wc == (unsigned short) TIFF_VARIABLE2) {
 
764
                        TIFFGetField(tif, fip->field_tag, &wc2, &cp);
 
765
                        dir->tdir_count = wc2;
 
766
                  } else 
 
767
                        TIFFGetField(tif, fip->field_tag, &cp);
 
768
                  if (!TIFFWriteByteArray(tif, dir, cp))
 
769
                        return (0);
 
770
                }
 
771
                break;
 
772
 
 
773
        case TIFF_NOTYPE:
 
774
                break;
 
775
        }
 
776
        return (1);
 
777
}
 
778
 
 
779
/*
 
780
 * Setup a directory entry with either a SHORT
 
781
 * or LONG type according to the value.
 
782
 */
 
783
static void
 
784
TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
 
785
{
 
786
        dir->tdir_tag = (uint16) tag;
 
787
        dir->tdir_count = 1;
 
788
        if (v > 0xffffL) {
 
789
                dir->tdir_type = (short) TIFF_LONG;
 
790
                dir->tdir_offset = v;
 
791
        } else {
 
792
                dir->tdir_type = (short) TIFF_SHORT;
 
793
                dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
 
794
        }
 
795
}
 
796
 
 
797
/*
 
798
 * Setup a SHORT directory entry
 
799
 */
 
800
static void
 
801
TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
 
802
{
 
803
        dir->tdir_tag = (uint16) tag;
 
804
        dir->tdir_count = 1;
 
805
        dir->tdir_type = (short) TIFF_SHORT;
 
806
        dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
 
807
}
 
808
#undef MakeShortDirent
 
809
 
 
810
#define NITEMS(x)       (sizeof (x) / sizeof (x[0]))
 
811
/*
 
812
 * Setup a directory entry that references a
 
813
 * samples/pixel array of SHORT values and
 
814
 * (potentially) write the associated indirect
 
815
 * values.
 
816
 */
 
817
static int
 
818
TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
 
819
{
 
820
        uint16 buf[10], v;
 
821
        uint16* w = buf;
 
822
        uint16 i, samples = tif->tif_dir.td_samplesperpixel;
 
823
        int status;
 
824
 
 
825
        if (samples > NITEMS(buf)) {
 
826
                w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
 
827
                if (w == NULL) {
 
828
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
829
                            "No space to write per-sample shorts");
 
830
                        return (0);
 
831
                }
 
832
        }
 
833
        TIFFGetField(tif, tag, &v);
 
834
        for (i = 0; i < samples; i++)
 
835
                w[i] = v;
 
836
        
 
837
        dir->tdir_tag = (uint16) tag;
 
838
        dir->tdir_type = (uint16) TIFF_SHORT;
 
839
        dir->tdir_count = samples;
 
840
        status = TIFFWriteShortArray(tif, dir, w);
 
841
        if (w != buf)
 
842
                _TIFFfree((char*) w);
 
843
        return (status);
 
844
}
 
845
 
 
846
/*
 
847
 * Setup a directory entry that references a samples/pixel array of ``type''
 
848
 * values and (potentially) write the associated indirect values.  The source
 
849
 * data from TIFFGetField() for the specified tag must be returned as double.
 
850
 */
 
851
static int
 
852
TIFFWritePerSampleAnys(TIFF* tif,
 
853
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
 
854
{
 
855
        double buf[10], v;
 
856
        double* w = buf;
 
857
        uint16 i, samples = tif->tif_dir.td_samplesperpixel;
 
858
        int status;
 
859
 
 
860
        if (samples > NITEMS(buf)) {
 
861
                w = (double*) _TIFFmalloc(samples * sizeof (double));
 
862
                if (w == NULL) {
 
863
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
864
                            "No space to write per-sample values");
 
865
                        return (0);
 
866
                }
 
867
        }
 
868
        TIFFGetField(tif, tag, &v);
 
869
        for (i = 0; i < samples; i++)
 
870
                w[i] = v;
 
871
        status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
 
872
        if (w != buf)
 
873
                _TIFFfree(w);
 
874
        return (status);
 
875
}
 
876
#undef NITEMS
 
877
 
 
878
/*
 
879
 * Setup a pair of shorts that are returned by
 
880
 * value, rather than as a reference to an array.
 
881
 */
 
882
static int
 
883
TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
 
884
{
 
885
        uint16 v[2];
 
886
 
 
887
        TIFFGetField(tif, tag, &v[0], &v[1]);
 
888
 
 
889
        dir->tdir_tag = (uint16) tag;
 
890
        dir->tdir_type = (uint16) TIFF_SHORT;
 
891
        dir->tdir_count = 2;
 
892
        return (TIFFWriteShortArray(tif, dir, v));
 
893
}
 
894
 
 
895
/*
 
896
 * Setup a directory entry for an NxM table of shorts,
 
897
 * where M is known to be 2**bitspersample, and write
 
898
 * the associated indirect data.
 
899
 */
 
900
static int
 
901
TIFFWriteShortTable(TIFF* tif,
 
902
    ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
 
903
{
 
904
        uint32 i, off;
 
905
 
 
906
        dir->tdir_tag = (uint16) tag;
 
907
        dir->tdir_type = (short) TIFF_SHORT;
 
908
        /* XXX -- yech, fool TIFFWriteData */
 
909
        dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
 
910
        off = tif->tif_dataoff;
 
911
        for (i = 0; i < n; i++)
 
912
                if (!TIFFWriteData(tif, dir, (char *)table[i]))
 
913
                        return (0);
 
914
        dir->tdir_count *= n;
 
915
        dir->tdir_offset = off;
 
916
        return (1);
 
917
}
 
918
 
 
919
/*
 
920
 * Write/copy data associated with an ASCII or opaque tag value.
 
921
 */
 
922
static int
 
923
TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
 
924
{
 
925
        if (dir->tdir_count <= 4) {
 
926
                if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
 
927
                        dir->tdir_offset = (uint32)cp[0] << 24;
 
928
                        if (dir->tdir_count >= 2)
 
929
                                dir->tdir_offset |= (uint32)cp[1] << 16;
 
930
                        if (dir->tdir_count >= 3)
 
931
                                dir->tdir_offset |= (uint32)cp[2] << 8;
 
932
                        if (dir->tdir_count == 4)
 
933
                                dir->tdir_offset |= cp[3];
 
934
                } else {
 
935
                        dir->tdir_offset = cp[0];
 
936
                        if (dir->tdir_count >= 2)
 
937
                                dir->tdir_offset |= (uint32) cp[1] << 8;
 
938
                        if (dir->tdir_count >= 3)
 
939
                                dir->tdir_offset |= (uint32) cp[2] << 16;
 
940
                        if (dir->tdir_count == 4)
 
941
                                dir->tdir_offset |= (uint32) cp[3] << 24;
 
942
                }
 
943
                return 1;
 
944
        } else
 
945
                return TIFFWriteData(tif, dir, cp);
 
946
}
 
947
 
 
948
/*
 
949
 * Setup a directory entry of an array of SHORT
 
950
 * or SSHORT and write the associated indirect values.
 
951
 */
 
952
static int
 
953
TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
 
954
{
 
955
        if (dir->tdir_count <= 2) {
 
956
                if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
 
957
                        dir->tdir_offset = (uint32) v[0] << 16;
 
958
                        if (dir->tdir_count == 2)
 
959
                                dir->tdir_offset |= v[1] & 0xffff;
 
960
                } else {
 
961
                        dir->tdir_offset = v[0] & 0xffff;
 
962
                        if (dir->tdir_count == 2)
 
963
                                dir->tdir_offset |= (uint32) v[1] << 16;
 
964
                }
 
965
                return (1);
 
966
        } else
 
967
                return (TIFFWriteData(tif, dir, (char*) v));
 
968
}
 
969
 
 
970
/*
 
971
 * Setup a directory entry of an array of LONG
 
972
 * or SLONG and write the associated indirect values.
 
973
 */
 
974
static int
 
975
TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
 
976
{
 
977
        if (dir->tdir_count == 1) {
 
978
                dir->tdir_offset = v[0];
 
979
                return (1);
 
980
        } else
 
981
                return (TIFFWriteData(tif, dir, (char*) v));
 
982
}
 
983
 
 
984
/*
 
985
 * Setup a directory entry of an array of RATIONAL
 
986
 * or SRATIONAL and write the associated indirect values.
 
987
 */
 
988
static int
 
989
TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
 
990
{
 
991
        uint32 i;
 
992
        uint32* t;
 
993
        int status;
 
994
 
 
995
        t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
 
996
        if (t == NULL) {
 
997
                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
998
                    "No space to write RATIONAL array");
 
999
                return (0);
 
1000
        }
 
1001
        for (i = 0; i < dir->tdir_count; i++) {
 
1002
                float fv = v[i];
 
1003
                int sign = 1;
 
1004
                uint32 den;
 
1005
 
 
1006
                if (fv < 0) {
 
1007
                        if (dir->tdir_type == TIFF_RATIONAL) {
 
1008
                                TIFFWarningExt(tif->tif_clientdata,
 
1009
                                               tif->tif_name,
 
1010
        "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
 
1011
                                _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
 
1012
                                                fv);
 
1013
                                fv = 0;
 
1014
                        } else
 
1015
                                fv = -fv, sign = -1;
 
1016
                }
 
1017
                den = 1L;
 
1018
                if (fv > 0) {
 
1019
                        while (fv < 1L<<(31-3) && den < 1L<<(31-3))
 
1020
                                fv *= 1<<3, den *= 1L<<3;
 
1021
                }
 
1022
                t[2*i+0] = (uint32) (sign * (fv + 0.5));
 
1023
                t[2*i+1] = den;
 
1024
        }
 
1025
        status = TIFFWriteData(tif, dir, (char *)t);
 
1026
        _TIFFfree((char*) t);
 
1027
        return (status);
 
1028
}
 
1029
 
 
1030
static int
 
1031
TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
 
1032
{
 
1033
        TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
 
1034
        if (dir->tdir_count == 1) {
 
1035
                dir->tdir_offset = *(uint32*) &v[0];
 
1036
                return (1);
 
1037
        } else
 
1038
                return (TIFFWriteData(tif, dir, (char*) v));
 
1039
}
 
1040
 
 
1041
static int
 
1042
TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
 
1043
{
 
1044
        TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
 
1045
        return (TIFFWriteData(tif, dir, (char*) v));
 
1046
}
 
1047
 
 
1048
/*
 
1049
 * Write an array of ``type'' values for a specified tag (i.e. this is a tag
 
1050
 * which is allowed to have different types, e.g. SMaxSampleType).
 
1051
 * Internally the data values are represented as double since a double can
 
1052
 * hold any of the TIFF tag types (yes, this should really be an abstract
 
1053
 * type tany_t for portability).  The data is converted into the specified
 
1054
 * type in a temporary buffer and then handed off to the appropriate array
 
1055
 * writer.
 
1056
 */
 
1057
static int
 
1058
TIFFWriteAnyArray(TIFF* tif,
 
1059
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
 
1060
{
 
1061
        char buf[10 * sizeof(double)];
 
1062
        char* w = buf;
 
1063
        int i, status = 0;
 
1064
 
 
1065
        if (n * TIFFDataWidth(type) > sizeof buf) {
 
1066
                w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
 
1067
                if (w == NULL) {
 
1068
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
1069
                                     "No space to write array");
 
1070
                        return (0);
 
1071
                }
 
1072
        }
 
1073
 
 
1074
        dir->tdir_tag = (uint16) tag;
 
1075
        dir->tdir_type = (uint16) type;
 
1076
        dir->tdir_count = n;
 
1077
 
 
1078
        switch (type) {
 
1079
        case TIFF_BYTE:
 
1080
                { 
 
1081
                        uint8* bp = (uint8*) w;
 
1082
                        for (i = 0; i < (int) n; i++)
 
1083
                                bp[i] = (uint8) v[i];
 
1084
                        if (!TIFFWriteByteArray(tif, dir, (char*) bp))
 
1085
                                goto out;
 
1086
                }
 
1087
                break;
 
1088
        case TIFF_SBYTE:
 
1089
                { 
 
1090
                        int8* bp = (int8*) w;
 
1091
                        for (i = 0; i < (int) n; i++)
 
1092
                                bp[i] = (int8) v[i];
 
1093
                        if (!TIFFWriteByteArray(tif, dir, (char*) bp))
 
1094
                                goto out;
 
1095
                }
 
1096
                break;
 
1097
        case TIFF_SHORT:
 
1098
                {
 
1099
                        uint16* bp = (uint16*) w;
 
1100
                        for (i = 0; i < (int) n; i++)
 
1101
                                bp[i] = (uint16) v[i];
 
1102
                        if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
 
1103
                                goto out;
 
1104
                }
 
1105
                break;
 
1106
        case TIFF_SSHORT:
 
1107
                { 
 
1108
                        int16* bp = (int16*) w;
 
1109
                        for (i = 0; i < (int) n; i++)
 
1110
                                bp[i] = (int16) v[i];
 
1111
                        if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
 
1112
                                goto out;
 
1113
                }
 
1114
                break;
 
1115
        case TIFF_LONG:
 
1116
                {
 
1117
                        uint32* bp = (uint32*) w;
 
1118
                        for (i = 0; i < (int) n; i++)
 
1119
                                bp[i] = (uint32) v[i];
 
1120
                        if (!TIFFWriteLongArray(tif, dir, bp))
 
1121
                                goto out;
 
1122
                }
 
1123
                break;
 
1124
        case TIFF_SLONG:
 
1125
                {
 
1126
                        int32* bp = (int32*) w;
 
1127
                        for (i = 0; i < (int) n; i++)
 
1128
                                bp[i] = (int32) v[i];
 
1129
                        if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
 
1130
                                goto out;
 
1131
                }
 
1132
                break;
 
1133
        case TIFF_FLOAT:
 
1134
                { 
 
1135
                        float* bp = (float*) w;
 
1136
                        for (i = 0; i < (int) n; i++)
 
1137
                                bp[i] = (float) v[i];
 
1138
                        if (!TIFFWriteFloatArray(tif, dir, bp))
 
1139
                                goto out;
 
1140
                }
 
1141
                break;
 
1142
        case TIFF_DOUBLE:
 
1143
                {
 
1144
                    if( !TIFFWriteDoubleArray(tif, dir, v))
 
1145
                        goto out;
 
1146
                }
 
1147
                break;
 
1148
        default:
 
1149
                /* TIFF_NOTYPE */
 
1150
                /* TIFF_ASCII */
 
1151
                /* TIFF_UNDEFINED */
 
1152
                /* TIFF_RATIONAL */
 
1153
                /* TIFF_SRATIONAL */
 
1154
                goto out;
 
1155
        }
 
1156
        status = 1;
 
1157
 out:
 
1158
        if (w != buf)
 
1159
                _TIFFfree(w);
 
1160
        return (status);
 
1161
}
 
1162
 
 
1163
static int
 
1164
TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
 
1165
{
 
1166
        TIFFDirectory* td = &tif->tif_dir;
 
1167
        tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
 
1168
        uint16** tf = td->td_transferfunction;
 
1169
        int ncols;
 
1170
 
 
1171
        /*
 
1172
         * Check if the table can be written as a single column,
 
1173
         * or if it must be written as 3 columns.  Note that we
 
1174
         * write a 3-column tag if there are 2 samples/pixel and
 
1175
         * a single column of data won't suffice--hmm.
 
1176
         */
 
1177
        switch (td->td_samplesperpixel - td->td_extrasamples) {
 
1178
        default:        if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
 
1179
        case 2:         if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
 
1180
        case 1: case 0: ncols = 1;
 
1181
        }
 
1182
        return (TIFFWriteShortTable(tif,
 
1183
            TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
 
1184
}
 
1185
 
 
1186
static int
 
1187
TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
 
1188
{
 
1189
        TIFFDirectory* td = &tif->tif_dir;
 
1190
 
 
1191
        dir->tdir_tag = TIFFTAG_INKNAMES;
 
1192
        dir->tdir_type = (short) TIFF_ASCII;
 
1193
        dir->tdir_count = td->td_inknameslen;
 
1194
        return (TIFFWriteByteArray(tif, dir, td->td_inknames));
 
1195
}
 
1196
 
 
1197
/*
 
1198
 * Write a contiguous directory item.
 
1199
 */
 
1200
static int
 
1201
TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
 
1202
{
 
1203
        tsize_t cc;
 
1204
 
 
1205
        if (tif->tif_flags & TIFF_SWAB) {
 
1206
                switch (dir->tdir_type) {
 
1207
                case TIFF_SHORT:
 
1208
                case TIFF_SSHORT:
 
1209
                        TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
 
1210
                        break;
 
1211
                case TIFF_LONG:
 
1212
                case TIFF_SLONG:
 
1213
                case TIFF_FLOAT:
 
1214
                        TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
 
1215
                        break;
 
1216
                case TIFF_RATIONAL:
 
1217
                case TIFF_SRATIONAL:
 
1218
                        TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
 
1219
                        break;
 
1220
                case TIFF_DOUBLE:
 
1221
                        TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
 
1222
                        break;
 
1223
                }
 
1224
        }
 
1225
        dir->tdir_offset = tif->tif_dataoff;
 
1226
        cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
 
1227
        if (SeekOK(tif, dir->tdir_offset) &&
 
1228
            WriteOK(tif, cp, cc)) {
 
1229
                tif->tif_dataoff += (cc + 1) & ~1;
 
1230
                return (1);
 
1231
        }
 
1232
        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
1233
                     "Error writing data for field \"%s\"",
 
1234
        _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
 
1235
        return (0);
 
1236
}
 
1237
 
 
1238
/*
 
1239
 * Similar to TIFFWriteDirectory(), but if the directory has already
 
1240
 * been written once, it is relocated to the end of the file, in case it
 
1241
 * has changed in size.  Note that this will result in the loss of the 
 
1242
 * previously used directory space. 
 
1243
 */ 
 
1244
 
 
1245
int 
 
1246
TIFFRewriteDirectory( TIFF *tif )
 
1247
{
 
1248
    static const char module[] = "TIFFRewriteDirectory";
 
1249
 
 
1250
    /* We don't need to do anything special if it hasn't been written. */
 
1251
    if( tif->tif_diroff == 0 )
 
1252
        return TIFFWriteDirectory( tif );
 
1253
 
 
1254
    /*
 
1255
    ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
 
1256
    ** will cause it to be added after this directories current pre-link.
 
1257
    */
 
1258
    
 
1259
    /* Is it the first directory in the file? */
 
1260
    if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
 
1261
    {
 
1262
        tif->tif_header.tiff_diroff = 0;
 
1263
        tif->tif_diroff = 0;
 
1264
 
 
1265
        TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
 
1266
                     SEEK_SET);
 
1267
        if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
 
1268
                     sizeof (tif->tif_diroff))) 
 
1269
        {
 
1270
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
1271
                                     "Error updating TIFF header");
 
1272
            return (0);
 
1273
        }
 
1274
    }
 
1275
    else
 
1276
    {
 
1277
        toff_t  nextdir, off;
 
1278
 
 
1279
        nextdir = tif->tif_header.tiff_diroff;
 
1280
        do {
 
1281
                uint16 dircount;
 
1282
 
 
1283
                if (!SeekOK(tif, nextdir) ||
 
1284
                    !ReadOK(tif, &dircount, sizeof (dircount))) {
 
1285
                        TIFFErrorExt(tif->tif_clientdata, module,
 
1286
                                     "Error fetching directory count");
 
1287
                        return (0);
 
1288
                }
 
1289
                if (tif->tif_flags & TIFF_SWAB)
 
1290
                        TIFFSwabShort(&dircount);
 
1291
                (void) TIFFSeekFile(tif,
 
1292
                    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
 
1293
                if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
 
1294
                        TIFFErrorExt(tif->tif_clientdata, module,
 
1295
                                     "Error fetching directory link");
 
1296
                        return (0);
 
1297
                }
 
1298
                if (tif->tif_flags & TIFF_SWAB)
 
1299
                        TIFFSwabLong(&nextdir);
 
1300
        } while (nextdir != tif->tif_diroff && nextdir != 0);
 
1301
        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
 
1302
        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
 
1303
        tif->tif_diroff = 0;
 
1304
        if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
 
1305
                TIFFErrorExt(tif->tif_clientdata, module,
 
1306
                             "Error writing directory link");
 
1307
                return (0);
 
1308
        }
 
1309
    }
 
1310
 
 
1311
    /*
 
1312
    ** Now use TIFFWriteDirectory() normally.
 
1313
    */
 
1314
 
 
1315
    return TIFFWriteDirectory( tif );
 
1316
}
 
1317
 
 
1318
 
 
1319
/*
 
1320
 * Link the current directory into the directory chain for the file.
 
1321
 */
 
1322
static int
 
1323
TIFFLinkDirectory(TIFF* tif)
 
1324
{
 
1325
        static const char module[] = "TIFFLinkDirectory";
 
1326
        toff_t nextdir;
 
1327
        toff_t diroff, off;
 
1328
 
 
1329
        tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
 
1330
        diroff = tif->tif_diroff;
 
1331
        if (tif->tif_flags & TIFF_SWAB)
 
1332
                TIFFSwabLong(&diroff);
 
1333
 
 
1334
        /*
 
1335
         * Handle SubIFDs
 
1336
         */
 
1337
        if (tif->tif_flags & TIFF_INSUBIFD) {
 
1338
                (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
 
1339
                if (!WriteOK(tif, &diroff, sizeof (diroff))) {
 
1340
                        TIFFErrorExt(tif->tif_clientdata, module,
 
1341
                                     "%s: Error writing SubIFD directory link",
 
1342
                                     tif->tif_name);
 
1343
                        return (0);
 
1344
                }
 
1345
                /*
 
1346
                 * Advance to the next SubIFD or, if this is
 
1347
                 * the last one configured, revert back to the
 
1348
                 * normal directory linkage.
 
1349
                 */
 
1350
                if (--tif->tif_nsubifd)
 
1351
                        tif->tif_subifdoff += sizeof (diroff);
 
1352
                else
 
1353
                        tif->tif_flags &= ~TIFF_INSUBIFD;
 
1354
                return (1);
 
1355
        }
 
1356
 
 
1357
        if (tif->tif_header.tiff_diroff == 0) {
 
1358
                /*
 
1359
                 * First directory, overwrite offset in header.
 
1360
                 */
 
1361
                tif->tif_header.tiff_diroff = tif->tif_diroff;
 
1362
                (void) TIFFSeekFile(tif,
 
1363
                                    (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
 
1364
                                    SEEK_SET);
 
1365
                if (!WriteOK(tif, &diroff, sizeof (diroff))) {
 
1366
                        TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
 
1367
                                     "Error writing TIFF header");
 
1368
                        return (0);
 
1369
                }
 
1370
                return (1);
 
1371
        }
 
1372
        /*
 
1373
         * Not the first directory, search to the last and append.
 
1374
         */
 
1375
        nextdir = tif->tif_header.tiff_diroff;
 
1376
        do {
 
1377
                uint16 dircount;
 
1378
 
 
1379
                if (!SeekOK(tif, nextdir) ||
 
1380
                    !ReadOK(tif, &dircount, sizeof (dircount))) {
 
1381
                        TIFFErrorExt(tif->tif_clientdata, module,
 
1382
                                     "Error fetching directory count");
 
1383
                        return (0);
 
1384
                }
 
1385
                if (tif->tif_flags & TIFF_SWAB)
 
1386
                        TIFFSwabShort(&dircount);
 
1387
                (void) TIFFSeekFile(tif,
 
1388
                    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
 
1389
                if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
 
1390
                        TIFFErrorExt(tif->tif_clientdata, module,
 
1391
                                     "Error fetching directory link");
 
1392
                        return (0);
 
1393
                }
 
1394
                if (tif->tif_flags & TIFF_SWAB)
 
1395
                        TIFFSwabLong(&nextdir);
 
1396
        } while (nextdir != 0);
 
1397
        off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
 
1398
        (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
 
1399
        if (!WriteOK(tif, &diroff, sizeof (diroff))) {
 
1400
                TIFFErrorExt(tif->tif_clientdata, module,
 
1401
                             "Error writing directory link");
 
1402
                return (0);
 
1403
        }
 
1404
        return (1);
 
1405
}
 
1406
 
 
1407
/* vim: set ts=8 sts=8 sw=8 noet: */
 
1408
/*
 
1409
 * Local Variables:
 
1410
 * mode: c
 
1411
 * c-basic-offset: 8
 
1412
 * fill-column: 78
 
1413
 * End:
 
1414
 */