Coverage Report

Created: 2025-07-23 07:06

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