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

OSGeo / gdal / 13813968540

12 Mar 2025 02:33PM UTC coverage: 70.43% (-0.02%) from 70.446%
13813968540

Pull #11951

github

web-flow
Merge 0560ed8f8 into 5ab779ac6
Pull Request #11951: Doc: Build docs using CMake

553276 of 785573 relevant lines covered (70.43%)

222076.27 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
extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
39
extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
40
#endif
41

42
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
43
                                 uint64_t *pdiroff);
44

45
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
46
                                                  TIFFDirEntry *dir,
47
                                                  uint16_t tag, uint32_t count,
48
                                                  double *value);
49

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

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

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

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

222
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
223
                                     TIFFDirEntry *dir, uint16_t tag,
224
                                     uint16_t datatype, uint32_t count,
225
                                     uint32_t datalength, void *data);
226

227
static int TIFFLinkDirectory(TIFF *);
228

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

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

279
    tif->tif_dir.td_deferstrilearraywriting = TRUE;
361✔
280
    return 1;
361✔
281
}
282

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

300
int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff)
×
301
{
302
    return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff);
×
303
}
304

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

312
static int TIFFRewriteDirectorySec(TIFF *tif, int isimage, int imagedone,
27,823✔
313
                                   uint64_t *pdiroff)
314
{
315
    static const char module[] = "TIFFRewriteDirectory";
316

317
    /* We don't need to do anything special if it hasn't been written. */
318
    if (tif->tif_diroff == 0)
27,823✔
319
        return TIFFWriteDirectory(tif);
26,490✔
320

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

327
    if (!(tif->tif_flags & TIFF_BIGTIFF))
1,333✔
328
    {
329
        if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
1,331✔
330
        {
331
            tif->tif_header.classic.tiff_diroff = 0;
1,325✔
332
            tif->tif_diroff = 0;
1,325✔
333

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

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

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

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

468
    /*
469
     * Now use TIFFWriteDirectorySec() normally.
470
     */
471
    return TIFFWriteDirectorySec(tif, isimage, imagedone, pdiroff);
1,332✔
472
} /*-- TIFFRewriteDirectorySec() --*/
473

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

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

497
    _TIFFFillStriles(tif);
38,623✔
498

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

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

1119
        /* Evaluate IFD data size: Finally, add the size of the IFD tag entries
1120
         * themselves. */
1121
        if (!(tif->tif_flags & TIFF_BIGTIFF))
38,624✔
1122
            tif->tif_dir.td_dirdatasize_write += 2 + ndir * 12 + 4;
38,469✔
1123
        else
1124
            tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
155✔
1125

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

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

1362
    tif->tif_dir.td_iswrittentofile = TRUE;
38,592✔
1363

1364
    /* Reset SubIFD writing stage after last SubIFD has been written. */
1365
    if (imagedone && (tif->tif_flags & TIFF_INSUBIFD) && tif->tif_nsubifd == 0)
38,592✔
1366
        tif->tif_flags &= ~TIFF_INSUBIFD;
×
1367

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

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

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

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

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

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

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

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

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

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

1537
    _TIFFfreeExt(tif, conv);
×
1538
    return (ok);
×
1539
}
1540

1541
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
9,503✔
1542
                                      TIFFDirEntry *dir, uint16_t tag,
1543
                                      uint32_t count, char *value)
1544
{
1545
    return (
1546
        TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
9,503✔
1547
}
1548

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

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

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

1573
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
311,894✔
1574
                                      TIFFDirEntry *dir, uint16_t tag,
1575
                                      uint16_t value)
1576
{
1577
    return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
311,894✔
1578
}
1579

1580
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
14,601✔
1581
                                           TIFFDirEntry *dir, uint16_t tag,
1582
                                           uint32_t count, uint16_t *value)
1583
{
1584
    return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
14,601✔
1585
                                                   value));
1586
}
1587

1588
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
154,021✔
1589
                                               TIFFDirEntry *dir, uint16_t tag,
1590
                                               uint16_t value)
1591
{
1592
    static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1593
    uint16_t *m;
1594
    uint16_t *na;
1595
    uint16_t nb;
1596
    int o;
1597
    if (dir == NULL)
154,021✔
1598
    {
1599
        /* only evaluate IFD data size and inc. ndir */
1600
        return (TIFFWriteDirectoryTagCheckedShortArray(
77,006✔
1601
            tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
77,009✔
1602
    }
1603
    m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
77,012✔
1604
    if (m == NULL)
77,011✔
1605
    {
1606
        TIFFErrorExtR(tif, module, "Out of memory");
3✔
1607
        return (0);
×
1608
    }
1609
    for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
579,359✔
1610
        *na = value;
502,351✔
1611
    o = TIFFWriteDirectoryTagCheckedShortArray(
77,008✔
1612
        tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
77,008✔
1613
    _TIFFfreeExt(tif, m);
77,012✔
1614
    return (o);
77,015✔
1615
}
1616

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

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

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

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

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

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

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

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

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

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

1706
    return (o);
×
1707
}
1708

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

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

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

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

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

1776
    return (o);
×
1777
}
1778

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

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

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

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

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

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

1831
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
17,509✔
1832
                                            TIFFDirEntry *dir, uint16_t tag,
1833
                                            uint32_t count, double *value)
1834
{
1835
    return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
17,509✔
1836
                                                    value));
1837
}
1838

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

1847
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
234,909✔
1848
                                          TIFFDirEntry *dir, uint16_t tag,
1849
                                          uint32_t value)
1850
{
1851
    if (value <= 0xFFFF)
234,909✔
1852
        return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
234,846✔
1853
                                                  (uint16_t)value));
234,851✔
1854
    else
1855
        return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
58✔
1856
}
1857

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

1883
static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
310✔
1884
{
1885
    return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
310✔
1886
}
1887

1888
static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
6,062✔
1889
{
1890
    return _WriteAsType(tif, strile_size, 0xFFFFU);
6,062✔
1891
}
1892

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

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

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

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

1944
    write_aslong4 = 1;
152,595✔
1945
    if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
152,595✔
1946
    {
1947
        write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
4,660✔
1948
    }
1949
    else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
147,935✔
1950
    {
1951
        write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1,244✔
1952
    }
1953
    if (write_aslong4)
152,593✔
1954
    {
1955
        /*
1956
        ** For classic tiff we want to verify everything is in range for LONG
1957
        ** and convert to long format.
1958
        */
1959

1960
        uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
148,174✔
1961
        uint32_t *q;
1962
        uint64_t *ma;
1963
        uint32_t mb;
1964

1965
        if (p == NULL)
148,173✔
1966
        {
1967
            TIFFErrorExtR(tif, module, "Out of memory");
×
1968
            return (0);
×
1969
        }
1970

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

1984
        o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
148,175✔
1985
                                                  p);
1986
        _TIFFfreeExt(tif, p);
148,175✔
1987
    }
1988
    else
1989
    {
1990
        uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
4,419✔
1991
        uint16_t *q;
1992
        uint64_t *ma;
1993
        uint32_t mb;
1994

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

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

2015
        o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
4,420✔
2016
                                                   p);
2017
        _TIFFfreeExt(tif, p);
4,420✔
2018
    }
2019

2020
    return (o);
152,596✔
2021
}
2022

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

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

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

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

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

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

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

2073
    return (o);
×
2074
}
2075

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

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

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

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

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

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

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

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

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

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

2264
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
9,503✔
2265
                                             TIFFDirEntry *dir, uint16_t tag,
2266
                                             uint32_t count, char *value)
2267
{
2268
    assert(sizeof(char) == 1);
2269
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
9,503✔
2270
    {
2271
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
4,768✔
2272
        return 1;
4,768✔
2273
    }
2274
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
4,735✔
2275
                                      count, value));
2276
}
2277

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

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

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

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

2343
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
173,106✔
2344
                                                  TIFFDirEntry *dir,
2345
                                                  uint16_t tag, uint32_t count,
2346
                                                  uint16_t *value)
2347
{
2348
    assert(count < 0x80000000);
173,106✔
2349
    assert(sizeof(uint16_t) == 2);
2350
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
173,106✔
2351
    {
2352
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
86,534✔
2353
        return 1;
86,533✔
2354
    }
2355
    if (tif->tif_flags & TIFF_SWAB)
86,572✔
2356
        TIFFSwabArrayOfShort(value, count);
366✔
2357
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
86,572✔
2358
                                      count * 2, value));
2359
}
2360

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

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

2398
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
148,571✔
2399
                                                 TIFFDirEntry *dir,
2400
                                                 uint16_t tag, uint32_t count,
2401
                                                 uint32_t *value)
2402
{
2403
    assert(count < 0x40000000);
148,571✔
2404
    assert(sizeof(uint32_t) == 4);
2405
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
148,571✔
2406
    {
2407
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
74,284✔
2408
        return 1;
74,284✔
2409
    }
2410
    if (tif->tif_flags & TIFF_SWAB)
74,287✔
2411
        TIFFSwabArrayOfLong(value, count);
220✔
2412
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
74,287✔
2413
                                      count * 4, value));
2414
}
2415

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

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

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

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

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

2508
    DoubleToRational(value, &m[0], &m[1]);
16✔
2509

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2805
} /*-- ToRationalEuclideanGCD() -------------- */
76✔
2806

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3033
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
452,779✔
3034
                                     TIFFDirEntry *dir, uint16_t tag,
3035
                                     uint16_t datatype, uint32_t count,
3036
                                     uint32_t datalength, void *data)
3037
{
3038
    static const char module[] = "TIFFWriteDirectoryTagData";
3039
    uint32_t m;
3040
    m = 0;
452,779✔
3041
    while (m < (*ndir))
2,709,110✔
3042
    {
3043
        assert(dir[m].tdir_tag != tag);
2,345,170✔
3044
        if (dir[m].tdir_tag > tag)
2,345,170✔
3045
            break;
88,839✔
3046
        m++;
2,256,330✔
3047
    }
3048
    if (m < (*ndir))
452,779✔
3049
    {
3050
        uint32_t n;
3051
        for (n = *ndir; n > m; n--)
303,928✔
3052
            dir[n] = dir[n - 1];
215,089✔
3053
    }
3054
    dir[m].tdir_tag = tag;
452,779✔
3055
    dir[m].tdir_type = datatype;
452,779✔
3056
    dir[m].tdir_count = count;
452,779✔
3057
    dir[m].tdir_offset.toff_long8 = 0;
452,779✔
3058
    if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
452,779✔
3059
    {
3060
        if (data && datalength)
413,743✔
3061
        {
3062
            _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
413,006✔
3063
        }
3064
    }
3065
    else
3066
    {
3067
        uint64_t na, nb;
3068
        na = tif->tif_dataoff;
39,036✔
3069
        nb = na + datalength;
39,036✔
3070
        if (!(tif->tif_flags & TIFF_BIGTIFF))
39,036✔
3071
            nb = (uint32_t)nb;
38,754✔
3072
        if ((nb < na) || (nb < datalength))
39,036✔
3073
        {
3074
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
×
3075
            return (0);
×
3076
        }
3077
        if (!SeekOK(tif, na))
39,036✔
3078
        {
3079
            TIFFErrorExtR(tif, module, "IO error writing tag data");
1✔
3080
            return (0);
×
3081
        }
3082
        if (datalength >= 0x80000000UL)
39,034✔
3083
        {
3084
            TIFFErrorExtR(tif, module,
×
3085
                          "libtiff does not allow writing more than 2147483647 "
3086
                          "bytes in a tag");
3087
            return (0);
×
3088
        }
3089
        if (!WriteOK(tif, data, (tmsize_t)datalength))
39,034✔
3090
        {
3091
            TIFFErrorExtR(tif, module, "IO error writing tag data");
34✔
3092
            return (0);
33✔
3093
        }
3094
        tif->tif_dataoff = nb;
39,003✔
3095
        if (tif->tif_dataoff & 1)
39,003✔
3096
            tif->tif_dataoff++;
2,442✔
3097
        if (!(tif->tif_flags & TIFF_BIGTIFF))
39,003✔
3098
        {
3099
            uint32_t o;
3100
            o = (uint32_t)na;
38,722✔
3101
            if (tif->tif_flags & TIFF_SWAB)
38,722✔
3102
                TIFFSwabLong(&o);
394✔
3103
            _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
38,722✔
3104
        }
3105
        else
3106
        {
3107
            dir[m].tdir_offset.toff_long8 = na;
281✔
3108
            if (tif->tif_flags & TIFF_SWAB)
281✔
3109
                TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
8✔
3110
        }
3111
    }
3112
    (*ndir)++;
452,749✔
3113
    return (1);
452,749✔
3114
}
3115

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

3123
    tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
38,609✔
3124

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

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

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

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

3226
        while (1)
3227
        {
31✔
3228
            uint16_t dircount;
3229
            uint32_t nextnextdir;
3230

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

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

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

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

3391
    /* -------------------------------------------------------------------- */
3392
    /*      Find field definition.                                          */
3393
    /* -------------------------------------------------------------------- */
3394
    /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
16,210✔
3395

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

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

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

3425
    read_offset = tif->tif_diroff;
16,210✔
3426

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

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

3468
        memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
136,464✔
3469
        if (tif->tif_flags & TIFF_SWAB)
136,464✔
3470
            TIFFSwabShort(&entry_tag);
1,897✔
3471

3472
        if (entry_tag == tag)
136,464✔
3473
            break;
16,210✔
3474

3475
        read_offset += dirsize;
120,254✔
3476
    }
3477

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

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

3492
    if (!(tif->tif_flags & TIFF_BIGTIFF))
16,210✔
3493
    {
3494
        uint32_t value;
3495

3496
        memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
15,960✔
3497
        if (tif->tif_flags & TIFF_SWAB)
15,960✔
3498
            TIFFSwabLong(&value);
206✔
3499
        entry_count = value;
15,960✔
3500

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

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

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

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

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

3604
    if (datatype == in_datatype)
16,210✔
3605
        memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
199✔
3606
    else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
16,011✔
3607
    {
×
3608
        tmsize_t i;
3609

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

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

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

3663
    if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
16,210✔
3664
    {
3665
        if (TIFFDataWidth(datatype) == 2)
206✔
3666
            TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
36✔
3667
        else if (TIFFDataWidth(datatype) == 4)
170✔
3668
            TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
170✔
3669
        else if (TIFFDataWidth(datatype) == 8)
×
3670
            TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
×
3671
    }
3672

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

3693
    if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
16,210✔
3694
        tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
8,105✔
3695
        tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
816✔
3696
        tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
816✔
3697
    {
3698
        tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
816✔
3699
        tif->tif_dir.td_stripoffset_entry.tdir_count = count;
816✔
3700
    }
3701
    else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
15,394✔
3702
              tag == TIFFTAG_STRIPBYTECOUNTS) &&
8,105✔
3703
             tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
8,105✔
3704
             tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
816✔
3705
             tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
816✔
3706
    {
3707
        tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
816✔
3708
        tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
816✔
3709
    }
3710

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

3733
        _TIFFfreeExt(tif, buf_to_write);
15,494✔
3734
        return 1;
15,494✔
3735
    }
3736

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

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

3766
    _TIFFfreeExt(tif, buf_to_write);
716✔
3767
    buf_to_write = 0;
716✔
3768

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

3778
    if (!(tif->tif_flags & TIFF_BIGTIFF))
716✔
3779
    {
3780
        uint32_t value;
3781

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

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

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

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

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

3820
    return 1;
716✔
3821
}
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