Coverage Report

Created: 2025-06-24 07:01

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