• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 15171299595

21 May 2025 07:51PM UTC coverage: 70.949% (+0.03%) from 70.921%
15171299595

Pull #12392

github

web-flow
Merge 405a716f5 into ce2393a45
Pull Request #12392: GDALOverviews: Limit external file size in GDALRegenerateOverviewsMultiBand

174 of 189 new or added lines in 2 files covered. (92.06%)

22859 existing lines in 88 files now uncovered.

568261 of 800943 relevant lines covered (70.95%)

235911.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.65
/frmts/gtiff/libtiff/tif_dirwrite.c
1
/*
2
 * Copyright (c) 1988-1997 Sam Leffler
3
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and
6
 * its documentation for any purpose is hereby granted without fee, provided
7
 * that (i) the above copyright notices and this permission notice appear in
8
 * all copies of the software and related documentation, and (ii) the names of
9
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10
 * publicity relating to the software without the specific, prior written
11
 * permission of Sam Leffler and Silicon Graphics.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
 * OF THIS SOFTWARE.
23
 */
24

25
/*
26
 * TIFF Library.
27
 *
28
 * Directory Write Support Routines.
29
 */
30
#include "tiffiop.h"
31
#include <float.h> /*--: for Rational2Double */
32
#include <math.h>  /*--: for Rational2Double */
33

34
#ifdef HAVE_IEEEFP
35
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
36
#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
37
#else
38
/* If your machine does not support IEEE floating point then you will need to
39
 * add support to tif_machdep.c to convert between the native format and
40
 * IEEE format. */
41
extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
42
extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
43
#endif
44

45
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
46
                                 uint64_t *pdiroff);
47

48
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
49
                                                  TIFFDirEntry *dir,
50
                                                  uint16_t tag, uint32_t count,
51
                                                  double *value);
52

53
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
54
                                      TIFFDirEntry *dir, uint16_t tag,
55
                                      uint32_t count, char *value);
56
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
57
                                               TIFFDirEntry *dir, uint16_t tag,
58
                                               uint32_t count, uint8_t *value);
59
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
60
                                          TIFFDirEntry *dir, uint16_t tag,
61
                                          uint32_t count, uint8_t *value);
62
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
63
                                           TIFFDirEntry *dir, uint16_t tag,
64
                                           uint32_t count, int8_t *value);
65
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
66
                                      TIFFDirEntry *dir, uint16_t tag,
67
                                      uint16_t value);
68
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
69
                                           TIFFDirEntry *dir, uint16_t tag,
70
                                           uint32_t count, uint16_t *value);
71
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
72
                                               TIFFDirEntry *dir, uint16_t tag,
73
                                               uint16_t value);
74
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
75
                                            TIFFDirEntry *dir, uint16_t tag,
76
                                            uint32_t count, int16_t *value);
77
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
78
                                     TIFFDirEntry *dir, uint16_t tag,
79
                                     uint32_t value);
80
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
81
                                          TIFFDirEntry *dir, uint16_t tag,
82
                                          uint32_t count, uint32_t *value);
83
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
84
                                           TIFFDirEntry *dir, uint16_t tag,
85
                                           uint32_t count, int32_t *value);
86
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
87
                                           TIFFDirEntry *dir, uint16_t tag,
88
                                           uint32_t count, uint64_t *value);
89
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
90
                                            TIFFDirEntry *dir, uint16_t tag,
91
                                            uint32_t count, int64_t *value);
92
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
93
                                         TIFFDirEntry *dir, uint16_t tag,
94
                                         double value);
95
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
96
                                              TIFFDirEntry *dir, uint16_t tag,
97
                                              uint32_t count, float *value);
98
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
99
                                               TIFFDirEntry *dir, uint16_t tag,
100
                                               uint32_t count, float *value);
101
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
102
                                           TIFFDirEntry *dir, uint16_t tag,
103
                                           uint32_t count, float *value);
104
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
105
                                            TIFFDirEntry *dir, uint16_t tag,
106
                                            uint32_t count, double *value);
107
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
108
                                         TIFFDirEntry *dir, uint16_t tag,
109
                                         uint32_t count, uint32_t *value);
110
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
111
                                          TIFFDirEntry *dir, uint16_t tag,
112
                                          uint32_t value);
113
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
114
                                               TIFFDirEntry *dir, uint16_t tag,
115
                                               uint32_t count, uint64_t *value);
116
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
117
                                             TIFFDirEntry *dir, uint16_t tag,
118
                                             uint32_t count, uint64_t *value);
119
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
120
                                         TIFFDirEntry *dir);
121
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
122
                                                 TIFFDirEntry *dir);
123
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
124
                                       TIFFDirEntry *dir);
125

126
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
127
                                             TIFFDirEntry *dir, uint16_t tag,
128
                                             uint32_t count, char *value);
129
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
130
                                                      TIFFDirEntry *dir,
131
                                                      uint16_t tag,
132
                                                      uint32_t count,
133
                                                      uint8_t *value);
134
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
135
                                                 TIFFDirEntry *dir,
136
                                                 uint16_t tag, uint32_t count,
137
                                                 uint8_t *value);
138
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
139
                                                  TIFFDirEntry *dir,
140
                                                  uint16_t tag, uint32_t count,
141
                                                  int8_t *value);
142
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
143
                                             TIFFDirEntry *dir, uint16_t tag,
144
                                             uint16_t value);
145
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
146
                                                  TIFFDirEntry *dir,
147
                                                  uint16_t tag, uint32_t count,
148
                                                  uint16_t *value);
149
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
150
                                                   TIFFDirEntry *dir,
151
                                                   uint16_t tag, uint32_t count,
152
                                                   int16_t *value);
153
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
154
                                            TIFFDirEntry *dir, uint16_t tag,
155
                                            uint32_t value);
156
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
157
                                                 TIFFDirEntry *dir,
158
                                                 uint16_t tag, uint32_t count,
159
                                                 uint32_t *value);
160
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
161
                                                  TIFFDirEntry *dir,
162
                                                  uint16_t tag, uint32_t count,
163
                                                  int32_t *value);
164
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
165
                                                  TIFFDirEntry *dir,
166
                                                  uint16_t tag, uint32_t count,
167
                                                  uint64_t *value);
168
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
169
                                                   TIFFDirEntry *dir,
170
                                                   uint16_t tag, uint32_t count,
171
                                                   int64_t *value);
172
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
173
                                                TIFFDirEntry *dir, uint16_t tag,
174
                                                double value);
175
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
176
                                                     TIFFDirEntry *dir,
177
                                                     uint16_t tag,
178
                                                     uint32_t count,
179
                                                     float *value);
180
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
181
                                                      TIFFDirEntry *dir,
182
                                                      uint16_t tag,
183
                                                      uint32_t count,
184
                                                      float *value);
185

186
/*--: Rational2Double: New functions to support true double-precision for custom
187
 * rational tag types. */
188
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
189
                                                    TIFFDirEntry *dir,
190
                                                    uint16_t tag,
191
                                                    uint32_t count,
192
                                                    double *value);
193
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
194
                                                     TIFFDirEntry *dir,
195
                                                     uint16_t tag,
196
                                                     uint32_t count,
197
                                                     double *value);
198
static int
199
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
200
                                                TIFFDirEntry *dir, uint16_t tag,
201
                                                uint32_t count, double *value);
202
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
203
    TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
204
    double *value);
205
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom);
206
static void DoubleToSrational(double value, int32_t *num, int32_t *denom);
207

208
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
209
                                                  TIFFDirEntry *dir,
210
                                                  uint16_t tag, uint32_t count,
211
                                                  float *value);
212
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
213
                                                   TIFFDirEntry *dir,
214
                                                   uint16_t tag, uint32_t count,
215
                                                   double *value);
216
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
217
                                                TIFFDirEntry *dir, uint16_t tag,
218
                                                uint32_t count,
219
                                                uint32_t *value);
220
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
221
                                                 TIFFDirEntry *dir,
222
                                                 uint16_t tag, uint32_t count,
223
                                                 uint64_t *value);
224

225
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
226
                                     TIFFDirEntry *dir, uint16_t tag,
227
                                     uint16_t datatype, uint32_t count,
228
                                     uint32_t datalength, void *data);
229

230
static int TIFFLinkDirectory(TIFF *);
231

232
/*
233
 * Write the contents of the current directory
234
 * to the specified file.  This routine doesn't
235
 * handle overwriting a directory with auxiliary
236
 * storage that's been changed.
237
 */
238
int TIFFWriteDirectory(TIFF *tif)
39,565✔
239
{
240
    return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
39,565✔
241
}
242

243
/*
244
 * This is an advanced writing function that must be used in a particular
245
 * sequence, and generally together with TIFFForceStrileArrayWriting(),
246
 * to make its intended effect. Its aim is to modify the location
247
 * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
248
 * More precisely, when TIFFWriteCheck() will be called, the tag entries for
249
 * those arrays will be written with type = count = offset = 0 as a temporary
250
 * value.
251
 *
252
 * Its effect is only valid for the current directory, and before
253
 * TIFFWriteDirectory() is first called, and  will be reset when
254
 * changing directory.
255
 *
256
 * The typical sequence of calls is:
257
 * TIFFOpen()
258
 * [ TIFFCreateDirectory(tif) ]
259
 * Set fields with calls to TIFFSetField(tif, ...)
260
 * TIFFDeferStrileArrayWriting(tif)
261
 * TIFFWriteCheck(tif, ...)
262
 * TIFFWriteDirectory(tif)
263
 * ... potentially create other directories and come back to the above directory
264
 * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
265
 *
266
 * Returns 1 in case of success, 0 otherwise.
267
 */
268
int TIFFDeferStrileArrayWriting(TIFF *tif)
367✔
269
{
270
    static const char module[] = "TIFFDeferStrileArrayWriting";
271
    if (tif->tif_mode == O_RDONLY)
367✔
272
    {
273
        TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
×
274
        return 0;
×
275
    }
276
    if (tif->tif_diroff != 0)
367✔
277
    {
278
        TIFFErrorExtR(tif, module, "Directory has already been written");
×
279
        return 0;
×
280
    }
281

282
    tif->tif_dir.td_deferstrilearraywriting = TRUE;
367✔
283
    return 1;
367✔
284
}
285

286
/*
287
 * Similar to TIFFWriteDirectory(), writes the directory out
288
 * but leaves all data structures in memory so that it can be
289
 * written again.  This will make a partially written TIFF file
290
 * readable before it is successfully completed/closed.
291
 */
292
int TIFFCheckpointDirectory(TIFF *tif)
×
293
{
294
    int rc;
295
    /* Setup the strips arrays, if they haven't already been. */
296
    if (tif->tif_dir.td_stripoffset_p == NULL)
×
297
        (void)TIFFSetupStrips(tif);
×
298
    rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL);
×
299
    (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
×
300
    return rc;
×
301
}
302

303
int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff)
×
304
{
305
    return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff);
×
306
}
307

308
/*
309
 * Similar to TIFFWriteDirectorySec(), but if the directory has already
310
 * been written once, it is relocated to the end of the file, in case it
311
 * has changed in size.  Note that this will result in the loss of the
312
 * previously used directory space.
313
 */
314

315
static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
27,888✔
316
                                   uint64_t *pdiroff)
317
{
318
    static const char module[] = "TIFFRewriteDirectory";
319

320
    /* We don't need to do anything special if it hasn't been written. */
321
    if (tif->tif_diroff == 0)
27,888✔
322
        return TIFFWriteDirectory(tif);
26,512✔
323

324
    /*
325
     * Find and zero the pointer to this directory, so that TIFFLinkDirectory
326
     * will cause it to be added after this directories current pre-link.
327
     */
328
    uint64_t torewritediroff = tif->tif_diroff;
1,376✔
329

330
    if (!(tif->tif_flags & TIFF_BIGTIFF))
1,376✔
331
    {
332
        if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
1,374✔
333
        {
334
            tif->tif_header.classic.tiff_diroff = 0;
1,368✔
335
            tif->tif_diroff = 0;
1,368✔
336

337
            TIFFSeekFile(tif, 4, SEEK_SET);
1,368✔
338
            if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
1,368✔
339
            {
340
                TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
×
341
                return (0);
×
342
            }
343
        }
344
        else if (tif->tif_diroff > 0xFFFFFFFFU)
6✔
345
        {
346
            TIFFErrorExtR(tif, module,
×
347
                          "tif->tif_diroff exceeds 32 bit range allowed for "
348
                          "Classic TIFF");
349
            return (0);
×
350
        }
351
        else
352
        {
353
            uint32_t nextdir;
354
            nextdir = tif->tif_header.classic.tiff_diroff;
6✔
355
            while (1)
356
            {
2✔
357
                uint16_t dircount;
358
                uint32_t nextnextdir;
359

360
                if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
8✔
361
                {
362
                    TIFFErrorExtR(tif, module,
×
363
                                  "Error fetching directory count");
364
                    return (0);
×
365
                }
366
                if (tif->tif_flags & TIFF_SWAB)
8✔
367
                    TIFFSwabShort(&dircount);
×
368
                (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
8✔
369
                if (!ReadOK(tif, &nextnextdir, 4))
8✔
370
                {
371
                    TIFFErrorExtR(tif, module, "Error fetching directory link");
×
372
                    return (0);
×
373
                }
374
                if (tif->tif_flags & TIFF_SWAB)
8✔
375
                    TIFFSwabLong(&nextnextdir);
×
376
                if (nextnextdir == tif->tif_diroff)
8✔
377
                {
378
                    uint32_t m;
379
                    m = 0;
6✔
380
                    (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
6✔
381
                                       SEEK_SET);
382
                    if (!WriteOK(tif, &m, 4))
6✔
383
                    {
384
                        TIFFErrorExtR(tif, module,
×
385
                                      "Error writing directory link");
386
                        return (0);
×
387
                    }
388
                    tif->tif_diroff = 0;
6✔
389
                    /* Force a full-traversal to reach the zeroed pointer */
390
                    tif->tif_lastdiroff = 0;
6✔
391
                    break;
6✔
392
                }
393
                nextdir = nextnextdir;
2✔
394
            }
395
        }
396
        /* Remove skipped offset from IFD loop directory list. */
397
        _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
1,374✔
398
    }
399
    else
400
    {
401
        if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
2✔
402
        {
403
            tif->tif_header.big.tiff_diroff = 0;
1✔
404
            tif->tif_diroff = 0;
1✔
405

406
            TIFFSeekFile(tif, 8, SEEK_SET);
1✔
407
            if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8))
1✔
408
            {
409
                TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
×
410
                return (0);
×
411
            }
412
        }
413
        else
414
        {
415
            uint64_t nextdir;
416
            nextdir = tif->tif_header.big.tiff_diroff;
1✔
417
            while (1)
418
            {
×
419
                uint64_t dircount64;
420
                uint16_t dircount;
421
                uint64_t nextnextdir;
422

423
                if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
1✔
424
                {
425
                    TIFFErrorExtR(tif, module,
×
426
                                  "Error fetching directory count");
427
                    return (0);
×
428
                }
429
                if (tif->tif_flags & TIFF_SWAB)
×
430
                    TIFFSwabLong8(&dircount64);
×
431
                if (dircount64 > 0xFFFF)
×
432
                {
433
                    TIFFErrorExtR(tif, module,
×
434
                                  "Sanity check on tag count failed, likely "
435
                                  "corrupt TIFF");
436
                    return (0);
×
437
                }
438
                dircount = (uint16_t)dircount64;
×
439
                (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
×
440
                if (!ReadOK(tif, &nextnextdir, 8))
×
441
                {
442
                    TIFFErrorExtR(tif, module, "Error fetching directory link");
×
443
                    return (0);
×
444
                }
445
                if (tif->tif_flags & TIFF_SWAB)
×
446
                    TIFFSwabLong8(&nextnextdir);
×
447
                if (nextnextdir == tif->tif_diroff)
×
448
                {
449
                    uint64_t m;
450
                    m = 0;
×
451
                    (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
×
452
                                       SEEK_SET);
453
                    if (!WriteOK(tif, &m, 8))
×
454
                    {
455
                        TIFFErrorExtR(tif, module,
×
456
                                      "Error writing directory link");
457
                        return (0);
×
458
                    }
459
                    tif->tif_diroff = 0;
×
460
                    /* Force a full-traversal to reach the zeroed pointer */
461
                    tif->tif_lastdiroff = 0;
×
462
                    break;
×
463
                }
464
                nextdir = nextnextdir;
×
465
            }
466
        }
467
        /* Remove skipped offset from IFD loop directory list. */
468
        _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
1✔
469
    }
470

471
    /*
472
     * Now use TIFFWriteDirectorySec() normally.
473
     */
474
    return TIFFWriteDirectorySec(tif, isimage, imagedone, pdiroff);
1,375✔
475
} /*-- TIFFRewriteDirectorySec() --*/
476

477
/*
478
 * Similar to TIFFWriteDirectory(), but if the directory has already
479
 * been written once, it is relocated to the end of the file, in case it
480
 * has changed in size.  Note that this will result in the loss of the
481
 * previously used directory space.
482
 */
483
int TIFFRewriteDirectory(TIFF *tif)
27,893✔
484
{
485
    return TIFFRewriteDirectorySec(tif, TRUE, TRUE, NULL);
27,893✔
486
}
487

488
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
40,939✔
489
                                 uint64_t *pdiroff)
490
{
491
    static const char module[] = "TIFFWriteDirectorySec";
492
    uint32_t ndir;
493
    TIFFDirEntry *dir;
494
    uint32_t dirsize;
495
    void *dirmem;
496
    uint32_t m;
497
    if (tif->tif_mode == O_RDONLY)
40,939✔
498
        return (1);
×
499

500
    _TIFFFillStriles(tif);
40,939✔
501

502
    /*
503
     * Clear write state so that subsequent images with
504
     * different characteristics get the right buffers
505
     * setup for them.
506
     */
507
    if (imagedone)
40,937✔
508
    {
509
        if (tif->tif_flags & TIFF_POSTENCODE)
40,936✔
510
        {
511
            tif->tif_flags &= ~TIFF_POSTENCODE;
×
512
            if (!(*tif->tif_postencode)(tif))
×
513
            {
514
                TIFFErrorExtR(tif, module,
×
515
                              "Error post-encoding before directory write");
516
                return (0);
×
517
            }
518
        }
519
        (*tif->tif_close)(tif); /* shutdown encoder */
40,936✔
520
        /*
521
         * Flush any data that might have been written
522
         * by the compression close+cleanup routines.  But
523
         * be careful not to write stuff if we didn't add data
524
         * in the previous steps as the "rawcc" data may well be
525
         * a previously read tile/strip in mixed read/write mode.
526
         */
527
        if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0)
40,937✔
528
        {
529
            if (!TIFFFlushData1(tif))
5✔
530
            {
UNCOV
531
                TIFFErrorExtR(tif, module,
×
532
                              "Error flushing data before directory write");
533
                return (0);
×
534
            }
535
        }
536
        if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
40,938✔
537
        {
538
            _TIFFfreeExt(tif, tif->tif_rawdata);
28,145✔
539
            tif->tif_rawdata = NULL;
28,148✔
540
            tif->tif_rawcc = 0;
28,148✔
541
            tif->tif_rawdatasize = 0;
28,148✔
542
            tif->tif_rawdataoff = 0;
28,148✔
543
            tif->tif_rawdataloaded = 0;
28,148✔
544
        }
545
        tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
40,941✔
546
    }
547

548
    if (TIFFFieldSet(tif, FIELD_COMPRESSION) &&
40,942✔
549
        (tif->tif_dir.td_compression == COMPRESSION_DEFLATE))
40,941✔
550
    {
551
        TIFFWarningExtR(tif, module,
×
552
                        "Creating TIFF with legacy Deflate codec identifier, "
553
                        "COMPRESSION_ADOBE_DEFLATE is more widely supported");
554
    }
555
    dir = NULL;
40,940✔
556
    dirmem = NULL;
40,940✔
557
    dirsize = 0;
40,940✔
558
    while (1)
559
    {
560
        /* The first loop only determines "ndir" and uses TIFFLinkDirectory() to
561
         * set the offset at which the IFD is to be written to the file.
562
         * The second loop writes IFD entries to the file. */
563
        ndir = 0;
81,854✔
564
        if (dir == NULL)
81,854✔
565
            tif->tif_dir.td_dirdatasize_write = 0;
40,938✔
566
        if (isimage)
81,854✔
567
        {
568
            /*-- Step 1: Process named tags for an image with FIELD bits
569
             *           assocciated. --*/
570
            if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
81,871✔
571
            {
572
                if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
81,871✔
573
                                                    TIFFTAG_IMAGEWIDTH,
574
                                                    tif->tif_dir.td_imagewidth))
575
                    goto bad;
×
576
                if (!TIFFWriteDirectoryTagShortLong(
81,875✔
577
                        tif, &ndir, dir, TIFFTAG_IMAGELENGTH,
578
                        tif->tif_dir.td_imagelength))
579
                    goto bad;
×
580
            }
581
            if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
81,876✔
582
            {
583
                if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
3,296✔
584
                                                    TIFFTAG_TILEWIDTH,
585
                                                    tif->tif_dir.td_tilewidth))
586
                    goto bad;
×
587
                if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
3,296✔
588
                                                    TIFFTAG_TILELENGTH,
589
                                                    tif->tif_dir.td_tilelength))
590
                    goto bad;
×
591
            }
592
            if (TIFFFieldSet(tif, FIELD_RESOLUTION))
81,876✔
593
            {
594
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
16✔
595
                                                   TIFFTAG_XRESOLUTION,
596
                                                   tif->tif_dir.td_xresolution))
16✔
597
                    goto bad;
×
598
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
16✔
599
                                                   TIFFTAG_YRESOLUTION,
600
                                                   tif->tif_dir.td_yresolution))
16✔
601
                    goto bad;
×
602
            }
603
            if (TIFFFieldSet(tif, FIELD_POSITION))
81,876✔
604
            {
605
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
×
606
                                                   TIFFTAG_XPOSITION,
607
                                                   tif->tif_dir.td_xposition))
×
608
                    goto bad;
×
609
                if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
×
610
                                                   TIFFTAG_YPOSITION,
611
                                                   tif->tif_dir.td_yposition))
×
612
                    goto bad;
×
613
            }
614
            if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
81,876✔
615
            {
616
                if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
1,992✔
617
                                               TIFFTAG_SUBFILETYPE,
618
                                               tif->tif_dir.td_subfiletype))
619
                    goto bad;
×
620
            }
621
            if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
81,876✔
622
            {
623
                if (!TIFFWriteDirectoryTagShortPerSample(
81,878✔
624
                        tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE,
625
                        tif->tif_dir.td_bitspersample))
81,871✔
626
                    goto bad;
×
627
            }
628
            if (TIFFFieldSet(tif, FIELD_COMPRESSION))
81,883✔
629
            {
630
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
81,878✔
631
                                                TIFFTAG_COMPRESSION,
632
                                                tif->tif_dir.td_compression))
81,875✔
633
                    goto bad;
×
634
            }
635
            if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
81,886✔
636
            {
637
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
81,872✔
638
                                                TIFFTAG_PHOTOMETRIC,
639
                                                tif->tif_dir.td_photometric))
81,869✔
640
                    goto bad;
×
641
            }
642
            if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
81,889✔
643
            {
644
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
×
645
                                                TIFFTAG_THRESHHOLDING,
646
                                                tif->tif_dir.td_threshholding))
×
647
                    goto bad;
×
648
            }
649
            if (TIFFFieldSet(tif, FIELD_FILLORDER))
81,889✔
650
            {
651
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
2✔
652
                                                TIFFTAG_FILLORDER,
653
                                                tif->tif_dir.td_fillorder))
2✔
654
                    goto bad;
×
655
            }
656
            if (TIFFFieldSet(tif, FIELD_ORIENTATION))
81,889✔
657
            {
658
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
×
659
                                                TIFFTAG_ORIENTATION,
660
                                                tif->tif_dir.td_orientation))
×
661
                    goto bad;
×
662
            }
663
            if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
81,889✔
664
            {
665
                if (!TIFFWriteDirectoryTagShort(
81,880✔
666
                        tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL,
667
                        tif->tif_dir.td_samplesperpixel))
81,878✔
668
                    goto bad;
×
669
            }
670
            if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
81,891✔
671
            {
672
                if (!TIFFWriteDirectoryTagShortLong(
78,576✔
673
                        tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP,
674
                        tif->tif_dir.td_rowsperstrip))
675
                    goto bad;
×
676
            }
677
            if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
81,891✔
678
            {
679
                if (!TIFFWriteDirectoryTagShortPerSample(
4✔
680
                        tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE,
681
                        tif->tif_dir.td_minsamplevalue))
4✔
682
                    goto bad;
×
683
            }
684
            if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
81,891✔
685
            {
686
                if (!TIFFWriteDirectoryTagShortPerSample(
4✔
687
                        tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE,
688
                        tif->tif_dir.td_maxsamplevalue))
4✔
689
                    goto bad;
×
690
            }
691
            if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
81,891✔
692
            {
693
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
81,880✔
694
                                                TIFFTAG_PLANARCONFIG,
695
                                                tif->tif_dir.td_planarconfig))
81,878✔
696
                    goto bad;
×
697
            }
698
            if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
81,893✔
699
            {
700
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
18✔
701
                                                TIFFTAG_RESOLUTIONUNIT,
702
                                                tif->tif_dir.td_resolutionunit))
18✔
703
                    goto bad;
×
704
            }
705
            if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
81,893✔
706
            {
707
                if (!TIFFWriteDirectoryTagShortArray(
×
708
                        tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2,
709
                        &tif->tif_dir.td_pagenumber[0]))
710
                    goto bad;
×
711
            }
712
            if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
81,893✔
713
            {
714
                if (!isTiled(tif))
81,867✔
715
                {
716
                    if (!TIFFWriteDirectoryTagLongLong8Array(
78,571✔
717
                            tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS,
718
                            tif->tif_dir.td_nstrips,
719
                            tif->tif_dir.td_stripbytecount_p))
720
                        goto bad;
×
721
                }
722
                else
723
                {
724
                    if (!TIFFWriteDirectoryTagLongLong8Array(
3,296✔
725
                            tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS,
726
                            tif->tif_dir.td_nstrips,
727
                            tif->tif_dir.td_stripbytecount_p))
728
                        goto bad;
×
729
                }
730
            }
731
            if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
81,892✔
732
            {
733
                if (!isTiled(tif))
81,864✔
734
                {
735
                    /* td_stripoffset_p might be NULL in an odd OJPEG case. See
736
                     *  tif_dirread.c around line 3634.
737
                     * XXX: OJPEG hack.
738
                     * If a) compression is OJPEG, b) it's not a tiled TIFF,
739
                     * and c) the number of strips is 1,
740
                     * then we tolerate the absence of stripoffsets tag,
741
                     * because, presumably, all required data is in the
742
                     * JpegInterchangeFormat stream.
743
                     * We can get here when using tiffset on such a file.
744
                     * See http://bugzilla.maptools.org/show_bug.cgi?id=2500
745
                     */
746
                    if (tif->tif_dir.td_stripoffset_p != NULL &&
157,146✔
747
                        !TIFFWriteDirectoryTagLongLong8Array(
78,568✔
748
                            tif, &ndir, dir, TIFFTAG_STRIPOFFSETS,
749
                            tif->tif_dir.td_nstrips,
750
                            tif->tif_dir.td_stripoffset_p))
751
                        goto bad;
×
752
                }
753
                else
754
                {
755
                    if (!TIFFWriteDirectoryTagLongLong8Array(
3,294✔
756
                            tif, &ndir, dir, TIFFTAG_TILEOFFSETS,
757
                            tif->tif_dir.td_nstrips,
758
                            tif->tif_dir.td_stripoffset_p))
759
                        goto bad;
×
760
                }
761
            }
762
            if (TIFFFieldSet(tif, FIELD_COLORMAP))
81,900✔
763
            {
764
                if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir))
142✔
765
                    goto bad;
×
766
            }
767
            if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES))
81,900✔
768
            {
769
                if (tif->tif_dir.td_extrasamples)
6,244✔
770
                {
771
                    uint16_t na;
772
                    uint16_t *nb;
773
                    TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb);
6,244✔
774
                    if (!TIFFWriteDirectoryTagShortArray(
6,244✔
775
                            tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb))
776
                        goto bad;
×
777
                }
778
            }
779
            if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
81,900✔
780
            {
781
                if (!TIFFWriteDirectoryTagShortPerSample(
81,405✔
782
                        tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT,
783
                        tif->tif_dir.td_sampleformat))
81,405✔
784
                    goto bad;
×
785
            }
786
            if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
81,900✔
787
            {
788
                if (!TIFFWriteDirectoryTagSampleformatArray(
×
789
                        tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE,
790
                        tif->tif_dir.td_samplesperpixel,
×
791
                        tif->tif_dir.td_sminsamplevalue))
792
                    goto bad;
×
793
            }
794
            if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
81,900✔
795
            {
796
                if (!TIFFWriteDirectoryTagSampleformatArray(
×
797
                        tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE,
798
                        tif->tif_dir.td_samplesperpixel,
×
799
                        tif->tif_dir.td_smaxsamplevalue))
800
                    goto bad;
×
801
            }
802
            if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
81,900✔
803
            {
804
                if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
×
805
                                               TIFFTAG_IMAGEDEPTH,
806
                                               tif->tif_dir.td_imagedepth))
807
                    goto bad;
×
808
            }
809
            if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
81,900✔
810
            {
811
                if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
×
812
                                               TIFFTAG_TILEDEPTH,
813
                                               tif->tif_dir.td_tiledepth))
814
                    goto bad;
×
815
            }
816
            if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
81,900✔
817
            {
818
                if (!TIFFWriteDirectoryTagShortArray(
×
819
                        tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2,
820
                        &tif->tif_dir.td_halftonehints[0]))
821
                    goto bad;
×
822
            }
823
            if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
81,900✔
824
            {
825
                if (!TIFFWriteDirectoryTagShortArray(
2,342✔
826
                        tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2,
827
                        &tif->tif_dir.td_ycbcrsubsampling[0]))
828
                    goto bad;
×
829
            }
830
            if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
81,900✔
831
            {
832
                if (!TIFFWriteDirectoryTagShort(
×
833
                        tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING,
834
                        tif->tif_dir.td_ycbcrpositioning))
×
835
                    goto bad;
×
836
            }
837
            if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
81,900✔
838
            {
839
                if (!TIFFWriteDirectoryTagRationalArray(
1,670✔
840
                        tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6,
841
                        tif->tif_dir.td_refblackwhite))
842
                    goto bad;
×
843
            }
844
            if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
81,900✔
845
            {
846
                if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir))
8✔
847
                    goto bad;
×
848
            }
849
            if (TIFFFieldSet(tif, FIELD_INKNAMES))
81,900✔
850
            {
851
                if (!TIFFWriteDirectoryTagAscii(
×
852
                        tif, &ndir, dir, TIFFTAG_INKNAMES,
853
                        tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
×
854
                    goto bad;
×
855
            }
856
            if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
81,900✔
857
            {
858
                if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
×
859
                                                TIFFTAG_NUMBEROFINKS,
860
                                                tif->tif_dir.td_numberofinks))
×
861
                    goto bad;
×
862
            }
863
            if (TIFFFieldSet(tif, FIELD_SUBIFD))
81,900✔
864
            {
865
                if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir))
×
866
                    goto bad;
×
867
            }
868
            /*-- Step 2: Process named tags for an image with FIELD bits
869
                         added by a codec.
870
                         Attention: There is only code for some field_types,
871
                         which are actually used by current codecs. --*/
872
            {
873
                uint32_t n;
874
                for (n = 0; n < tif->tif_nfields; n++)
13,685,100✔
875
                {
876
                    const TIFFField *o;
877
                    o = tif->tif_fields[n];
13,603,200✔
878
                    if ((o->field_bit >= FIELD_CODEC) &&
13,603,200✔
879
                        (TIFFFieldSet(tif, o->field_bit)))
47,168✔
880
                    {
881
                        switch (o->set_get_field_type)
7,682✔
882
                        {
883
                            case TIFF_SETGET_ASCII:
×
884
                            {
885
                                uint32_t pa;
886
                                char *pb;
887
                                assert(o->field_type == TIFF_ASCII);
×
888
                                assert(o->field_readcount == TIFF_VARIABLE);
×
889
                                assert(o->field_passcount == 0);
×
890
                                TIFFGetField(tif, o->field_tag, &pb);
×
891
                                pa = (uint32_t)(strlen(pb) + 1);
×
892
                                if (!TIFFWriteDirectoryTagAscii(
×
893
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
×
894
                                        pa, pb))
895
                                    goto bad;
×
896
                            }
897
                            break;
×
898
                            case TIFF_SETGET_UINT16:
3,141✔
899
                            {
900
                                uint16_t p;
901
                                assert(o->field_type == TIFF_SHORT);
3,141✔
902
                                assert(o->field_readcount == 1);
3,141✔
903
                                assert(o->field_passcount == 0);
3,141✔
904
                                TIFFGetField(tif, o->field_tag, &p);
3,141✔
905
                                if (!TIFFWriteDirectoryTagShort(
3,143✔
906
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
3,143✔
907
                                        p))
908
                                    goto bad;
×
909
                            }
910
                            break;
3,143✔
911
                            case TIFF_SETGET_UINT32:
2✔
912
                            {
913
                                uint32_t p;
914
                                assert(o->field_type == TIFF_LONG);
2✔
915
                                assert(o->field_readcount == 1);
2✔
916
                                assert(o->field_passcount == 0);
2✔
917
                                TIFFGetField(tif, o->field_tag, &p);
2✔
918
                                if (!TIFFWriteDirectoryTagLong(
2✔
919
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
2✔
920
                                        p))
921
                                    goto bad;
×
922
                            }
923
                            break;
2✔
924
                            case TIFF_SETGET_C32_UINT8:
4,538✔
925
                            {
926
                                uint32_t pa;
927
                                void *pb;
928
                                assert(o->field_type == TIFF_UNDEFINED);
4,538✔
929
                                assert(o->field_readcount == TIFF_VARIABLE2);
4,538✔
930
                                assert(o->field_passcount == 1);
4,538✔
931
                                TIFFGetField(tif, o->field_tag, &pa, &pb);
4,538✔
932
                                if (!TIFFWriteDirectoryTagUndefinedArray(
4,538✔
933
                                        tif, &ndir, dir, (uint16_t)o->field_tag,
4,538✔
934
                                        pa, pb))
935
                                    goto bad;
×
936
                            }
937
                            break;
4,538✔
938
                            default:
1✔
939
                                TIFFErrorExtR(
1✔
940
                                    tif, module,
941
                                    "Cannot write tag %" PRIu32 " (%s)",
942
                                    TIFFFieldTag(o),
943
                                    o->field_name ? o->field_name : "unknown");
1✔
944
                                goto bad;
×
945
                        }
946
                    }
13,595,500✔
947
                }
948
            }
949
        }
950
        /*-- Step 3: Process custom tags without FIELD bit for an image
951
         *           or for custom IFDs (e.g. EXIF) with !isimage. --*/
952
        for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
117,566✔
953
        {
954
            uint16_t tag =
35,715✔
955
                (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
35,715✔
956
            uint32_t count = tif->tif_dir.td_customValues[m].count;
35,715✔
957
            switch (tif->tif_dir.td_customValues[m].info->field_type)
35,715✔
958
            {
959
                case TIFF_ASCII:
10,155✔
960
                    if (!TIFFWriteDirectoryTagAscii(
10,155✔
961
                            tif, &ndir, dir, tag, count,
962
                            tif->tif_dir.td_customValues[m].value))
10,155✔
963
                        goto bad;
×
964
                    break;
10,155✔
965
                case TIFF_UNDEFINED:
16✔
966
                    if (!TIFFWriteDirectoryTagUndefinedArray(
16✔
967
                            tif, &ndir, dir, tag, count,
968
                            tif->tif_dir.td_customValues[m].value))
16✔
969
                        goto bad;
×
970
                    break;
16✔
971
                case TIFF_BYTE:
22✔
972
                    if (!TIFFWriteDirectoryTagByteArray(
22✔
973
                            tif, &ndir, dir, tag, count,
974
                            tif->tif_dir.td_customValues[m].value))
22✔
975
                        goto bad;
×
976
                    break;
22✔
977
                case TIFF_SBYTE:
×
978
                    if (!TIFFWriteDirectoryTagSbyteArray(
×
979
                            tif, &ndir, dir, tag, count,
980
                            tif->tif_dir.td_customValues[m].value))
×
981
                        goto bad;
×
982
                    break;
×
983
                case TIFF_SHORT:
6,541✔
984
                    if (!TIFFWriteDirectoryTagShortArray(
6,541✔
985
                            tif, &ndir, dir, tag, count,
986
                            tif->tif_dir.td_customValues[m].value))
6,541✔
987
                        goto bad;
2✔
988
                    break;
6,539✔
989
                case TIFF_SSHORT:
×
990
                    if (!TIFFWriteDirectoryTagSshortArray(
×
991
                            tif, &ndir, dir, tag, count,
992
                            tif->tif_dir.td_customValues[m].value))
×
993
                        goto bad;
×
994
                    break;
×
995
                case TIFF_LONG:
398✔
996
                    if (!TIFFWriteDirectoryTagLongArray(
398✔
997
                            tif, &ndir, dir, tag, count,
998
                            tif->tif_dir.td_customValues[m].value))
398✔
999
                        goto bad;
×
1000
                    break;
398✔
1001
                case TIFF_SLONG:
×
1002
                    if (!TIFFWriteDirectoryTagSlongArray(
×
1003
                            tif, &ndir, dir, tag, count,
1004
                            tif->tif_dir.td_customValues[m].value))
×
1005
                        goto bad;
×
1006
                    break;
×
1007
                case TIFF_LONG8:
×
1008
                    if (!TIFFWriteDirectoryTagLong8Array(
×
1009
                            tif, &ndir, dir, tag, count,
1010
                            tif->tif_dir.td_customValues[m].value))
×
1011
                        goto bad;
×
1012
                    break;
×
1013
                case TIFF_SLONG8:
×
1014
                    if (!TIFFWriteDirectoryTagSlong8Array(
×
1015
                            tif, &ndir, dir, tag, count,
1016
                            tif->tif_dir.td_customValues[m].value))
×
1017
                        goto bad;
×
1018
                    break;
×
1019
                case TIFF_RATIONAL:
20✔
1020
                {
1021
                    /*-- Rational2Double: For Rationals evaluate
1022
                     * "set_get_field_type" to determine internal storage size.
1023
                     */
1024
                    int tv_size;
1025
                    tv_size = TIFFFieldSetGetSize(
20✔
1026
                        tif->tif_dir.td_customValues[m].info);
20✔
1027
                    if (tv_size == 8)
20✔
1028
                    {
1029
                        if (!TIFFWriteDirectoryTagRationalDoubleArray(
×
1030
                                tif, &ndir, dir, tag, count,
1031
                                tif->tif_dir.td_customValues[m].value))
×
1032
                            goto bad;
×
1033
                    }
1034
                    else
1035
                    {
1036
                        /*-- default should be tv_size == 4 */
1037
                        if (!TIFFWriteDirectoryTagRationalArray(
20✔
1038
                                tif, &ndir, dir, tag, count,
1039
                                tif->tif_dir.td_customValues[m].value))
20✔
1040
                            goto bad;
×
1041
                        /*-- ToDo: After Testing, this should be removed and
1042
                         * tv_size==4 should be set as default. */
1043
                        if (tv_size != 4)
20✔
1044
                        {
1045
                            TIFFErrorExtR(
×
1046
                                tif, "TIFFLib: _TIFFWriteDirectorySec()",
1047
                                "Rational2Double: .set_get_field_type is "
1048
                                "not 4 but %d",
1049
                                tv_size);
1050
                        }
1051
                    }
1052
                }
1053
                break;
20✔
1054
                case TIFF_SRATIONAL:
×
1055
                {
1056
                    /*-- Rational2Double: For Rationals evaluate
1057
                     * "set_get_field_type" to determine internal storage size.
1058
                     */
1059
                    int tv_size;
1060
                    tv_size = TIFFFieldSetGetSize(
×
1061
                        tif->tif_dir.td_customValues[m].info);
×
1062
                    if (tv_size == 8)
×
1063
                    {
1064
                        if (!TIFFWriteDirectoryTagSrationalDoubleArray(
×
1065
                                tif, &ndir, dir, tag, count,
1066
                                tif->tif_dir.td_customValues[m].value))
×
1067
                            goto bad;
×
1068
                    }
1069
                    else
1070
                    {
1071
                        /*-- default should be tv_size == 4 */
1072
                        if (!TIFFWriteDirectoryTagSrationalArray(
×
1073
                                tif, &ndir, dir, tag, count,
1074
                                tif->tif_dir.td_customValues[m].value))
×
1075
                            goto bad;
×
1076
                        /*-- ToDo: After Testing, this should be removed and
1077
                         * tv_size==4 should be set as default. */
1078
                        if (tv_size != 4)
×
1079
                        {
1080
                            TIFFErrorExtR(
×
1081
                                tif, "TIFFLib: _TIFFWriteDirectorySec()",
1082
                                "Rational2Double: .set_get_field_type is "
1083
                                "not 4 but %d",
1084
                                tv_size);
1085
                        }
1086
                    }
1087
                }
1088
                break;
×
1089
                case TIFF_FLOAT:
×
1090
                    if (!TIFFWriteDirectoryTagFloatArray(
×
1091
                            tif, &ndir, dir, tag, count,
1092
                            tif->tif_dir.td_customValues[m].value))
×
1093
                        goto bad;
×
1094
                    break;
×
1095
                case TIFF_DOUBLE:
18,563✔
1096
                    if (!TIFFWriteDirectoryTagDoubleArray(
18,563✔
1097
                            tif, &ndir, dir, tag, count,
1098
                            tif->tif_dir.td_customValues[m].value))
18,563✔
1099
                        goto bad;
31✔
1100
                    break;
18,532✔
1101
                case TIFF_IFD:
×
1102
                    if (!TIFFWriteDirectoryTagIfdArray(
×
1103
                            tif, &ndir, dir, tag, count,
1104
                            tif->tif_dir.td_customValues[m].value))
×
1105
                        goto bad;
×
1106
                    break;
×
1107
                case TIFF_IFD8:
×
1108
                    if (!TIFFWriteDirectoryTagIfdIfd8Array(
×
1109
                            tif, &ndir, dir, tag, count,
1110
                            tif->tif_dir.td_customValues[m].value))
×
1111
                        goto bad;
×
1112
                    break;
×
1113
                default:
×
1114
                    assert(0); /* we should never get here */
×
1115
                    break;
1116
            }
1117
        }
1118
        /* "break" if IFD has been written above in second pass.*/
1119
        if (dir != NULL)
81,851✔
1120
            break;
40,909✔
1121

1122
        /* Evaluate IFD data size: Finally, add the size of the IFD tag entries
1123
         * themselves. */
1124
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,942✔
1125
            tif->tif_dir.td_dirdatasize_write += 2 + ndir * 12 + 4;
40,783✔
1126
        else
1127
            tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
159✔
1128

1129
        /* Setup a new directory within first pass. */
1130
        dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
40,942✔
1131
        if (dir == NULL)
40,942✔
1132
        {
1133
            TIFFErrorExtR(tif, module, "Out of memory");
×
1134
            goto bad;
×
1135
        }
1136
        if (isimage)
40,942✔
1137
        {
1138
            /* Check, weather the IFD to be written is new or an already written
1139
             * IFD can be overwritten or needs to be re-written to a different
1140
             * location in the file because the IFD is extended with additional
1141
             * tags or the IFD data size is increased.
1142
             * - tif_diroff == 0, if a new directory has to be linked.
1143
             * - tif_diroff != 0, IFD has been re-read from file and will be
1144
             *   overwritten or re-written.
1145
             */
1146
            if (tif->tif_diroff == 0)
40,942✔
1147
            {
1148
                if (!TIFFLinkDirectory(tif))
40,926✔
1149
                    goto bad;
×
1150
            }
1151
            else if (tif->tif_dir.td_dirdatasize_write >
16✔
1152
                     tif->tif_dir.td_dirdatasize_read)
16✔
1153
            {
1154
                if (dir != NULL)
×
1155
                {
1156
                    _TIFFfreeExt(tif, dir);
×
1157
                    dir = NULL;
×
1158
                }
1159
                if (!TIFFRewriteDirectorySec(tif, isimage, imagedone, pdiroff))
×
1160
                    goto bad;
×
1161
                return (1);
×
1162
            }
1163
        }
1164
        else
1165
        {
1166
            /* For !isimage, which means custom-IFD like EXIFIFD or
1167
             * checkpointing an IFD, determine whether to overwrite or append at
1168
             * the end of the file.
1169
             */
1170
            if (!((tif->tif_dir.td_dirdatasize_read > 0) &&
×
1171
                  (tif->tif_dir.td_dirdatasize_write <=
×
1172
                   tif->tif_dir.td_dirdatasize_read)))
×
1173
            {
1174
                /* Append at end of file and increment to an even offset. */
1175
                tif->tif_diroff =
×
1176
                    (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
6✔
1177
            }
1178
        }
1179
        /* Return IFD offset */
1180
        if (pdiroff != NULL)
40,934✔
1181
            *pdiroff = tif->tif_diroff;
×
1182
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,934✔
1183
            dirsize = 2 + ndir * 12 + 4;
40,777✔
1184
        else
1185
            dirsize = 8 + ndir * 20 + 8;
157✔
1186
        /* Append IFD data stright after the IFD tag entries.
1187
         * Data that does not fit into an IFD tag entry is written to the file
1188
         * in the second pass of the while loop. That offset is stored in "dir".
1189
         */
1190
        tif->tif_dataoff = tif->tif_diroff + dirsize;
40,934✔
1191
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,934✔
1192
            tif->tif_dataoff = (uint32_t)tif->tif_dataoff;
40,778✔
1193
        if ((tif->tif_dataoff < tif->tif_diroff) ||
40,934✔
1194
            (tif->tif_dataoff < (uint64_t)dirsize))
40,937✔
1195
        {
1196
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
20✔
1197
            goto bad;
×
1198
        }
1199
        if (tif->tif_dataoff & 1)
40,914✔
1200
            tif->tif_dataoff++;
×
1201
    } /* while() */
1202
    if (isimage)
40,909✔
1203
    {
1204
        /* For SubIFDs remember offset of SubIFD tag within main IFD.
1205
         * However, might be already done in TIFFWriteDirectoryTagSubifd() if
1206
         * there are more than one SubIFD. */
1207
        if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
40,907✔
1208
        {
1209
            uint32_t na;
1210
            TIFFDirEntry *nb;
1211
            for (na = 0, nb = dir;; na++, nb++)
×
1212
            {
1213
                if (na == ndir)
×
1214
                {
1215
                    TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
×
1216
                    goto bad;
×
1217
                }
1218
                if (nb->tdir_tag == TIFFTAG_SUBIFD)
×
1219
                    break;
×
1220
            }
1221
            if (!(tif->tif_flags & TIFF_BIGTIFF))
×
1222
                tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8;
×
1223
            else
1224
                tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12;
×
1225
        }
1226
    }
1227
    /* Copy/swab IFD entries from "dir" into "dirmem",
1228
     * which is then written to file. */
1229
    dirmem = _TIFFmallocExt(tif, dirsize);
40,909✔
1230
    if (dirmem == NULL)
40,908✔
1231
    {
1232
        TIFFErrorExtR(tif, module, "Out of memory");
×
1233
        goto bad;
×
1234
    }
1235
    if (!(tif->tif_flags & TIFF_BIGTIFF))
40,908✔
1236
    {
1237
        uint8_t *n;
1238
        uint32_t nTmp;
1239
        TIFFDirEntry *o;
1240
        n = dirmem;
40,751✔
1241
        *(uint16_t *)n = (uint16_t)ndir;
40,751✔
1242
        if (tif->tif_flags & TIFF_SWAB)
40,751✔
1243
            TIFFSwabShort((uint16_t *)n);
125✔
1244
        n += 2;
40,752✔
1245
        o = dir;
40,752✔
1246
        for (m = 0; m < ndir; m++)
517,612✔
1247
        {
1248
            *(uint16_t *)n = o->tdir_tag;
476,866✔
1249
            if (tif->tif_flags & TIFF_SWAB)
476,866✔
1250
                TIFFSwabShort((uint16_t *)n);
1,684✔
1251
            n += 2;
476,866✔
1252
            *(uint16_t *)n = o->tdir_type;
476,866✔
1253
            if (tif->tif_flags & TIFF_SWAB)
476,866✔
1254
                TIFFSwabShort((uint16_t *)n);
1,684✔
1255
            n += 2;
476,866✔
1256
            nTmp = (uint32_t)o->tdir_count;
476,866✔
1257
            _TIFFmemcpy(n, &nTmp, 4);
476,866✔
1258
            if (tif->tif_flags & TIFF_SWAB)
476,851✔
1259
                TIFFSwabLong((uint32_t *)n);
1,684✔
1260
            n += 4;
476,851✔
1261
            /* This is correct. The data has been */
1262
            /* swabbed previously in TIFFWriteDirectoryTagData */
1263
            _TIFFmemcpy(n, &o->tdir_offset, 4);
476,851✔
1264
            n += 4;
476,860✔
1265
            o++;
476,860✔
1266
        }
1267
        nTmp = (uint32_t)tif->tif_nextdiroff;
40,746✔
1268
        if (tif->tif_flags & TIFF_SWAB)
40,746✔
1269
            TIFFSwabLong(&nTmp);
125✔
1270
        _TIFFmemcpy(n, &nTmp, 4);
40,746✔
1271
    }
1272
    else
1273
    {
1274
        uint8_t *n;
1275
        TIFFDirEntry *o;
1276
        n = dirmem;
157✔
1277
        *(uint64_t *)n = ndir;
157✔
1278
        if (tif->tif_flags & TIFF_SWAB)
157✔
1279
            TIFFSwabLong8((uint64_t *)n);
4✔
1280
        n += 8;
157✔
1281
        o = dir;
157✔
1282
        for (m = 0; m < ndir; m++)
2,433✔
1283
        {
1284
            *(uint16_t *)n = o->tdir_tag;
2,276✔
1285
            if (tif->tif_flags & TIFF_SWAB)
2,276✔
1286
                TIFFSwabShort((uint16_t *)n);
44✔
1287
            n += 2;
2,276✔
1288
            *(uint16_t *)n = o->tdir_type;
2,276✔
1289
            if (tif->tif_flags & TIFF_SWAB)
2,276✔
1290
                TIFFSwabShort((uint16_t *)n);
44✔
1291
            n += 2;
2,276✔
1292
            _TIFFmemcpy(n, &o->tdir_count, 8);
2,276✔
1293
            if (tif->tif_flags & TIFF_SWAB)
2,276✔
1294
                TIFFSwabLong8((uint64_t *)n);
44✔
1295
            n += 8;
2,276✔
1296
            _TIFFmemcpy(n, &o->tdir_offset, 8);
2,276✔
1297
            n += 8;
2,276✔
1298
            o++;
2,276✔
1299
        }
1300
        _TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
157✔
1301
        if (tif->tif_flags & TIFF_SWAB)
157✔
1302
            TIFFSwabLong8((uint64_t *)n);
4✔
1303
    }
1304
    _TIFFfreeExt(tif, dir);
40,908✔
1305
    dir = NULL;
40,907✔
1306
    if (!SeekOK(tif, tif->tif_diroff))
40,907✔
1307
    {
1308
        TIFFErrorExtR(tif, module,
×
1309
                      "IO error writing directory at seek to offset");
1310
        goto bad;
×
1311
    }
1312
    if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
40,906✔
1313
    {
1314
        TIFFErrorExtR(tif, module, "IO error writing directory");
×
1315
        goto bad;
×
1316
    }
1317
    _TIFFfreeExt(tif, dirmem);
40,907✔
1318

1319
    /* Increment tif_curdir if IFD wasn't already written to file and no error
1320
     * occurred during IFD writing above. */
1321
    if (isimage && !tif->tif_dir.td_iswrittentofile)
40,907✔
1322
    {
1323
        if (!((tif->tif_flags & TIFF_INSUBIFD) &&
39,537✔
1324
              !(TIFFFieldSet(tif, FIELD_SUBIFD))))
×
1325
        {
1326
            /*-- Normal main-IFD case --*/
1327
            if (tif->tif_curdircount != TIFF_NON_EXISTENT_DIR_NUMBER)
39,537✔
1328
            {
1329
                tif->tif_curdir = tif->tif_curdircount;
39,536✔
1330
            }
1331
            else
1332
            {
1333
                /*ToDo SU: NEW_IFD_CURDIR_INCREMENTING:  Delete this
1334
                 * unexpected case after some testing time. */
1335
                /* Attention: tif->tif_curdircount is already set within
1336
                 * TIFFNumberOfDirectories() */
1337
                tif->tif_curdircount = TIFFNumberOfDirectories(tif);
1✔
1338
                tif->tif_curdir = tif->tif_curdircount;
×
1339
                TIFFErrorExtR(
×
1340
                    tif, module,
1341
                    "tif_curdircount is TIFF_NON_EXISTENT_DIR_NUMBER, "
1342
                    "not expected !! Line %d",
1343
                    __LINE__);
1344
                goto bad;
×
1345
            }
1346
        }
1347
        else
1348
        {
1349
            /*-- SubIFD case -- */
1350
            /* tif_curdir is always set to 0 for all SubIFDs. */
1351
            tif->tif_curdir = 0;
×
1352
        }
1353
    }
1354
    /* Increment tif_curdircount only if main-IFD of an image was not already
1355
     * present on file. */
1356
    /* Check in combination with (... && !(TIFFFieldSet(tif, FIELD_SUBIFD)))
1357
     * is necessary here because TIFF_INSUBIFD was already set above for the
1358
     * next SubIFD when this main-IFD (with FIELD_SUBIFD) is currently being
1359
     * written. */
1360
    if (isimage && !tif->tif_dir.td_iswrittentofile &&
40,906✔
1361
        !((tif->tif_flags & TIFF_INSUBIFD) &&
39,534✔
1362
          !(TIFFFieldSet(tif, FIELD_SUBIFD))))
×
1363
        tif->tif_curdircount++;
39,532✔
1364

1365
    tif->tif_dir.td_iswrittentofile = TRUE;
40,906✔
1366

1367
    /* Reset SubIFD writing stage after last SubIFD has been written. */
1368
    if (imagedone && (tif->tif_flags & TIFF_INSUBIFD) && tif->tif_nsubifd == 0)
40,906✔
1369
        tif->tif_flags &= ~TIFF_INSUBIFD;
×
1370

1371
    /* Add or update this directory to the IFD list. */
1372
    if (!_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, tif->tif_diroff))
40,906✔
1373
    {
1374
        TIFFErrorExtR(tif, module,
×
1375
                      "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1376
                      ") might cause an IFD loop",
1377
                      tif->tif_curdir, tif->tif_diroff, tif->tif_diroff);
1378
    }
1379

1380
    if (imagedone)
40,906✔
1381
    {
1382
        TIFFFreeDirectory(tif);
40,906✔
1383
        tif->tif_flags &= ~TIFF_DIRTYDIRECT;
40,905✔
1384
        tif->tif_flags &= ~TIFF_DIRTYSTRIP;
40,905✔
1385
        /* Reset directory-related state for subsequent directories. */
1386
        TIFFCreateDirectory(tif);
40,905✔
1387
    }
1388
    else
1389
    {
1390
        /* IFD is only checkpointed to file (or a custom IFD like EXIF is
1391
         * written), thus set IFD data size written to file. */
1392
        tif->tif_dir.td_dirdatasize_read = tif->tif_dir.td_dirdatasize_write;
×
1393
    }
1394
    return (1);
40,909✔
1395
bad:
33✔
1396
    if (dir != NULL)
33✔
1397
        _TIFFfreeExt(tif, dir);
33✔
1398
    if (dirmem != NULL)
33✔
1399
        _TIFFfreeExt(tif, dirmem);
×
1400
    return (0);
33✔
1401
}
1402

1403
static int8_t TIFFClampDoubleToInt8(double val)
×
1404
{
1405
    if (val > 127)
×
1406
        return 127;
×
1407
    if (val < -128 || val != val)
×
1408
        return -128;
×
1409
    return (int8_t)val;
×
1410
}
1411

1412
static int16_t TIFFClampDoubleToInt16(double val)
×
1413
{
1414
    if (val > 32767)
×
1415
        return 32767;
×
1416
    if (val < -32768 || val != val)
×
1417
        return -32768;
×
1418
    return (int16_t)val;
×
1419
}
1420

1421
static int32_t TIFFClampDoubleToInt32(double val)
×
1422
{
1423
    if (val > 0x7FFFFFFF)
×
1424
        return 0x7FFFFFFF;
×
1425
    if (val < -0x7FFFFFFF - 1 || val != val)
×
1426
        return -0x7FFFFFFF - 1;
×
1427
    return (int32_t)val;
×
1428
}
1429

1430
static uint8_t TIFFClampDoubleToUInt8(double val)
×
1431
{
1432
    if (val < 0)
×
1433
        return 0;
×
1434
    if (val > 255 || val != val)
×
1435
        return 255;
×
1436
    return (uint8_t)val;
×
1437
}
1438

1439
static uint16_t TIFFClampDoubleToUInt16(double val)
×
1440
{
1441
    if (val < 0)
×
1442
        return 0;
×
1443
    if (val > 65535 || val != val)
×
1444
        return 65535;
×
1445
    return (uint16_t)val;
×
1446
}
1447

1448
static uint32_t TIFFClampDoubleToUInt32(double val)
×
1449
{
1450
    if (val < 0)
×
1451
        return 0;
×
1452
    if (val > 0xFFFFFFFFU || val != val)
×
1453
        return 0xFFFFFFFFU;
×
1454
    return (uint32_t)val;
×
1455
}
1456

1457
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
×
1458
                                                  TIFFDirEntry *dir,
1459
                                                  uint16_t tag, uint32_t count,
1460
                                                  double *value)
1461
{
1462
    static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
1463
    void *conv;
1464
    uint32_t i;
1465
    int ok;
1466
    conv = _TIFFmallocExt(tif, count * sizeof(double));
×
1467
    if (conv == NULL)
×
1468
    {
1469
        TIFFErrorExtR(tif, module, "Out of memory");
×
1470
        return (0);
×
1471
    }
1472

1473
    switch (tif->tif_dir.td_sampleformat)
×
1474
    {
1475
        case SAMPLEFORMAT_IEEEFP:
×
1476
            if (tif->tif_dir.td_bitspersample <= 32)
×
1477
            {
1478
                for (i = 0; i < count; ++i)
×
1479
                    ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
×
1480
                ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count,
×
1481
                                                     (float *)conv);
1482
            }
1483
            else
1484
            {
1485
                ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
×
1486
                                                      count, value);
1487
            }
1488
            break;
×
1489
        case SAMPLEFORMAT_INT:
×
1490
            if (tif->tif_dir.td_bitspersample <= 8)
×
1491
            {
1492
                for (i = 0; i < count; ++i)
×
1493
                    ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]);
×
1494
                ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count,
×
1495
                                                     (int8_t *)conv);
1496
            }
1497
            else if (tif->tif_dir.td_bitspersample <= 16)
×
1498
            {
1499
                for (i = 0; i < count; ++i)
×
1500
                    ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]);
×
1501
                ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag,
×
1502
                                                      count, (int16_t *)conv);
1503
            }
1504
            else
1505
            {
1506
                for (i = 0; i < count; ++i)
×
1507
                    ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]);
×
1508
                ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count,
×
1509
                                                     (int32_t *)conv);
1510
            }
1511
            break;
×
1512
        case SAMPLEFORMAT_UINT:
×
1513
            if (tif->tif_dir.td_bitspersample <= 8)
×
1514
            {
1515
                for (i = 0; i < count; ++i)
×
1516
                    ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
×
1517
                ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count,
×
1518
                                                    (uint8_t *)conv);
1519
            }
1520
            else if (tif->tif_dir.td_bitspersample <= 16)
×
1521
            {
1522
                for (i = 0; i < count; ++i)
×
1523
                    ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
×
1524
                ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count,
×
1525
                                                     (uint16_t *)conv);
1526
            }
1527
            else
1528
            {
1529
                for (i = 0; i < count; ++i)
×
1530
                    ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
×
1531
                ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count,
×
1532
                                                    (uint32_t *)conv);
1533
            }
1534
            break;
×
1535
        default:
×
1536
            ok = 0;
×
1537
    }
1538

1539
    _TIFFfreeExt(tif, conv);
×
1540
    return (ok);
×
1541
}
1542

1543
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
10,155✔
1544
                                      TIFFDirEntry *dir, uint16_t tag,
1545
                                      uint32_t count, char *value)
1546
{
1547
    return (
1548
        TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
10,155✔
1549
}
1550

1551
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
4,554✔
1552
                                               TIFFDirEntry *dir, uint16_t tag,
1553
                                               uint32_t count, uint8_t *value)
1554
{
1555
    return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
4,554✔
1556
                                                       count, value));
1557
}
1558

1559
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
22✔
1560
                                          TIFFDirEntry *dir, uint16_t tag,
1561
                                          uint32_t count, uint8_t *value)
1562
{
1563
    return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
22✔
1564
                                                  value));
1565
}
1566

1567
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
×
1568
                                           TIFFDirEntry *dir, uint16_t tag,
1569
                                           uint32_t count, int8_t *value)
1570
{
1571
    return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
×
1572
                                                   value));
1573
}
1574

1575
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
330,669✔
1576
                                      TIFFDirEntry *dir, uint16_t tag,
1577
                                      uint16_t value)
1578
{
1579
    return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
330,669✔
1580
}
1581

1582
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
15,127✔
1583
                                           TIFFDirEntry *dir, uint16_t tag,
1584
                                           uint32_t count, uint16_t *value)
1585
{
1586
    return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
15,127✔
1587
                                                   value));
1588
}
1589

1590
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
163,293✔
1591
                                               TIFFDirEntry *dir, uint16_t tag,
1592
                                               uint16_t value)
1593
{
1594
    static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1595
    uint16_t *m;
1596
    uint16_t *na;
1597
    uint16_t nb;
1598
    int o;
1599
    if (dir == NULL)
163,293✔
1600
    {
1601
        /* only evaluate IFD data size and inc. ndir */
1602
        return (TIFFWriteDirectoryTagCheckedShortArray(
81,639✔
1603
            tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
81,646✔
1604
    }
1605
    m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
81,647✔
1606
    if (m == NULL)
81,647✔
1607
    {
1608
        TIFFErrorExtR(tif, module, "Out of memory");
×
1609
        return (0);
×
1610
    }
1611
    for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
589,421✔
1612
        *na = value;
507,774✔
1613
    o = TIFFWriteDirectoryTagCheckedShortArray(
81,647✔
1614
        tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
81,647✔
1615
    _TIFFfreeExt(tif, m);
81,648✔
1616
    return (o);
81,649✔
1617
}
1618

1619
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
×
1620
                                            TIFFDirEntry *dir, uint16_t tag,
1621
                                            uint32_t count, int16_t *value)
1622
{
1623
    return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
×
1624
                                                    value));
1625
}
1626

1627
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
1,994✔
1628
                                     TIFFDirEntry *dir, uint16_t tag,
1629
                                     uint32_t value)
1630
{
1631
    return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1,994✔
1632
}
1633

1634
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
398✔
1635
                                          TIFFDirEntry *dir, uint16_t tag,
1636
                                          uint32_t count, uint32_t *value)
1637
{
1638
    return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
398✔
1639
                                                  value));
1640
}
1641

1642
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
×
1643
                                           TIFFDirEntry *dir, uint16_t tag,
1644
                                           uint32_t count, int32_t *value)
1645
{
1646
    return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
×
1647
                                                   value));
1648
}
1649

1650
/************************************************************************/
1651
/*                 TIFFWriteDirectoryTagLong8Array()                    */
1652
/*                                                                      */
1653
/*      Write either Long8 or Long array depending on file type.        */
1654
/************************************************************************/
1655
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
×
1656
                                           TIFFDirEntry *dir, uint16_t tag,
1657
                                           uint32_t count, uint64_t *value)
1658
{
1659
    static const char module[] = "TIFFWriteDirectoryTagLong8Array";
1660
    uint64_t *ma;
1661
    uint32_t mb;
1662
    uint32_t *p;
1663
    uint32_t *q;
1664
    int o;
1665

1666
    /* is this just a counting pass? */
1667
    if (dir == NULL)
×
1668
    {
1669
        /* only evaluate IFD data size and inc. ndir */
1670
        return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
×
1671
                                                       count, value));
1672
    }
1673

1674
    /* We always write Long8 for BigTIFF, no checking needed. */
1675
    if (tif->tif_flags & TIFF_BIGTIFF)
×
1676
        return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
×
1677
                                                       count, value));
1678

1679
    /*
1680
    ** For classic tiff we want to verify everything is in range for long
1681
    ** and convert to long format.
1682
    */
1683
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
×
1684
    if (p == NULL)
×
1685
    {
1686
        TIFFErrorExtR(tif, module, "Out of memory");
×
1687
        return (0);
×
1688
    }
1689

1690
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
×
1691
    {
1692
        if (*ma > 0xFFFFFFFF)
×
1693
        {
1694
            TIFFErrorExtR(tif, module,
×
1695
                          "Attempt to write unsigned long value %" PRIu64
1696
                          " larger than 0xFFFFFFFF for tag %d in Classic TIFF "
1697
                          "file. TIFF file writing aborted",
1698
                          *ma, tag);
1699
            _TIFFfreeExt(tif, p);
×
1700
            return (0);
×
1701
        }
1702
        *q = (uint32_t)(*ma);
×
1703
    }
1704

1705
    o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
×
1706
    _TIFFfreeExt(tif, p);
×
1707

1708
    return (o);
×
1709
}
1710

1711
/************************************************************************/
1712
/*                 TIFFWriteDirectoryTagSlong8Array()                   */
1713
/*                                                                      */
1714
/*      Write either SLong8 or SLong array depending on file type.      */
1715
/************************************************************************/
1716
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
×
1717
                                            TIFFDirEntry *dir, uint16_t tag,
1718
                                            uint32_t count, int64_t *value)
1719
{
1720
    static const char module[] = "TIFFWriteDirectoryTagSlong8Array";
1721
    int64_t *ma;
1722
    uint32_t mb;
1723
    int32_t *p;
1724
    int32_t *q;
1725
    int o;
1726

1727
    /* is this just a counting pass? */
1728
    if (dir == NULL)
×
1729
    {
1730
        /* only evaluate IFD data size and inc. ndir */
1731
        return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
×
1732
                                                        count, value));
1733
    }
1734
    /* We always write SLong8 for BigTIFF, no checking needed. */
1735
    if (tif->tif_flags & TIFF_BIGTIFF)
×
1736
        return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
×
1737
                                                        count, value));
1738

1739
    /*
1740
    ** For classic tiff we want to verify everything is in range for signed-long
1741
    ** and convert to signed-long format.
1742
    */
1743
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
×
1744
    if (p == NULL)
×
1745
    {
1746
        TIFFErrorExtR(tif, module, "Out of memory");
×
1747
        return (0);
×
1748
    }
1749

1750
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
×
1751
    {
1752
        if (*ma > (2147483647))
×
1753
        {
1754
            TIFFErrorExtR(tif, module,
×
1755
                          "Attempt to write signed long value %" PRIi64
1756
                          " larger than 0x7FFFFFFF (2147483647) for tag %d in "
1757
                          "Classic TIFF file. TIFF writing to file aborted",
1758
                          *ma, tag);
1759
            _TIFFfreeExt(tif, p);
×
1760
            return (0);
×
1761
        }
1762
        else if (*ma < (-2147483647 - 1))
×
1763
        {
1764
            TIFFErrorExtR(tif, module,
×
1765
                          "Attempt to write signed long value %" PRIi64
1766
                          " smaller than 0x80000000 (-2147483648) for tag %d "
1767
                          "in Classic TIFF file. TIFF writing to file aborted",
1768
                          *ma, tag);
1769
            _TIFFfreeExt(tif, p);
×
1770
            return (0);
×
1771
        }
1772
        *q = (int32_t)(*ma);
×
1773
    }
1774

1775
    o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p);
×
1776
    _TIFFfreeExt(tif, p);
×
1777

1778
    return (o);
×
1779
}
1780

1781
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
32✔
1782
                                         TIFFDirEntry *dir, uint16_t tag,
1783
                                         double value)
1784
{
1785
    return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
32✔
1786
}
1787

1788
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
1,690✔
1789
                                              TIFFDirEntry *dir, uint16_t tag,
1790
                                              uint32_t count, float *value)
1791
{
1792
    return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
1,690✔
1793
                                                      count, value));
1794
}
1795

1796
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
×
1797
                                               TIFFDirEntry *dir, uint16_t tag,
1798
                                               uint32_t count, float *value)
1799
{
1800
    return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
×
1801
                                                       count, value));
1802
}
1803

1804
/*-- Rational2Double: additional write functions */
1805
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
×
1806
                                                    TIFFDirEntry *dir,
1807
                                                    uint16_t tag,
1808
                                                    uint32_t count,
1809
                                                    double *value)
1810
{
1811
    return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
×
1812
                                                            count, value));
1813
}
1814

1815
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
×
1816
                                                     TIFFDirEntry *dir,
1817
                                                     uint16_t tag,
1818
                                                     uint32_t count,
1819
                                                     double *value)
1820
{
1821
    return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
×
1822
        tif, ndir, dir, tag, count, value));
1823
}
1824

1825
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
×
1826
                                           TIFFDirEntry *dir, uint16_t tag,
1827
                                           uint32_t count, float *value)
1828
{
1829
    return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
×
1830
                                                   value));
1831
}
1832

1833
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
18,563✔
1834
                                            TIFFDirEntry *dir, uint16_t tag,
1835
                                            uint32_t count, double *value)
1836
{
1837
    return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
18,563✔
1838
                                                    value));
1839
}
1840

1841
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
×
1842
                                         TIFFDirEntry *dir, uint16_t tag,
1843
                                         uint32_t count, uint32_t *value)
1844
{
1845
    return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
×
1846
                                                 value));
1847
}
1848

1849
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
248,923✔
1850
                                          TIFFDirEntry *dir, uint16_t tag,
1851
                                          uint32_t value)
1852
{
1853
    if (value <= 0xFFFF)
248,923✔
1854
        return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
248,866✔
1855
                                                  (uint16_t)value));
248,867✔
1856
    else
1857
        return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
56✔
1858
}
1859

1860
static int _WriteAsType(TIFF *tif, uint64_t strile_size,
6,688✔
1861
                        uint64_t uncompressed_threshold)
1862
{
1863
    const uint16_t compression = tif->tif_dir.td_compression;
6,688✔
1864
    if (compression == COMPRESSION_NONE)
6,688✔
1865
    {
1866
        return strile_size > uncompressed_threshold;
4,146✔
1867
    }
1868
    else if (compression == COMPRESSION_JPEG ||
2,542✔
1869
             compression == COMPRESSION_LZW ||
810✔
1870
             compression == COMPRESSION_ADOBE_DEFLATE ||
462✔
1871
             compression == COMPRESSION_DEFLATE ||
462✔
1872
             compression == COMPRESSION_LZMA ||
460✔
1873
             compression == COMPRESSION_LERC ||
388✔
1874
             compression == COMPRESSION_ZSTD ||
134✔
1875
             compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL)
68✔
1876
    {
1877
        /* For a few select compression types, we assume that in the worst */
1878
        /* case the compressed size will be 10 times the uncompressed size. */
1879
        /* This is overly pessismistic ! */
1880
        return strile_size >= uncompressed_threshold / 10;
2,474✔
1881
    }
1882
    return 1;
68✔
1883
}
1884

1885
static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
321✔
1886
{
1887
    return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
321✔
1888
}
1889

1890
static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
6,367✔
1891
{
1892
    return _WriteAsType(tif, strile_size, 0xFFFFU);
6,367✔
1893
}
1894

1895
/************************************************************************/
1896
/*                TIFFWriteDirectoryTagLongLong8Array()                 */
1897
/*                                                                      */
1898
/*      Write out LONG8 array and write a SHORT/LONG/LONG8 depending    */
1899
/*      on strile size and Classic/BigTIFF mode.                        */
1900
/************************************************************************/
1901

1902
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
163,736✔
1903
                                               TIFFDirEntry *dir, uint16_t tag,
1904
                                               uint32_t count, uint64_t *value)
1905
{
1906
    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1907
    int o;
1908
    int write_aslong4;
1909

1910
    if (tif->tif_dir.td_deferstrilearraywriting)
163,736✔
1911
    {
1912
        if (dir == NULL)
1,492✔
1913
        {
1914
            /* This is just a counting pass to count IFD entries.
1915
             * For deferstrilearraywriting no extra bytes will be written
1916
             * into IFD space. */
1917
            (*ndir)++;
746✔
1918
            return 1;
746✔
1919
        }
1920
        return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
746✔
1921
                                         NULL);
1922
    }
1923

1924
    if (tif->tif_flags & TIFF_BIGTIFF)
162,244✔
1925
    {
1926
        int write_aslong8 = 1;
564✔
1927
        /* In the case of ByteCounts array, we may be able to write them on LONG
1928
         * if the strip/tilesize is not too big. Also do that for count > 1 in
1929
         * the case someone would want to create a single-strip file with a
1930
         * growing height, in which case using LONG8 will be safer. */
1931
        if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
564✔
1932
        {
1933
            write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
32✔
1934
        }
1935
        else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
532✔
1936
        {
1937
            write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
124✔
1938
        }
1939
        if (write_aslong8)
564✔
1940
        {
1941
            return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
408✔
1942
                                                          count, value);
1943
        }
1944
    }
1945

1946
    write_aslong4 = 1;
161,836✔
1947
    if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
161,836✔
1948
    {
1949
        write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
4,888✔
1950
    }
1951
    else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
156,948✔
1952
    {
1953
        write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1,314✔
1954
    }
1955
    if (write_aslong4)
161,838✔
1956
    {
1957
        /*
1958
        ** For classic tiff we want to verify everything is in range for LONG
1959
        ** and convert to long format.
1960
        */
1961

1962
        uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
157,208✔
1963
        uint32_t *q;
1964
        uint64_t *ma;
1965
        uint32_t mb;
1966

1967
        if (p == NULL)
157,200✔
1968
        {
1969
            TIFFErrorExtR(tif, module, "Out of memory");
×
1970
            return (0);
×
1971
        }
1972

1973
        for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
11,327,300✔
1974
        {
1975
            if (*ma > 0xFFFFFFFF)
11,170,100✔
1976
            {
1977
                TIFFErrorExtR(tif, module,
×
1978
                              "Attempt to write value larger than 0xFFFFFFFF "
1979
                              "in LONG array.");
1980
                _TIFFfreeExt(tif, p);
×
1981
                return (0);
×
1982
            }
1983
            *q = (uint32_t)(*ma);
11,170,100✔
1984
        }
1985

1986
        o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
157,200✔
1987
                                                  p);
1988
        _TIFFfreeExt(tif, p);
157,207✔
1989
    }
1990
    else
1991
    {
1992
        uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
4,630✔
1993
        uint16_t *q;
1994
        uint64_t *ma;
1995
        uint32_t mb;
1996

1997
        if (p == NULL)
4,630✔
1998
        {
1999
            TIFFErrorExtR(tif, module, "Out of memory");
×
2000
            return (0);
×
2001
        }
2002

2003
        for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
6,127,640✔
2004
        {
2005
            if (*ma > 0xFFFF)
6,123,010✔
2006
            {
2007
                /* Should not happen normally given the check we did before */
2008
                TIFFErrorExtR(tif, module,
×
2009
                              "Attempt to write value larger than 0xFFFF in "
2010
                              "SHORT array.");
2011
                _TIFFfreeExt(tif, p);
×
2012
                return (0);
×
2013
            }
2014
            *q = (uint16_t)(*ma);
6,123,010✔
2015
        }
2016

2017
        o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
4,630✔
2018
                                                   p);
2019
        _TIFFfreeExt(tif, p);
4,630✔
2020
    }
2021

2022
    return (o);
161,836✔
2023
}
2024

2025
/************************************************************************/
2026
/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
2027
/*                                                                      */
2028
/*      Write either IFD8 or IFD array depending on file type.          */
2029
/************************************************************************/
2030

2031
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
×
2032
                                             TIFFDirEntry *dir, uint16_t tag,
2033
                                             uint32_t count, uint64_t *value)
2034
{
2035
    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
2036
    uint64_t *ma;
2037
    uint32_t mb;
2038
    uint32_t *p;
2039
    uint32_t *q;
2040
    int o;
2041

2042
    /* We always write IFD8 for BigTIFF, no checking needed. */
2043
    if (tif->tif_flags & TIFF_BIGTIFF)
×
2044
        return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count,
×
2045
                                                     value);
2046

2047
    /*
2048
    ** For classic tiff we want to verify everything is in range for IFD
2049
    ** and convert to long format.
2050
    */
2051

2052
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
×
2053
    if (p == NULL)
×
2054
    {
2055
        TIFFErrorExtR(tif, module, "Out of memory");
×
2056
        return (0);
×
2057
    }
2058

2059
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
×
2060
    {
2061
        if (*ma > 0xFFFFFFFF)
×
2062
        {
2063
            TIFFErrorExtR(tif, module,
×
2064
                          "Attempt to write value larger than 0xFFFFFFFF in "
2065
                          "Classic TIFF file.");
2066
            _TIFFfreeExt(tif, p);
×
2067
            return (0);
×
2068
        }
2069
        *q = (uint32_t)(*ma);
×
2070
    }
2071

2072
    o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
×
2073
    _TIFFfreeExt(tif, p);
×
2074

2075
    return (o);
×
2076
}
2077

2078
/*
2079
 * Auxiliary function to determine the IFD data size to be written to the file.
2080
 * The IFD data size is finally the size of the IFD tag entries plus the IFD
2081
 * data that is written directly after the IFD tag entries.
2082
 */
2083
static void EvaluateIFDdatasizeWrite(TIFF *tif, uint32_t count,
188,157✔
2084
                                     uint32_t typesize, uint32_t *ndir)
2085
{
2086
    uint64_t datalength = (uint64_t)count * typesize;
188,157✔
2087
    if (datalength > ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
188,157✔
2088
    {
2089
        /* LibTIFF increments write address to an even offset, thus datalength
2090
         * written is also incremented. */
2091
        if (datalength & 1)
40,635✔
2092
            datalength++;
2,536✔
2093
        tif->tif_dir.td_dirdatasize_write += datalength;
40,635✔
2094
    }
2095
    (*ndir)++;
188,157✔
2096
}
188,157✔
2097

2098
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
142✔
2099
                                         TIFFDirEntry *dir)
2100
{
2101
    static const char module[] = "TIFFWriteDirectoryTagColormap";
2102
    uint32_t m;
2103
    uint16_t *n;
2104
    int o;
2105
    m = (1 << tif->tif_dir.td_bitspersample);
142✔
2106
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
142✔
2107
    {
2108
        EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir);
71✔
2109
        return 1;
71✔
2110
    }
2111

2112
    n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
71✔
2113
    if (n == NULL)
71✔
2114
    {
2115
        TIFFErrorExtR(tif, module, "Out of memory");
×
2116
        return (0);
×
2117
    }
2118
    _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
71✔
2119
    _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
71✔
2120
    _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
71✔
2121
    o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
71✔
2122
                                               3 * m, n);
2123
    _TIFFfreeExt(tif, n);
71✔
2124
    return (o);
71✔
2125
}
2126

2127
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
8✔
2128
                                                 TIFFDirEntry *dir)
2129
{
2130
    static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
2131
    uint32_t m;
2132
    uint16_t n;
2133
    uint16_t *o;
2134
    int p;
2135
    /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
2136
     *  (1 << BitsPerSample) * uint16_t values.
2137
     */
2138
    m = (1 << tif->tif_dir.td_bitspersample);
8✔
2139
    /* clang-format off */
2140
    n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
8✔
2141
    /* clang-format on */
2142

2143
    /* Check for proper number of transferfunctions */
2144
    for (int i = 0; i < n; i++)
32✔
2145
    {
2146
        if (tif->tif_dir.td_transferfunction[i] == NULL)
24✔
2147
        {
2148
            TIFFWarningExtR(tif, module,
×
2149
                            "Too few TransferFunctions provided. Tag "
2150
                            "not written to file");
2151
            return (1); /* Not an error; only tag is not written. */
×
2152
        }
2153
    }
2154
    /*
2155
     * Check if the table can be written as a single column,
2156
     * or if it must be written as 3 columns.  Note that we
2157
     * write a 3-column tag if there are 2 samples/pixel and
2158
     * a single column of data won't suffice--hmm.
2159
     */
2160
    if (n == 3)
8✔
2161
    {
2162
        if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
8✔
2163
                         tif->tif_dir.td_transferfunction[2],
8✔
2164
                         m * sizeof(uint16_t)) &&
8✔
2165
            !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
×
2166
                         tif->tif_dir.td_transferfunction[1],
×
2167
                         m * sizeof(uint16_t)))
×
2168
            n = 1;
×
2169
    }
2170
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
8✔
2171
    {
2172
        EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir);
4✔
2173
        return 1;
4✔
2174
    }
2175

2176
    o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
4✔
2177
    if (o == NULL)
4✔
2178
    {
2179
        TIFFErrorExtR(tif, module, "Out of memory");
×
2180
        return (0);
×
2181
    }
2182
    _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
4✔
2183
                m * sizeof(uint16_t));
4✔
2184
    if (n > 1)
4✔
2185
        _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
4✔
2186
                    m * sizeof(uint16_t));
4✔
2187
    if (n > 2)
4✔
2188
        _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
4✔
2189
                    m * sizeof(uint16_t));
4✔
2190
    p = TIFFWriteDirectoryTagCheckedShortArray(
4✔
2191
        tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
2192
    _TIFFfreeExt(tif, o);
4✔
2193
    return (p);
4✔
2194
}
2195

2196
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
×
2197
                                       TIFFDirEntry *dir)
2198
{
2199
    static const char module[] = "TIFFWriteDirectoryTagSubifd";
2200
    uint64_t m;
2201
    int n;
2202
    if (tif->tif_dir.td_nsubifd == 0)
×
2203
        return (1);
×
2204
    m = tif->tif_dataoff;
×
2205
    if (!(tif->tif_flags & TIFF_BIGTIFF))
×
2206
    {
2207
        uint32_t *o;
2208
        uint64_t *pa;
2209
        uint32_t *pb;
2210
        uint16_t p;
2211
        o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
×
2212
        if (o == NULL)
×
2213
        {
2214
            TIFFErrorExtR(tif, module, "Out of memory");
×
2215
            return (0);
×
2216
        }
2217
        pa = tif->tif_dir.td_subifd;
×
2218
        pb = o;
×
2219
        for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
×
2220
        {
2221
            assert(pa != 0);
×
2222

2223
            /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
2224
             * is illegal) */
2225
            if (*pa > 0xFFFFFFFFUL)
×
2226
            {
2227
                TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
×
2228
                _TIFFfreeExt(tif, o);
×
2229
                return (0);
×
2230
            }
2231
            *pb++ = (uint32_t)(*pa++);
×
2232
        }
2233
        n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
×
2234
                                                 tif->tif_dir.td_nsubifd, o);
×
2235
        _TIFFfreeExt(tif, o);
×
2236
    }
2237
    else
2238
        n = TIFFWriteDirectoryTagCheckedIfd8Array(
×
2239
            tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
×
2240
            tif->tif_dir.td_subifd);
2241

2242
    if (dir == NULL)
×
2243
        /* Just have evaluated IFD data size and incremented ndir
2244
         * above in sub-functions. */
2245
        return (n);
×
2246

2247
    if (!n)
×
2248
        return (0);
×
2249
    /*
2250
     * Total hack: if this directory includes a SubIFD
2251
     * tag then force the next <n> directories to be
2252
     * written as ``sub directories'' of this one.  This
2253
     * is used to write things like thumbnails and
2254
     * image masks that one wants to keep out of the
2255
     * normal directory linkage access mechanism.
2256
     */
2257
    tif->tif_flags |= TIFF_INSUBIFD;
×
2258
    tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
×
2259
    if (tif->tif_dir.td_nsubifd == 1)
×
2260
        tif->tif_subifdoff = 0;
×
2261
    else
2262
        tif->tif_subifdoff = m;
×
2263
    return (1);
×
2264
}
2265

2266
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
10,155✔
2267
                                             TIFFDirEntry *dir, uint16_t tag,
2268
                                             uint32_t count, char *value)
2269
{
2270
    assert(sizeof(char) == 1);
2271
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
10,155✔
2272
    {
2273
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
5,094✔
2274
        return 1;
5,094✔
2275
    }
2276
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
5,061✔
2277
                                      count, value));
2278
}
2279

2280
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
4,554✔
2281
                                                      TIFFDirEntry *dir,
2282
                                                      uint16_t tag,
2283
                                                      uint32_t count,
2284
                                                      uint8_t *value)
2285
{
2286
    assert(sizeof(uint8_t) == 1);
2287
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
4,554✔
2288
    {
2289
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2,277✔
2290
        return 1;
2,277✔
2291
    }
2292
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
2,277✔
2293
                                      count, count, value));
2294
}
2295

2296
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
22✔
2297
                                                 TIFFDirEntry *dir,
2298
                                                 uint16_t tag, uint32_t count,
2299
                                                 uint8_t *value)
2300
{
2301
    assert(sizeof(uint8_t) == 1);
2302
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
22✔
2303
    {
2304
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
11✔
2305
        return 1;
11✔
2306
    }
2307
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
11✔
2308
                                      count, value));
2309
}
2310

2311
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
×
2312
                                                  TIFFDirEntry *dir,
2313
                                                  uint16_t tag, uint32_t count,
2314
                                                  int8_t *value)
2315
{
2316
    assert(sizeof(int8_t) == 1);
2317
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2318
    {
2319
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
×
2320
        return 1;
×
2321
    }
2322
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
×
2323
                                      count, value));
2324
}
2325

2326
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
579,532✔
2327
                                             TIFFDirEntry *dir, uint16_t tag,
2328
                                             uint16_t value)
2329
{
2330
    uint16_t m;
2331
    assert(sizeof(uint16_t) == 2);
2332
    if (dir == NULL)
579,532✔
2333
    {
2334
        /* No additional data to IFD data size just increment ndir. */
2335
        (*ndir)++;
289,768✔
2336
        return 1;
289,768✔
2337
    }
2338
    m = value;
289,764✔
2339
    if (tif->tif_flags & TIFF_SWAB)
289,764✔
2340
        TIFFSwabShort(&m);
959✔
2341
    return (
2342
        TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
289,764✔
2343
}
2344

2345
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
183,123✔
2346
                                                  TIFFDirEntry *dir,
2347
                                                  uint16_t tag, uint32_t count,
2348
                                                  uint16_t *value)
2349
{
2350
    assert(count < 0x80000000);
183,123✔
2351
    assert(sizeof(uint16_t) == 2);
2352
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
183,123✔
2353
    {
2354
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
91,536✔
2355
        return 1;
91,536✔
2356
    }
2357
    if (tif->tif_flags & TIFF_SWAB)
91,587✔
2358
        TIFFSwabArrayOfShort(value, count);
368✔
2359
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
91,587✔
2360
                                      count * 2, value));
2361
}
2362

2363
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
×
2364
                                                   TIFFDirEntry *dir,
2365
                                                   uint16_t tag, uint32_t count,
2366
                                                   int16_t *value)
2367
{
2368
    assert(count < 0x80000000);
×
2369
    assert(sizeof(int16_t) == 2);
2370
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2371
    {
2372
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
×
2373
        return 1;
×
2374
    }
2375
    if (tif->tif_flags & TIFF_SWAB)
×
2376
        TIFFSwabArrayOfShort((uint16_t *)value, count);
×
2377
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
×
2378
                                      count * 2, value));
2379
}
2380

2381
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
2,050✔
2382
                                            TIFFDirEntry *dir, uint16_t tag,
2383
                                            uint32_t value)
2384
{
2385
    uint32_t m;
2386
    assert(sizeof(uint32_t) == 4);
2387
    if (dir == NULL)
2,050✔
2388
    {
2389
        /* No additional data to IFD data size just increment ndir. */
2390
        (*ndir)++;
1,025✔
2391
        return 1;
1,025✔
2392
    }
2393
    m = value;
1,025✔
2394
    if (tif->tif_flags & TIFF_SWAB)
1,025✔
2395
        TIFFSwabLong(&m);
41✔
2396
    return (
2397
        TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
1,025✔
2398
}
2399

2400
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
157,601✔
2401
                                                 TIFFDirEntry *dir,
2402
                                                 uint16_t tag, uint32_t count,
2403
                                                 uint32_t *value)
2404
{
2405
    assert(count < 0x40000000);
157,601✔
2406
    assert(sizeof(uint32_t) == 4);
2407
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
157,601✔
2408
    {
2409
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
78,802✔
2410
        return 1;
78,800✔
2411
    }
2412
    if (tif->tif_flags & TIFF_SWAB)
78,799✔
2413
        TIFFSwabArrayOfLong(value, count);
218✔
2414
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
78,799✔
2415
                                      count * 4, value));
2416
}
2417

2418
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
×
2419
                                                  TIFFDirEntry *dir,
2420
                                                  uint16_t tag, uint32_t count,
2421
                                                  int32_t *value)
2422
{
2423
    assert(count < 0x40000000);
×
2424
    assert(sizeof(int32_t) == 4);
2425
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2426
    {
2427
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
×
2428
        return 1;
×
2429
    }
2430
    if (tif->tif_flags & TIFF_SWAB)
×
2431
        TIFFSwabArrayOfLong((uint32_t *)value, count);
×
2432
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
×
2433
                                      count * 4, value));
2434
}
2435

2436
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
408✔
2437
                                                  TIFFDirEntry *dir,
2438
                                                  uint16_t tag, uint32_t count,
2439
                                                  uint64_t *value)
2440
{
2441
    assert(count < 0x20000000);
408✔
2442
    assert(sizeof(uint64_t) == 8);
2443
    if (!(tif->tif_flags & TIFF_BIGTIFF))
408✔
2444
    {
2445
        TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
×
2446
                      "LONG8 not allowed for ClassicTIFF");
2447
        return (0);
×
2448
    }
2449
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
408✔
2450
    {
2451
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
204✔
2452
        return 1;
204✔
2453
    }
2454
    if (tif->tif_flags & TIFF_SWAB)
204✔
2455
        TIFFSwabArrayOfLong8(value, count);
4✔
2456
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
204✔
2457
                                      count * 8, value));
2458
}
2459

2460
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
×
2461
                                                   TIFFDirEntry *dir,
2462
                                                   uint16_t tag, uint32_t count,
2463
                                                   int64_t *value)
2464
{
2465
    assert(count < 0x20000000);
×
2466
    assert(sizeof(int64_t) == 8);
2467
    if (!(tif->tif_flags & TIFF_BIGTIFF))
×
2468
    {
2469
        TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
×
2470
                      "SLONG8 not allowed for ClassicTIFF");
2471
        return (0);
×
2472
    }
2473
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2474
    {
2475
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
×
2476
        return 1;
×
2477
    }
2478
    if (tif->tif_flags & TIFF_SWAB)
×
2479
        TIFFSwabArrayOfLong8((uint64_t *)value, count);
×
2480
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
×
2481
                                      count * 8, value));
2482
}
2483

2484
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
32✔
2485
                                                TIFFDirEntry *dir, uint16_t tag,
2486
                                                double value)
2487
{
2488
    static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2489
    uint32_t m[2];
2490
    assert(sizeof(uint32_t) == 4);
2491
    if (value < 0)
32✔
2492
    {
2493
        TIFFErrorExtR(tif, module, "Negative value is illegal");
×
2494
        return 0;
×
2495
    }
2496
    else if (value != value)
32✔
2497
    {
2498
        TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
×
2499
        return 0;
×
2500
    }
2501

2502
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
32✔
2503
    {
2504
        tif->tif_dir.td_dirdatasize_write +=
32✔
2505
            (tif->tif_flags & TIFF_BIGTIFF) ? 0 : 0x8U;
16✔
2506
        (*ndir)++;
16✔
2507
        return 1;
16✔
2508
    }
2509

2510
    DoubleToRational(value, &m[0], &m[1]);
16✔
2511

2512
    if (tif->tif_flags & TIFF_SWAB)
16✔
2513
    {
2514
        TIFFSwabLong(&m[0]);
×
2515
        TIFFSwabLong(&m[1]);
×
2516
    }
2517
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
16✔
2518
                                      &m[0]));
2519
}
2520

2521
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
1,690✔
2522
                                                     TIFFDirEntry *dir,
2523
                                                     uint16_t tag,
2524
                                                     uint32_t count,
2525
                                                     float *value)
2526
{
2527
    static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2528
    uint32_t *m;
2529
    float *na;
2530
    uint32_t *nb;
2531
    uint32_t nc;
2532
    int o;
2533
    assert(sizeof(uint32_t) == 4);
2534
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
1,690✔
2535
    {
2536
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
845✔
2537
        return 1;
845✔
2538
    }
2539
    m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
845✔
2540
    if (m == NULL)
845✔
2541
    {
2542
        TIFFErrorExtR(tif, module, "Out of memory");
×
2543
        return (0);
×
2544
    }
2545
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
5,895✔
2546
    {
2547
        DoubleToRational(*na, &nb[0], &nb[1]);
5,050✔
2548
    }
2549
    if (tif->tif_flags & TIFF_SWAB)
845✔
2550
        TIFFSwabArrayOfLong(m, count * 2);
10✔
2551
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
845✔
2552
                                  count * 8, &m[0]);
2553
    _TIFFfreeExt(tif, m);
845✔
2554
    return (o);
845✔
2555
}
2556

2557
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
×
2558
                                                      TIFFDirEntry *dir,
2559
                                                      uint16_t tag,
2560
                                                      uint32_t count,
2561
                                                      float *value)
2562
{
2563
    static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2564
    int32_t *m;
2565
    float *na;
2566
    int32_t *nb;
2567
    uint32_t nc;
2568
    int o;
2569
    assert(sizeof(int32_t) == 4);
2570
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2571
    {
2572
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
×
2573
        return 1;
×
2574
    }
2575
    m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
×
2576
    if (m == NULL)
×
2577
    {
2578
        TIFFErrorExtR(tif, module, "Out of memory");
×
2579
        return (0);
×
2580
    }
2581
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
×
2582
    {
2583
        DoubleToSrational(*na, &nb[0], &nb[1]);
×
2584
    }
2585
    if (tif->tif_flags & TIFF_SWAB)
×
2586
        TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
×
2587
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
×
2588
                                  count * 8, &m[0]);
2589
    _TIFFfreeExt(tif, m);
×
2590
    return (o);
×
2591
}
2592

2593
/*-- Rational2Double: additional write functions for double arrays */
2594
static int
2595
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
×
2596
                                                TIFFDirEntry *dir, uint16_t tag,
2597
                                                uint32_t count, double *value)
2598
{
2599
    static const char module[] =
2600
        "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
2601
    uint32_t *m;
2602
    double *na;
2603
    uint32_t *nb;
2604
    uint32_t nc;
2605
    int o;
2606
    assert(sizeof(uint32_t) == 4);
2607
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2608
    {
2609
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
×
2610
        return 1;
×
2611
    }
2612
    m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
×
2613
    if (m == NULL)
×
2614
    {
2615
        TIFFErrorExtR(tif, module, "Out of memory");
×
2616
        return (0);
×
2617
    }
2618
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
×
2619
    {
2620
        DoubleToRational(*na, &nb[0], &nb[1]);
×
2621
    }
2622
    if (tif->tif_flags & TIFF_SWAB)
×
2623
        TIFFSwabArrayOfLong(m, count * 2);
×
2624
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
×
2625
                                  count * 8, &m[0]);
2626
    _TIFFfreeExt(tif, m);
×
2627
    return (o);
×
2628
} /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
2629

2630
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
×
2631
    TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
2632
    double *value)
2633
{
2634
    static const char module[] =
2635
        "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
2636
    int32_t *m;
2637
    double *na;
2638
    int32_t *nb;
2639
    uint32_t nc;
2640
    int o;
2641
    assert(sizeof(int32_t) == 4);
2642
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2643
    {
2644
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
×
2645
        return 1;
×
2646
    }
2647
    m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
×
2648
    if (m == NULL)
×
2649
    {
2650
        TIFFErrorExtR(tif, module, "Out of memory");
×
2651
        return (0);
×
2652
    }
2653
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
×
2654
    {
2655
        DoubleToSrational(*na, &nb[0], &nb[1]);
×
2656
    }
2657
    if (tif->tif_flags & TIFF_SWAB)
×
2658
        TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
×
2659
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
×
2660
                                  count * 8, &m[0]);
2661
    _TIFFfreeExt(tif, m);
×
2662
    return (o);
×
2663
} /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
2664

2665
/** -----  Rational2Double: Double To Rational Conversion
2666
----------------------------------------------------------
2667
* There is a mathematical theorem to convert real numbers into a rational
2668
(integer fraction) number.
2669
* This is called "continuous fraction" which uses the Euclidean algorithm to
2670
find the greatest common divisor (GCD).
2671
*  (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
2672
https://en.wikipedia.org/wiki/Continued_fraction
2673
*             https://en.wikipedia.org/wiki/Euclidean_algorithm)
2674
* The following functions implement the
2675
* - ToRationalEuclideanGCD()                auxiliary function which mainly
2676
implements euclidean GCD
2677
* - DoubleToRational()                        conversion function for un-signed
2678
rationals
2679
* - DoubleToSrational()                        conversion function for signed rationals
2680
------------------------------------------------------------------------------------------------------------------*/
2681

2682
/**---- ToRationalEuclideanGCD() -----------------------------------------
2683
* Calculates the rational fractional of a double input value
2684
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2685
------------------------------------------------------------------------*/
2686
static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
76✔
2687
                                   int blnUseSmallRange, uint64_t *ullNum,
2688
                                   uint64_t *ullDenom)
2689
{
2690
    /* Internally, the integer variables can be bigger than the external ones,
2691
     * as long as the result will fit into the external variable size.
2692
     */
2693
    uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
76✔
2694
    uint64_t aux, bigNum, bigDenom;
2695
    uint64_t returnLimit;
2696
    int i;
2697
    uint64_t nMax;
2698
    double fMax;
2699
    unsigned long maxDenom;
2700
    /*-- nMax and fMax defines the initial accuracy of the starting fractional,
2701
     *   or better, the highest used integer numbers used within the starting
2702
     * fractional (bigNum/bigDenom). There are two approaches, which can
2703
     * accidentally lead to different accuracies just depending on the value.
2704
     *   Therefore, blnUseSmallRange steers this behavior.
2705
     *   For long long nMax = ((9223372036854775807-1)/2); for long nMax =
2706
     * ((2147483647-1)/2);
2707
     */
2708
    if (blnUseSmallRange)
76✔
2709
    {
2710
        nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
38✔
2711
    }
2712
    else
2713
    {
2714
        nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
38✔
2715
    }
2716
    fMax = (double)nMax;
76✔
2717

2718
    /*-- For the Euclidean GCD define the denominator range, so that it stays
2719
     * within size of unsigned long variables. maxDenom should be LONG_MAX for
2720
     * negative values and ULONG_MAX for positive ones. Also the final returned
2721
     * value of ullNum and ullDenom is limited according to signed- or
2722
     * unsigned-range.
2723
     */
2724
    if (blnUseSignedRange)
76✔
2725
    {
2726
        maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
×
2727
        returnLimit = maxDenom;
×
2728
    }
2729
    else
2730
    {
2731
        maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
76✔
2732
        returnLimit = maxDenom;
76✔
2733
    }
2734

2735
    /*-- First generate a rational fraction (bigNum/bigDenom) which represents
2736
     *the value as a rational number with the highest accuracy. Therefore,
2737
     *uint64_t (uint64_t) is needed. This rational fraction is then reduced
2738
     *using the Euclidean algorithm to find the greatest common divisor (GCD).
2739
     *   bigNum   = big numinator of value without fraction (or cut residual
2740
     *fraction) bigDenom = big denominator of value
2741
     *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
2742
     *and bigDenom has no overflow, and stop with enlargement of fraction when
2743
     *the double-value of it reaches an integer number without fractional part.
2744
     */
2745
    bigDenom = 1;
76✔
2746
    while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
1,902✔
2747
    {
2748
        bigDenom <<= 1;
1,826✔
2749
        value *= 2;
1,826✔
2750
    }
2751
    bigNum = (uint64_t)value;
76✔
2752

2753
    /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
2754
     */
2755
#define MAX_ITERATIONS 64
2756
    for (i = 0; i < MAX_ITERATIONS; i++)
778✔
2757
    {
2758
        uint64_t val;
2759
        /* if bigDenom is not zero, calculate integer part of fraction. */
2760
        if (bigDenom == 0)
778✔
2761
        {
2762
            break;
76✔
2763
        }
2764
        val = bigNum / bigDenom;
702✔
2765

2766
        /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
2767
         * denominator bigDenom. */
2768
        aux = bigNum;
702✔
2769
        bigNum = bigDenom;
702✔
2770
        bigDenom = aux % bigDenom;
702✔
2771

2772
        /* calculate next denominator and check for its given maximum */
2773
        aux = val;
702✔
2774
        if (denomSum[1] * val + denomSum[0] >= maxDenom)
702✔
2775
        {
2776
            aux = (maxDenom - denomSum[0]) / denomSum[1];
×
2777
            if (aux * 2 >= val || denomSum[1] >= maxDenom)
×
2778
                i = (MAX_ITERATIONS +
×
2779
                     1); /* exit but execute rest of for-loop */
2780
            else
2781
                break;
2782
        }
2783
        /* calculate next numerator to numSum2 and save previous one to numSum0;
2784
         * numSum1 just copy of numSum2. */
2785
        numSum[2] = aux * numSum[1] + numSum[0];
702✔
2786
        numSum[0] = numSum[1];
702✔
2787
        numSum[1] = numSum[2];
702✔
2788
        /* calculate next denominator to denomSum2 and save previous one to
2789
         * denomSum0; denomSum1 just copy of denomSum2. */
2790
        denomSum[2] = aux * denomSum[1] + denomSum[0];
702✔
2791
        denomSum[0] = denomSum[1];
702✔
2792
        denomSum[1] = denomSum[2];
702✔
2793
    }
2794

2795
    /*-- Check and adapt for final variable size and return values; reduces
2796
     * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
2797
    while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
76✔
2798
    {
2799
        numSum[1] = numSum[1] / 2;
×
2800
        denomSum[1] = denomSum[1] / 2;
×
2801
    }
2802

2803
    /* return values */
2804
    *ullNum = numSum[1];
76✔
2805
    *ullDenom = denomSum[1];
76✔
2806

2807
} /*-- ToRationalEuclideanGCD() -------------- */
76✔
2808

2809
/**---- DoubleToRational() -----------------------------------------------
2810
* Calculates the rational fractional of a double input value
2811
* for UN-SIGNED rationals,
2812
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2813
------------------------------------------------------------------------*/
2814
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
5,066✔
2815
{
2816
    /*---- UN-SIGNED RATIONAL ---- */
2817
    double dblDiff, dblDiff2;
2818
    uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2819

2820
    /*-- Check for negative values. If so it is an error. */
2821
    /* Test written that way to catch NaN */
2822
    if (!(value >= 0))
5,066✔
2823
    {
2824
        *num = *denom = 0;
×
2825
        TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
×
2826
                     " Negative Value for Unsigned Rational given.");
2827
        return;
5,028✔
2828
    }
2829

2830
    /*-- Check for too big numbers (> ULONG_MAX) -- */
2831
    if (value > 0xFFFFFFFFUL)
5,066✔
2832
    {
2833
        *num = 0xFFFFFFFFU;
×
2834
        *denom = 0;
×
2835
        return;
×
2836
    }
2837
    /*-- Check for easy integer numbers -- */
2838
    if (value == (uint32_t)(value))
5,066✔
2839
    {
2840
        *num = (uint32_t)value;
5,028✔
2841
        *denom = 1;
5,028✔
2842
        return;
5,028✔
2843
    }
2844
    /*-- Check for too small numbers for "unsigned long" type rationals -- */
2845
    if (value < 1.0 / (double)0xFFFFFFFFUL)
38✔
2846
    {
2847
        *num = 0;
×
2848
        *denom = 0xFFFFFFFFU;
×
2849
        return;
×
2850
    }
2851

2852
    /*-- There are two approaches using the Euclidean algorithm,
2853
     *   which can accidentally lead to different accuracies just depending on
2854
     * the value. Try both and define which one was better.
2855
     */
2856
    ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
38✔
2857
    ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
38✔
2858
    /*-- Double-Check, that returned values fit into ULONG :*/
2859
    if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
38✔
2860
        ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
38✔
2861
    {
2862
        TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
×
2863
                     " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
2864
                     ", denom=%12" PRIu64 " | num2=%12" PRIu64
2865
                     ", denom2=%12" PRIu64 "",
2866
                     value, ullNum, ullDenom, ullNum2, ullDenom2);
2867
        assert(0);
×
2868
    }
2869

2870
    /* Check, which one has higher accuracy and take that. */
2871
    dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
38✔
2872
    dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
38✔
2873
    if (dblDiff < dblDiff2)
38✔
2874
    {
2875
        *num = (uint32_t)ullNum;
×
2876
        *denom = (uint32_t)ullDenom;
×
2877
    }
2878
    else
2879
    {
2880
        *num = (uint32_t)ullNum2;
38✔
2881
        *denom = (uint32_t)ullDenom2;
38✔
2882
    }
2883
} /*-- DoubleToRational() -------------- */
2884

2885
/**---- DoubleToSrational() -----------------------------------------------
2886
* Calculates the rational fractional of a double input value
2887
* for SIGNED rationals,
2888
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2889
------------------------------------------------------------------------*/
2890
static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
×
2891
{
2892
    /*---- SIGNED RATIONAL ----*/
2893
    int neg = 1;
×
2894
    double dblDiff, dblDiff2;
2895
    uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2896

2897
    /*-- Check for negative values and use then the positive one for internal
2898
     * calculations, but take the sign into account before returning. */
2899
    if (value < 0)
×
2900
    {
2901
        neg = -1;
×
2902
        value = -value;
×
2903
    }
2904

2905
    /*-- Check for too big numbers (> LONG_MAX) -- */
2906
    if (value > 0x7FFFFFFFL)
×
2907
    {
2908
        *num = 0x7FFFFFFFL;
×
2909
        *denom = 0;
×
2910
        return;
×
2911
    }
2912
    /*-- Check for easy numbers -- */
2913
    if (value == (int32_t)(value))
×
2914
    {
2915
        *num = (int32_t)(neg * value);
×
2916
        *denom = 1;
×
2917
        return;
×
2918
    }
2919
    /*-- Check for too small numbers for "long" type rationals -- */
2920
    if (value < 1.0 / (double)0x7FFFFFFFL)
×
2921
    {
2922
        *num = 0;
×
2923
        *denom = 0x7FFFFFFFL;
×
2924
        return;
×
2925
    }
2926

2927
    /*-- There are two approaches using the Euclidean algorithm,
2928
     *   which can accidentally lead to different accuracies just depending on
2929
     * the value. Try both and define which one was better. Furthermore, set
2930
     * behavior of ToRationalEuclideanGCD() to the range of signed-long.
2931
     */
2932
    ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
×
2933
    ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
×
2934
    /*-- Double-Check, that returned values fit into LONG :*/
2935
    if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
×
2936
        ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
×
2937
    {
2938
        TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
×
2939
                     " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
2940
                     ", denom=%12" PRIu64 " | num2=%12" PRIu64
2941
                     ", denom2=%12" PRIu64 "",
2942
                     neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
2943
        assert(0);
×
2944
    }
2945

2946
    /* Check, which one has higher accuracy and take that. */
2947
    dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
×
2948
    dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
×
2949
    if (dblDiff < dblDiff2)
×
2950
    {
2951
        *num = (int32_t)(neg * (long)ullNum);
×
2952
        *denom = (int32_t)ullDenom;
×
2953
    }
2954
    else
2955
    {
2956
        *num = (int32_t)(neg * (long)ullNum2);
×
2957
        *denom = (int32_t)ullDenom2;
×
2958
    }
2959
} /*-- DoubleToSrational() --------------*/
2960

2961
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
×
2962
                                                  TIFFDirEntry *dir,
2963
                                                  uint16_t tag, uint32_t count,
2964
                                                  float *value)
2965
{
2966
    assert(count < 0x40000000);
×
2967
    assert(sizeof(float) == 4);
2968
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2969
    {
2970
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
×
2971
        return 1;
×
2972
    }
2973
    TIFFCvtNativeToIEEEFloat(tif, count, value);
2974
    if (tif->tif_flags & TIFF_SWAB)
×
2975
        TIFFSwabArrayOfFloat(value, count);
×
2976
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
×
2977
                                      count * 4, value));
2978
}
2979

2980
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
18,563✔
2981
                                                   TIFFDirEntry *dir,
2982
                                                   uint16_t tag, uint32_t count,
2983
                                                   double *value)
2984
{
2985
    assert(count < 0x20000000);
18,563✔
2986
    assert(sizeof(double) == 8);
2987
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
18,563✔
2988
    {
2989
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
9,311✔
2990
        return 1;
9,311✔
2991
    }
2992
    TIFFCvtNativeToIEEEDouble(tif, count, value);
2993
    if (tif->tif_flags & TIFF_SWAB)
9,252✔
2994
        TIFFSwabArrayOfDouble(value, count);
44✔
2995
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
9,252✔
2996
                                      count * 8, value));
2997
}
2998

2999
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
×
3000
                                                TIFFDirEntry *dir, uint16_t tag,
3001
                                                uint32_t count, uint32_t *value)
3002
{
3003
    assert(count < 0x40000000);
×
3004
    assert(sizeof(uint32_t) == 4);
3005
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
3006
    {
3007
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
×
3008
        return 1;
×
3009
    }
3010
    if (tif->tif_flags & TIFF_SWAB)
×
3011
        TIFFSwabArrayOfLong(value, count);
×
3012
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
×
3013
                                      count * 4, value));
3014
}
3015

3016
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
×
3017
                                                 TIFFDirEntry *dir,
3018
                                                 uint16_t tag, uint32_t count,
3019
                                                 uint64_t *value)
3020
{
3021
    assert(count < 0x20000000);
×
3022
    assert(sizeof(uint64_t) == 8);
3023
    assert(tif->tif_flags & TIFF_BIGTIFF);
×
3024
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
3025
    {
3026
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
×
3027
        return 1;
×
3028
    }
3029
    if (tif->tif_flags & TIFF_SWAB)
×
3030
        TIFFSwabArrayOfLong8(value, count);
×
3031
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
×
3032
                                      count * 8, value));
3033
}
3034

3035
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
479,595✔
3036
                                     TIFFDirEntry *dir, uint16_t tag,
3037
                                     uint16_t datatype, uint32_t count,
3038
                                     uint32_t datalength, void *data)
3039
{
3040
    static const char module[] = "TIFFWriteDirectoryTagData";
3041
    uint32_t m;
3042
    m = 0;
479,595✔
3043
    while (m < (*ndir))
2,867,620✔
3044
    {
3045
        assert(dir[m].tdir_tag != tag);
2,482,150✔
3046
        if (dir[m].tdir_tag > tag)
2,482,150✔
3047
            break;
94,126✔
3048
        m++;
2,388,030✔
3049
    }
3050
    if (m < (*ndir))
479,595✔
3051
    {
3052
        uint32_t n;
3053
        for (n = *ndir; n > m; n--)
321,796✔
3054
            dir[n] = dir[n - 1];
227,669✔
3055
    }
3056
    dir[m].tdir_tag = tag;
479,595✔
3057
    dir[m].tdir_type = datatype;
479,595✔
3058
    dir[m].tdir_count = count;
479,595✔
3059
    dir[m].tdir_offset.toff_long8 = 0;
479,595✔
3060
    if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
479,595✔
3061
    {
3062
        if (data && datalength)
439,060✔
3063
        {
3064
            _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
438,314✔
3065
        }
3066
    }
3067
    else
3068
    {
3069
        uint64_t na, nb;
3070
        na = tif->tif_dataoff;
40,535✔
3071
        nb = na + datalength;
40,535✔
3072
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,535✔
3073
            nb = (uint32_t)nb;
40,241✔
3074
        if ((nb < na) || (nb < datalength))
40,535✔
3075
        {
3076
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
8✔
3077
            return (0);
×
3078
        }
3079
        if (!SeekOK(tif, na))
40,527✔
3080
        {
3081
            TIFFErrorExtR(tif, module, "IO error writing tag data");
1✔
3082
            return (0);
×
3083
        }
3084
        if (datalength >= 0x80000000UL)
40,527✔
3085
        {
3086
            TIFFErrorExtR(tif, module,
×
3087
                          "libtiff does not allow writing more than 2147483647 "
3088
                          "bytes in a tag");
3089
            return (0);
×
3090
        }
3091
        if (!WriteOK(tif, data, (tmsize_t)datalength))
40,527✔
3092
        {
3093
            TIFFErrorExtR(tif, module, "IO error writing tag data");
33✔
3094
            return (0);
33✔
3095
        }
3096
        tif->tif_dataoff = nb;
40,495✔
3097
        if (tif->tif_dataoff & 1)
40,495✔
3098
            tif->tif_dataoff++;
2,536✔
3099
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,495✔
3100
        {
3101
            uint32_t o;
3102
            o = (uint32_t)na;
40,208✔
3103
            if (tif->tif_flags & TIFF_SWAB)
40,208✔
3104
                TIFFSwabLong(&o);
398✔
3105
            _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
40,208✔
3106
        }
3107
        else
3108
        {
3109
            dir[m].tdir_offset.toff_long8 = na;
287✔
3110
            if (tif->tif_flags & TIFF_SWAB)
287✔
3111
                TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
8✔
3112
        }
3113
    }
3114
    (*ndir)++;
479,557✔
3115
    return (1);
479,557✔
3116
}
3117

3118
/*
3119
 * Link the current directory into the directory chain for the file.
3120
 */
3121
static int TIFFLinkDirectory(TIFF *tif)
40,926✔
3122
{
3123
    static const char module[] = "TIFFLinkDirectory";
3124

3125
    tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
40,926✔
3126

3127
    /*
3128
     * Handle SubIFDs
3129
     */
3130
    if (tif->tif_flags & TIFF_INSUBIFD)
40,925✔
3131
    {
3132
        if (!(tif->tif_flags & TIFF_BIGTIFF))
×
3133
        {
3134
            uint32_t m;
3135
            m = (uint32_t)tif->tif_diroff;
×
3136
            if (tif->tif_flags & TIFF_SWAB)
×
3137
                TIFFSwabLong(&m);
×
3138
            (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
×
3139
            if (!WriteOK(tif, &m, 4))
×
3140
            {
3141
                TIFFErrorExtR(tif, module,
×
3142
                              "Error writing SubIFD directory link");
3143
                return (0);
×
3144
            }
3145

3146
            /*
3147
             * Advance to the next SubIFD or, if this is
3148
             * the last one configured, reverting back to the
3149
             * normal directory linkage is done in TIFFWriteDirectorySec()
3150
             * by tif->tif_flags &= ~TIFF_INSUBIFD;.
3151
             */
3152
            if (--tif->tif_nsubifd)
×
3153
                tif->tif_subifdoff += 4;
×
3154
            return (1);
×
3155
        }
3156
        else
3157
        {
3158
            uint64_t m;
3159
            m = tif->tif_diroff;
×
3160
            if (tif->tif_flags & TIFF_SWAB)
×
3161
                TIFFSwabLong8(&m);
×
3162
            (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
×
3163
            if (!WriteOK(tif, &m, 8))
×
3164
            {
3165
                TIFFErrorExtR(tif, module,
×
3166
                              "Error writing SubIFD directory link");
3167
                return (0);
×
3168
            }
3169

3170
            /*
3171
             * Advance to the next SubIFD or, if this is
3172
             * the last one configured, reverting back to the
3173
             * normal directory linkage is done in TIFFWriteDirectorySec()
3174
             * by tif->tif_flags &= ~TIFF_INSUBIFD;.
3175
             */
3176
            if (--tif->tif_nsubifd)
×
3177
                tif->tif_subifdoff += 8;
×
3178
            return (1);
×
3179
        }
3180
    }
3181

3182
    /*
3183
     * Handle main-IFDs
3184
     */
3185
    tdir_t ndir = 1; /* count current number of main-IFDs */
40,925✔
3186
    if (!(tif->tif_flags & TIFF_BIGTIFF))
40,925✔
3187
    {
3188
        uint32_t m;
3189
        uint32_t nextdir;
3190
        m = (uint32_t)(tif->tif_diroff);
40,771✔
3191
        if (tif->tif_flags & TIFF_SWAB)
40,771✔
3192
            TIFFSwabLong(&m);
125✔
3193
        if (tif->tif_header.classic.tiff_diroff == 0)
40,769✔
3194
        {
3195
            /*
3196
             * First directory, overwrite offset in header.
3197
             */
3198
            tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff;
40,061✔
3199
            tif->tif_lastdiroff = tif->tif_diroff;
40,061✔
3200
            (void)TIFFSeekFile(tif, 4, SEEK_SET);
40,061✔
3201
            if (!WriteOK(tif, &m, 4))
40,060✔
3202
            {
3203
                TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
×
3204
                return (0);
40,059✔
3205
            }
3206
            if (!tif->tif_dir.td_iswrittentofile)
40,059✔
3207
                tif->tif_curdircount = 0;
38,713✔
3208
            return (1);
40,059✔
3209
        }
3210
        /*
3211
         * Not the first directory, search to the last and append.
3212
         */
3213
        tdir_t dirn = 0;
708✔
3214
        if (tif->tif_lastdiroff != 0 &&
1,176✔
3215
            _TIFFGetDirNumberFromOffset(tif, tif->tif_lastdiroff, &dirn))
468✔
3216
        {
3217
            /* Start searching from the lastely written IFD. Thus get its IFD
3218
             * number. */
3219
            nextdir = (uint32_t)tif->tif_lastdiroff;
468✔
3220
            ndir = dirn + 1;
468✔
3221
        }
3222
        else
3223
        {
3224
            nextdir = tif->tif_header.classic.tiff_diroff;
240✔
3225
            ndir = 1; /* start searching from the first IFD */
240✔
3226
        }
3227

3228
        while (1)
3229
        {
31✔
3230
            uint16_t dircount;
3231
            uint32_t nextnextdir;
3232

3233
            if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
739✔
3234
            {
3235
                TIFFErrorExtR(tif, module, "Error fetching directory count");
×
3236
                return (0);
×
3237
            }
3238
            if (tif->tif_flags & TIFF_SWAB)
739✔
3239
                TIFFSwabShort(&dircount);
33✔
3240
            (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
739✔
3241
            if (!ReadOK(tif, &nextnextdir, 4))
739✔
3242
            {
3243
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
3244
                return (0);
×
3245
            }
3246
            if (tif->tif_flags & TIFF_SWAB)
739✔
3247
                TIFFSwabLong(&nextnextdir);
33✔
3248
            if (nextnextdir == 0)
739✔
3249
            {
3250
                (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
708✔
3251
                if (!WriteOK(tif, &m, 4))
708✔
3252
                {
3253
                    TIFFErrorExtR(tif, module, "Error writing directory link");
×
3254
                    return (0);
×
3255
                }
3256
                tif->tif_lastdiroff = tif->tif_diroff;
708✔
3257
                break;
708✔
3258
            }
3259
            nextdir = nextnextdir;
31✔
3260
            ndir++;
31✔
3261
        }
3262
    }
3263
    else
3264
    {
3265
        /*- BigTIFF -*/
3266
        uint64_t m;
3267
        uint64_t nextdir;
3268
        m = tif->tif_diroff;
154✔
3269
        if (tif->tif_flags & TIFF_SWAB)
154✔
3270
            TIFFSwabLong8(&m);
4✔
3271
        if (tif->tif_header.big.tiff_diroff == 0)
155✔
3272
        {
3273
            /*
3274
             * First directory, overwrite offset in header.
3275
             */
3276
            tif->tif_header.big.tiff_diroff = tif->tif_diroff;
84✔
3277
            tif->tif_lastdiroff = tif->tif_diroff;
84✔
3278
            (void)TIFFSeekFile(tif, 8, SEEK_SET);
84✔
3279
            if (!WriteOK(tif, &m, 8))
84✔
3280
            {
3281
                TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
×
3282
                return (0);
84✔
3283
            }
3284
            if (!tif->tif_dir.td_iswrittentofile)
84✔
3285
                tif->tif_curdircount = 0;
83✔
3286
            return (1);
84✔
3287
        }
3288
        /*
3289
         * Not the first directory, search to the last and append.
3290
         */
3291
        tdir_t dirn = 0;
71✔
3292
        if (tif->tif_lastdiroff != 0 &&
138✔
3293
            _TIFFGetDirNumberFromOffset(tif, tif->tif_lastdiroff, &dirn))
67✔
3294
        {
3295
            /* Start searching from the lastely written IFD. Thus get its IFD
3296
             * number. */
3297
            nextdir = tif->tif_lastdiroff;
67✔
3298
            ndir = dirn + 1;
67✔
3299
        }
3300
        else
3301
        {
3302
            nextdir = tif->tif_header.big.tiff_diroff;
4✔
3303
            ndir = 1; /* start searching from the first IFD */
4✔
3304
        }
3305
        while (1)
3306
        {
×
3307
            uint64_t dircount64;
3308
            uint16_t dircount;
3309
            uint64_t nextnextdir;
3310

3311
            if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
71✔
3312
            {
3313
                TIFFErrorExtR(tif, module, "Error fetching directory count");
×
3314
                return (0);
×
3315
            }
3316
            if (tif->tif_flags & TIFF_SWAB)
71✔
3317
                TIFFSwabLong8(&dircount64);
×
3318
            if (dircount64 > 0xFFFF)
71✔
3319
            {
3320
                TIFFErrorExtR(tif, module,
×
3321
                              "Sanity check on tag count failed, "
3322
                              "likely corrupt TIFF");
3323
                return (0);
×
3324
            }
3325
            dircount = (uint16_t)dircount64;
71✔
3326
            (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
71✔
3327
            if (!ReadOK(tif, &nextnextdir, 8))
71✔
3328
            {
3329
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
3330
                return (0);
×
3331
            }
3332
            if (tif->tif_flags & TIFF_SWAB)
71✔
3333
                TIFFSwabLong8(&nextnextdir);
×
3334
            if (nextnextdir == 0)
71✔
3335
            {
3336
                (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
71✔
3337
                if (!WriteOK(tif, &m, 8))
71✔
3338
                {
3339
                    TIFFErrorExtR(tif, module, "Error writing directory link");
×
3340
                    return (0);
×
3341
                }
3342
                tif->tif_lastdiroff = tif->tif_diroff;
71✔
3343
                break;
71✔
3344
            }
3345
            nextdir = nextnextdir;
×
3346
            ndir++;
×
3347
        }
3348
    }
3349
    /* Offset of next IFD is written to file.
3350
     * Update number of main-IFDs in file.
3351
     * However, tif_curdircount shall count only newly written main-IFDs with
3352
     * entries and not only number of linked offsets! Thus, tif_curdircount is
3353
     * incremented at the end of TIFFWriteDirectorySec().
3354
     * TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'
3355
     * 0 means 'empty file opened for writing, but no IFD written yet' */
3356
    if (!tif->tif_dir.td_iswrittentofile && !(tif->tif_flags & TIFF_INSUBIFD))
779✔
3357
    {
3358
        tif->tif_curdircount = ndir;
773✔
3359
    }
3360
    return (1);
779✔
3361
}
3362

3363
/************************************************************************/
3364
/*                          TIFFRewriteField()                          */
3365
/*                                                                      */
3366
/*      Rewrite a field in the directory on disk without regard to      */
3367
/*      updating the TIFF directory structure in memory.  Currently     */
3368
/*      only supported for field that already exist in the on-disk      */
3369
/*      directory.  Mainly used for updating stripoffset /              */
3370
/*      stripbytecount values after the directory is already on         */
3371
/*      disk.                                                           */
3372
/*                                                                      */
3373
/*      Returns zero on failure, and one on success.                    */
3374
/************************************************************************/
3375

3376
int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
20,690✔
3377
                      tmsize_t count, void *data)
3378
{
3379
    static const char module[] = "TIFFResetField";
3380
    /* const TIFFField* fip = NULL; */
3381
    uint16_t dircount;
3382
    tmsize_t dirsize;
3383
    uint8_t direntry_raw[20];
3384
    uint16_t entry_tag = 0;
20,690✔
3385
    uint16_t entry_type = 0;
20,690✔
3386
    uint64_t entry_count = 0;
20,690✔
3387
    uint64_t entry_offset = 0;
20,690✔
3388
    int value_in_entry = 0;
20,690✔
3389
    uint64_t read_offset;
3390
    uint8_t *buf_to_write = NULL;
20,690✔
3391
    TIFFDataType datatype;
3392

3393
    /* -------------------------------------------------------------------- */
3394
    /*      Find field definition.                                          */
3395
    /* -------------------------------------------------------------------- */
3396
    /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
20,690✔
3397

3398
    /* -------------------------------------------------------------------- */
3399
    /*      Do some checking this is a straight forward case.               */
3400
    /* -------------------------------------------------------------------- */
3401
    if (isMapped(tif))
20,690✔
3402
    {
3403
        TIFFErrorExtR(tif, module,
×
3404
                      "Memory mapped files not currently supported for "
3405
                      "this operation.");
3406
        return 0;
×
3407
    }
3408

3409
    if (tif->tif_diroff == 0)
20,690✔
3410
    {
3411
        TIFFErrorExtR(
×
3412
            tif, module,
3413
            "Attempt to reset field on directory not already on disk.");
3414
        return 0;
×
3415
    }
3416

3417
    /* -------------------------------------------------------------------- */
3418
    /*      Read the directory entry count.                                 */
3419
    /* -------------------------------------------------------------------- */
3420
    if (!SeekOK(tif, tif->tif_diroff))
20,690✔
3421
    {
3422
        TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
×
3423
                      tif->tif_name);
3424
        return 0;
×
3425
    }
3426

3427
    read_offset = tif->tif_diroff;
20,690✔
3428

3429
    if (!(tif->tif_flags & TIFF_BIGTIFF))
20,690✔
3430
    {
3431
        if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
20,440✔
3432
        {
3433
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
×
3434
                          tif->tif_name);
3435
            return 0;
×
3436
        }
3437
        if (tif->tif_flags & TIFF_SWAB)
20,440✔
3438
            TIFFSwabShort(&dircount);
206✔
3439
        dirsize = 12;
20,440✔
3440
        read_offset += 2;
20,440✔
3441
    }
3442
    else
3443
    {
3444
        uint64_t dircount64;
3445
        if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
250✔
3446
        {
3447
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
×
3448
                          tif->tif_name);
3449
            return 0;
×
3450
        }
3451
        if (tif->tif_flags & TIFF_SWAB)
250✔
3452
            TIFFSwabLong8(&dircount64);
×
3453
        dircount = (uint16_t)dircount64;
250✔
3454
        dirsize = 20;
250✔
3455
        read_offset += 8;
250✔
3456
    }
3457

3458
    /* -------------------------------------------------------------------- */
3459
    /*      Read through directory to find target tag.                      */
3460
    /* -------------------------------------------------------------------- */
3461
    while (dircount > 0)
170,552✔
3462
    {
3463
        if (!ReadOK(tif, direntry_raw, dirsize))
170,552✔
3464
        {
3465
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
×
3466
                          tif->tif_name);
3467
            return 0;
×
3468
        }
3469

3470
        memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
170,552✔
3471
        if (tif->tif_flags & TIFF_SWAB)
170,552✔
3472
            TIFFSwabShort(&entry_tag);
1,897✔
3473

3474
        if (entry_tag == tag)
170,552✔
3475
            break;
20,690✔
3476

3477
        read_offset += dirsize;
149,862✔
3478
    }
3479

3480
    if (entry_tag != tag)
20,690✔
3481
    {
3482
        TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
×
3483
                      tif->tif_name, tag);
3484
        return 0;
×
3485
    }
3486

3487
    /* -------------------------------------------------------------------- */
3488
    /*      Extract the type, count and offset for this entry.              */
3489
    /* -------------------------------------------------------------------- */
3490
    memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
20,690✔
3491
    if (tif->tif_flags & TIFF_SWAB)
20,690✔
3492
        TIFFSwabShort(&entry_type);
206✔
3493

3494
    if (!(tif->tif_flags & TIFF_BIGTIFF))
20,690✔
3495
    {
3496
        uint32_t value;
3497

3498
        memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
20,440✔
3499
        if (tif->tif_flags & TIFF_SWAB)
20,440✔
3500
            TIFFSwabLong(&value);
206✔
3501
        entry_count = value;
20,440✔
3502

3503
        memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
20,440✔
3504
        if (tif->tif_flags & TIFF_SWAB)
20,440✔
3505
            TIFFSwabLong(&value);
206✔
3506
        entry_offset = value;
20,440✔
3507
    }
3508
    else
3509
    {
3510
        memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
250✔
3511
        if (tif->tif_flags & TIFF_SWAB)
250✔
3512
            TIFFSwabLong8(&entry_count);
×
3513

3514
        memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
250✔
3515
        if (tif->tif_flags & TIFF_SWAB)
250✔
3516
            TIFFSwabLong8(&entry_offset);
×
3517
    }
3518

3519
    /* -------------------------------------------------------------------- */
3520
    /*      When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
3521
    /* -------------------------------------------------------------------- */
3522
    if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
20,690✔
3523
    {
3524
        if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
728✔
3525
        {
3526
            entry_type =
364✔
3527
                (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
364✔
3528
        }
3529
        else
3530
        {
3531
            int write_aslong8 = 1;
364✔
3532
            if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
364✔
3533
            {
3534
                write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
10✔
3535
            }
3536
            else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
354✔
3537
            {
3538
                write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
155✔
3539
            }
3540
            if (write_aslong8)
364✔
3541
            {
3542
                entry_type = TIFF_LONG8;
199✔
3543
            }
3544
            else
3545
            {
3546
                int write_aslong4 = 1;
165✔
3547
                if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
165✔
3548
                {
3549
                    write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
10✔
3550
                }
3551
                else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
155✔
3552
                {
3553
                    write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
155✔
3554
                }
3555
                if (write_aslong4)
165✔
3556
                {
3557
                    entry_type = TIFF_LONG;
129✔
3558
                }
3559
                else
3560
                {
3561
                    entry_type = TIFF_SHORT;
36✔
3562
                }
3563
            }
3564
        }
3565
    }
3566

3567
    /* -------------------------------------------------------------------- */
3568
    /*      What data type do we want to write this as?                     */
3569
    /* -------------------------------------------------------------------- */
3570
    if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
20,690✔
3571
    {
3572
        if (in_datatype == TIFF_LONG8)
20,440✔
3573
            datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
20,440✔
3574
        else if (in_datatype == TIFF_SLONG8)
×
3575
            datatype = TIFF_SLONG;
×
3576
        else if (in_datatype == TIFF_IFD8)
×
3577
            datatype = TIFF_IFD;
×
3578
        else
3579
            datatype = in_datatype;
×
3580
    }
3581
    else
3582
    {
3583
        if (in_datatype == TIFF_LONG8 &&
250✔
3584
            (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
250✔
3585
             entry_type == TIFF_LONG8))
199✔
3586
            datatype = entry_type;
250✔
3587
        else if (in_datatype == TIFF_SLONG8 &&
×
3588
                 (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
×
3589
            datatype = entry_type;
×
3590
        else if (in_datatype == TIFF_IFD8 &&
×
3591
                 (entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
×
3592
            datatype = entry_type;
×
3593
        else
3594
            datatype = in_datatype;
×
3595
    }
3596

3597
    /* -------------------------------------------------------------------- */
3598
    /*      Prepare buffer of actual data to write.  This includes          */
3599
    /*      swabbing as needed.                                             */
3600
    /* -------------------------------------------------------------------- */
3601
    buf_to_write = (uint8_t *)_TIFFCheckMalloc(
20,690✔
3602
        tif, count, TIFFDataWidth(datatype), "for field buffer.");
20,690✔
3603
    if (!buf_to_write)
20,690✔
3604
        return 0;
×
3605

3606
    if (datatype == in_datatype)
20,690✔
3607
        memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
199✔
3608
    else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
20,491✔
3609
    {
×
3610
        tmsize_t i;
3611

3612
        for (i = 0; i < count; i++)
×
3613
        {
3614
            ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
×
3615
            if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
×
3616
            {
3617
                _TIFFfreeExt(tif, buf_to_write);
×
3618
                TIFFErrorExtR(tif, module,
×
3619
                              "Value exceeds 32bit range of output type.");
3620
                return 0;
×
3621
            }
3622
        }
3623
    }
3624
    else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
20,491✔
3625
             (datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
×
3626
    {
17,610✔
3627
        tmsize_t i;
3628

3629
        for (i = 0; i < count; i++)
3,542,230✔
3630
        {
3631
            ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
3,524,620✔
3632
            if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
3,524,620✔
3633
                ((uint64_t *)data)[i])
3,524,620✔
3634
            {
3635
                _TIFFfreeExt(tif, buf_to_write);
×
3636
                TIFFErrorExtR(tif, module,
×
3637
                              "Value exceeds 32bit range of output type.");
3638
                return 0;
×
3639
            }
3640
        }
3641
    }
3642
    else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
2,881✔
3643
    {
2,881✔
3644
        tmsize_t i;
3645

3646
        for (i = 0; i < count; i++)
3,330,880✔
3647
        {
3648
            ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
3,328,000✔
3649
            if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
3,328,000✔
3650
                ((uint64_t *)data)[i])
3,328,000✔
3651
            {
3652
                _TIFFfreeExt(tif, buf_to_write);
×
3653
                TIFFErrorExtR(tif, module,
×
3654
                              "Value exceeds 16bit range of output type.");
3655
                return 0;
×
3656
            }
3657
        }
3658
    }
3659
    else
3660
    {
3661
        TIFFErrorExtR(tif, module, "Unhandled type conversion.");
×
3662
        return 0;
×
3663
    }
3664

3665
    if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
20,690✔
3666
    {
3667
        if (TIFFDataWidth(datatype) == 2)
206✔
3668
            TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
38✔
3669
        else if (TIFFDataWidth(datatype) == 4)
168✔
3670
            TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
168✔
3671
        else if (TIFFDataWidth(datatype) == 8)
×
3672
            TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
×
3673
    }
3674

3675
    /* -------------------------------------------------------------------- */
3676
    /*      Is this a value that fits into the directory entry?             */
3677
    /* -------------------------------------------------------------------- */
3678
    if (!(tif->tif_flags & TIFF_BIGTIFF))
20,690✔
3679
    {
3680
        if (TIFFDataWidth(datatype) * count <= 4)
20,440✔
3681
        {
3682
            entry_offset = read_offset + 8;
13,479✔
3683
            value_in_entry = 1;
13,479✔
3684
        }
3685
    }
3686
    else
3687
    {
3688
        if (TIFFDataWidth(datatype) * count <= 8)
250✔
3689
        {
3690
            entry_offset = read_offset + 12;
153✔
3691
            value_in_entry = 1;
153✔
3692
        }
3693
    }
3694

3695
    if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
20,690✔
3696
        tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
10,345✔
3697
        tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
837✔
3698
        tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
837✔
3699
    {
3700
        tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
837✔
3701
        tif->tif_dir.td_stripoffset_entry.tdir_count = count;
837✔
3702
    }
3703
    else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
19,853✔
3704
              tag == TIFFTAG_STRIPBYTECOUNTS) &&
10,345✔
3705
             tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
10,345✔
3706
             tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
837✔
3707
             tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
837✔
3708
    {
3709
        tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
837✔
3710
        tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
837✔
3711
    }
3712

3713
    /* -------------------------------------------------------------------- */
3714
    /*      If the tag type, and count match, then we just write it out     */
3715
    /*      over the old values without altering the directory entry at     */
3716
    /*      all.                                                            */
3717
    /* -------------------------------------------------------------------- */
3718
    if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
20,690✔
3719
    {
3720
        if (!SeekOK(tif, entry_offset))
19,962✔
3721
        {
3722
            _TIFFfreeExt(tif, buf_to_write);
×
3723
            TIFFErrorExtR(tif, module,
×
3724
                          "%s: Seek error accessing TIFF directory",
3725
                          tif->tif_name);
3726
            return 0;
×
3727
        }
3728
        if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
19,962✔
3729
        {
3730
            _TIFFfreeExt(tif, buf_to_write);
×
3731
            TIFFErrorExtR(tif, module, "Error writing directory link");
×
3732
            return (0);
×
3733
        }
3734

3735
        _TIFFfreeExt(tif, buf_to_write);
19,962✔
3736
        return 1;
19,962✔
3737
    }
3738

3739
    /* -------------------------------------------------------------------- */
3740
    /*      Otherwise, we write the new tag data at the end of the file.    */
3741
    /* -------------------------------------------------------------------- */
3742
    if (!value_in_entry)
728✔
3743
    {
3744
        entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
325✔
3745

3746
        if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
325✔
3747
        {
3748
            _TIFFfreeExt(tif, buf_to_write);
×
3749
            TIFFErrorExtR(tif, module, "Error writing directory link");
×
3750
            return (0);
×
3751
        }
3752
    }
3753
    else
3754
    {
3755
        if (count * TIFFDataWidth(datatype) == 4)
403✔
3756
        {
3757
            uint32_t value;
3758
            memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
387✔
3759
            entry_offset = value;
387✔
3760
        }
3761
        else
3762
        {
3763
            memcpy(&entry_offset, buf_to_write,
16✔
3764
                   count * TIFFDataWidth(datatype));
16✔
3765
        }
3766
    }
3767

3768
    _TIFFfreeExt(tif, buf_to_write);
728✔
3769
    buf_to_write = 0;
728✔
3770

3771
    /* -------------------------------------------------------------------- */
3772
    /*      Adjust the directory entry.                                     */
3773
    /* -------------------------------------------------------------------- */
3774
    entry_type = datatype;
728✔
3775
    entry_count = (uint64_t)count;
728✔
3776
    memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
728✔
3777
    if (tif->tif_flags & TIFF_SWAB)
728✔
3778
        TIFFSwabShort((uint16_t *)(direntry_raw + 2));
×
3779

3780
    if (!(tif->tif_flags & TIFF_BIGTIFF))
728✔
3781
    {
3782
        uint32_t value;
3783

3784
        value = (uint32_t)entry_count;
696✔
3785
        memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
696✔
3786
        if (tif->tif_flags & TIFF_SWAB)
696✔
3787
            TIFFSwabLong((uint32_t *)(direntry_raw + 4));
×
3788

3789
        value = (uint32_t)entry_offset;
696✔
3790
        memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
696✔
3791
        if (tif->tif_flags & TIFF_SWAB)
696✔
3792
            TIFFSwabLong((uint32_t *)(direntry_raw + 8));
×
3793
    }
3794
    else
3795
    {
3796
        memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
32✔
3797
        if (tif->tif_flags & TIFF_SWAB)
32✔
3798
            TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
×
3799

3800
        memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
32✔
3801
        if (tif->tif_flags & TIFF_SWAB)
32✔
3802
            TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
×
3803
    }
3804

3805
    /* -------------------------------------------------------------------- */
3806
    /*      Write the directory entry out to disk.                          */
3807
    /* -------------------------------------------------------------------- */
3808
    if (!SeekOK(tif, read_offset))
728✔
3809
    {
3810
        TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
×
3811
                      tif->tif_name);
3812
        return 0;
×
3813
    }
3814

3815
    if (!WriteOK(tif, direntry_raw, dirsize))
728✔
3816
    {
3817
        TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
×
3818
                      tif->tif_name);
3819
        return 0;
×
3820
    }
3821

3822
    return 1;
728✔
3823
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc