Coverage Report

Created: 2024-07-27 06:27

/src/libtiff/libtiff/tif_dirwrite.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 1988-1997 Sam Leffler
3
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and
6
 * its documentation for any purpose is hereby granted without fee, provided
7
 * that (i) the above copyright notices and this permission notice appear in
8
 * all copies of the software and related documentation, and (ii) the names of
9
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10
 * publicity relating to the software without the specific, prior written
11
 * permission of Sam Leffler and Silicon Graphics.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
 * OF THIS SOFTWARE.
23
 */
24
25
/*
26
 * TIFF Library.
27
 *
28
 * Directory Write Support Routines.
29
 */
30
#include "tiffiop.h"
31
#include <float.h> /*--: for Rational2Double */
32
#include <math.h>  /*--: for Rational2Double */
33
34
#ifdef HAVE_IEEEFP
35
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
36
#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
37
#else
38
extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
39
extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
40
#endif
41
42
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
43
                                 uint64_t *pdiroff);
44
45
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
46
                                                  TIFFDirEntry *dir,
47
                                                  uint16_t tag, uint32_t count,
48
                                                  double *value);
49
50
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
51
                                      TIFFDirEntry *dir, uint16_t tag,
52
                                      uint32_t count, char *value);
53
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
54
                                               TIFFDirEntry *dir, uint16_t tag,
55
                                               uint32_t count, uint8_t *value);
56
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
57
                                          TIFFDirEntry *dir, uint16_t tag,
58
                                          uint32_t count, uint8_t *value);
59
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
60
                                           TIFFDirEntry *dir, uint16_t tag,
61
                                           uint32_t count, int8_t *value);
62
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
63
                                      TIFFDirEntry *dir, uint16_t tag,
64
                                      uint16_t value);
65
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
66
                                           TIFFDirEntry *dir, uint16_t tag,
67
                                           uint32_t count, uint16_t *value);
68
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
69
                                               TIFFDirEntry *dir, uint16_t tag,
70
                                               uint16_t value);
71
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
72
                                            TIFFDirEntry *dir, uint16_t tag,
73
                                            uint32_t count, int16_t *value);
74
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
75
                                     TIFFDirEntry *dir, uint16_t tag,
76
                                     uint32_t value);
77
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
78
                                          TIFFDirEntry *dir, uint16_t tag,
79
                                          uint32_t count, uint32_t *value);
80
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
81
                                           TIFFDirEntry *dir, uint16_t tag,
82
                                           uint32_t count, int32_t *value);
83
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
84
                                           TIFFDirEntry *dir, uint16_t tag,
85
                                           uint32_t count, uint64_t *value);
86
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
87
                                            TIFFDirEntry *dir, uint16_t tag,
88
                                            uint32_t count, int64_t *value);
89
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
90
                                         TIFFDirEntry *dir, uint16_t tag,
91
                                         double value);
92
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
93
                                              TIFFDirEntry *dir, uint16_t tag,
94
                                              uint32_t count, float *value);
95
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
96
                                               TIFFDirEntry *dir, uint16_t tag,
97
                                               uint32_t count, float *value);
98
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
99
                                           TIFFDirEntry *dir, uint16_t tag,
100
                                           uint32_t count, float *value);
101
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
102
                                            TIFFDirEntry *dir, uint16_t tag,
103
                                            uint32_t count, double *value);
104
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
105
                                         TIFFDirEntry *dir, uint16_t tag,
106
                                         uint32_t count, uint32_t *value);
107
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
108
                                          TIFFDirEntry *dir, uint16_t tag,
109
                                          uint32_t value);
110
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
111
                                               TIFFDirEntry *dir, uint16_t tag,
112
                                               uint32_t count, uint64_t *value);
113
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
114
                                             TIFFDirEntry *dir, uint16_t tag,
115
                                             uint32_t count, uint64_t *value);
116
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
117
                                         TIFFDirEntry *dir);
118
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
119
                                                 TIFFDirEntry *dir);
120
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
121
                                       TIFFDirEntry *dir);
122
123
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
124
                                             TIFFDirEntry *dir, uint16_t tag,
125
                                             uint32_t count, char *value);
126
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
127
                                                      TIFFDirEntry *dir,
128
                                                      uint16_t tag,
129
                                                      uint32_t count,
130
                                                      uint8_t *value);
131
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
132
                                                 TIFFDirEntry *dir,
133
                                                 uint16_t tag, uint32_t count,
134
                                                 uint8_t *value);
135
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
136
                                                  TIFFDirEntry *dir,
137
                                                  uint16_t tag, uint32_t count,
138
                                                  int8_t *value);
139
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
140
                                             TIFFDirEntry *dir, uint16_t tag,
141
                                             uint16_t value);
142
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
143
                                                  TIFFDirEntry *dir,
144
                                                  uint16_t tag, uint32_t count,
145
                                                  uint16_t *value);
146
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
147
                                                   TIFFDirEntry *dir,
148
                                                   uint16_t tag, uint32_t count,
149
                                                   int16_t *value);
150
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
151
                                            TIFFDirEntry *dir, uint16_t tag,
152
                                            uint32_t value);
153
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
154
                                                 TIFFDirEntry *dir,
155
                                                 uint16_t tag, uint32_t count,
156
                                                 uint32_t *value);
157
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
158
                                                  TIFFDirEntry *dir,
159
                                                  uint16_t tag, uint32_t count,
160
                                                  int32_t *value);
161
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
162
                                                  TIFFDirEntry *dir,
163
                                                  uint16_t tag, uint32_t count,
164
                                                  uint64_t *value);
165
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
166
                                                   TIFFDirEntry *dir,
167
                                                   uint16_t tag, uint32_t count,
168
                                                   int64_t *value);
169
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
170
                                                TIFFDirEntry *dir, uint16_t tag,
171
                                                double value);
172
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
173
                                                     TIFFDirEntry *dir,
174
                                                     uint16_t tag,
175
                                                     uint32_t count,
176
                                                     float *value);
177
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
178
                                                      TIFFDirEntry *dir,
179
                                                      uint16_t tag,
180
                                                      uint32_t count,
181
                                                      float *value);
182
183
/*--: Rational2Double: New functions to support true double-precision for custom
184
 * rational tag types. */
185
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
186
                                                    TIFFDirEntry *dir,
187
                                                    uint16_t tag,
188
                                                    uint32_t count,
189
                                                    double *value);
190
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
191
                                                     TIFFDirEntry *dir,
192
                                                     uint16_t tag,
193
                                                     uint32_t count,
194
                                                     double *value);
195
static int
196
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
197
                                                TIFFDirEntry *dir, uint16_t tag,
198
                                                uint32_t count, double *value);
199
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
200
    TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
201
    double *value);
202
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom);
203
static void DoubleToSrational(double value, int32_t *num, int32_t *denom);
204
205
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
206
                                                  TIFFDirEntry *dir,
207
                                                  uint16_t tag, uint32_t count,
208
                                                  float *value);
209
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
210
                                                   TIFFDirEntry *dir,
211
                                                   uint16_t tag, uint32_t count,
212
                                                   double *value);
213
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
214
                                                TIFFDirEntry *dir, uint16_t tag,
215
                                                uint32_t count,
216
                                                uint32_t *value);
217
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
218
                                                 TIFFDirEntry *dir,
219
                                                 uint16_t tag, uint32_t count,
220
                                                 uint64_t *value);
221
222
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
223
                                     TIFFDirEntry *dir, uint16_t tag,
224
                                     uint16_t datatype, uint32_t count,
225
                                     uint32_t datalength, void *data);
226
227
static int TIFFLinkDirectory(TIFF *);
228
229
/*
230
 * Write the contents of the current directory
231
 * to the specified file.  This routine doesn't
232
 * handle overwriting a directory with auxiliary
233
 * storage that's been changed.
234
 */
235
int TIFFWriteDirectory(TIFF *tif)
236
0
{
237
0
    return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
238
0
}
239
240
/*
241
 * This is an advanced writing function that must be used in a particular
242
 * sequence, and generally together with TIFFForceStrileArrayWriting(),
243
 * to make its intended effect. Its aim is to modify the location
244
 * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
245
 * More precisely, when TIFFWriteCheck() will be called, the tag entries for
246
 * those arrays will be written with type = count = offset = 0 as a temporary
247
 * value.
248
 *
249
 * Its effect is only valid for the current directory, and before
250
 * TIFFWriteDirectory() is first called, and  will be reset when
251
 * changing directory.
252
 *
253
 * The typical sequence of calls is:
254
 * TIFFOpen()
255
 * [ TIFFCreateDirectory(tif) ]
256
 * Set fields with calls to TIFFSetField(tif, ...)
257
 * TIFFDeferStrileArrayWriting(tif)
258
 * TIFFWriteCheck(tif, ...)
259
 * TIFFWriteDirectory(tif)
260
 * ... potentially create other directories and come back to the above directory
261
 * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
262
 *
263
 * Returns 1 in case of success, 0 otherwise.
264
 */
265
int TIFFDeferStrileArrayWriting(TIFF *tif)
266
0
{
267
0
    static const char module[] = "TIFFDeferStrileArrayWriting";
268
0
    if (tif->tif_mode == O_RDONLY)
269
0
    {
270
0
        TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
271
0
        return 0;
272
0
    }
273
0
    if (tif->tif_diroff != 0)
274
0
    {
275
0
        TIFFErrorExtR(tif, module, "Directory has already been written");
276
0
        return 0;
277
0
    }
278
279
0
    tif->tif_dir.td_deferstrilearraywriting = TRUE;
280
0
    return 1;
281
0
}
282
283
/*
284
 * Similar to TIFFWriteDirectory(), writes the directory out
285
 * but leaves all data structures in memory so that it can be
286
 * written again.  This will make a partially written TIFF file
287
 * readable before it is successfully completed/closed.
288
 */
289
int TIFFCheckpointDirectory(TIFF *tif)
290
0
{
291
0
    int rc;
292
    /* Setup the strips arrays, if they haven't already been. */
293
0
    if (tif->tif_dir.td_stripoffset_p == NULL)
294
0
        (void)TIFFSetupStrips(tif);
295
0
    rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL);
296
0
    (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
297
0
    return rc;
298
0
}
299
300
int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff)
301
0
{
302
0
    return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff);
303
0
}
304
305
/*
306
 * Similar to TIFFWriteDirectorySec(), but if the directory has already
307
 * been written once, it is relocated to the end of the file, in case it
308
 * has changed in size.  Note that this will result in the loss of the
309
 * previously used directory space.
310
 */
311
312
static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
313
                                   uint64_t *pdiroff)
314
0
{
315
0
    static const char module[] = "TIFFRewriteDirectory";
316
317
    /* We don't need to do anything special if it hasn't been written. */
318
0
    if (tif->tif_diroff == 0)
319
0
        return TIFFWriteDirectory(tif);
320
321
    /*
322
     * Find and zero the pointer to this directory, so that TIFFLinkDirectory
323
     * will cause it to be added after this directories current pre-link.
324
     */
325
0
    uint64_t torewritediroff = tif->tif_diroff;
326
327
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
328
0
    {
329
0
        if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
330
0
        {
331
0
            tif->tif_header.classic.tiff_diroff = 0;
332
0
            tif->tif_diroff = 0;
333
334
0
            TIFFSeekFile(tif, 4, SEEK_SET);
335
0
            if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
336
0
            {
337
0
                TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
338
0
                return (0);
339
0
            }
340
0
        }
341
0
        else if (tif->tif_diroff > 0xFFFFFFFFU)
342
0
        {
343
0
            TIFFErrorExtR(tif, module,
344
0
                          "tif->tif_diroff exceeds 32 bit range allowed for "
345
0
                          "Classic TIFF");
346
0
            return (0);
347
0
        }
348
0
        else
349
0
        {
350
0
            uint32_t nextdir;
351
0
            nextdir = tif->tif_header.classic.tiff_diroff;
352
0
            while (1)
353
0
            {
354
0
                uint16_t dircount;
355
0
                uint32_t nextnextdir;
356
357
0
                if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
358
0
                {
359
0
                    TIFFErrorExtR(tif, module,
360
0
                                  "Error fetching directory count");
361
0
                    return (0);
362
0
                }
363
0
                if (tif->tif_flags & TIFF_SWAB)
364
0
                    TIFFSwabShort(&dircount);
365
0
                (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
366
0
                if (!ReadOK(tif, &nextnextdir, 4))
367
0
                {
368
0
                    TIFFErrorExtR(tif, module, "Error fetching directory link");
369
0
                    return (0);
370
0
                }
371
0
                if (tif->tif_flags & TIFF_SWAB)
372
0
                    TIFFSwabLong(&nextnextdir);
373
0
                if (nextnextdir == tif->tif_diroff)
374
0
                {
375
0
                    uint32_t m;
376
0
                    m = 0;
377
0
                    (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
378
0
                                       SEEK_SET);
379
0
                    if (!WriteOK(tif, &m, 4))
380
0
                    {
381
0
                        TIFFErrorExtR(tif, module,
382
0
                                      "Error writing directory link");
383
0
                        return (0);
384
0
                    }
385
0
                    tif->tif_diroff = 0;
386
                    /* Force a full-traversal to reach the zeroed pointer */
387
0
                    tif->tif_lastdiroff = 0;
388
0
                    break;
389
0
                }
390
0
                nextdir = nextnextdir;
391
0
            }
392
0
        }
393
        /* Remove skipped offset from IFD loop directory list. */
394
0
        _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
395
0
    }
396
0
    else
397
0
    {
398
0
        if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
399
0
        {
400
0
            tif->tif_header.big.tiff_diroff = 0;
401
0
            tif->tif_diroff = 0;
402
403
0
            TIFFSeekFile(tif, 8, SEEK_SET);
404
0
            if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8))
405
0
            {
406
0
                TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
407
0
                return (0);
408
0
            }
409
0
        }
410
0
        else
411
0
        {
412
0
            uint64_t nextdir;
413
0
            nextdir = tif->tif_header.big.tiff_diroff;
414
0
            while (1)
415
0
            {
416
0
                uint64_t dircount64;
417
0
                uint16_t dircount;
418
0
                uint64_t nextnextdir;
419
420
0
                if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
421
0
                {
422
0
                    TIFFErrorExtR(tif, module,
423
0
                                  "Error fetching directory count");
424
0
                    return (0);
425
0
                }
426
0
                if (tif->tif_flags & TIFF_SWAB)
427
0
                    TIFFSwabLong8(&dircount64);
428
0
                if (dircount64 > 0xFFFF)
429
0
                {
430
0
                    TIFFErrorExtR(tif, module,
431
0
                                  "Sanity check on tag count failed, likely "
432
0
                                  "corrupt TIFF");
433
0
                    return (0);
434
0
                }
435
0
                dircount = (uint16_t)dircount64;
436
0
                (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
437
0
                if (!ReadOK(tif, &nextnextdir, 8))
438
0
                {
439
0
                    TIFFErrorExtR(tif, module, "Error fetching directory link");
440
0
                    return (0);
441
0
                }
442
0
                if (tif->tif_flags & TIFF_SWAB)
443
0
                    TIFFSwabLong8(&nextnextdir);
444
0
                if (nextnextdir == tif->tif_diroff)
445
0
                {
446
0
                    uint64_t m;
447
0
                    m = 0;
448
0
                    (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
449
0
                                       SEEK_SET);
450
0
                    if (!WriteOK(tif, &m, 8))
451
0
                    {
452
0
                        TIFFErrorExtR(tif, module,
453
0
                                      "Error writing directory link");
454
0
                        return (0);
455
0
                    }
456
0
                    tif->tif_diroff = 0;
457
                    /* Force a full-traversal to reach the zeroed pointer */
458
0
                    tif->tif_lastdiroff = 0;
459
0
                    break;
460
0
                }
461
0
                nextdir = nextnextdir;
462
0
            }
463
0
        }
464
        /* Remove skipped offset from IFD loop directory list. */
465
0
        _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
466
0
    }
467
468
    /*
469
     * Now use TIFFWriteDirectorySec() normally.
470
     */
471
0
    return TIFFWriteDirectorySec(tif, isimage, imagedone, pdiroff);
472
0
} /*-- TIFFRewriteDirectorySec() --*/
473
474
/*
475
 * Similar to TIFFWriteDirectory(), but if the directory has already
476
 * been written once, it is relocated to the end of the file, in case it
477
 * has changed in size.  Note that this will result in the loss of the
478
 * previously used directory space.
479
 */
480
int TIFFRewriteDirectory(TIFF *tif)
481
0
{
482
0
    return TIFFRewriteDirectorySec(tif, TRUE, TRUE, NULL);
483
0
}
484
485
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
486
                                 uint64_t *pdiroff)
487
0
{
488
0
    static const char module[] = "TIFFWriteDirectorySec";
489
0
    uint32_t ndir;
490
0
    TIFFDirEntry *dir;
491
0
    uint32_t dirsize;
492
0
    void *dirmem;
493
0
    uint32_t m;
494
0
    if (tif->tif_mode == O_RDONLY)
495
0
        return (1);
496
497
0
    _TIFFFillStriles(tif);
498
499
    /*
500
     * Clear write state so that subsequent images with
501
     * different characteristics get the right buffers
502
     * setup for them.
503
     */
504
0
    if (imagedone)
505
0
    {
506
0
        if (tif->tif_flags & TIFF_POSTENCODE)
507
0
        {
508
0
            tif->tif_flags &= ~TIFF_POSTENCODE;
509
0
            if (!(*tif->tif_postencode)(tif))
510
0
            {
511
0
                TIFFErrorExtR(tif, module,
512
0
                              "Error post-encoding before directory write");
513
0
                return (0);
514
0
            }
515
0
        }
516
0
        (*tif->tif_close)(tif); /* shutdown encoder */
517
        /*
518
         * Flush any data that might have been written
519
         * by the compression close+cleanup routines.  But
520
         * be careful not to write stuff if we didn't add data
521
         * in the previous steps as the "rawcc" data may well be
522
         * a previously read tile/strip in mixed read/write mode.
523
         */
524
0
        if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0)
525
0
        {
526
0
            if (!TIFFFlushData1(tif))
527
0
            {
528
0
                TIFFErrorExtR(tif, module,
529
0
                              "Error flushing data before directory write");
530
0
                return (0);
531
0
            }
532
0
        }
533
0
        if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
534
0
        {
535
0
            _TIFFfreeExt(tif, tif->tif_rawdata);
536
0
            tif->tif_rawdata = NULL;
537
0
            tif->tif_rawcc = 0;
538
0
            tif->tif_rawdatasize = 0;
539
0
            tif->tif_rawdataoff = 0;
540
0
            tif->tif_rawdataloaded = 0;
541
0
        }
542
0
        tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
543
0
    }
544
545
0
    if (TIFFFieldSet(tif, FIELD_COMPRESSION) &&
546
0
        (tif->tif_dir.td_compression == COMPRESSION_DEFLATE))
547
0
    {
548
0
        TIFFWarningExtR(tif, module,
549
0
                        "Creating TIFF with legacy Deflate codec identifier, "
550
0
                        "COMPRESSION_ADOBE_DEFLATE is more widely supported");
551
0
    }
552
0
    dir = NULL;
553
0
    dirmem = NULL;
554
0
    dirsize = 0;
555
0
    while (1)
556
0
    {
557
        /* The first loop only determines "ndir" and uses TIFFLinkDirectory() to
558
         * set the offset at which the IFD is to be written to the file.
559
         * The second loop writes IFD entries to the file. */
560
0
        ndir = 0;
561
0
        if (dir == NULL)
562
0
            tif->tif_dir.td_dirdatasize_write = 0;
563
0
        if (isimage)
564
0
        {
565
0
            if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
566
0
            {
567
0
                if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
568
0
                                                    TIFFTAG_IMAGEWIDTH,
569
0
                                                    tif->tif_dir.td_imagewidth))
570
0
                    goto bad;
571
0
                if (!TIFFWriteDirectoryTagShortLong(
572
0
                        tif, &ndir, dir, TIFFTAG_IMAGELENGTH,
573
0
                        tif->tif_dir.td_imagelength))
574
0
                    goto bad;
575
0
            }
576
0
            if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
577
0
            {
578
0
                if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
579
0
                                                    TIFFTAG_TILEWIDTH,
580
0
                                                    tif->tif_dir.td_tilewidth))
581
0
                    goto bad;
582
0
                if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
583
0
                                                    TIFFTAG_TILELENGTH,
584
0
                                                    tif->tif_dir.td_tilelength))
585
0
                    goto bad;
586
0
            }
587
0
            if (TIFFFieldSet(tif, FIELD_RESOLUTION))
588
0
            {
589
0
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
590
0
                                                   TIFFTAG_XRESOLUTION,
591
0
                                                   tif->tif_dir.td_xresolution))
592
0
                    goto bad;
593
0
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
594
0
                                                   TIFFTAG_YRESOLUTION,
595
0
                                                   tif->tif_dir.td_yresolution))
596
0
                    goto bad;
597
0
            }
598
0
            if (TIFFFieldSet(tif, FIELD_POSITION))
599
0
            {
600
0
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
601
0
                                                   TIFFTAG_XPOSITION,
602
0
                                                   tif->tif_dir.td_xposition))
603
0
                    goto bad;
604
0
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
605
0
                                                   TIFFTAG_YPOSITION,
606
0
                                                   tif->tif_dir.td_yposition))
607
0
                    goto bad;
608
0
            }
609
0
            if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
610
0
            {
611
0
                if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
612
0
                                               TIFFTAG_SUBFILETYPE,
613
0
                                               tif->tif_dir.td_subfiletype))
614
0
                    goto bad;
615
0
            }
616
0
            if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
617
0
            {
618
0
                if (!TIFFWriteDirectoryTagShortPerSample(
619
0
                        tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE,
620
0
                        tif->tif_dir.td_bitspersample))
621
0
                    goto bad;
622
0
            }
623
0
            if (TIFFFieldSet(tif, FIELD_COMPRESSION))
624
0
            {
625
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
626
0
                                                TIFFTAG_COMPRESSION,
627
0
                                                tif->tif_dir.td_compression))
628
0
                    goto bad;
629
0
            }
630
0
            if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
631
0
            {
632
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
633
0
                                                TIFFTAG_PHOTOMETRIC,
634
0
                                                tif->tif_dir.td_photometric))
635
0
                    goto bad;
636
0
            }
637
0
            if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
638
0
            {
639
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
640
0
                                                TIFFTAG_THRESHHOLDING,
641
0
                                                tif->tif_dir.td_threshholding))
642
0
                    goto bad;
643
0
            }
644
0
            if (TIFFFieldSet(tif, FIELD_FILLORDER))
645
0
            {
646
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
647
0
                                                TIFFTAG_FILLORDER,
648
0
                                                tif->tif_dir.td_fillorder))
649
0
                    goto bad;
650
0
            }
651
0
            if (TIFFFieldSet(tif, FIELD_ORIENTATION))
652
0
            {
653
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
654
0
                                                TIFFTAG_ORIENTATION,
655
0
                                                tif->tif_dir.td_orientation))
656
0
                    goto bad;
657
0
            }
658
0
            if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
659
0
            {
660
0
                if (!TIFFWriteDirectoryTagShort(
661
0
                        tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL,
662
0
                        tif->tif_dir.td_samplesperpixel))
663
0
                    goto bad;
664
0
            }
665
0
            if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
666
0
            {
667
0
                if (!TIFFWriteDirectoryTagShortLong(
668
0
                        tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP,
669
0
                        tif->tif_dir.td_rowsperstrip))
670
0
                    goto bad;
671
0
            }
672
0
            if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
673
0
            {
674
0
                if (!TIFFWriteDirectoryTagShortPerSample(
675
0
                        tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE,
676
0
                        tif->tif_dir.td_minsamplevalue))
677
0
                    goto bad;
678
0
            }
679
0
            if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
680
0
            {
681
0
                if (!TIFFWriteDirectoryTagShortPerSample(
682
0
                        tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE,
683
0
                        tif->tif_dir.td_maxsamplevalue))
684
0
                    goto bad;
685
0
            }
686
0
            if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
687
0
            {
688
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
689
0
                                                TIFFTAG_PLANARCONFIG,
690
0
                                                tif->tif_dir.td_planarconfig))
691
0
                    goto bad;
692
0
            }
693
0
            if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
694
0
            {
695
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
696
0
                                                TIFFTAG_RESOLUTIONUNIT,
697
0
                                                tif->tif_dir.td_resolutionunit))
698
0
                    goto bad;
699
0
            }
700
0
            if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
701
0
            {
702
0
                if (!TIFFWriteDirectoryTagShortArray(
703
0
                        tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2,
704
0
                        &tif->tif_dir.td_pagenumber[0]))
705
0
                    goto bad;
706
0
            }
707
0
            if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
708
0
            {
709
0
                if (!isTiled(tif))
710
0
                {
711
0
                    if (!TIFFWriteDirectoryTagLongLong8Array(
712
0
                            tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS,
713
0
                            tif->tif_dir.td_nstrips,
714
0
                            tif->tif_dir.td_stripbytecount_p))
715
0
                        goto bad;
716
0
                }
717
0
                else
718
0
                {
719
0
                    if (!TIFFWriteDirectoryTagLongLong8Array(
720
0
                            tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS,
721
0
                            tif->tif_dir.td_nstrips,
722
0
                            tif->tif_dir.td_stripbytecount_p))
723
0
                        goto bad;
724
0
                }
725
0
            }
726
0
            if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
727
0
            {
728
0
                if (!isTiled(tif))
729
0
                {
730
                    /* td_stripoffset_p might be NULL in an odd OJPEG case. See
731
                     *  tif_dirread.c around line 3634.
732
                     * XXX: OJPEG hack.
733
                     * If a) compression is OJPEG, b) it's not a tiled TIFF,
734
                     * and c) the number of strips is 1,
735
                     * then we tolerate the absence of stripoffsets tag,
736
                     * because, presumably, all required data is in the
737
                     * JpegInterchangeFormat stream.
738
                     * We can get here when using tiffset on such a file.
739
                     * See http://bugzilla.maptools.org/show_bug.cgi?id=2500
740
                     */
741
0
                    if (tif->tif_dir.td_stripoffset_p != NULL &&
742
0
                        !TIFFWriteDirectoryTagLongLong8Array(
743
0
                            tif, &ndir, dir, TIFFTAG_STRIPOFFSETS,
744
0
                            tif->tif_dir.td_nstrips,
745
0
                            tif->tif_dir.td_stripoffset_p))
746
0
                        goto bad;
747
0
                }
748
0
                else
749
0
                {
750
0
                    if (!TIFFWriteDirectoryTagLongLong8Array(
751
0
                            tif, &ndir, dir, TIFFTAG_TILEOFFSETS,
752
0
                            tif->tif_dir.td_nstrips,
753
0
                            tif->tif_dir.td_stripoffset_p))
754
0
                        goto bad;
755
0
                }
756
0
            }
757
0
            if (TIFFFieldSet(tif, FIELD_COLORMAP))
758
0
            {
759
0
                if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir))
760
0
                    goto bad;
761
0
            }
762
0
            if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES))
763
0
            {
764
0
                if (tif->tif_dir.td_extrasamples)
765
0
                {
766
0
                    uint16_t na;
767
0
                    uint16_t *nb;
768
0
                    TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb);
769
0
                    if (!TIFFWriteDirectoryTagShortArray(
770
0
                            tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb))
771
0
                        goto bad;
772
0
                }
773
0
            }
774
0
            if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
775
0
            {
776
0
                if (!TIFFWriteDirectoryTagShortPerSample(
777
0
                        tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT,
778
0
                        tif->tif_dir.td_sampleformat))
779
0
                    goto bad;
780
0
            }
781
0
            if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
782
0
            {
783
0
                if (!TIFFWriteDirectoryTagSampleformatArray(
784
0
                        tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE,
785
0
                        tif->tif_dir.td_samplesperpixel,
786
0
                        tif->tif_dir.td_sminsamplevalue))
787
0
                    goto bad;
788
0
            }
789
0
            if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
790
0
            {
791
0
                if (!TIFFWriteDirectoryTagSampleformatArray(
792
0
                        tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE,
793
0
                        tif->tif_dir.td_samplesperpixel,
794
0
                        tif->tif_dir.td_smaxsamplevalue))
795
0
                    goto bad;
796
0
            }
797
0
            if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
798
0
            {
799
0
                if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
800
0
                                               TIFFTAG_IMAGEDEPTH,
801
0
                                               tif->tif_dir.td_imagedepth))
802
0
                    goto bad;
803
0
            }
804
0
            if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
805
0
            {
806
0
                if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
807
0
                                               TIFFTAG_TILEDEPTH,
808
0
                                               tif->tif_dir.td_tiledepth))
809
0
                    goto bad;
810
0
            }
811
0
            if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
812
0
            {
813
0
                if (!TIFFWriteDirectoryTagShortArray(
814
0
                        tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2,
815
0
                        &tif->tif_dir.td_halftonehints[0]))
816
0
                    goto bad;
817
0
            }
818
0
            if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
819
0
            {
820
0
                if (!TIFFWriteDirectoryTagShortArray(
821
0
                        tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2,
822
0
                        &tif->tif_dir.td_ycbcrsubsampling[0]))
823
0
                    goto bad;
824
0
            }
825
0
            if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
826
0
            {
827
0
                if (!TIFFWriteDirectoryTagShort(
828
0
                        tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING,
829
0
                        tif->tif_dir.td_ycbcrpositioning))
830
0
                    goto bad;
831
0
            }
832
0
            if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
833
0
            {
834
0
                if (!TIFFWriteDirectoryTagRationalArray(
835
0
                        tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6,
836
0
                        tif->tif_dir.td_refblackwhite))
837
0
                    goto bad;
838
0
            }
839
0
            if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
840
0
            {
841
0
                if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir))
842
0
                    goto bad;
843
0
            }
844
0
            if (TIFFFieldSet(tif, FIELD_INKNAMES))
845
0
            {
846
0
                if (!TIFFWriteDirectoryTagAscii(
847
0
                        tif, &ndir, dir, TIFFTAG_INKNAMES,
848
0
                        tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
849
0
                    goto bad;
850
0
            }
851
0
            if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
852
0
            {
853
0
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
854
0
                                                TIFFTAG_NUMBEROFINKS,
855
0
                                                tif->tif_dir.td_numberofinks))
856
0
                    goto bad;
857
0
            }
858
0
            if (TIFFFieldSet(tif, FIELD_SUBIFD))
859
0
            {
860
0
                if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir))
861
0
                    goto bad;
862
0
            }
863
0
            {
864
0
                uint32_t n;
865
0
                for (n = 0; n < tif->tif_nfields; n++)
866
0
                {
867
0
                    const TIFFField *o;
868
0
                    o = tif->tif_fields[n];
869
0
                    if ((o->field_bit >= FIELD_CODEC) &&
870
0
                        (TIFFFieldSet(tif, o->field_bit)))
871
0
                    {
872
0
                        switch (o->get_field_type)
873
0
                        {
874
0
                            case TIFF_SETGET_ASCII:
875
0
                            {
876
0
                                uint32_t pa;
877
0
                                char *pb;
878
0
                                assert(o->field_type == TIFF_ASCII);
879
0
                                assert(o->field_readcount == TIFF_VARIABLE);
880
0
                                assert(o->field_passcount == 0);
881
0
                                TIFFGetField(tif, o->field_tag, &pb);
882
0
                                pa = (uint32_t)(strlen(pb));
883
0
                                if (!TIFFWriteDirectoryTagAscii(
884
0
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
885
0
                                        pa, pb))
886
0
                                    goto bad;
887
0
                            }
888
0
                            break;
889
0
                            case TIFF_SETGET_UINT16:
890
0
                            {
891
0
                                uint16_t p;
892
0
                                assert(o->field_type == TIFF_SHORT);
893
0
                                assert(o->field_readcount == 1);
894
0
                                assert(o->field_passcount == 0);
895
0
                                TIFFGetField(tif, o->field_tag, &p);
896
0
                                if (!TIFFWriteDirectoryTagShort(
897
0
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
898
0
                                        p))
899
0
                                    goto bad;
900
0
                            }
901
0
                            break;
902
0
                            case TIFF_SETGET_UINT32:
903
0
                            {
904
0
                                uint32_t p;
905
0
                                assert(o->field_type == TIFF_LONG);
906
0
                                assert(o->field_readcount == 1);
907
0
                                assert(o->field_passcount == 0);
908
0
                                TIFFGetField(tif, o->field_tag, &p);
909
0
                                if (!TIFFWriteDirectoryTagLong(
910
0
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
911
0
                                        p))
912
0
                                    goto bad;
913
0
                            }
914
0
                            break;
915
0
                            case TIFF_SETGET_C32_UINT8:
916
0
                            {
917
0
                                uint32_t pa;
918
0
                                void *pb;
919
0
                                assert(o->field_type == TIFF_UNDEFINED);
920
0
                                assert(o->field_readcount == TIFF_VARIABLE2);
921
0
                                assert(o->field_passcount == 1);
922
0
                                TIFFGetField(tif, o->field_tag, &pa, &pb);
923
0
                                if (!TIFFWriteDirectoryTagUndefinedArray(
924
0
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
925
0
                                        pa, pb))
926
0
                                    goto bad;
927
0
                            }
928
0
                            break;
929
0
                            default:
930
0
                                TIFFErrorExtR(
931
0
                                    tif, module,
932
0
                                    "Cannot write tag %" PRIu32 " (%s)",
933
0
                                    TIFFFieldTag(o),
934
0
                                    o->field_name ? o->field_name : "unknown");
935
0
                                goto bad;
936
0
                        }
937
0
                    }
938
0
                }
939
0
            }
940
0
        }
941
0
        for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
942
0
        {
943
0
            uint16_t tag =
944
0
                (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
945
0
            uint32_t count = tif->tif_dir.td_customValues[m].count;
946
0
            switch (tif->tif_dir.td_customValues[m].info->field_type)
947
0
            {
948
0
                case TIFF_ASCII:
949
0
                    if (!TIFFWriteDirectoryTagAscii(
950
0
                            tif, &ndir, dir, tag, count,
951
0
                            tif->tif_dir.td_customValues[m].value))
952
0
                        goto bad;
953
0
                    break;
954
0
                case TIFF_UNDEFINED:
955
0
                    if (!TIFFWriteDirectoryTagUndefinedArray(
956
0
                            tif, &ndir, dir, tag, count,
957
0
                            tif->tif_dir.td_customValues[m].value))
958
0
                        goto bad;
959
0
                    break;
960
0
                case TIFF_BYTE:
961
0
                    if (!TIFFWriteDirectoryTagByteArray(
962
0
                            tif, &ndir, dir, tag, count,
963
0
                            tif->tif_dir.td_customValues[m].value))
964
0
                        goto bad;
965
0
                    break;
966
0
                case TIFF_SBYTE:
967
0
                    if (!TIFFWriteDirectoryTagSbyteArray(
968
0
                            tif, &ndir, dir, tag, count,
969
0
                            tif->tif_dir.td_customValues[m].value))
970
0
                        goto bad;
971
0
                    break;
972
0
                case TIFF_SHORT:
973
0
                    if (!TIFFWriteDirectoryTagShortArray(
974
0
                            tif, &ndir, dir, tag, count,
975
0
                            tif->tif_dir.td_customValues[m].value))
976
0
                        goto bad;
977
0
                    break;
978
0
                case TIFF_SSHORT:
979
0
                    if (!TIFFWriteDirectoryTagSshortArray(
980
0
                            tif, &ndir, dir, tag, count,
981
0
                            tif->tif_dir.td_customValues[m].value))
982
0
                        goto bad;
983
0
                    break;
984
0
                case TIFF_LONG:
985
0
                    if (!TIFFWriteDirectoryTagLongArray(
986
0
                            tif, &ndir, dir, tag, count,
987
0
                            tif->tif_dir.td_customValues[m].value))
988
0
                        goto bad;
989
0
                    break;
990
0
                case TIFF_SLONG:
991
0
                    if (!TIFFWriteDirectoryTagSlongArray(
992
0
                            tif, &ndir, dir, tag, count,
993
0
                            tif->tif_dir.td_customValues[m].value))
994
0
                        goto bad;
995
0
                    break;
996
0
                case TIFF_LONG8:
997
0
                    if (!TIFFWriteDirectoryTagLong8Array(
998
0
                            tif, &ndir, dir, tag, count,
999
0
                            tif->tif_dir.td_customValues[m].value))
1000
0
                        goto bad;
1001
0
                    break;
1002
0
                case TIFF_SLONG8:
1003
0
                    if (!TIFFWriteDirectoryTagSlong8Array(
1004
0
                            tif, &ndir, dir, tag, count,
1005
0
                            tif->tif_dir.td_customValues[m].value))
1006
0
                        goto bad;
1007
0
                    break;
1008
0
                case TIFF_RATIONAL:
1009
0
                {
1010
                    /*-- Rational2Double: For Rationals evaluate
1011
                     * "set_field_type" to determine internal storage size. */
1012
0
                    int tv_size;
1013
0
                    tv_size = TIFFFieldSetGetSize(
1014
0
                        tif->tif_dir.td_customValues[m].info);
1015
0
                    if (tv_size == 8)
1016
0
                    {
1017
0
                        if (!TIFFWriteDirectoryTagRationalDoubleArray(
1018
0
                                tif, &ndir, dir, tag, count,
1019
0
                                tif->tif_dir.td_customValues[m].value))
1020
0
                            goto bad;
1021
0
                    }
1022
0
                    else
1023
0
                    {
1024
                        /*-- default should be tv_size == 4 */
1025
0
                        if (!TIFFWriteDirectoryTagRationalArray(
1026
0
                                tif, &ndir, dir, tag, count,
1027
0
                                tif->tif_dir.td_customValues[m].value))
1028
0
                            goto bad;
1029
                        /*-- ToDo: After Testing, this should be removed and
1030
                         * tv_size==4 should be set as default. */
1031
0
                        if (tv_size != 4)
1032
0
                        {
1033
0
                            TIFFErrorExtR(tif,
1034
0
                                          "TIFFLib: _TIFFWriteDirectorySec()",
1035
0
                                          "Rational2Double: .set_field_type is "
1036
0
                                          "not 4 but %d",
1037
0
                                          tv_size);
1038
0
                        }
1039
0
                    }
1040
0
                }
1041
0
                break;
1042
0
                case TIFF_SRATIONAL:
1043
0
                {
1044
                    /*-- Rational2Double: For Rationals evaluate
1045
                     * "set_field_type" to determine internal storage size. */
1046
0
                    int tv_size;
1047
0
                    tv_size = TIFFFieldSetGetSize(
1048
0
                        tif->tif_dir.td_customValues[m].info);
1049
0
                    if (tv_size == 8)
1050
0
                    {
1051
0
                        if (!TIFFWriteDirectoryTagSrationalDoubleArray(
1052
0
                                tif, &ndir, dir, tag, count,
1053
0
                                tif->tif_dir.td_customValues[m].value))
1054
0
                            goto bad;
1055
0
                    }
1056
0
                    else
1057
0
                    {
1058
                        /*-- default should be tv_size == 4 */
1059
0
                        if (!TIFFWriteDirectoryTagSrationalArray(
1060
0
                                tif, &ndir, dir, tag, count,
1061
0
                                tif->tif_dir.td_customValues[m].value))
1062
0
                            goto bad;
1063
                        /*-- ToDo: After Testing, this should be removed and
1064
                         * tv_size==4 should be set as default. */
1065
0
                        if (tv_size != 4)
1066
0
                        {
1067
0
                            TIFFErrorExtR(tif,
1068
0
                                          "TIFFLib: _TIFFWriteDirectorySec()",
1069
0
                                          "Rational2Double: .set_field_type is "
1070
0
                                          "not 4 but %d",
1071
0
                                          tv_size);
1072
0
                        }
1073
0
                    }
1074
0
                }
1075
0
                break;
1076
0
                case TIFF_FLOAT:
1077
0
                    if (!TIFFWriteDirectoryTagFloatArray(
1078
0
                            tif, &ndir, dir, tag, count,
1079
0
                            tif->tif_dir.td_customValues[m].value))
1080
0
                        goto bad;
1081
0
                    break;
1082
0
                case TIFF_DOUBLE:
1083
0
                    if (!TIFFWriteDirectoryTagDoubleArray(
1084
0
                            tif, &ndir, dir, tag, count,
1085
0
                            tif->tif_dir.td_customValues[m].value))
1086
0
                        goto bad;
1087
0
                    break;
1088
0
                case TIFF_IFD:
1089
0
                    if (!TIFFWriteDirectoryTagIfdArray(
1090
0
                            tif, &ndir, dir, tag, count,
1091
0
                            tif->tif_dir.td_customValues[m].value))
1092
0
                        goto bad;
1093
0
                    break;
1094
0
                case TIFF_IFD8:
1095
0
                    if (!TIFFWriteDirectoryTagIfdIfd8Array(
1096
0
                            tif, &ndir, dir, tag, count,
1097
0
                            tif->tif_dir.td_customValues[m].value))
1098
0
                        goto bad;
1099
0
                    break;
1100
0
                default:
1101
0
                    assert(0); /* we should never get here */
1102
0
                    break;
1103
0
            }
1104
0
        }
1105
        /* "break" if IFD has been written above in second pass.*/
1106
0
        if (dir != NULL)
1107
0
            break;
1108
1109
        /* Evaluate IFD data size: Finally, add the size of the IFD tag entries
1110
         * themselves. */
1111
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
1112
0
            tif->tif_dir.td_dirdatasize_write += 2 + ndir * 12 + 4;
1113
0
        else
1114
0
            tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
1115
1116
        /* Setup a new directory within first pass. */
1117
0
        dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
1118
0
        if (dir == NULL)
1119
0
        {
1120
0
            TIFFErrorExtR(tif, module, "Out of memory");
1121
0
            goto bad;
1122
0
        }
1123
0
        if (isimage)
1124
0
        {
1125
            /* Check, weather the IFD to be written is new or an already written
1126
             * IFD can be overwritten or needs to be re-written to a different
1127
             * location in the file because the IFD is extended with additional
1128
             * tags or the IFD data size is increased.
1129
             * - tif_diroff == 0, if a new directory has to be linked.
1130
             * - tif_diroff != 0, IFD has been re-read from file and will be
1131
             *   overwritten or re-written.
1132
             */
1133
0
            if (tif->tif_diroff == 0)
1134
0
            {
1135
0
                if (!TIFFLinkDirectory(tif))
1136
0
                    goto bad;
1137
0
            }
1138
0
            else if (tif->tif_dir.td_dirdatasize_write >
1139
0
                     tif->tif_dir.td_dirdatasize_read)
1140
0
            {
1141
0
                if (dir != NULL)
1142
0
                {
1143
0
                    _TIFFfreeExt(tif, dir);
1144
0
                    dir = NULL;
1145
0
                }
1146
0
                if (!TIFFRewriteDirectorySec(tif, isimage, imagedone, pdiroff))
1147
0
                    goto bad;
1148
0
                return (1);
1149
0
            }
1150
0
        }
1151
0
        else
1152
0
        {
1153
            /* For !isimage, which means custom-IFD like EXIFIFD or
1154
             * checkpointing an IFD, determine whether to overwrite or append at
1155
             * the end of the file.
1156
             */
1157
0
            if (!((tif->tif_dir.td_dirdatasize_read > 0) &&
1158
0
                  (tif->tif_dir.td_dirdatasize_write <=
1159
0
                   tif->tif_dir.td_dirdatasize_read)))
1160
0
            {
1161
                /* Append at end of file and increment to an even offset. */
1162
0
                tif->tif_diroff =
1163
0
                    (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
1164
0
            }
1165
0
        }
1166
        /* Return IFD offset */
1167
0
        if (pdiroff != NULL)
1168
0
            *pdiroff = tif->tif_diroff;
1169
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
1170
0
            dirsize = 2 + ndir * 12 + 4;
1171
0
        else
1172
0
            dirsize = 8 + ndir * 20 + 8;
1173
        /* Append IFD data stright after the IFD tag entries.
1174
         * Data that does not fit into an IFD tag entry is written to the file
1175
         * in the second pass of the while loop. That offset is stored in "dir".
1176
         */
1177
0
        tif->tif_dataoff = tif->tif_diroff + dirsize;
1178
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
1179
0
            tif->tif_dataoff = (uint32_t)tif->tif_dataoff;
1180
0
        if ((tif->tif_dataoff < tif->tif_diroff) ||
1181
0
            (tif->tif_dataoff < (uint64_t)dirsize))
1182
0
        {
1183
0
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
1184
0
            goto bad;
1185
0
        }
1186
0
        if (tif->tif_dataoff & 1)
1187
0
            tif->tif_dataoff++;
1188
0
        if (isimage)
1189
0
        {
1190
0
            if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
1191
0
                tif->tif_curdir = 0;
1192
0
            else
1193
0
                tif->tif_curdir++;
1194
0
        }
1195
0
    } /* while() */
1196
0
    if (isimage)
1197
0
    {
1198
        /* For SubIFDs remember offset of SubIFD tag within main IFD. */
1199
0
        if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
1200
0
        {
1201
0
            uint32_t na;
1202
0
            TIFFDirEntry *nb;
1203
0
            for (na = 0, nb = dir;; na++, nb++)
1204
0
            {
1205
0
                if (na == ndir)
1206
0
                {
1207
0
                    TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
1208
0
                    goto bad;
1209
0
                }
1210
0
                if (nb->tdir_tag == TIFFTAG_SUBIFD)
1211
0
                    break;
1212
0
            }
1213
0
            if (!(tif->tif_flags & TIFF_BIGTIFF))
1214
0
                tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8;
1215
0
            else
1216
0
                tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12;
1217
0
        }
1218
0
    }
1219
    /* Copy/swab IFD entries from "dir" into "dirmem",
1220
     * which is then written to file. */
1221
0
    dirmem = _TIFFmallocExt(tif, dirsize);
1222
0
    if (dirmem == NULL)
1223
0
    {
1224
0
        TIFFErrorExtR(tif, module, "Out of memory");
1225
0
        goto bad;
1226
0
    }
1227
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
1228
0
    {
1229
0
        uint8_t *n;
1230
0
        uint32_t nTmp;
1231
0
        TIFFDirEntry *o;
1232
0
        n = dirmem;
1233
0
        *(uint16_t *)n = (uint16_t)ndir;
1234
0
        if (tif->tif_flags & TIFF_SWAB)
1235
0
            TIFFSwabShort((uint16_t *)n);
1236
0
        n += 2;
1237
0
        o = dir;
1238
0
        for (m = 0; m < ndir; m++)
1239
0
        {
1240
0
            *(uint16_t *)n = o->tdir_tag;
1241
0
            if (tif->tif_flags & TIFF_SWAB)
1242
0
                TIFFSwabShort((uint16_t *)n);
1243
0
            n += 2;
1244
0
            *(uint16_t *)n = o->tdir_type;
1245
0
            if (tif->tif_flags & TIFF_SWAB)
1246
0
                TIFFSwabShort((uint16_t *)n);
1247
0
            n += 2;
1248
0
            nTmp = (uint32_t)o->tdir_count;
1249
0
            _TIFFmemcpy(n, &nTmp, 4);
1250
0
            if (tif->tif_flags & TIFF_SWAB)
1251
0
                TIFFSwabLong((uint32_t *)n);
1252
0
            n += 4;
1253
            /* This is correct. The data has been */
1254
            /* swabbed previously in TIFFWriteDirectoryTagData */
1255
0
            _TIFFmemcpy(n, &o->tdir_offset, 4);
1256
0
            n += 4;
1257
0
            o++;
1258
0
        }
1259
0
        nTmp = (uint32_t)tif->tif_nextdiroff;
1260
0
        if (tif->tif_flags & TIFF_SWAB)
1261
0
            TIFFSwabLong(&nTmp);
1262
0
        _TIFFmemcpy(n, &nTmp, 4);
1263
0
    }
1264
0
    else
1265
0
    {
1266
0
        uint8_t *n;
1267
0
        TIFFDirEntry *o;
1268
0
        n = dirmem;
1269
0
        *(uint64_t *)n = ndir;
1270
0
        if (tif->tif_flags & TIFF_SWAB)
1271
0
            TIFFSwabLong8((uint64_t *)n);
1272
0
        n += 8;
1273
0
        o = dir;
1274
0
        for (m = 0; m < ndir; m++)
1275
0
        {
1276
0
            *(uint16_t *)n = o->tdir_tag;
1277
0
            if (tif->tif_flags & TIFF_SWAB)
1278
0
                TIFFSwabShort((uint16_t *)n);
1279
0
            n += 2;
1280
0
            *(uint16_t *)n = o->tdir_type;
1281
0
            if (tif->tif_flags & TIFF_SWAB)
1282
0
                TIFFSwabShort((uint16_t *)n);
1283
0
            n += 2;
1284
0
            _TIFFmemcpy(n, &o->tdir_count, 8);
1285
0
            if (tif->tif_flags & TIFF_SWAB)
1286
0
                TIFFSwabLong8((uint64_t *)n);
1287
0
            n += 8;
1288
0
            _TIFFmemcpy(n, &o->tdir_offset, 8);
1289
0
            n += 8;
1290
0
            o++;
1291
0
        }
1292
0
        _TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
1293
0
        if (tif->tif_flags & TIFF_SWAB)
1294
0
            TIFFSwabLong8((uint64_t *)n);
1295
0
    }
1296
0
    _TIFFfreeExt(tif, dir);
1297
0
    dir = NULL;
1298
0
    if (!SeekOK(tif, tif->tif_diroff))
1299
0
    {
1300
0
        TIFFErrorExtR(tif, module, "IO error writing directory");
1301
0
        goto bad;
1302
0
    }
1303
0
    if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
1304
0
    {
1305
0
        TIFFErrorExtR(tif, module, "IO error writing directory");
1306
0
        goto bad;
1307
0
    }
1308
0
    _TIFFfreeExt(tif, dirmem);
1309
0
    if (imagedone)
1310
0
    {
1311
0
        TIFFFreeDirectory(tif);
1312
0
        tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1313
0
        tif->tif_flags &= ~TIFF_DIRTYSTRIP;
1314
0
        (*tif->tif_cleanup)(tif);
1315
        /* Reset directory-related state for subsequent directories. */
1316
0
        TIFFCreateDirectory(tif);
1317
0
    }
1318
0
    else
1319
0
    {
1320
        /* IFD is only checkpointed to file, thus set IFD data size written to
1321
         * file.
1322
         */
1323
0
        tif->tif_dir.td_dirdatasize_read = tif->tif_dir.td_dirdatasize_write;
1324
0
    }
1325
0
    return (1);
1326
0
bad:
1327
0
    if (dir != NULL)
1328
0
        _TIFFfreeExt(tif, dir);
1329
0
    if (dirmem != NULL)
1330
0
        _TIFFfreeExt(tif, dirmem);
1331
0
    return (0);
1332
0
}
1333
1334
static int8_t TIFFClampDoubleToInt8(double val)
1335
0
{
1336
0
    if (val > 127)
1337
0
        return 127;
1338
0
    if (val < -128 || val != val)
1339
0
        return -128;
1340
0
    return (int8_t)val;
1341
0
}
1342
1343
static int16_t TIFFClampDoubleToInt16(double val)
1344
0
{
1345
0
    if (val > 32767)
1346
0
        return 32767;
1347
0
    if (val < -32768 || val != val)
1348
0
        return -32768;
1349
0
    return (int16_t)val;
1350
0
}
1351
1352
static int32_t TIFFClampDoubleToInt32(double val)
1353
0
{
1354
0
    if (val > 0x7FFFFFFF)
1355
0
        return 0x7FFFFFFF;
1356
0
    if (val < -0x7FFFFFFF - 1 || val != val)
1357
0
        return -0x7FFFFFFF - 1;
1358
0
    return (int32_t)val;
1359
0
}
1360
1361
static uint8_t TIFFClampDoubleToUInt8(double val)
1362
0
{
1363
0
    if (val < 0)
1364
0
        return 0;
1365
0
    if (val > 255 || val != val)
1366
0
        return 255;
1367
0
    return (uint8_t)val;
1368
0
}
1369
1370
static uint16_t TIFFClampDoubleToUInt16(double val)
1371
0
{
1372
0
    if (val < 0)
1373
0
        return 0;
1374
0
    if (val > 65535 || val != val)
1375
0
        return 65535;
1376
0
    return (uint16_t)val;
1377
0
}
1378
1379
static uint32_t TIFFClampDoubleToUInt32(double val)
1380
0
{
1381
0
    if (val < 0)
1382
0
        return 0;
1383
0
    if (val > 0xFFFFFFFFU || val != val)
1384
0
        return 0xFFFFFFFFU;
1385
0
    return (uint32_t)val;
1386
0
}
1387
1388
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
1389
                                                  TIFFDirEntry *dir,
1390
                                                  uint16_t tag, uint32_t count,
1391
                                                  double *value)
1392
0
{
1393
0
    static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
1394
0
    void *conv;
1395
0
    uint32_t i;
1396
0
    int ok;
1397
0
    conv = _TIFFmallocExt(tif, count * sizeof(double));
1398
0
    if (conv == NULL)
1399
0
    {
1400
0
        TIFFErrorExtR(tif, module, "Out of memory");
1401
0
        return (0);
1402
0
    }
1403
1404
0
    switch (tif->tif_dir.td_sampleformat)
1405
0
    {
1406
0
        case SAMPLEFORMAT_IEEEFP:
1407
0
            if (tif->tif_dir.td_bitspersample <= 32)
1408
0
            {
1409
0
                for (i = 0; i < count; ++i)
1410
0
                    ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
1411
0
                ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count,
1412
0
                                                     (float *)conv);
1413
0
            }
1414
0
            else
1415
0
            {
1416
0
                ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
1417
0
                                                      count, value);
1418
0
            }
1419
0
            break;
1420
0
        case SAMPLEFORMAT_INT:
1421
0
            if (tif->tif_dir.td_bitspersample <= 8)
1422
0
            {
1423
0
                for (i = 0; i < count; ++i)
1424
0
                    ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]);
1425
0
                ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count,
1426
0
                                                     (int8_t *)conv);
1427
0
            }
1428
0
            else if (tif->tif_dir.td_bitspersample <= 16)
1429
0
            {
1430
0
                for (i = 0; i < count; ++i)
1431
0
                    ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]);
1432
0
                ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag,
1433
0
                                                      count, (int16_t *)conv);
1434
0
            }
1435
0
            else
1436
0
            {
1437
0
                for (i = 0; i < count; ++i)
1438
0
                    ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]);
1439
0
                ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count,
1440
0
                                                     (int32_t *)conv);
1441
0
            }
1442
0
            break;
1443
0
        case SAMPLEFORMAT_UINT:
1444
0
            if (tif->tif_dir.td_bitspersample <= 8)
1445
0
            {
1446
0
                for (i = 0; i < count; ++i)
1447
0
                    ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
1448
0
                ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count,
1449
0
                                                    (uint8_t *)conv);
1450
0
            }
1451
0
            else if (tif->tif_dir.td_bitspersample <= 16)
1452
0
            {
1453
0
                for (i = 0; i < count; ++i)
1454
0
                    ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
1455
0
                ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count,
1456
0
                                                     (uint16_t *)conv);
1457
0
            }
1458
0
            else
1459
0
            {
1460
0
                for (i = 0; i < count; ++i)
1461
0
                    ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
1462
0
                ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count,
1463
0
                                                    (uint32_t *)conv);
1464
0
            }
1465
0
            break;
1466
0
        default:
1467
0
            ok = 0;
1468
0
    }
1469
1470
0
    _TIFFfreeExt(tif, conv);
1471
0
    return (ok);
1472
0
}
1473
1474
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
1475
                                      TIFFDirEntry *dir, uint16_t tag,
1476
                                      uint32_t count, char *value)
1477
0
{
1478
0
    return (
1479
0
        TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
1480
0
}
1481
1482
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
1483
                                               TIFFDirEntry *dir, uint16_t tag,
1484
                                               uint32_t count, uint8_t *value)
1485
0
{
1486
0
    return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
1487
0
                                                       count, value));
1488
0
}
1489
1490
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
1491
                                          TIFFDirEntry *dir, uint16_t tag,
1492
                                          uint32_t count, uint8_t *value)
1493
0
{
1494
0
    return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
1495
0
                                                  value));
1496
0
}
1497
1498
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
1499
                                           TIFFDirEntry *dir, uint16_t tag,
1500
                                           uint32_t count, int8_t *value)
1501
0
{
1502
0
    return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
1503
0
                                                   value));
1504
0
}
1505
1506
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
1507
                                      TIFFDirEntry *dir, uint16_t tag,
1508
                                      uint16_t value)
1509
0
{
1510
0
    return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
1511
0
}
1512
1513
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
1514
                                           TIFFDirEntry *dir, uint16_t tag,
1515
                                           uint32_t count, uint16_t *value)
1516
0
{
1517
0
    return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1518
0
                                                   value));
1519
0
}
1520
1521
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
1522
                                               TIFFDirEntry *dir, uint16_t tag,
1523
                                               uint16_t value)
1524
0
{
1525
0
    static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1526
0
    uint16_t *m;
1527
0
    uint16_t *na;
1528
0
    uint16_t nb;
1529
0
    int o;
1530
0
    if (dir == NULL)
1531
0
    {
1532
        /* only evaluate IFD data size and inc. ndir */
1533
0
        return (TIFFWriteDirectoryTagCheckedShortArray(
1534
0
            tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
1535
0
    }
1536
0
    m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
1537
0
    if (m == NULL)
1538
0
    {
1539
0
        TIFFErrorExtR(tif, module, "Out of memory");
1540
0
        return (0);
1541
0
    }
1542
0
    for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
1543
0
        *na = value;
1544
0
    o = TIFFWriteDirectoryTagCheckedShortArray(
1545
0
        tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
1546
0
    _TIFFfreeExt(tif, m);
1547
0
    return (o);
1548
0
}
1549
1550
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
1551
                                            TIFFDirEntry *dir, uint16_t tag,
1552
                                            uint32_t count, int16_t *value)
1553
0
{
1554
0
    return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
1555
0
                                                    value));
1556
0
}
1557
1558
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
1559
                                     TIFFDirEntry *dir, uint16_t tag,
1560
                                     uint32_t value)
1561
0
{
1562
0
    return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1563
0
}
1564
1565
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
1566
                                          TIFFDirEntry *dir, uint16_t tag,
1567
                                          uint32_t count, uint32_t *value)
1568
0
{
1569
0
    return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1570
0
                                                  value));
1571
0
}
1572
1573
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
1574
                                           TIFFDirEntry *dir, uint16_t tag,
1575
                                           uint32_t count, int32_t *value)
1576
0
{
1577
0
    return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
1578
0
                                                   value));
1579
0
}
1580
1581
/************************************************************************/
1582
/*                 TIFFWriteDirectoryTagLong8Array()                    */
1583
/*                                                                      */
1584
/*      Write either Long8 or Long array depending on file type.        */
1585
/************************************************************************/
1586
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
1587
                                           TIFFDirEntry *dir, uint16_t tag,
1588
                                           uint32_t count, uint64_t *value)
1589
0
{
1590
0
    static const char module[] = "TIFFWriteDirectoryTagLong8Array";
1591
0
    uint64_t *ma;
1592
0
    uint32_t mb;
1593
0
    uint32_t *p;
1594
0
    uint32_t *q;
1595
0
    int o;
1596
1597
    /* is this just a counting pass? */
1598
0
    if (dir == NULL)
1599
0
    {
1600
        /* only evaluate IFD data size and inc. ndir */
1601
0
        return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1602
0
                                                       count, value));
1603
0
    }
1604
1605
    /* We always write Long8 for BigTIFF, no checking needed. */
1606
0
    if (tif->tif_flags & TIFF_BIGTIFF)
1607
0
        return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1608
0
                                                       count, value));
1609
1610
    /*
1611
    ** For classic tiff we want to verify everything is in range for long
1612
    ** and convert to long format.
1613
    */
1614
0
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1615
0
    if (p == NULL)
1616
0
    {
1617
0
        TIFFErrorExtR(tif, module, "Out of memory");
1618
0
        return (0);
1619
0
    }
1620
1621
0
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1622
0
    {
1623
0
        if (*ma > 0xFFFFFFFF)
1624
0
        {
1625
0
            TIFFErrorExtR(tif, module,
1626
0
                          "Attempt to write unsigned long value %" PRIu64
1627
0
                          " larger than 0xFFFFFFFF for tag %d in Classic TIFF "
1628
0
                          "file. TIFF file writing aborted",
1629
0
                          *ma, tag);
1630
0
            _TIFFfreeExt(tif, p);
1631
0
            return (0);
1632
0
        }
1633
0
        *q = (uint32_t)(*ma);
1634
0
    }
1635
1636
0
    o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
1637
0
    _TIFFfreeExt(tif, p);
1638
1639
0
    return (o);
1640
0
}
1641
1642
/************************************************************************/
1643
/*                 TIFFWriteDirectoryTagSlong8Array()                   */
1644
/*                                                                      */
1645
/*      Write either SLong8 or SLong array depending on file type.      */
1646
/************************************************************************/
1647
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
1648
                                            TIFFDirEntry *dir, uint16_t tag,
1649
                                            uint32_t count, int64_t *value)
1650
0
{
1651
0
    static const char module[] = "TIFFWriteDirectoryTagSlong8Array";
1652
0
    int64_t *ma;
1653
0
    uint32_t mb;
1654
0
    int32_t *p;
1655
0
    int32_t *q;
1656
0
    int o;
1657
1658
    /* is this just a counting pass? */
1659
0
    if (dir == NULL)
1660
0
    {
1661
        /* only evaluate IFD data size and inc. ndir */
1662
0
        return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
1663
0
                                                        count, value));
1664
0
    }
1665
    /* We always write SLong8 for BigTIFF, no checking needed. */
1666
0
    if (tif->tif_flags & TIFF_BIGTIFF)
1667
0
        return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
1668
0
                                                        count, value));
1669
1670
    /*
1671
    ** For classic tiff we want to verify everything is in range for signed-long
1672
    ** and convert to signed-long format.
1673
    */
1674
0
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1675
0
    if (p == NULL)
1676
0
    {
1677
0
        TIFFErrorExtR(tif, module, "Out of memory");
1678
0
        return (0);
1679
0
    }
1680
1681
0
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1682
0
    {
1683
0
        if (*ma > (2147483647))
1684
0
        {
1685
0
            TIFFErrorExtR(tif, module,
1686
0
                          "Attempt to write signed long value %" PRIi64
1687
0
                          " larger than 0x7FFFFFFF (2147483647) for tag %d in "
1688
0
                          "Classic TIFF file. TIFF writing to file aborted",
1689
0
                          *ma, tag);
1690
0
            _TIFFfreeExt(tif, p);
1691
0
            return (0);
1692
0
        }
1693
0
        else if (*ma < (-2147483647 - 1))
1694
0
        {
1695
0
            TIFFErrorExtR(tif, module,
1696
0
                          "Attempt to write signed long value %" PRIi64
1697
0
                          " smaller than 0x80000000 (-2147483648) for tag %d "
1698
0
                          "in Classic TIFF file. TIFF writing to file aborted",
1699
0
                          *ma, tag);
1700
0
            _TIFFfreeExt(tif, p);
1701
0
            return (0);
1702
0
        }
1703
0
        *q = (int32_t)(*ma);
1704
0
    }
1705
1706
0
    o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p);
1707
0
    _TIFFfreeExt(tif, p);
1708
1709
0
    return (o);
1710
0
}
1711
1712
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
1713
                                         TIFFDirEntry *dir, uint16_t tag,
1714
                                         double value)
1715
0
{
1716
0
    return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
1717
0
}
1718
1719
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
1720
                                              TIFFDirEntry *dir, uint16_t tag,
1721
                                              uint32_t count, float *value)
1722
0
{
1723
0
    return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
1724
0
                                                      count, value));
1725
0
}
1726
1727
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
1728
                                               TIFFDirEntry *dir, uint16_t tag,
1729
                                               uint32_t count, float *value)
1730
0
{
1731
0
    return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
1732
0
                                                       count, value));
1733
0
}
1734
1735
/*-- Rational2Double: additional write functions */
1736
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
1737
                                                    TIFFDirEntry *dir,
1738
                                                    uint16_t tag,
1739
                                                    uint32_t count,
1740
                                                    double *value)
1741
0
{
1742
0
    return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
1743
0
                                                            count, value));
1744
0
}
1745
1746
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
1747
                                                     TIFFDirEntry *dir,
1748
                                                     uint16_t tag,
1749
                                                     uint32_t count,
1750
                                                     double *value)
1751
0
{
1752
0
    return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
1753
0
        tif, ndir, dir, tag, count, value));
1754
0
}
1755
1756
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
1757
                                           TIFFDirEntry *dir, uint16_t tag,
1758
                                           uint32_t count, float *value)
1759
0
{
1760
0
    return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
1761
0
                                                   value));
1762
0
}
1763
1764
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
1765
                                            TIFFDirEntry *dir, uint16_t tag,
1766
                                            uint32_t count, double *value)
1767
0
{
1768
0
    return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
1769
0
                                                    value));
1770
0
}
1771
1772
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
1773
                                         TIFFDirEntry *dir, uint16_t tag,
1774
                                         uint32_t count, uint32_t *value)
1775
0
{
1776
0
    return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
1777
0
                                                 value));
1778
0
}
1779
1780
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
1781
                                          TIFFDirEntry *dir, uint16_t tag,
1782
                                          uint32_t value)
1783
0
{
1784
0
    if (value <= 0xFFFF)
1785
0
        return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
1786
0
                                                  (uint16_t)value));
1787
0
    else
1788
0
        return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1789
0
}
1790
1791
static int _WriteAsType(TIFF *tif, uint64_t strile_size,
1792
                        uint64_t uncompressed_threshold)
1793
0
{
1794
0
    const uint16_t compression = tif->tif_dir.td_compression;
1795
0
    if (compression == COMPRESSION_NONE)
1796
0
    {
1797
0
        return strile_size > uncompressed_threshold;
1798
0
    }
1799
0
    else if (compression == COMPRESSION_JPEG ||
1800
0
             compression == COMPRESSION_LZW ||
1801
0
             compression == COMPRESSION_ADOBE_DEFLATE ||
1802
0
             compression == COMPRESSION_DEFLATE ||
1803
0
             compression == COMPRESSION_LZMA ||
1804
0
             compression == COMPRESSION_LERC ||
1805
0
             compression == COMPRESSION_ZSTD ||
1806
0
             compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL)
1807
0
    {
1808
        /* For a few select compression types, we assume that in the worst */
1809
        /* case the compressed size will be 10 times the uncompressed size. */
1810
        /* This is overly pessismistic ! */
1811
0
        return strile_size >= uncompressed_threshold / 10;
1812
0
    }
1813
0
    return 1;
1814
0
}
1815
1816
static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
1817
0
{
1818
0
    return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
1819
0
}
1820
1821
static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
1822
0
{
1823
0
    return _WriteAsType(tif, strile_size, 0xFFFFU);
1824
0
}
1825
1826
/************************************************************************/
1827
/*                TIFFWriteDirectoryTagLongLong8Array()                 */
1828
/*                                                                      */
1829
/*      Write out LONG8 array and write a SHORT/LONG/LONG8 depending    */
1830
/*      on strile size and Classic/BigTIFF mode.                        */
1831
/************************************************************************/
1832
1833
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
1834
                                               TIFFDirEntry *dir, uint16_t tag,
1835
                                               uint32_t count, uint64_t *value)
1836
0
{
1837
0
    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1838
0
    int o;
1839
0
    int write_aslong4;
1840
1841
0
    if (tif->tif_dir.td_deferstrilearraywriting)
1842
0
    {
1843
0
        if (dir == NULL)
1844
0
        {
1845
            /* This is just a counting pass to count IFD entries.
1846
             * For deferstrilearraywriting no extra bytes will be written
1847
             * into IFD space. */
1848
0
            (*ndir)++;
1849
0
            return 1;
1850
0
        }
1851
0
        return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
1852
0
                                         NULL);
1853
0
    }
1854
1855
0
    if (tif->tif_flags & TIFF_BIGTIFF)
1856
0
    {
1857
0
        int write_aslong8 = 1;
1858
        /* In the case of ByteCounts array, we may be able to write them on LONG
1859
         * if the strip/tilesize is not too big. Also do that for count > 1 in
1860
         * the case someone would want to create a single-strip file with a
1861
         * growing height, in which case using LONG8 will be safer. */
1862
0
        if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1863
0
        {
1864
0
            write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
1865
0
        }
1866
0
        else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1867
0
        {
1868
0
            write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
1869
0
        }
1870
0
        if (write_aslong8)
1871
0
        {
1872
0
            return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1873
0
                                                          count, value);
1874
0
        }
1875
0
    }
1876
1877
0
    write_aslong4 = 1;
1878
0
    if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1879
0
    {
1880
0
        write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
1881
0
    }
1882
0
    else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1883
0
    {
1884
0
        write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1885
0
    }
1886
0
    if (write_aslong4)
1887
0
    {
1888
        /*
1889
        ** For classic tiff we want to verify everything is in range for LONG
1890
        ** and convert to long format.
1891
        */
1892
1893
0
        uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1894
0
        uint32_t *q;
1895
0
        uint64_t *ma;
1896
0
        uint32_t mb;
1897
1898
0
        if (p == NULL)
1899
0
        {
1900
0
            TIFFErrorExtR(tif, module, "Out of memory");
1901
0
            return (0);
1902
0
        }
1903
1904
0
        for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1905
0
        {
1906
0
            if (*ma > 0xFFFFFFFF)
1907
0
            {
1908
0
                TIFFErrorExtR(tif, module,
1909
0
                              "Attempt to write value larger than 0xFFFFFFFF "
1910
0
                              "in LONG array.");
1911
0
                _TIFFfreeExt(tif, p);
1912
0
                return (0);
1913
0
            }
1914
0
            *q = (uint32_t)(*ma);
1915
0
        }
1916
1917
0
        o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1918
0
                                                  p);
1919
0
        _TIFFfreeExt(tif, p);
1920
0
    }
1921
0
    else
1922
0
    {
1923
0
        uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
1924
0
        uint16_t *q;
1925
0
        uint64_t *ma;
1926
0
        uint32_t mb;
1927
1928
0
        if (p == NULL)
1929
0
        {
1930
0
            TIFFErrorExtR(tif, module, "Out of memory");
1931
0
            return (0);
1932
0
        }
1933
1934
0
        for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1935
0
        {
1936
0
            if (*ma > 0xFFFF)
1937
0
            {
1938
                /* Should not happen normally given the check we did before */
1939
0
                TIFFErrorExtR(tif, module,
1940
0
                              "Attempt to write value larger than 0xFFFF in "
1941
0
                              "SHORT array.");
1942
0
                _TIFFfreeExt(tif, p);
1943
0
                return (0);
1944
0
            }
1945
0
            *q = (uint16_t)(*ma);
1946
0
        }
1947
1948
0
        o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1949
0
                                                   p);
1950
0
        _TIFFfreeExt(tif, p);
1951
0
    }
1952
1953
0
    return (o);
1954
0
}
1955
1956
/************************************************************************/
1957
/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
1958
/*                                                                      */
1959
/*      Write either IFD8 or IFD array depending on file type.          */
1960
/************************************************************************/
1961
1962
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
1963
                                             TIFFDirEntry *dir, uint16_t tag,
1964
                                             uint32_t count, uint64_t *value)
1965
0
{
1966
0
    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
1967
0
    uint64_t *ma;
1968
0
    uint32_t mb;
1969
0
    uint32_t *p;
1970
0
    uint32_t *q;
1971
0
    int o;
1972
1973
    /* We always write IFD8 for BigTIFF, no checking needed. */
1974
0
    if (tif->tif_flags & TIFF_BIGTIFF)
1975
0
        return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count,
1976
0
                                                     value);
1977
1978
    /*
1979
    ** For classic tiff we want to verify everything is in range for IFD
1980
    ** and convert to long format.
1981
    */
1982
1983
0
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1984
0
    if (p == NULL)
1985
0
    {
1986
0
        TIFFErrorExtR(tif, module, "Out of memory");
1987
0
        return (0);
1988
0
    }
1989
1990
0
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1991
0
    {
1992
0
        if (*ma > 0xFFFFFFFF)
1993
0
        {
1994
0
            TIFFErrorExtR(tif, module,
1995
0
                          "Attempt to write value larger than 0xFFFFFFFF in "
1996
0
                          "Classic TIFF file.");
1997
0
            _TIFFfreeExt(tif, p);
1998
0
            return (0);
1999
0
        }
2000
0
        *q = (uint32_t)(*ma);
2001
0
    }
2002
2003
0
    o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
2004
0
    _TIFFfreeExt(tif, p);
2005
2006
0
    return (o);
2007
0
}
2008
2009
/*
2010
 * Auxiliary function to determine the IFD data size to be written to the file.
2011
 * The IFD data size is finally the size of the IFD tag entries plus the IFD
2012
 * data that is written directly after the IFD tag entries.
2013
 */
2014
static void EvaluateIFDdatasizeWrite(TIFF *tif, uint32_t count,
2015
                                     uint32_t typesize, uint32_t *ndir)
2016
0
{
2017
0
    uint64_t datalength = (uint64_t)count * typesize;
2018
0
    if (datalength > ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
2019
0
    {
2020
        /* LibTIFF increments write address to an even offset, thus datalength
2021
         * written is also incremented. */
2022
0
        if (datalength & 1)
2023
0
            datalength++;
2024
0
        tif->tif_dir.td_dirdatasize_write += datalength;
2025
0
    }
2026
0
    (*ndir)++;
2027
0
}
2028
2029
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
2030
                                         TIFFDirEntry *dir)
2031
0
{
2032
0
    static const char module[] = "TIFFWriteDirectoryTagColormap";
2033
0
    uint32_t m;
2034
0
    uint16_t *n;
2035
0
    int o;
2036
0
    m = (1 << tif->tif_dir.td_bitspersample);
2037
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2038
0
    {
2039
0
        EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir);
2040
0
        return 1;
2041
0
    }
2042
2043
0
    n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
2044
0
    if (n == NULL)
2045
0
    {
2046
0
        TIFFErrorExtR(tif, module, "Out of memory");
2047
0
        return (0);
2048
0
    }
2049
0
    _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
2050
0
    _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
2051
0
    _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
2052
0
    o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
2053
0
                                               3 * m, n);
2054
0
    _TIFFfreeExt(tif, n);
2055
0
    return (o);
2056
0
}
2057
2058
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
2059
                                                 TIFFDirEntry *dir)
2060
0
{
2061
0
    static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
2062
0
    uint32_t m;
2063
0
    uint16_t n;
2064
0
    uint16_t *o;
2065
0
    int p;
2066
    /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
2067
     *  (1 << BitsPerSample) * uint16_t values.
2068
     */
2069
0
    m = (1 << tif->tif_dir.td_bitspersample);
2070
    /* clang-format off */
2071
0
    n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
2072
    /* clang-format on */
2073
2074
    /* Check for proper number of transferfunctions */
2075
0
    for (int i = 0; i < n; i++)
2076
0
    {
2077
0
        if (tif->tif_dir.td_transferfunction[i] == NULL)
2078
0
        {
2079
0
            TIFFWarningExtR(tif, module,
2080
0
                            "Too few TransferFunctions provided. Tag "
2081
0
                            "not written to file");
2082
0
            return (1); /* Not an error; only tag is not written. */
2083
0
        }
2084
0
    }
2085
    /*
2086
     * Check if the table can be written as a single column,
2087
     * or if it must be written as 3 columns.  Note that we
2088
     * write a 3-column tag if there are 2 samples/pixel and
2089
     * a single column of data won't suffice--hmm.
2090
     */
2091
0
    if (n == 3)
2092
0
    {
2093
0
        if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2094
0
                         tif->tif_dir.td_transferfunction[2],
2095
0
                         m * sizeof(uint16_t)) &&
2096
0
            !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2097
0
                         tif->tif_dir.td_transferfunction[1],
2098
0
                         m * sizeof(uint16_t)))
2099
0
            n = 1;
2100
0
    }
2101
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2102
0
    {
2103
0
        EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir);
2104
0
        return 1;
2105
0
    }
2106
2107
0
    o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
2108
0
    if (o == NULL)
2109
0
    {
2110
0
        TIFFErrorExtR(tif, module, "Out of memory");
2111
0
        return (0);
2112
0
    }
2113
0
    _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
2114
0
                m * sizeof(uint16_t));
2115
0
    if (n > 1)
2116
0
        _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
2117
0
                    m * sizeof(uint16_t));
2118
0
    if (n > 2)
2119
0
        _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
2120
0
                    m * sizeof(uint16_t));
2121
0
    p = TIFFWriteDirectoryTagCheckedShortArray(
2122
0
        tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
2123
0
    _TIFFfreeExt(tif, o);
2124
0
    return (p);
2125
0
}
2126
2127
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
2128
                                       TIFFDirEntry *dir)
2129
0
{
2130
0
    static const char module[] = "TIFFWriteDirectoryTagSubifd";
2131
0
    uint64_t m;
2132
0
    int n;
2133
0
    if (tif->tif_dir.td_nsubifd == 0)
2134
0
        return (1);
2135
0
    m = tif->tif_dataoff;
2136
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
2137
0
    {
2138
0
        uint32_t *o;
2139
0
        uint64_t *pa;
2140
0
        uint32_t *pb;
2141
0
        uint16_t p;
2142
0
        o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
2143
0
        if (o == NULL)
2144
0
        {
2145
0
            TIFFErrorExtR(tif, module, "Out of memory");
2146
0
            return (0);
2147
0
        }
2148
0
        pa = tif->tif_dir.td_subifd;
2149
0
        pb = o;
2150
0
        for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
2151
0
        {
2152
0
            assert(pa != 0);
2153
2154
            /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
2155
             * is illegal) */
2156
0
            if (*pa > 0xFFFFFFFFUL)
2157
0
            {
2158
0
                TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
2159
0
                _TIFFfreeExt(tif, o);
2160
0
                return (0);
2161
0
            }
2162
0
            *pb++ = (uint32_t)(*pa++);
2163
0
        }
2164
0
        n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
2165
0
                                                 tif->tif_dir.td_nsubifd, o);
2166
0
        _TIFFfreeExt(tif, o);
2167
0
    }
2168
0
    else
2169
0
        n = TIFFWriteDirectoryTagCheckedIfd8Array(
2170
0
            tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
2171
0
            tif->tif_dir.td_subifd);
2172
2173
0
    if (dir == NULL)
2174
        /* Just have evaluated IFD data size and incremented ndir
2175
         * above in sub-functions. */
2176
0
        return (n);
2177
2178
0
    if (!n)
2179
0
        return (0);
2180
    /*
2181
     * Total hack: if this directory includes a SubIFD
2182
     * tag then force the next <n> directories to be
2183
     * written as ``sub directories'' of this one.  This
2184
     * is used to write things like thumbnails and
2185
     * image masks that one wants to keep out of the
2186
     * normal directory linkage access mechanism.
2187
     */
2188
0
    tif->tif_flags |= TIFF_INSUBIFD;
2189
0
    tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
2190
0
    if (tif->tif_dir.td_nsubifd == 1)
2191
0
        tif->tif_subifdoff = 0;
2192
0
    else
2193
0
        tif->tif_subifdoff = m;
2194
0
    return (1);
2195
0
}
2196
2197
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
2198
                                             TIFFDirEntry *dir, uint16_t tag,
2199
                                             uint32_t count, char *value)
2200
0
{
2201
0
    assert(sizeof(char) == 1);
2202
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2203
0
    {
2204
0
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2205
0
        return 1;
2206
0
    }
2207
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
2208
0
                                      count, value));
2209
0
}
2210
2211
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
2212
                                                      TIFFDirEntry *dir,
2213
                                                      uint16_t tag,
2214
                                                      uint32_t count,
2215
                                                      uint8_t *value)
2216
0
{
2217
0
    assert(sizeof(uint8_t) == 1);
2218
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2219
0
    {
2220
0
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2221
0
        return 1;
2222
0
    }
2223
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
2224
0
                                      count, count, value));
2225
0
}
2226
2227
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
2228
                                                 TIFFDirEntry *dir,
2229
                                                 uint16_t tag, uint32_t count,
2230
                                                 uint8_t *value)
2231
0
{
2232
0
    assert(sizeof(uint8_t) == 1);
2233
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2234
0
    {
2235
0
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2236
0
        return 1;
2237
0
    }
2238
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
2239
0
                                      count, value));
2240
0
}
2241
2242
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
2243
                                                  TIFFDirEntry *dir,
2244
                                                  uint16_t tag, uint32_t count,
2245
                                                  int8_t *value)
2246
0
{
2247
0
    assert(sizeof(int8_t) == 1);
2248
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2249
0
    {
2250
0
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2251
0
        return 1;
2252
0
    }
2253
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
2254
0
                                      count, value));
2255
0
}
2256
2257
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
2258
                                             TIFFDirEntry *dir, uint16_t tag,
2259
                                             uint16_t value)
2260
0
{
2261
0
    uint16_t m;
2262
0
    assert(sizeof(uint16_t) == 2);
2263
0
    if (dir == NULL)
2264
0
    {
2265
        /* No additional data to IFD data size just increment ndir. */
2266
0
        (*ndir)++;
2267
0
        return 1;
2268
0
    }
2269
0
    m = value;
2270
0
    if (tif->tif_flags & TIFF_SWAB)
2271
0
        TIFFSwabShort(&m);
2272
0
    return (
2273
0
        TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
2274
0
}
2275
2276
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
2277
                                                  TIFFDirEntry *dir,
2278
                                                  uint16_t tag, uint32_t count,
2279
                                                  uint16_t *value)
2280
0
{
2281
0
    assert(count < 0x80000000);
2282
0
    assert(sizeof(uint16_t) == 2);
2283
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2284
0
    {
2285
0
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
2286
0
        return 1;
2287
0
    }
2288
0
    if (tif->tif_flags & TIFF_SWAB)
2289
0
        TIFFSwabArrayOfShort(value, count);
2290
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
2291
0
                                      count * 2, value));
2292
0
}
2293
2294
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
2295
                                                   TIFFDirEntry *dir,
2296
                                                   uint16_t tag, uint32_t count,
2297
                                                   int16_t *value)
2298
0
{
2299
0
    assert(count < 0x80000000);
2300
0
    assert(sizeof(int16_t) == 2);
2301
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2302
0
    {
2303
0
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
2304
0
        return 1;
2305
0
    }
2306
0
    if (tif->tif_flags & TIFF_SWAB)
2307
0
        TIFFSwabArrayOfShort((uint16_t *)value, count);
2308
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
2309
0
                                      count * 2, value));
2310
0
}
2311
2312
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
2313
                                            TIFFDirEntry *dir, uint16_t tag,
2314
                                            uint32_t value)
2315
0
{
2316
0
    uint32_t m;
2317
0
    assert(sizeof(uint32_t) == 4);
2318
0
    if (dir == NULL)
2319
0
    {
2320
        /* No additional data to IFD data size just increment ndir. */
2321
0
        (*ndir)++;
2322
0
        return 1;
2323
0
    }
2324
0
    m = value;
2325
0
    if (tif->tif_flags & TIFF_SWAB)
2326
0
        TIFFSwabLong(&m);
2327
0
    return (
2328
0
        TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
2329
0
}
2330
2331
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
2332
                                                 TIFFDirEntry *dir,
2333
                                                 uint16_t tag, uint32_t count,
2334
                                                 uint32_t *value)
2335
0
{
2336
0
    assert(count < 0x40000000);
2337
0
    assert(sizeof(uint32_t) == 4);
2338
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2339
0
    {
2340
0
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2341
0
        return 1;
2342
0
    }
2343
0
    if (tif->tif_flags & TIFF_SWAB)
2344
0
        TIFFSwabArrayOfLong(value, count);
2345
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
2346
0
                                      count * 4, value));
2347
0
}
2348
2349
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
2350
                                                  TIFFDirEntry *dir,
2351
                                                  uint16_t tag, uint32_t count,
2352
                                                  int32_t *value)
2353
0
{
2354
0
    assert(count < 0x40000000);
2355
0
    assert(sizeof(int32_t) == 4);
2356
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2357
0
    {
2358
0
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2359
0
        return 1;
2360
0
    }
2361
0
    if (tif->tif_flags & TIFF_SWAB)
2362
0
        TIFFSwabArrayOfLong((uint32_t *)value, count);
2363
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
2364
0
                                      count * 4, value));
2365
0
}
2366
2367
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
2368
                                                  TIFFDirEntry *dir,
2369
                                                  uint16_t tag, uint32_t count,
2370
                                                  uint64_t *value)
2371
0
{
2372
0
    assert(count < 0x20000000);
2373
0
    assert(sizeof(uint64_t) == 8);
2374
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
2375
0
    {
2376
0
        TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
2377
0
                      "LONG8 not allowed for ClassicTIFF");
2378
0
        return (0);
2379
0
    }
2380
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2381
0
    {
2382
0
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2383
0
        return 1;
2384
0
    }
2385
0
    if (tif->tif_flags & TIFF_SWAB)
2386
0
        TIFFSwabArrayOfLong8(value, count);
2387
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
2388
0
                                      count * 8, value));
2389
0
}
2390
2391
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
2392
                                                   TIFFDirEntry *dir,
2393
                                                   uint16_t tag, uint32_t count,
2394
                                                   int64_t *value)
2395
0
{
2396
0
    assert(count < 0x20000000);
2397
0
    assert(sizeof(int64_t) == 8);
2398
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
2399
0
    {
2400
0
        TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
2401
0
                      "SLONG8 not allowed for ClassicTIFF");
2402
0
        return (0);
2403
0
    }
2404
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2405
0
    {
2406
0
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2407
0
        return 1;
2408
0
    }
2409
0
    if (tif->tif_flags & TIFF_SWAB)
2410
0
        TIFFSwabArrayOfLong8((uint64_t *)value, count);
2411
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
2412
0
                                      count * 8, value));
2413
0
}
2414
2415
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
2416
                                                TIFFDirEntry *dir, uint16_t tag,
2417
                                                double value)
2418
0
{
2419
0
    static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2420
0
    uint32_t m[2];
2421
0
    assert(sizeof(uint32_t) == 4);
2422
0
    if (value < 0)
2423
0
    {
2424
0
        TIFFErrorExtR(tif, module, "Negative value is illegal");
2425
0
        return 0;
2426
0
    }
2427
0
    else if (value != value)
2428
0
    {
2429
0
        TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
2430
0
        return 0;
2431
0
    }
2432
2433
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2434
0
    {
2435
0
        tif->tif_dir.td_dirdatasize_write +=
2436
0
            (tif->tif_flags & TIFF_BIGTIFF) ? 0 : 0x8U;
2437
0
        (*ndir)++;
2438
0
        return 1;
2439
0
    }
2440
2441
0
    DoubleToRational(value, &m[0], &m[1]);
2442
2443
0
    if (tif->tif_flags & TIFF_SWAB)
2444
0
    {
2445
0
        TIFFSwabLong(&m[0]);
2446
0
        TIFFSwabLong(&m[1]);
2447
0
    }
2448
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
2449
0
                                      &m[0]));
2450
0
}
2451
2452
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
2453
                                                     TIFFDirEntry *dir,
2454
                                                     uint16_t tag,
2455
                                                     uint32_t count,
2456
                                                     float *value)
2457
0
{
2458
0
    static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2459
0
    uint32_t *m;
2460
0
    float *na;
2461
0
    uint32_t *nb;
2462
0
    uint32_t nc;
2463
0
    int o;
2464
0
    assert(sizeof(uint32_t) == 4);
2465
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2466
0
    {
2467
0
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
2468
0
        return 1;
2469
0
    }
2470
0
    m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2471
0
    if (m == NULL)
2472
0
    {
2473
0
        TIFFErrorExtR(tif, module, "Out of memory");
2474
0
        return (0);
2475
0
    }
2476
0
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2477
0
    {
2478
0
        DoubleToRational(*na, &nb[0], &nb[1]);
2479
0
    }
2480
0
    if (tif->tif_flags & TIFF_SWAB)
2481
0
        TIFFSwabArrayOfLong(m, count * 2);
2482
0
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2483
0
                                  count * 8, &m[0]);
2484
0
    _TIFFfreeExt(tif, m);
2485
0
    return (o);
2486
0
}
2487
2488
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
2489
                                                      TIFFDirEntry *dir,
2490
                                                      uint16_t tag,
2491
                                                      uint32_t count,
2492
                                                      float *value)
2493
0
{
2494
0
    static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2495
0
    int32_t *m;
2496
0
    float *na;
2497
0
    int32_t *nb;
2498
0
    uint32_t nc;
2499
0
    int o;
2500
0
    assert(sizeof(int32_t) == 4);
2501
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2502
0
    {
2503
0
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
2504
0
        return 1;
2505
0
    }
2506
0
    m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2507
0
    if (m == NULL)
2508
0
    {
2509
0
        TIFFErrorExtR(tif, module, "Out of memory");
2510
0
        return (0);
2511
0
    }
2512
0
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2513
0
    {
2514
0
        DoubleToSrational(*na, &nb[0], &nb[1]);
2515
0
    }
2516
0
    if (tif->tif_flags & TIFF_SWAB)
2517
0
        TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2518
0
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2519
0
                                  count * 8, &m[0]);
2520
0
    _TIFFfreeExt(tif, m);
2521
0
    return (o);
2522
0
}
2523
2524
/*-- Rational2Double: additional write functions for double arrays */
2525
static int
2526
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
2527
                                                TIFFDirEntry *dir, uint16_t tag,
2528
                                                uint32_t count, double *value)
2529
0
{
2530
0
    static const char module[] =
2531
0
        "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
2532
0
    uint32_t *m;
2533
0
    double *na;
2534
0
    uint32_t *nb;
2535
0
    uint32_t nc;
2536
0
    int o;
2537
0
    assert(sizeof(uint32_t) == 4);
2538
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2539
0
    {
2540
0
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
2541
0
        return 1;
2542
0
    }
2543
0
    m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2544
0
    if (m == NULL)
2545
0
    {
2546
0
        TIFFErrorExtR(tif, module, "Out of memory");
2547
0
        return (0);
2548
0
    }
2549
0
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2550
0
    {
2551
0
        DoubleToRational(*na, &nb[0], &nb[1]);
2552
0
    }
2553
0
    if (tif->tif_flags & TIFF_SWAB)
2554
0
        TIFFSwabArrayOfLong(m, count * 2);
2555
0
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2556
0
                                  count * 8, &m[0]);
2557
0
    _TIFFfreeExt(tif, m);
2558
0
    return (o);
2559
0
} /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
2560
2561
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
2562
    TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
2563
    double *value)
2564
0
{
2565
0
    static const char module[] =
2566
0
        "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
2567
0
    int32_t *m;
2568
0
    double *na;
2569
0
    int32_t *nb;
2570
0
    uint32_t nc;
2571
0
    int o;
2572
0
    assert(sizeof(int32_t) == 4);
2573
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2574
0
    {
2575
0
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
2576
0
        return 1;
2577
0
    }
2578
0
    m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2579
0
    if (m == NULL)
2580
0
    {
2581
0
        TIFFErrorExtR(tif, module, "Out of memory");
2582
0
        return (0);
2583
0
    }
2584
0
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2585
0
    {
2586
0
        DoubleToSrational(*na, &nb[0], &nb[1]);
2587
0
    }
2588
0
    if (tif->tif_flags & TIFF_SWAB)
2589
0
        TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2590
0
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2591
0
                                  count * 8, &m[0]);
2592
0
    _TIFFfreeExt(tif, m);
2593
0
    return (o);
2594
0
} /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
2595
2596
/** -----  Rational2Double: Double To Rational Conversion
2597
----------------------------------------------------------
2598
* There is a mathematical theorem to convert real numbers into a rational
2599
(integer fraction) number.
2600
* This is called "continuous fraction" which uses the Euclidean algorithm to
2601
find the greatest common divisor (GCD).
2602
*  (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
2603
https://en.wikipedia.org/wiki/Continued_fraction
2604
*             https://en.wikipedia.org/wiki/Euclidean_algorithm)
2605
* The following functions implement the
2606
* - ToRationalEuclideanGCD()    auxiliary function which mainly
2607
implements euclidean GCD
2608
* - DoubleToRational()      conversion function for un-signed
2609
rationals
2610
* - DoubleToSrational()     conversion function for signed rationals
2611
------------------------------------------------------------------------------------------------------------------*/
2612
2613
/**---- ToRationalEuclideanGCD() -----------------------------------------
2614
* Calculates the rational fractional of a double input value
2615
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2616
------------------------------------------------------------------------*/
2617
static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
2618
                                   int blnUseSmallRange, uint64_t *ullNum,
2619
                                   uint64_t *ullDenom)
2620
0
{
2621
    /* Internally, the integer variables can be bigger than the external ones,
2622
     * as long as the result will fit into the external variable size.
2623
     */
2624
0
    uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
2625
0
    uint64_t aux, bigNum, bigDenom;
2626
0
    uint64_t returnLimit;
2627
0
    int i;
2628
0
    uint64_t nMax;
2629
0
    double fMax;
2630
0
    unsigned long maxDenom;
2631
    /*-- nMax and fMax defines the initial accuracy of the starting fractional,
2632
     *   or better, the highest used integer numbers used within the starting
2633
     * fractional (bigNum/bigDenom). There are two approaches, which can
2634
     * accidentally lead to different accuracies just depending on the value.
2635
     *   Therefore, blnUseSmallRange steers this behavior.
2636
     *   For long long nMax = ((9223372036854775807-1)/2); for long nMax =
2637
     * ((2147483647-1)/2);
2638
     */
2639
0
    if (blnUseSmallRange)
2640
0
    {
2641
0
        nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
2642
0
    }
2643
0
    else
2644
0
    {
2645
0
        nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
2646
0
    }
2647
0
    fMax = (double)nMax;
2648
2649
    /*-- For the Euclidean GCD define the denominator range, so that it stays
2650
     * within size of unsigned long variables. maxDenom should be LONG_MAX for
2651
     * negative values and ULONG_MAX for positive ones. Also the final returned
2652
     * value of ullNum and ullDenom is limited according to signed- or
2653
     * unsigned-range.
2654
     */
2655
0
    if (blnUseSignedRange)
2656
0
    {
2657
0
        maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
2658
0
        returnLimit = maxDenom;
2659
0
    }
2660
0
    else
2661
0
    {
2662
0
        maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
2663
0
        returnLimit = maxDenom;
2664
0
    }
2665
2666
    /*-- First generate a rational fraction (bigNum/bigDenom) which represents
2667
     *the value as a rational number with the highest accuracy. Therefore,
2668
     *uint64_t (uint64_t) is needed. This rational fraction is then reduced
2669
     *using the Euclidean algorithm to find the greatest common divisor (GCD).
2670
     *   bigNum   = big numinator of value without fraction (or cut residual
2671
     *fraction) bigDenom = big denominator of value
2672
     *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
2673
     *and bigDenom has no overflow, and stop with enlargement of fraction when
2674
     *the double-value of it reaches an integer number without fractional part.
2675
     */
2676
0
    bigDenom = 1;
2677
0
    while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
2678
0
    {
2679
0
        bigDenom <<= 1;
2680
0
        value *= 2;
2681
0
    }
2682
0
    bigNum = (uint64_t)value;
2683
2684
    /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
2685
     */
2686
0
#define MAX_ITERATIONS 64
2687
0
    for (i = 0; i < MAX_ITERATIONS; i++)
2688
0
    {
2689
0
        uint64_t val;
2690
        /* if bigDenom is not zero, calculate integer part of fraction. */
2691
0
        if (bigDenom == 0)
2692
0
        {
2693
0
            break;
2694
0
        }
2695
0
        val = bigNum / bigDenom;
2696
2697
        /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
2698
         * denominator bigDenom. */
2699
0
        aux = bigNum;
2700
0
        bigNum = bigDenom;
2701
0
        bigDenom = aux % bigDenom;
2702
2703
        /* calculate next denominator and check for its given maximum */
2704
0
        aux = val;
2705
0
        if (denomSum[1] * val + denomSum[0] >= maxDenom)
2706
0
        {
2707
0
            aux = (maxDenom - denomSum[0]) / denomSum[1];
2708
0
            if (aux * 2 >= val || denomSum[1] >= maxDenom)
2709
0
                i = (MAX_ITERATIONS +
2710
0
                     1); /* exit but execute rest of for-loop */
2711
0
            else
2712
0
                break;
2713
0
        }
2714
        /* calculate next numerator to numSum2 and save previous one to numSum0;
2715
         * numSum1 just copy of numSum2. */
2716
0
        numSum[2] = aux * numSum[1] + numSum[0];
2717
0
        numSum[0] = numSum[1];
2718
0
        numSum[1] = numSum[2];
2719
        /* calculate next denominator to denomSum2 and save previous one to
2720
         * denomSum0; denomSum1 just copy of denomSum2. */
2721
0
        denomSum[2] = aux * denomSum[1] + denomSum[0];
2722
0
        denomSum[0] = denomSum[1];
2723
0
        denomSum[1] = denomSum[2];
2724
0
    }
2725
2726
    /*-- Check and adapt for final variable size and return values; reduces
2727
     * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
2728
0
    while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
2729
0
    {
2730
0
        numSum[1] = numSum[1] / 2;
2731
0
        denomSum[1] = denomSum[1] / 2;
2732
0
    }
2733
2734
    /* return values */
2735
0
    *ullNum = numSum[1];
2736
0
    *ullDenom = denomSum[1];
2737
2738
0
} /*-- ToRationalEuclideanGCD() -------------- */
2739
2740
/**---- DoubleToRational() -----------------------------------------------
2741
* Calculates the rational fractional of a double input value
2742
* for UN-SIGNED rationals,
2743
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2744
------------------------------------------------------------------------*/
2745
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
2746
0
{
2747
    /*---- UN-SIGNED RATIONAL ---- */
2748
0
    double dblDiff, dblDiff2;
2749
0
    uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2750
2751
    /*-- Check for negative values. If so it is an error. */
2752
    /* Test written that way to catch NaN */
2753
0
    if (!(value >= 0))
2754
0
    {
2755
0
        *num = *denom = 0;
2756
0
        TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2757
0
                     " Negative Value for Unsigned Rational given.");
2758
0
        return;
2759
0
    }
2760
2761
    /*-- Check for too big numbers (> ULONG_MAX) -- */
2762
0
    if (value > 0xFFFFFFFFUL)
2763
0
    {
2764
0
        *num = 0xFFFFFFFFU;
2765
0
        *denom = 0;
2766
0
        return;
2767
0
    }
2768
    /*-- Check for easy integer numbers -- */
2769
0
    if (value == (uint32_t)(value))
2770
0
    {
2771
0
        *num = (uint32_t)value;
2772
0
        *denom = 1;
2773
0
        return;
2774
0
    }
2775
    /*-- Check for too small numbers for "unsigned long" type rationals -- */
2776
0
    if (value < 1.0 / (double)0xFFFFFFFFUL)
2777
0
    {
2778
0
        *num = 0;
2779
0
        *denom = 0xFFFFFFFFU;
2780
0
        return;
2781
0
    }
2782
2783
    /*-- There are two approaches using the Euclidean algorithm,
2784
     *   which can accidentally lead to different accuracies just depending on
2785
     * the value. Try both and define which one was better.
2786
     */
2787
0
    ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
2788
0
    ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
2789
    /*-- Double-Check, that returned values fit into ULONG :*/
2790
0
    if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
2791
0
        ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
2792
0
    {
2793
0
        TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2794
0
                     " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
2795
0
                     ", denom=%12" PRIu64 " | num2=%12" PRIu64
2796
0
                     ", denom2=%12" PRIu64 "",
2797
0
                     value, ullNum, ullDenom, ullNum2, ullDenom2);
2798
0
        assert(0);
2799
0
    }
2800
2801
    /* Check, which one has higher accuracy and take that. */
2802
0
    dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2803
0
    dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2804
0
    if (dblDiff < dblDiff2)
2805
0
    {
2806
0
        *num = (uint32_t)ullNum;
2807
0
        *denom = (uint32_t)ullDenom;
2808
0
    }
2809
0
    else
2810
0
    {
2811
0
        *num = (uint32_t)ullNum2;
2812
0
        *denom = (uint32_t)ullDenom2;
2813
0
    }
2814
0
} /*-- DoubleToRational() -------------- */
2815
2816
/**---- DoubleToSrational() -----------------------------------------------
2817
* Calculates the rational fractional of a double input value
2818
* for SIGNED rationals,
2819
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2820
------------------------------------------------------------------------*/
2821
static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
2822
0
{
2823
    /*---- SIGNED RATIONAL ----*/
2824
0
    int neg = 1;
2825
0
    double dblDiff, dblDiff2;
2826
0
    uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2827
2828
    /*-- Check for negative values and use then the positive one for internal
2829
     * calculations, but take the sign into account before returning. */
2830
0
    if (value < 0)
2831
0
    {
2832
0
        neg = -1;
2833
0
        value = -value;
2834
0
    }
2835
2836
    /*-- Check for too big numbers (> LONG_MAX) -- */
2837
0
    if (value > 0x7FFFFFFFL)
2838
0
    {
2839
0
        *num = 0x7FFFFFFFL;
2840
0
        *denom = 0;
2841
0
        return;
2842
0
    }
2843
    /*-- Check for easy numbers -- */
2844
0
    if (value == (int32_t)(value))
2845
0
    {
2846
0
        *num = (int32_t)(neg * value);
2847
0
        *denom = 1;
2848
0
        return;
2849
0
    }
2850
    /*-- Check for too small numbers for "long" type rationals -- */
2851
0
    if (value < 1.0 / (double)0x7FFFFFFFL)
2852
0
    {
2853
0
        *num = 0;
2854
0
        *denom = 0x7FFFFFFFL;
2855
0
        return;
2856
0
    }
2857
2858
    /*-- There are two approaches using the Euclidean algorithm,
2859
     *   which can accidentally lead to different accuracies just depending on
2860
     * the value. Try both and define which one was better. Furthermore, set
2861
     * behavior of ToRationalEuclideanGCD() to the range of signed-long.
2862
     */
2863
0
    ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
2864
0
    ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
2865
    /*-- Double-Check, that returned values fit into LONG :*/
2866
0
    if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
2867
0
        ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
2868
0
    {
2869
0
        TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
2870
0
                     " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
2871
0
                     ", denom=%12" PRIu64 " | num2=%12" PRIu64
2872
0
                     ", denom2=%12" PRIu64 "",
2873
0
                     neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
2874
0
        assert(0);
2875
0
    }
2876
2877
    /* Check, which one has higher accuracy and take that. */
2878
0
    dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2879
0
    dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2880
0
    if (dblDiff < dblDiff2)
2881
0
    {
2882
0
        *num = (int32_t)(neg * (long)ullNum);
2883
0
        *denom = (int32_t)ullDenom;
2884
0
    }
2885
0
    else
2886
0
    {
2887
0
        *num = (int32_t)(neg * (long)ullNum2);
2888
0
        *denom = (int32_t)ullDenom2;
2889
0
    }
2890
0
} /*-- DoubleToSrational() --------------*/
2891
2892
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
2893
                                                  TIFFDirEntry *dir,
2894
                                                  uint16_t tag, uint32_t count,
2895
                                                  float *value)
2896
0
{
2897
0
    assert(count < 0x40000000);
2898
0
    assert(sizeof(float) == 4);
2899
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2900
0
    {
2901
0
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2902
0
        return 1;
2903
0
    }
2904
0
    TIFFCvtNativeToIEEEFloat(tif, count, &value);
2905
0
    if (tif->tif_flags & TIFF_SWAB)
2906
0
        TIFFSwabArrayOfFloat(value, count);
2907
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
2908
0
                                      count * 4, value));
2909
0
}
2910
2911
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
2912
                                                   TIFFDirEntry *dir,
2913
                                                   uint16_t tag, uint32_t count,
2914
                                                   double *value)
2915
0
{
2916
0
    assert(count < 0x20000000);
2917
0
    assert(sizeof(double) == 8);
2918
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2919
0
    {
2920
0
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2921
0
        return 1;
2922
0
    }
2923
0
    TIFFCvtNativeToIEEEDouble(tif, count, &value);
2924
0
    if (tif->tif_flags & TIFF_SWAB)
2925
0
        TIFFSwabArrayOfDouble(value, count);
2926
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
2927
0
                                      count * 8, value));
2928
0
}
2929
2930
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
2931
                                                TIFFDirEntry *dir, uint16_t tag,
2932
                                                uint32_t count, uint32_t *value)
2933
0
{
2934
0
    assert(count < 0x40000000);
2935
0
    assert(sizeof(uint32_t) == 4);
2936
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2937
0
    {
2938
0
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2939
0
        return 1;
2940
0
    }
2941
0
    if (tif->tif_flags & TIFF_SWAB)
2942
0
        TIFFSwabArrayOfLong(value, count);
2943
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
2944
0
                                      count * 4, value));
2945
0
}
2946
2947
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
2948
                                                 TIFFDirEntry *dir,
2949
                                                 uint16_t tag, uint32_t count,
2950
                                                 uint64_t *value)
2951
0
{
2952
0
    assert(count < 0x20000000);
2953
0
    assert(sizeof(uint64_t) == 8);
2954
0
    assert(tif->tif_flags & TIFF_BIGTIFF);
2955
0
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2956
0
    {
2957
0
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2958
0
        return 1;
2959
0
    }
2960
0
    if (tif->tif_flags & TIFF_SWAB)
2961
0
        TIFFSwabArrayOfLong8(value, count);
2962
0
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
2963
0
                                      count * 8, value));
2964
0
}
2965
2966
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
2967
                                     TIFFDirEntry *dir, uint16_t tag,
2968
                                     uint16_t datatype, uint32_t count,
2969
                                     uint32_t datalength, void *data)
2970
0
{
2971
0
    static const char module[] = "TIFFWriteDirectoryTagData";
2972
0
    uint32_t m;
2973
0
    m = 0;
2974
0
    while (m < (*ndir))
2975
0
    {
2976
0
        assert(dir[m].tdir_tag != tag);
2977
0
        if (dir[m].tdir_tag > tag)
2978
0
            break;
2979
0
        m++;
2980
0
    }
2981
0
    if (m < (*ndir))
2982
0
    {
2983
0
        uint32_t n;
2984
0
        for (n = *ndir; n > m; n--)
2985
0
            dir[n] = dir[n - 1];
2986
0
    }
2987
0
    dir[m].tdir_tag = tag;
2988
0
    dir[m].tdir_type = datatype;
2989
0
    dir[m].tdir_count = count;
2990
0
    dir[m].tdir_offset.toff_long8 = 0;
2991
0
    if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
2992
0
    {
2993
0
        if (data && datalength)
2994
0
        {
2995
0
            _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
2996
0
        }
2997
0
    }
2998
0
    else
2999
0
    {
3000
0
        uint64_t na, nb;
3001
0
        na = tif->tif_dataoff;
3002
0
        nb = na + datalength;
3003
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
3004
0
            nb = (uint32_t)nb;
3005
0
        if ((nb < na) || (nb < datalength))
3006
0
        {
3007
0
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
3008
0
            return (0);
3009
0
        }
3010
0
        if (!SeekOK(tif, na))
3011
0
        {
3012
0
            TIFFErrorExtR(tif, module, "IO error writing tag data");
3013
0
            return (0);
3014
0
        }
3015
0
        if (datalength >= 0x80000000UL)
3016
0
        {
3017
0
            TIFFErrorExtR(tif, module,
3018
0
                          "libtiff does not allow writing more than 2147483647 "
3019
0
                          "bytes in a tag");
3020
0
            return (0);
3021
0
        }
3022
0
        if (!WriteOK(tif, data, (tmsize_t)datalength))
3023
0
        {
3024
0
            TIFFErrorExtR(tif, module, "IO error writing tag data");
3025
0
            return (0);
3026
0
        }
3027
0
        tif->tif_dataoff = nb;
3028
0
        if (tif->tif_dataoff & 1)
3029
0
            tif->tif_dataoff++;
3030
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
3031
0
        {
3032
0
            uint32_t o;
3033
0
            o = (uint32_t)na;
3034
0
            if (tif->tif_flags & TIFF_SWAB)
3035
0
                TIFFSwabLong(&o);
3036
0
            _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
3037
0
        }
3038
0
        else
3039
0
        {
3040
0
            dir[m].tdir_offset.toff_long8 = na;
3041
0
            if (tif->tif_flags & TIFF_SWAB)
3042
0
                TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
3043
0
        }
3044
0
    }
3045
0
    (*ndir)++;
3046
0
    return (1);
3047
0
}
3048
3049
/*
3050
 * Link the current directory into the directory chain for the file.
3051
 */
3052
static int TIFFLinkDirectory(TIFF *tif)
3053
0
{
3054
0
    static const char module[] = "TIFFLinkDirectory";
3055
3056
0
    tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
3057
3058
    /*
3059
     * Handle SubIFDs
3060
     */
3061
0
    if (tif->tif_flags & TIFF_INSUBIFD)
3062
0
    {
3063
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
3064
0
        {
3065
0
            uint32_t m;
3066
0
            m = (uint32_t)tif->tif_diroff;
3067
0
            if (tif->tif_flags & TIFF_SWAB)
3068
0
                TIFFSwabLong(&m);
3069
0
            (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
3070
0
            if (!WriteOK(tif, &m, 4))
3071
0
            {
3072
0
                TIFFErrorExtR(tif, module,
3073
0
                              "Error writing SubIFD directory link");
3074
0
                return (0);
3075
0
            }
3076
            /*
3077
             * Advance to the next SubIFD or, if this is
3078
             * the last one configured, revert back to the
3079
             * normal directory linkage.
3080
             */
3081
0
            if (--tif->tif_nsubifd)
3082
0
                tif->tif_subifdoff += 4;
3083
0
            else
3084
0
                tif->tif_flags &= ~TIFF_INSUBIFD;
3085
0
            return (1);
3086
0
        }
3087
0
        else
3088
0
        {
3089
0
            uint64_t m;
3090
0
            m = tif->tif_diroff;
3091
0
            if (tif->tif_flags & TIFF_SWAB)
3092
0
                TIFFSwabLong8(&m);
3093
0
            (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
3094
0
            if (!WriteOK(tif, &m, 8))
3095
0
            {
3096
0
                TIFFErrorExtR(tif, module,
3097
0
                              "Error writing SubIFD directory link");
3098
0
                return (0);
3099
0
            }
3100
            /*
3101
             * Advance to the next SubIFD or, if this is
3102
             * the last one configured, revert back to the
3103
             * normal directory linkage.
3104
             */
3105
0
            if (--tif->tif_nsubifd)
3106
0
                tif->tif_subifdoff += 8;
3107
0
            else
3108
0
                tif->tif_flags &= ~TIFF_INSUBIFD;
3109
0
            return (1);
3110
0
        }
3111
0
    }
3112
3113
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
3114
0
    {
3115
0
        uint32_t m;
3116
0
        uint32_t nextdir;
3117
0
        m = (uint32_t)(tif->tif_diroff);
3118
0
        if (tif->tif_flags & TIFF_SWAB)
3119
0
            TIFFSwabLong(&m);
3120
0
        if (tif->tif_header.classic.tiff_diroff == 0)
3121
0
        {
3122
            /*
3123
             * First directory, overwrite offset in header.
3124
             */
3125
0
            tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff;
3126
0
            tif->tif_lastdiroff = tif->tif_diroff;
3127
0
            (void)TIFFSeekFile(tif, 4, SEEK_SET);
3128
0
            if (!WriteOK(tif, &m, 4))
3129
0
            {
3130
0
                TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3131
0
                return (0);
3132
0
            }
3133
0
            return (1);
3134
0
        }
3135
        /*
3136
         * Not the first directory, search to the last and append.
3137
         */
3138
0
        if (tif->tif_lastdiroff != 0)
3139
0
        {
3140
0
            nextdir = (uint32_t)tif->tif_lastdiroff;
3141
0
        }
3142
0
        else
3143
0
        {
3144
0
            nextdir = tif->tif_header.classic.tiff_diroff;
3145
0
        }
3146
3147
0
        while (1)
3148
0
        {
3149
0
            uint16_t dircount;
3150
0
            uint32_t nextnextdir;
3151
3152
0
            if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
3153
0
            {
3154
0
                TIFFErrorExtR(tif, module, "Error fetching directory count");
3155
0
                return (0);
3156
0
            }
3157
0
            if (tif->tif_flags & TIFF_SWAB)
3158
0
                TIFFSwabShort(&dircount);
3159
0
            (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3160
0
            if (!ReadOK(tif, &nextnextdir, 4))
3161
0
            {
3162
0
                TIFFErrorExtR(tif, module, "Error fetching directory link");
3163
0
                return (0);
3164
0
            }
3165
0
            if (tif->tif_flags & TIFF_SWAB)
3166
0
                TIFFSwabLong(&nextnextdir);
3167
0
            if (nextnextdir == 0)
3168
0
            {
3169
0
                (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3170
0
                if (!WriteOK(tif, &m, 4))
3171
0
                {
3172
0
                    TIFFErrorExtR(tif, module, "Error writing directory link");
3173
0
                    return (0);
3174
0
                }
3175
0
                tif->tif_lastdiroff = tif->tif_diroff;
3176
0
                break;
3177
0
            }
3178
0
            nextdir = nextnextdir;
3179
0
        }
3180
0
    }
3181
0
    else
3182
0
    {
3183
0
        uint64_t m;
3184
0
        uint64_t nextdir;
3185
0
        m = tif->tif_diroff;
3186
0
        if (tif->tif_flags & TIFF_SWAB)
3187
0
            TIFFSwabLong8(&m);
3188
0
        if (tif->tif_header.big.tiff_diroff == 0)
3189
0
        {
3190
            /*
3191
             * First directory, overwrite offset in header.
3192
             */
3193
0
            tif->tif_header.big.tiff_diroff = tif->tif_diroff;
3194
0
            tif->tif_lastdiroff = tif->tif_diroff;
3195
0
            (void)TIFFSeekFile(tif, 8, SEEK_SET);
3196
0
            if (!WriteOK(tif, &m, 8))
3197
0
            {
3198
0
                TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3199
0
                return (0);
3200
0
            }
3201
0
            return (1);
3202
0
        }
3203
        /*
3204
         * Not the first directory, search to the last and append.
3205
         */
3206
0
        if (tif->tif_lastdiroff != 0)
3207
0
        {
3208
0
            nextdir = tif->tif_lastdiroff;
3209
0
        }
3210
0
        else
3211
0
        {
3212
0
            nextdir = tif->tif_header.big.tiff_diroff;
3213
0
        }
3214
0
        while (1)
3215
0
        {
3216
0
            uint64_t dircount64;
3217
0
            uint16_t dircount;
3218
0
            uint64_t nextnextdir;
3219
3220
0
            if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
3221
0
            {
3222
0
                TIFFErrorExtR(tif, module, "Error fetching directory count");
3223
0
                return (0);
3224
0
            }
3225
0
            if (tif->tif_flags & TIFF_SWAB)
3226
0
                TIFFSwabLong8(&dircount64);
3227
0
            if (dircount64 > 0xFFFF)
3228
0
            {
3229
0
                TIFFErrorExtR(tif, module,
3230
0
                              "Sanity check on tag count failed, "
3231
0
                              "likely corrupt TIFF");
3232
0
                return (0);
3233
0
            }
3234
0
            dircount = (uint16_t)dircount64;
3235
0
            (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3236
0
            if (!ReadOK(tif, &nextnextdir, 8))
3237
0
            {
3238
0
                TIFFErrorExtR(tif, module, "Error fetching directory link");
3239
0
                return (0);
3240
0
            }
3241
0
            if (tif->tif_flags & TIFF_SWAB)
3242
0
                TIFFSwabLong8(&nextnextdir);
3243
0
            if (nextnextdir == 0)
3244
0
            {
3245
0
                (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3246
0
                if (!WriteOK(tif, &m, 8))
3247
0
                {
3248
0
                    TIFFErrorExtR(tif, module, "Error writing directory link");
3249
0
                    return (0);
3250
0
                }
3251
0
                tif->tif_lastdiroff = tif->tif_diroff;
3252
0
                break;
3253
0
            }
3254
0
            nextdir = nextnextdir;
3255
0
        }
3256
0
    }
3257
0
    return (1);
3258
0
}
3259
3260
/************************************************************************/
3261
/*                          TIFFRewriteField()                          */
3262
/*                                                                      */
3263
/*      Rewrite a field in the directory on disk without regard to      */
3264
/*      updating the TIFF directory structure in memory.  Currently     */
3265
/*      only supported for field that already exist in the on-disk      */
3266
/*      directory.  Mainly used for updating stripoffset /              */
3267
/*      stripbytecount values after the directory is already on         */
3268
/*      disk.                                                           */
3269
/*                                                                      */
3270
/*      Returns zero on failure, and one on success.                    */
3271
/************************************************************************/
3272
3273
int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
3274
                      tmsize_t count, void *data)
3275
0
{
3276
0
    static const char module[] = "TIFFResetField";
3277
    /* const TIFFField* fip = NULL; */
3278
0
    uint16_t dircount;
3279
0
    tmsize_t dirsize;
3280
0
    uint8_t direntry_raw[20];
3281
0
    uint16_t entry_tag = 0;
3282
0
    uint16_t entry_type = 0;
3283
0
    uint64_t entry_count = 0;
3284
0
    uint64_t entry_offset = 0;
3285
0
    int value_in_entry = 0;
3286
0
    uint64_t read_offset;
3287
0
    uint8_t *buf_to_write = NULL;
3288
0
    TIFFDataType datatype;
3289
3290
    /* -------------------------------------------------------------------- */
3291
    /*      Find field definition.                                          */
3292
    /* -------------------------------------------------------------------- */
3293
0
    /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
3294
3295
    /* -------------------------------------------------------------------- */
3296
    /*      Do some checking this is a straight forward case.               */
3297
    /* -------------------------------------------------------------------- */
3298
0
    if (isMapped(tif))
3299
0
    {
3300
0
        TIFFErrorExtR(tif, module,
3301
0
                      "Memory mapped files not currently supported for "
3302
0
                      "this operation.");
3303
0
        return 0;
3304
0
    }
3305
3306
0
    if (tif->tif_diroff == 0)
3307
0
    {
3308
0
        TIFFErrorExtR(
3309
0
            tif, module,
3310
0
            "Attempt to reset field on directory not already on disk.");
3311
0
        return 0;
3312
0
    }
3313
3314
    /* -------------------------------------------------------------------- */
3315
    /*      Read the directory entry count.                                 */
3316
    /* -------------------------------------------------------------------- */
3317
0
    if (!SeekOK(tif, tif->tif_diroff))
3318
0
    {
3319
0
        TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3320
0
                      tif->tif_name);
3321
0
        return 0;
3322
0
    }
3323
3324
0
    read_offset = tif->tif_diroff;
3325
3326
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
3327
0
    {
3328
0
        if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
3329
0
        {
3330
0
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3331
0
                          tif->tif_name);
3332
0
            return 0;
3333
0
        }
3334
0
        if (tif->tif_flags & TIFF_SWAB)
3335
0
            TIFFSwabShort(&dircount);
3336
0
        dirsize = 12;
3337
0
        read_offset += 2;
3338
0
    }
3339
0
    else
3340
0
    {
3341
0
        uint64_t dircount64;
3342
0
        if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
3343
0
        {
3344
0
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3345
0
                          tif->tif_name);
3346
0
            return 0;
3347
0
        }
3348
0
        if (tif->tif_flags & TIFF_SWAB)
3349
0
            TIFFSwabLong8(&dircount64);
3350
0
        dircount = (uint16_t)dircount64;
3351
0
        dirsize = 20;
3352
0
        read_offset += 8;
3353
0
    }
3354
3355
    /* -------------------------------------------------------------------- */
3356
    /*      Read through directory to find target tag.                      */
3357
    /* -------------------------------------------------------------------- */
3358
0
    while (dircount > 0)
3359
0
    {
3360
0
        if (!ReadOK(tif, direntry_raw, dirsize))
3361
0
        {
3362
0
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
3363
0
                          tif->tif_name);
3364
0
            return 0;
3365
0
        }
3366
3367
0
        memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
3368
0
        if (tif->tif_flags & TIFF_SWAB)
3369
0
            TIFFSwabShort(&entry_tag);
3370
3371
0
        if (entry_tag == tag)
3372
0
            break;
3373
3374
0
        read_offset += dirsize;
3375
0
    }
3376
3377
0
    if (entry_tag != tag)
3378
0
    {
3379
0
        TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
3380
0
                      tif->tif_name, tag);
3381
0
        return 0;
3382
0
    }
3383
3384
    /* -------------------------------------------------------------------- */
3385
    /*      Extract the type, count and offset for this entry.              */
3386
    /* -------------------------------------------------------------------- */
3387
0
    memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
3388
0
    if (tif->tif_flags & TIFF_SWAB)
3389
0
        TIFFSwabShort(&entry_type);
3390
3391
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
3392
0
    {
3393
0
        uint32_t value;
3394
3395
0
        memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
3396
0
        if (tif->tif_flags & TIFF_SWAB)
3397
0
            TIFFSwabLong(&value);
3398
0
        entry_count = value;
3399
3400
0
        memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
3401
0
        if (tif->tif_flags & TIFF_SWAB)
3402
0
            TIFFSwabLong(&value);
3403
0
        entry_offset = value;
3404
0
    }
3405
0
    else
3406
0
    {
3407
0
        memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
3408
0
        if (tif->tif_flags & TIFF_SWAB)
3409
0
            TIFFSwabLong8(&entry_count);
3410
3411
0
        memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
3412
0
        if (tif->tif_flags & TIFF_SWAB)
3413
0
            TIFFSwabLong8(&entry_offset);
3414
0
    }
3415
3416
    /* -------------------------------------------------------------------- */
3417
    /*      When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
3418
    /* -------------------------------------------------------------------- */
3419
0
    if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
3420
0
    {
3421
0
        if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
3422
0
        {
3423
0
            entry_type =
3424
0
                (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
3425
0
        }
3426
0
        else
3427
0
        {
3428
0
            int write_aslong8 = 1;
3429
0
            if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3430
0
            {
3431
0
                write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
3432
0
            }
3433
0
            else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3434
0
            {
3435
0
                write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
3436
0
            }
3437
0
            if (write_aslong8)
3438
0
            {
3439
0
                entry_type = TIFF_LONG8;
3440
0
            }
3441
0
            else
3442
0
            {
3443
0
                int write_aslong4 = 1;
3444
0
                if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3445
0
                {
3446
0
                    write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
3447
0
                }
3448
0
                else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3449
0
                {
3450
0
                    write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
3451
0
                }
3452
0
                if (write_aslong4)
3453
0
                {
3454
0
                    entry_type = TIFF_LONG;
3455
0
                }
3456
0
                else
3457
0
                {
3458
0
                    entry_type = TIFF_SHORT;
3459
0
                }
3460
0
            }
3461
0
        }
3462
0
    }
3463
3464
    /* -------------------------------------------------------------------- */
3465
    /*      What data type do we want to write this as?                     */
3466
    /* -------------------------------------------------------------------- */
3467
0
    if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
3468
0
    {
3469
0
        if (in_datatype == TIFF_LONG8)
3470
0
            datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
3471
0
        else if (in_datatype == TIFF_SLONG8)
3472
0
            datatype = TIFF_SLONG;
3473
0
        else if (in_datatype == TIFF_IFD8)
3474
0
            datatype = TIFF_IFD;
3475
0
        else
3476
0
            datatype = in_datatype;
3477
0
    }
3478
0
    else
3479
0
    {
3480
0
        if (in_datatype == TIFF_LONG8 &&
3481
0
            (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
3482
0
             entry_type == TIFF_LONG8))
3483
0
            datatype = entry_type;
3484
0
        else if (in_datatype == TIFF_SLONG8 &&
3485
0
                 (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
3486
0
            datatype = entry_type;
3487
0
        else if (in_datatype == TIFF_IFD8 &&
3488
0
                 (entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
3489
0
            datatype = entry_type;
3490
0
        else
3491
0
            datatype = in_datatype;
3492
0
    }
3493
3494
    /* -------------------------------------------------------------------- */
3495
    /*      Prepare buffer of actual data to write.  This includes          */
3496
    /*      swabbing as needed.                                             */
3497
    /* -------------------------------------------------------------------- */
3498
0
    buf_to_write = (uint8_t *)_TIFFCheckMalloc(
3499
0
        tif, count, TIFFDataWidth(datatype), "for field buffer.");
3500
0
    if (!buf_to_write)
3501
0
        return 0;
3502
3503
0
    if (datatype == in_datatype)
3504
0
        memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
3505
0
    else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
3506
0
    {
3507
0
        tmsize_t i;
3508
3509
0
        for (i = 0; i < count; i++)
3510
0
        {
3511
0
            ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
3512
0
            if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
3513
0
            {
3514
0
                _TIFFfreeExt(tif, buf_to_write);
3515
0
                TIFFErrorExtR(tif, module,
3516
0
                              "Value exceeds 32bit range of output type.");
3517
0
                return 0;
3518
0
            }
3519
0
        }
3520
0
    }
3521
0
    else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
3522
0
             (datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
3523
0
    {
3524
0
        tmsize_t i;
3525
3526
0
        for (i = 0; i < count; i++)
3527
0
        {
3528
0
            ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
3529
0
            if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
3530
0
                ((uint64_t *)data)[i])
3531
0
            {
3532
0
                _TIFFfreeExt(tif, buf_to_write);
3533
0
                TIFFErrorExtR(tif, module,
3534
0
                              "Value exceeds 32bit range of output type.");
3535
0
                return 0;
3536
0
            }
3537
0
        }
3538
0
    }
3539
0
    else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
3540
0
    {
3541
0
        tmsize_t i;
3542
3543
0
        for (i = 0; i < count; i++)
3544
0
        {
3545
0
            ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
3546
0
            if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
3547
0
                ((uint64_t *)data)[i])
3548
0
            {
3549
0
                _TIFFfreeExt(tif, buf_to_write);
3550
0
                TIFFErrorExtR(tif, module,
3551
0
                              "Value exceeds 16bit range of output type.");
3552
0
                return 0;
3553
0
            }
3554
0
        }
3555
0
    }
3556
0
    else
3557
0
    {
3558
0
        TIFFErrorExtR(tif, module, "Unhandled type conversion.");
3559
0
        return 0;
3560
0
    }
3561
3562
0
    if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
3563
0
    {
3564
0
        if (TIFFDataWidth(datatype) == 2)
3565
0
            TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
3566
0
        else if (TIFFDataWidth(datatype) == 4)
3567
0
            TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
3568
0
        else if (TIFFDataWidth(datatype) == 8)
3569
0
            TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
3570
0
    }
3571
3572
    /* -------------------------------------------------------------------- */
3573
    /*      Is this a value that fits into the directory entry?             */
3574
    /* -------------------------------------------------------------------- */
3575
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
3576
0
    {
3577
0
        if (TIFFDataWidth(datatype) * count <= 4)
3578
0
        {
3579
0
            entry_offset = read_offset + 8;
3580
0
            value_in_entry = 1;
3581
0
        }
3582
0
    }
3583
0
    else
3584
0
    {
3585
0
        if (TIFFDataWidth(datatype) * count <= 8)
3586
0
        {
3587
0
            entry_offset = read_offset + 12;
3588
0
            value_in_entry = 1;
3589
0
        }
3590
0
    }
3591
3592
0
    if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
3593
0
        tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
3594
0
        tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
3595
0
        tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
3596
0
    {
3597
0
        tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
3598
0
        tif->tif_dir.td_stripoffset_entry.tdir_count = count;
3599
0
    }
3600
0
    else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
3601
0
              tag == TIFFTAG_STRIPBYTECOUNTS) &&
3602
0
             tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
3603
0
             tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
3604
0
             tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
3605
0
    {
3606
0
        tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
3607
0
        tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
3608
0
    }
3609
3610
    /* -------------------------------------------------------------------- */
3611
    /*      If the tag type, and count match, then we just write it out     */
3612
    /*      over the old values without altering the directory entry at     */
3613
    /*      all.                                                            */
3614
    /* -------------------------------------------------------------------- */
3615
0
    if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
3616
0
    {
3617
0
        if (!SeekOK(tif, entry_offset))
3618
0
        {
3619
0
            _TIFFfreeExt(tif, buf_to_write);
3620
0
            TIFFErrorExtR(tif, module,
3621
0
                          "%s: Seek error accessing TIFF directory",
3622
0
                          tif->tif_name);
3623
0
            return 0;
3624
0
        }
3625
0
        if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3626
0
        {
3627
0
            _TIFFfreeExt(tif, buf_to_write);
3628
0
            TIFFErrorExtR(tif, module, "Error writing directory link");
3629
0
            return (0);
3630
0
        }
3631
3632
0
        _TIFFfreeExt(tif, buf_to_write);
3633
0
        return 1;
3634
0
    }
3635
3636
    /* -------------------------------------------------------------------- */
3637
    /*      Otherwise, we write the new tag data at the end of the file.    */
3638
    /* -------------------------------------------------------------------- */
3639
0
    if (!value_in_entry)
3640
0
    {
3641
0
        entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
3642
3643
0
        if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3644
0
        {
3645
0
            _TIFFfreeExt(tif, buf_to_write);
3646
0
            TIFFErrorExtR(tif, module, "Error writing directory link");
3647
0
            return (0);
3648
0
        }
3649
0
    }
3650
0
    else
3651
0
    {
3652
0
        if (count * TIFFDataWidth(datatype) == 4)
3653
0
        {
3654
0
            uint32_t value;
3655
0
            memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
3656
0
            entry_offset = value;
3657
0
        }
3658
0
        else
3659
0
        {
3660
0
            memcpy(&entry_offset, buf_to_write,
3661
0
                   count * TIFFDataWidth(datatype));
3662
0
        }
3663
0
    }
3664
3665
0
    _TIFFfreeExt(tif, buf_to_write);
3666
0
    buf_to_write = 0;
3667
3668
    /* -------------------------------------------------------------------- */
3669
    /*      Adjust the directory entry.                                     */
3670
    /* -------------------------------------------------------------------- */
3671
0
    entry_type = datatype;
3672
0
    entry_count = (uint64_t)count;
3673
0
    memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
3674
0
    if (tif->tif_flags & TIFF_SWAB)
3675
0
        TIFFSwabShort((uint16_t *)(direntry_raw + 2));
3676
3677
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
3678
0
    {
3679
0
        uint32_t value;
3680
3681
0
        value = (uint32_t)entry_count;
3682
0
        memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
3683
0
        if (tif->tif_flags & TIFF_SWAB)
3684
0
            TIFFSwabLong((uint32_t *)(direntry_raw + 4));
3685
3686
0
        value = (uint32_t)entry_offset;
3687
0
        memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
3688
0
        if (tif->tif_flags & TIFF_SWAB)
3689
0
            TIFFSwabLong((uint32_t *)(direntry_raw + 8));
3690
0
    }
3691
0
    else
3692
0
    {
3693
0
        memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
3694
0
        if (tif->tif_flags & TIFF_SWAB)
3695
0
            TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
3696
3697
0
        memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
3698
0
        if (tif->tif_flags & TIFF_SWAB)
3699
0
            TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
3700
0
    }
3701
3702
    /* -------------------------------------------------------------------- */
3703
    /*      Write the directory entry out to disk.                          */
3704
    /* -------------------------------------------------------------------- */
3705
0
    if (!SeekOK(tif, read_offset))
3706
0
    {
3707
0
        TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3708
0
                      tif->tif_name);
3709
0
        return 0;
3710
0
    }
3711
3712
0
    if (!WriteOK(tif, direntry_raw, dirsize))
3713
0
    {
3714
0
        TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
3715
0
                      tif->tif_name);
3716
0
        return 0;
3717
0
    }
3718
3719
0
    return 1;
3720
0
}