Coverage Report

Created: 2026-07-25 06:50

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