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

OSGeo / gdal / 15899162844

26 Jun 2025 10:14AM UTC coverage: 71.088% (+0.004%) from 71.084%
15899162844

Pull #12623

github

web-flow
Merge c704a8392 into f5cb024d4
Pull Request #12623: gdal raster overview add: add a --overview-src option

209 of 244 new or added lines in 5 files covered. (85.66%)

96 existing lines in 44 files now uncovered.

574014 of 807474 relevant lines covered (71.09%)

250815.03 hits per line

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

54.49
/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,763✔
239
{
240
    return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
39,763✔
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,876✔
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,876✔
322
        return TIFFWriteDirectory(tif);
26,510✔
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,366✔
329

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

337
            TIFFSeekFile(tif, 4, SEEK_SET);
1,357✔
338
            if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
1,357✔
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,363✔
398
    }
399
    else
400
    {
401
        if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
3✔
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;
2✔
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))
2✔
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,364✔
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,877✔
484
{
485
    return TIFFRewriteDirectorySec(tif, TRUE, TRUE, NULL);
27,877✔
486
}
487

488
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
41,123✔
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)
41,123✔
498
        return (1);
×
499

500
    _TIFFFillStriles(tif);
41,123✔
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)
41,120✔
508
    {
509
        if (tif->tif_flags & TIFF_POSTENCODE)
41,119✔
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 */
41,119✔
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)
41,119✔
528
        {
529
            if (!TIFFFlushData1(tif))
5✔
530
            {
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)
41,120✔
537
        {
538
            _TIFFfreeExt(tif, tif->tif_rawdata);
28,133✔
539
            tif->tif_rawdata = NULL;
28,134✔
540
            tif->tif_rawcp = NULL;
28,134✔
541
            tif->tif_rawcc = 0;
28,134✔
542
            tif->tif_rawdatasize = 0;
28,134✔
543
            tif->tif_rawdataoff = 0;
28,134✔
544
            tif->tif_rawdataloaded = 0;
28,134✔
545
        }
546
        tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
41,121✔
547
    }
548

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

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

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

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

1366
    tif->tif_dir.td_iswrittentofile = TRUE;
41,090✔
1367

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1591
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
164,037✔
1592
                                               TIFFDirEntry *dir, uint16_t tag,
1593
                                               uint16_t value)
1594
{
1595
    static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1596
    uint16_t *m;
1597
    uint16_t *na;
1598
    uint16_t nb;
1599
    int o;
1600
    if (dir == NULL)
164,037✔
1601
    {
1602
        /* only evaluate IFD data size and inc. ndir */
1603
        return (TIFFWriteDirectoryTagCheckedShortArray(
82,009✔
1604
            tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
82,012✔
1605
    }
1606
    m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
82,025✔
1607
    if (m == NULL)
82,013✔
1608
    {
1609
        TIFFErrorExtR(tif, module, "Out of memory");
1✔
1610
        return (0);
×
1611
    }
1612
    for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
787,301✔
1613
        *na = value;
705,289✔
1614
    o = TIFFWriteDirectoryTagCheckedShortArray(
82,012✔
1615
        tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
82,012✔
1616
    _TIFFfreeExt(tif, m);
82,014✔
1617
    return (o);
82,015✔
1618
}
1619

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

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

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

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

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

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

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

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

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

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

1709
    return (o);
×
1710
}
1711

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

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

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

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

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

1779
    return (o);
×
1780
}
1781

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

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

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

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

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

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

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

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

1850
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
250,033✔
1851
                                          TIFFDirEntry *dir, uint16_t tag,
1852
                                          uint32_t value)
1853
{
1854
    if (value <= 0xFFFF)
250,033✔
1855
        return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
249,988✔
1856
                                                  (uint16_t)value));
249,986✔
1857
    else
1858
        return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
47✔
1859
}
1860

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

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

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

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

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

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

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

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

1963
        uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
158,002✔
1964
        uint32_t *q;
1965
        uint64_t *ma;
1966
        uint32_t mb;
1967

1968
        if (p == NULL)
158,007✔
1969
        {
UNCOV
1970
            TIFFErrorExtR(tif, module, "Out of memory");
×
1971
            return (0);
×
1972
        }
1973

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

1987
        o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
158,009✔
1988
                                                  p);
1989
        _TIFFfreeExt(tif, p);
158,005✔
1990
    }
1991
    else
1992
    {
1993
        uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
4,566✔
1994
        uint16_t *q;
1995
        uint64_t *ma;
1996
        uint32_t mb;
1997

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

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

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

2023
    return (o);
162,579✔
2024
}
2025

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

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

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

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

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

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

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

2076
    return (o);
×
2077
}
2078

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3036
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
481,623✔
3037
                                     TIFFDirEntry *dir, uint16_t tag,
3038
                                     uint16_t datatype, uint32_t count,
3039
                                     uint32_t datalength, void *data)
3040
{
3041
    static const char module[] = "TIFFWriteDirectoryTagData";
3042
    uint32_t m;
3043
    m = 0;
481,623✔
3044
    while (m < (*ndir))
2,878,550✔
3045
    {
3046
        assert(dir[m].tdir_tag != tag);
2,491,430✔
3047
        if (dir[m].tdir_tag > tag)
2,491,430✔
3048
            break;
94,506✔
3049
        m++;
2,396,920✔
3050
    }
3051
    if (m < (*ndir))
481,623✔
3052
    {
3053
        uint32_t n;
3054
        for (n = *ndir; n > m; n--)
323,127✔
3055
            dir[n] = dir[n - 1];
228,623✔
3056
    }
3057
    dir[m].tdir_tag = tag;
481,623✔
3058
    dir[m].tdir_type = datatype;
481,623✔
3059
    dir[m].tdir_count = count;
481,623✔
3060
    dir[m].tdir_offset.toff_long8 = 0;
481,623✔
3061
    if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
481,623✔
3062
    {
3063
        if (data && datalength)
441,133✔
3064
        {
3065
            _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
440,389✔
3066
        }
3067
    }
3068
    else
3069
    {
3070
        uint64_t na, nb;
3071
        na = tif->tif_dataoff;
40,490✔
3072
        nb = na + datalength;
40,490✔
3073
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,490✔
3074
            nb = (uint32_t)nb;
40,198✔
3075
        if ((nb < na) || (nb < datalength))
40,490✔
3076
        {
3077
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
7✔
3078
            return (0);
×
3079
        }
3080
        if (!SeekOK(tif, na))
40,483✔
3081
        {
3082
            TIFFErrorExtR(tif, module, "IO error writing tag data");
1✔
3083
            return (0);
×
3084
        }
3085
        if (datalength >= 0x80000000UL)
40,485✔
3086
        {
3087
            TIFFErrorExtR(tif, module,
×
3088
                          "libtiff does not allow writing more than 2147483647 "
3089
                          "bytes in a tag");
3090
            return (0);
×
3091
        }
3092
        if (!WriteOK(tif, data, (tmsize_t)datalength))
40,485✔
3093
        {
3094
            TIFFErrorExtR(tif, module, "IO error writing tag data");
33✔
3095
            return (0);
33✔
3096
        }
3097
        tif->tif_dataoff = nb;
40,453✔
3098
        if (tif->tif_dataoff & 1)
40,453✔
3099
            tif->tif_dataoff++;
2,500✔
3100
        if (!(tif->tif_flags & TIFF_BIGTIFF))
40,453✔
3101
        {
3102
            uint32_t o;
3103
            o = (uint32_t)na;
40,166✔
3104
            if (tif->tif_flags & TIFF_SWAB)
40,166✔
3105
                TIFFSwabLong(&o);
398✔
3106
            _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
40,166✔
3107
        }
3108
        else
3109
        {
3110
            dir[m].tdir_offset.toff_long8 = na;
287✔
3111
            if (tif->tif_flags & TIFF_SWAB)
287✔
3112
                TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
8✔
3113
        }
3114
    }
3115
    (*ndir)++;
481,587✔
3116
    return (1);
481,587✔
3117
}
3118

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

3126
    tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
41,112✔
3127

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

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

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

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

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

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

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

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

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

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

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

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

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

3428
    read_offset = tif->tif_diroff;
20,954✔
3429

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

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

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

3475
        if (entry_tag == tag)
172,592✔
3476
            break;
20,954✔
3477

3478
        read_offset += dirsize;
151,638✔
3479
    }
3480

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3736
        _TIFFfreeExt(tif, buf_to_write);
20,226✔
3737
        return 1;
20,226✔
3738
    }
3739

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

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

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

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

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

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

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

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

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

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

3823
    return 1;
728✔
3824
}
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