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

OSGeo / gdal / 8872387746

29 Apr 2024 02:16AM UTC coverage: 69.076% (+0.003%) from 69.073%
8872387746

Pull #9801

github

web-flow
Bump actions/upload-artifact from 4.3.2 to 4.3.3

Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/1746f4ab6...65462800f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #9801: Bump actions/upload-artifact from 4.3.2 to 4.3.3

534153 of 773282 relevant lines covered (69.08%)

205719.18 hits per line

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

54.13
/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)
35,662✔
236
{
237
    return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
35,662✔
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)
315✔
266
{
267
    static const char module[] = "TIFFDeferStrileArrayWriting";
268
    if (tif->tif_mode == O_RDONLY)
315✔
269
    {
270
        TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
×
271
        return 0;
×
272
    }
273
    if (tif->tif_diroff != 0)
315✔
274
    {
275
        TIFFErrorExtR(tif, module, "Directory has already been written");
×
276
        return 0;
×
277
    }
278

279
    tif->tif_dir.td_deferstrilearraywriting = TRUE;
315✔
280
    return 1;
315✔
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,270✔
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,270✔
319
        return TIFFWriteDirectory(tif);
25,970✔
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,300✔
326

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

334
            TIFFSeekFile(tif, 4, SEEK_SET);
1,289✔
335
            if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
1,289✔
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,295✔
395
    }
396
    else
397
    {
398
        if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
5✔
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;
4✔
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))
4✔
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,296✔
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,275✔
481
{
482
    return TIFFRewriteDirectorySec(tif, TRUE, TRUE, NULL);
27,275✔
483
}
484

485
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
36,954✔
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)
36,954✔
495
        return (1);
×
496

497
    _TIFFFillStriles(tif);
36,954✔
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)
36,952✔
505
    {
506
        if (tif->tif_flags & TIFF_POSTENCODE)
36,953✔
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 */
36,953✔
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)
36,953✔
525
        {
526
            if (!TIFFFlushData1(tif))
5✔
527
            {
528
                TIFFErrorExtR(tif, module,
2✔
529
                              "Error flushing data before directory write");
530
                return (0);
×
531
            }
532
        }
533
        if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
36,951✔
534
        {
535
            _TIFFfreeExt(tif, tif->tif_rawdata);
27,520✔
536
            tif->tif_rawdata = NULL;
27,525✔
537
            tif->tif_rawcc = 0;
27,525✔
538
            tif->tif_rawdatasize = 0;
27,525✔
539
            tif->tif_rawdataoff = 0;
27,525✔
540
            tif->tif_rawdataloaded = 0;
27,525✔
541
        }
542
        tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
36,956✔
543
    }
544

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

1109
        /* Evaluate IFD data size: Finally, add the size of the IFD tag entries
1110
         * themselves. */
1111
        if (!(tif->tif_flags & TIFF_BIGTIFF))
36,963✔
1112
            tif->tif_dir.td_dirdatasize_write += 2 + ndir * 12 + 4;
36,823✔
1113
        else
1114
            tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
140✔
1115

1116
        /* Setup a new directory within first pass. */
1117
        dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
36,963✔
1118
        if (dir == NULL)
36,958✔
1119
        {
1120
            TIFFErrorExtR(tif, module, "Out of memory");
×
1121
            goto bad;
×
1122
        }
1123
        if (isimage)
36,958✔
1124
        {
1125
            /* Check, weather the IFD to be written is new or an already written
1126
             * IFD can be overwritten or needs to be re-written to a different
1127
             * location in the file because the IFD is extended with additional
1128
             * tags or the IFD data size is increased.
1129
             * - tif_diroff == 0, if a new directory has to be linked.
1130
             * - tif_diroff != 0, IFD has been re-read from file and will be
1131
             *   overwritten or re-written.
1132
             */
1133
            if (tif->tif_diroff == 0)
36,958✔
1134
            {
1135
                if (!TIFFLinkDirectory(tif))
36,942✔
1136
                    goto bad;
×
1137
            }
1138
            else if (tif->tif_dir.td_dirdatasize_write >
16✔
1139
                     tif->tif_dir.td_dirdatasize_read)
16✔
1140
            {
1141
                if (dir != NULL)
×
1142
                {
1143
                    _TIFFfreeExt(tif, dir);
×
1144
                    dir = NULL;
×
1145
                }
1146
                if (!TIFFRewriteDirectorySec(tif, isimage, imagedone, pdiroff))
×
1147
                    goto bad;
×
1148
                return (1);
×
1149
            }
1150
        }
1151
        else
1152
        {
1153
            /* For !isimage, which means custom-IFD like EXIFIFD or
1154
             * checkpointing an IFD, determine whether to overwrite or append at
1155
             * the end of the file.
1156
             */
1157
            if (!((tif->tif_dir.td_dirdatasize_read > 0) &&
×
1158
                  (tif->tif_dir.td_dirdatasize_write <=
×
1159
                   tif->tif_dir.td_dirdatasize_read)))
×
1160
            {
1161
                /* Append at end of file and increment to an even offset. */
1162
                tif->tif_diroff =
×
1163
                    (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
9✔
1164
            }
1165
        }
1166
        /* Return IFD offset */
1167
        if (pdiroff != NULL)
36,946✔
1168
            *pdiroff = tif->tif_diroff;
×
1169
        if (!(tif->tif_flags & TIFF_BIGTIFF))
36,946✔
1170
            dirsize = 2 + ndir * 12 + 4;
36,811✔
1171
        else
1172
            dirsize = 8 + ndir * 20 + 8;
135✔
1173
        /* Append IFD data stright after the IFD tag entries.
1174
         * Data that does not fit into an IFD tag entry is written to the file
1175
         * in the second pass of the while loop. That offset is stored in "dir".
1176
         */
1177
        tif->tif_dataoff = tif->tif_diroff + dirsize;
36,946✔
1178
        if (!(tif->tif_flags & TIFF_BIGTIFF))
36,946✔
1179
            tif->tif_dataoff = (uint32_t)tif->tif_dataoff;
36,810✔
1180
        if ((tif->tif_dataoff < tif->tif_diroff) ||
36,946✔
1181
            (tif->tif_dataoff < (uint64_t)dirsize))
36,943✔
1182
        {
1183
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
×
1184
            goto bad;
×
1185
        }
1186
        if (tif->tif_dataoff & 1)
36,964✔
1187
            tif->tif_dataoff++;
×
1188
        if (isimage)
36,964✔
1189
        {
1190
            if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
36,944✔
1191
                tif->tif_curdir = 0;
35,070✔
1192
            else
1193
                tif->tif_curdir++;
1,874✔
1194
        }
1195
    } /* while() */
1196
    if (isimage)
36,932✔
1197
    {
1198
        /* For SubIFDs remember offset of SubIFD tag within main IFD. */
1199
        if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
36,931✔
1200
        {
1201
            uint32_t na;
1202
            TIFFDirEntry *nb;
1203
            for (na = 0, nb = dir;; na++, nb++)
×
1204
            {
1205
                if (na == ndir)
×
1206
                {
1207
                    TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
×
1208
                    goto bad;
×
1209
                }
1210
                if (nb->tdir_tag == TIFFTAG_SUBIFD)
×
1211
                    break;
×
1212
            }
1213
            if (!(tif->tif_flags & TIFF_BIGTIFF))
×
1214
                tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8;
×
1215
            else
1216
                tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12;
×
1217
        }
1218
    }
1219
    /* Copy/swab IFD entries from "dir" into "dirmem",
1220
     * which is then written to file. */
1221
    dirmem = _TIFFmallocExt(tif, dirsize);
36,932✔
1222
    if (dirmem == NULL)
36,928✔
1223
    {
1224
        TIFFErrorExtR(tif, module, "Out of memory");
×
1225
        goto bad;
×
1226
    }
1227
    if (!(tif->tif_flags & TIFF_BIGTIFF))
36,929✔
1228
    {
1229
        uint8_t *n;
1230
        uint32_t nTmp;
1231
        TIFFDirEntry *o;
1232
        n = dirmem;
36,794✔
1233
        *(uint16_t *)n = (uint16_t)ndir;
36,794✔
1234
        if (tif->tif_flags & TIFF_SWAB)
36,794✔
1235
            TIFFSwabShort((uint16_t *)n);
124✔
1236
        n += 2;
36,790✔
1237
        o = dir;
36,790✔
1238
        for (m = 0; m < ndir; m++)
463,785✔
1239
        {
1240
            *(uint16_t *)n = o->tdir_tag;
427,003✔
1241
            if (tif->tif_flags & TIFF_SWAB)
427,003✔
1242
                TIFFSwabShort((uint16_t *)n);
1,668✔
1243
            n += 2;
427,003✔
1244
            *(uint16_t *)n = o->tdir_type;
427,003✔
1245
            if (tif->tif_flags & TIFF_SWAB)
427,003✔
1246
                TIFFSwabShort((uint16_t *)n);
1,668✔
1247
            n += 2;
427,003✔
1248
            nTmp = (uint32_t)o->tdir_count;
427,003✔
1249
            _TIFFmemcpy(n, &nTmp, 4);
427,003✔
1250
            if (tif->tif_flags & TIFF_SWAB)
426,988✔
1251
                TIFFSwabLong((uint32_t *)n);
1,668✔
1252
            n += 4;
426,988✔
1253
            /* This is correct. The data has been */
1254
            /* swabbed previously in TIFFWriteDirectoryTagData */
1255
            _TIFFmemcpy(n, &o->tdir_offset, 4);
426,988✔
1256
            n += 4;
426,995✔
1257
            o++;
426,995✔
1258
        }
1259
        nTmp = (uint32_t)tif->tif_nextdiroff;
36,782✔
1260
        if (tif->tif_flags & TIFF_SWAB)
36,782✔
1261
            TIFFSwabLong(&nTmp);
124✔
1262
        _TIFFmemcpy(n, &nTmp, 4);
36,782✔
1263
    }
1264
    else
1265
    {
1266
        uint8_t *n;
1267
        TIFFDirEntry *o;
1268
        n = dirmem;
135✔
1269
        *(uint64_t *)n = ndir;
135✔
1270
        if (tif->tif_flags & TIFF_SWAB)
135✔
1271
            TIFFSwabLong8((uint64_t *)n);
4✔
1272
        n += 8;
135✔
1273
        o = dir;
135✔
1274
        for (m = 0; m < ndir; m++)
2,087✔
1275
        {
1276
            *(uint16_t *)n = o->tdir_tag;
1,952✔
1277
            if (tif->tif_flags & TIFF_SWAB)
1,952✔
1278
                TIFFSwabShort((uint16_t *)n);
44✔
1279
            n += 2;
1,952✔
1280
            *(uint16_t *)n = o->tdir_type;
1,952✔
1281
            if (tif->tif_flags & TIFF_SWAB)
1,952✔
1282
                TIFFSwabShort((uint16_t *)n);
44✔
1283
            n += 2;
1,952✔
1284
            _TIFFmemcpy(n, &o->tdir_count, 8);
1,952✔
1285
            if (tif->tif_flags & TIFF_SWAB)
1,952✔
1286
                TIFFSwabLong8((uint64_t *)n);
44✔
1287
            n += 8;
1,952✔
1288
            _TIFFmemcpy(n, &o->tdir_offset, 8);
1,952✔
1289
            n += 8;
1,952✔
1290
            o++;
1,952✔
1291
        }
1292
        _TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
135✔
1293
        if (tif->tif_flags & TIFF_SWAB)
135✔
1294
            TIFFSwabLong8((uint64_t *)n);
4✔
1295
    }
1296
    _TIFFfreeExt(tif, dir);
36,928✔
1297
    dir = NULL;
36,926✔
1298
    if (!SeekOK(tif, tif->tif_diroff))
36,926✔
1299
    {
1300
        TIFFErrorExtR(tif, module, "IO error writing directory");
×
1301
        goto bad;
×
1302
    }
1303
    if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
36,926✔
1304
    {
1305
        TIFFErrorExtR(tif, module, "IO error writing directory");
×
1306
        goto bad;
×
1307
    }
1308
    _TIFFfreeExt(tif, dirmem);
36,928✔
1309
    if (imagedone)
36,926✔
1310
    {
1311
        TIFFFreeDirectory(tif);
36,926✔
1312
        tif->tif_flags &= ~TIFF_DIRTYDIRECT;
36,920✔
1313
        tif->tif_flags &= ~TIFF_DIRTYSTRIP;
36,920✔
1314
        (*tif->tif_cleanup)(tif);
36,920✔
1315
        /* Reset directory-related state for subsequent directories. */
1316
        TIFFCreateDirectory(tif);
36,923✔
1317
    }
1318
    else
1319
    {
1320
        /* IFD is only checkpointed to file, thus set IFD data size written to
1321
         * file.
1322
         */
1323
        tif->tif_dir.td_dirdatasize_read = tif->tif_dir.td_dirdatasize_write;
×
1324
    }
1325
    return (1);
36,931✔
1326
bad:
30✔
1327
    if (dir != NULL)
30✔
1328
        _TIFFfreeExt(tif, dir);
30✔
1329
    if (dirmem != NULL)
30✔
1330
        _TIFFfreeExt(tif, dirmem);
×
1331
    return (0);
30✔
1332
}
1333

1334
static int8_t TIFFClampDoubleToInt8(double val)
×
1335
{
1336
    if (val > 127)
×
1337
        return 127;
×
1338
    if (val < -128 || val != val)
×
1339
        return -128;
×
1340
    return (int8_t)val;
×
1341
}
1342

1343
static int16_t TIFFClampDoubleToInt16(double val)
×
1344
{
1345
    if (val > 32767)
×
1346
        return 32767;
×
1347
    if (val < -32768 || val != val)
×
1348
        return -32768;
×
1349
    return (int16_t)val;
×
1350
}
1351

1352
static int32_t TIFFClampDoubleToInt32(double val)
×
1353
{
1354
    if (val > 0x7FFFFFFF)
×
1355
        return 0x7FFFFFFF;
×
1356
    if (val < -0x7FFFFFFF - 1 || val != val)
×
1357
        return -0x7FFFFFFF - 1;
×
1358
    return (int32_t)val;
×
1359
}
1360

1361
static uint8_t TIFFClampDoubleToUInt8(double val)
×
1362
{
1363
    if (val < 0)
×
1364
        return 0;
×
1365
    if (val > 255 || val != val)
×
1366
        return 255;
×
1367
    return (uint8_t)val;
×
1368
}
1369

1370
static uint16_t TIFFClampDoubleToUInt16(double val)
×
1371
{
1372
    if (val < 0)
×
1373
        return 0;
×
1374
    if (val > 65535 || val != val)
×
1375
        return 65535;
×
1376
    return (uint16_t)val;
×
1377
}
1378

1379
static uint32_t TIFFClampDoubleToUInt32(double val)
×
1380
{
1381
    if (val < 0)
×
1382
        return 0;
×
1383
    if (val > 0xFFFFFFFFU || val != val)
×
1384
        return 0xFFFFFFFFU;
×
1385
    return (uint32_t)val;
×
1386
}
1387

1388
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
×
1389
                                                  TIFFDirEntry *dir,
1390
                                                  uint16_t tag, uint32_t count,
1391
                                                  double *value)
1392
{
1393
    static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
1394
    void *conv;
1395
    uint32_t i;
1396
    int ok;
1397
    conv = _TIFFmallocExt(tif, count * sizeof(double));
×
1398
    if (conv == NULL)
×
1399
    {
1400
        TIFFErrorExtR(tif, module, "Out of memory");
×
1401
        return (0);
×
1402
    }
1403

1404
    switch (tif->tif_dir.td_sampleformat)
×
1405
    {
1406
        case SAMPLEFORMAT_IEEEFP:
×
1407
            if (tif->tif_dir.td_bitspersample <= 32)
×
1408
            {
1409
                for (i = 0; i < count; ++i)
×
1410
                    ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
×
1411
                ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count,
×
1412
                                                     (float *)conv);
1413
            }
1414
            else
1415
            {
1416
                ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
×
1417
                                                      count, value);
1418
            }
1419
            break;
×
1420
        case SAMPLEFORMAT_INT:
×
1421
            if (tif->tif_dir.td_bitspersample <= 8)
×
1422
            {
1423
                for (i = 0; i < count; ++i)
×
1424
                    ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]);
×
1425
                ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count,
×
1426
                                                     (int8_t *)conv);
1427
            }
1428
            else if (tif->tif_dir.td_bitspersample <= 16)
×
1429
            {
1430
                for (i = 0; i < count; ++i)
×
1431
                    ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]);
×
1432
                ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag,
×
1433
                                                      count, (int16_t *)conv);
1434
            }
1435
            else
1436
            {
1437
                for (i = 0; i < count; ++i)
×
1438
                    ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]);
×
1439
                ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count,
×
1440
                                                     (int32_t *)conv);
1441
            }
1442
            break;
×
1443
        case SAMPLEFORMAT_UINT:
×
1444
            if (tif->tif_dir.td_bitspersample <= 8)
×
1445
            {
1446
                for (i = 0; i < count; ++i)
×
1447
                    ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
×
1448
                ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count,
×
1449
                                                    (uint8_t *)conv);
1450
            }
1451
            else if (tif->tif_dir.td_bitspersample <= 16)
×
1452
            {
1453
                for (i = 0; i < count; ++i)
×
1454
                    ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
×
1455
                ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count,
×
1456
                                                     (uint16_t *)conv);
1457
            }
1458
            else
1459
            {
1460
                for (i = 0; i < count; ++i)
×
1461
                    ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
×
1462
                ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count,
×
1463
                                                    (uint32_t *)conv);
1464
            }
1465
            break;
×
1466
        default:
×
1467
            ok = 0;
×
1468
    }
1469

1470
    _TIFFfreeExt(tif, conv);
×
1471
    return (ok);
×
1472
}
1473

1474
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
7,492✔
1475
                                      TIFFDirEntry *dir, uint16_t tag,
1476
                                      uint32_t count, char *value)
1477
{
1478
    return (
1479
        TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
7,492✔
1480
}
1481

1482
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
4,536✔
1483
                                               TIFFDirEntry *dir, uint16_t tag,
1484
                                               uint32_t count, uint8_t *value)
1485
{
1486
    return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
4,536✔
1487
                                                       count, value));
1488
}
1489

1490
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
22✔
1491
                                          TIFFDirEntry *dir, uint16_t tag,
1492
                                          uint32_t count, uint8_t *value)
1493
{
1494
    return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
22✔
1495
                                                  value));
1496
}
1497

1498
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
×
1499
                                           TIFFDirEntry *dir, uint16_t tag,
1500
                                           uint32_t count, int8_t *value)
1501
{
1502
    return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
×
1503
                                                   value));
1504
}
1505

1506
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
298,372✔
1507
                                      TIFFDirEntry *dir, uint16_t tag,
1508
                                      uint16_t value)
1509
{
1510
    return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
298,372✔
1511
}
1512

1513
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
12,568✔
1514
                                           TIFFDirEntry *dir, uint16_t tag,
1515
                                           uint32_t count, uint16_t *value)
1516
{
1517
    return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
12,568✔
1518
                                                   value));
1519
}
1520

1521
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
147,377✔
1522
                                               TIFFDirEntry *dir, uint16_t tag,
1523
                                               uint16_t value)
1524
{
1525
    static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1526
    uint16_t *m;
1527
    uint16_t *na;
1528
    uint16_t nb;
1529
    int o;
1530
    if (dir == NULL)
147,377✔
1531
    {
1532
        /* only evaluate IFD data size and inc. ndir */
1533
        return (TIFFWriteDirectoryTagCheckedShortArray(
73,665✔
1534
            tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
73,683✔
1535
    }
1536
    m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
73,694✔
1537
    if (m == NULL)
73,679✔
1538
    {
1539
        TIFFErrorExtR(tif, module, "Out of memory");
7✔
1540
        return (0);
×
1541
    }
1542
    for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
567,139✔
1543
        *na = value;
493,467✔
1544
    o = TIFFWriteDirectoryTagCheckedShortArray(
73,672✔
1545
        tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
73,672✔
1546
    _TIFFfreeExt(tif, m);
73,679✔
1547
    return (o);
73,685✔
1548
}
1549

1550
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
×
1551
                                            TIFFDirEntry *dir, uint16_t tag,
1552
                                            uint32_t count, int16_t *value)
1553
{
1554
    return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
×
1555
                                                    value));
1556
}
1557

1558
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
1,762✔
1559
                                     TIFFDirEntry *dir, uint16_t tag,
1560
                                     uint32_t value)
1561
{
1562
    return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1,762✔
1563
}
1564

1565
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
398✔
1566
                                          TIFFDirEntry *dir, uint16_t tag,
1567
                                          uint32_t count, uint32_t *value)
1568
{
1569
    return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
398✔
1570
                                                  value));
1571
}
1572

1573
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
×
1574
                                           TIFFDirEntry *dir, uint16_t tag,
1575
                                           uint32_t count, int32_t *value)
1576
{
1577
    return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
×
1578
                                                   value));
1579
}
1580

1581
/************************************************************************/
1582
/*                 TIFFWriteDirectoryTagLong8Array()                    */
1583
/*                                                                      */
1584
/*      Write either Long8 or Long array depending on file type.        */
1585
/************************************************************************/
1586
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
×
1587
                                           TIFFDirEntry *dir, uint16_t tag,
1588
                                           uint32_t count, uint64_t *value)
1589
{
1590
    static const char module[] = "TIFFWriteDirectoryTagLong8Array";
1591
    uint64_t *ma;
1592
    uint32_t mb;
1593
    uint32_t *p;
1594
    uint32_t *q;
1595
    int o;
1596

1597
    /* is this just a counting pass? */
1598
    if (dir == NULL)
×
1599
    {
1600
        /* only evaluate IFD data size and inc. ndir */
1601
        return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
×
1602
                                                       count, value));
1603
    }
1604

1605
    /* We always write Long8 for BigTIFF, no checking needed. */
1606
    if (tif->tif_flags & TIFF_BIGTIFF)
×
1607
        return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
×
1608
                                                       count, value));
1609

1610
    /*
1611
    ** For classic tiff we want to verify everything is in range for long
1612
    ** and convert to long format.
1613
    */
1614
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
×
1615
    if (p == NULL)
×
1616
    {
1617
        TIFFErrorExtR(tif, module, "Out of memory");
×
1618
        return (0);
×
1619
    }
1620

1621
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
×
1622
    {
1623
        if (*ma > 0xFFFFFFFF)
×
1624
        {
1625
            TIFFErrorExtR(tif, module,
×
1626
                          "Attempt to write unsigned long value %" PRIu64
1627
                          " larger than 0xFFFFFFFF for tag %d in Classic TIFF "
1628
                          "file. TIFF file writing aborted",
1629
                          *ma, tag);
1630
            _TIFFfreeExt(tif, p);
×
1631
            return (0);
×
1632
        }
1633
        *q = (uint32_t)(*ma);
×
1634
    }
1635

1636
    o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
×
1637
    _TIFFfreeExt(tif, p);
×
1638

1639
    return (o);
×
1640
}
1641

1642
/************************************************************************/
1643
/*                 TIFFWriteDirectoryTagSlong8Array()                   */
1644
/*                                                                      */
1645
/*      Write either SLong8 or SLong array depending on file type.      */
1646
/************************************************************************/
1647
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
×
1648
                                            TIFFDirEntry *dir, uint16_t tag,
1649
                                            uint32_t count, int64_t *value)
1650
{
1651
    static const char module[] = "TIFFWriteDirectoryTagSlong8Array";
1652
    int64_t *ma;
1653
    uint32_t mb;
1654
    int32_t *p;
1655
    int32_t *q;
1656
    int o;
1657

1658
    /* is this just a counting pass? */
1659
    if (dir == NULL)
×
1660
    {
1661
        /* only evaluate IFD data size and inc. ndir */
1662
        return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
×
1663
                                                        count, value));
1664
    }
1665
    /* We always write SLong8 for BigTIFF, no checking needed. */
1666
    if (tif->tif_flags & TIFF_BIGTIFF)
×
1667
        return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
×
1668
                                                        count, value));
1669

1670
    /*
1671
    ** For classic tiff we want to verify everything is in range for signed-long
1672
    ** and convert to signed-long format.
1673
    */
1674
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
×
1675
    if (p == NULL)
×
1676
    {
1677
        TIFFErrorExtR(tif, module, "Out of memory");
×
1678
        return (0);
×
1679
    }
1680

1681
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
×
1682
    {
1683
        if (*ma > (2147483647))
×
1684
        {
1685
            TIFFErrorExtR(tif, module,
×
1686
                          "Attempt to write signed long value %" PRIi64
1687
                          " larger than 0x7FFFFFFF (2147483647) for tag %d in "
1688
                          "Classic TIFF file. TIFF writing to file aborted",
1689
                          *ma, tag);
1690
            _TIFFfreeExt(tif, p);
×
1691
            return (0);
×
1692
        }
1693
        else if (*ma < (-2147483647 - 1))
×
1694
        {
1695
            TIFFErrorExtR(tif, module,
×
1696
                          "Attempt to write signed long value %" PRIi64
1697
                          " smaller than 0x80000000 (-2147483648) for tag %d "
1698
                          "in Classic TIFF file. TIFF writing to file aborted",
1699
                          *ma, tag);
1700
            _TIFFfreeExt(tif, p);
×
1701
            return (0);
×
1702
        }
1703
        *q = (int32_t)(*ma);
×
1704
    }
1705

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

1709
    return (o);
×
1710
}
1711

1712
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
32✔
1713
                                         TIFFDirEntry *dir, uint16_t tag,
1714
                                         double value)
1715
{
1716
    return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
32✔
1717
}
1718

1719
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
1,686✔
1720
                                              TIFFDirEntry *dir, uint16_t tag,
1721
                                              uint32_t count, float *value)
1722
{
1723
    return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
1,686✔
1724
                                                      count, value));
1725
}
1726

1727
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
×
1728
                                               TIFFDirEntry *dir, uint16_t tag,
1729
                                               uint32_t count, float *value)
1730
{
1731
    return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
×
1732
                                                       count, value));
1733
}
1734

1735
/*-- Rational2Double: additional write functions */
1736
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
×
1737
                                                    TIFFDirEntry *dir,
1738
                                                    uint16_t tag,
1739
                                                    uint32_t count,
1740
                                                    double *value)
1741
{
1742
    return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
×
1743
                                                            count, value));
1744
}
1745

1746
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
×
1747
                                                     TIFFDirEntry *dir,
1748
                                                     uint16_t tag,
1749
                                                     uint32_t count,
1750
                                                     double *value)
1751
{
1752
    return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
×
1753
        tif, ndir, dir, tag, count, value));
1754
}
1755

1756
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
×
1757
                                           TIFFDirEntry *dir, uint16_t tag,
1758
                                           uint32_t count, float *value)
1759
{
1760
    return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
×
1761
                                                   value));
1762
}
1763

1764
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
12,022✔
1765
                                            TIFFDirEntry *dir, uint16_t tag,
1766
                                            uint32_t count, double *value)
1767
{
1768
    return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
12,022✔
1769
                                                    value));
1770
}
1771

1772
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
×
1773
                                         TIFFDirEntry *dir, uint16_t tag,
1774
                                         uint32_t count, uint32_t *value)
1775
{
1776
    return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
×
1777
                                                 value));
1778
}
1779

1780
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
224,688✔
1781
                                          TIFFDirEntry *dir, uint16_t tag,
1782
                                          uint32_t value)
1783
{
1784
    if (value <= 0xFFFF)
224,688✔
1785
        return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
224,615✔
1786
                                                  (uint16_t)value));
224,639✔
1787
    else
1788
        return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
49✔
1789
}
1790

1791
static int _WriteAsType(TIFF *tif, uint64_t strile_size,
3,670✔
1792
                        uint64_t uncompressed_threshold)
1793
{
1794
    const uint16_t compression = tif->tif_dir.td_compression;
3,670✔
1795
    if (compression == COMPRESSION_NONE)
3,670✔
1796
    {
1797
        return strile_size > uncompressed_threshold;
2,156✔
1798
    }
1799
    else if (compression == COMPRESSION_JPEG ||
1,514✔
1800
             compression == COMPRESSION_LZW ||
724✔
1801
             compression == COMPRESSION_ADOBE_DEFLATE ||
402✔
1802
             compression == COMPRESSION_DEFLATE ||
402✔
1803
             compression == COMPRESSION_LZMA ||
400✔
1804
             compression == COMPRESSION_LERC ||
328✔
1805
             compression == COMPRESSION_ZSTD ||
134✔
1806
             compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL)
68✔
1807
    {
1808
        /* For a few select compression types, we assume that in the worst */
1809
        /* case the compressed size will be 10 times the uncompressed size. */
1810
        /* This is overly pessismistic ! */
1811
        return strile_size >= uncompressed_threshold / 10;
1,506✔
1812
    }
1813
    return 1;
8✔
1814
}
1815

1816
static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
248✔
1817
{
1818
    return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
248✔
1819
}
1820

1821
static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
3,422✔
1822
{
1823
    return _WriteAsType(tif, strile_size, 0xFFFFU);
3,422✔
1824
}
1825

1826
/************************************************************************/
1827
/*                TIFFWriteDirectoryTagLongLong8Array()                 */
1828
/*                                                                      */
1829
/*      Write out LONG8 array and write a SHORT/LONG/LONG8 depending    */
1830
/*      on strile size and Classic/BigTIFF mode.                        */
1831
/************************************************************************/
1832

1833
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
147,805✔
1834
                                               TIFFDirEntry *dir, uint16_t tag,
1835
                                               uint32_t count, uint64_t *value)
1836
{
1837
    static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1838
    int o;
1839
    int write_aslong4;
1840

1841
    if (tif->tif_dir.td_deferstrilearraywriting)
147,805✔
1842
    {
1843
        if (dir == NULL)
1,284✔
1844
        {
1845
            /* This is just a counting pass to count IFD entries.
1846
             * For deferstrilearraywriting no extra bytes will be written
1847
             * into IFD space. */
1848
            (*ndir)++;
642✔
1849
            return 1;
642✔
1850
        }
1851
        return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
642✔
1852
                                         NULL);
1853
    }
1854

1855
    if (tif->tif_flags & TIFF_BIGTIFF)
146,521✔
1856
    {
1857
        int write_aslong8 = 1;
476✔
1858
        /* In the case of ByteCounts array, we may be able to write them on LONG
1859
         * if the strip/tilesize is not too big. Also do that for count > 1 in
1860
         * the case someone would want to create a single-strip file with a
1861
         * growing height, in which case using LONG8 will be safer. */
1862
        if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
476✔
1863
        {
1864
            write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
32✔
1865
        }
1866
        else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
444✔
1867
        {
1868
            write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
112✔
1869
        }
1870
        if (write_aslong8)
476✔
1871
        {
1872
            return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
332✔
1873
                                                          count, value);
1874
        }
1875
    }
1876

1877
    write_aslong4 = 1;
146,189✔
1878
    if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
146,189✔
1879
    {
1880
        write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
2,114✔
1881
    }
1882
    else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
144,075✔
1883
    {
1884
        write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1,204✔
1885
    }
1886
    if (write_aslong4)
146,182✔
1887
    {
1888
        /*
1889
        ** For classic tiff we want to verify everything is in range for LONG
1890
        ** and convert to long format.
1891
        */
1892

1893
        uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
143,950✔
1894
        uint32_t *q;
1895
        uint64_t *ma;
1896
        uint32_t mb;
1897

1898
        if (p == NULL)
143,965✔
1899
        {
1900
            TIFFErrorExtR(tif, module, "Out of memory");
×
1901
            return (0);
×
1902
        }
1903

1904
        for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
11,108,600✔
1905
        {
1906
            if (*ma > 0xFFFFFFFF)
10,964,600✔
1907
            {
1908
                TIFFErrorExtR(tif, module,
×
1909
                              "Attempt to write value larger than 0xFFFFFFFF "
1910
                              "in LONG array.");
1911
                _TIFFfreeExt(tif, p);
×
1912
                return (0);
×
1913
            }
1914
            *q = (uint32_t)(*ma);
10,964,600✔
1915
        }
1916

1917
        o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
143,965✔
1918
                                                  p);
1919
        _TIFFfreeExt(tif, p);
143,953✔
1920
    }
1921
    else
1922
    {
1923
        uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
2,232✔
1924
        uint16_t *q;
1925
        uint64_t *ma;
1926
        uint32_t mb;
1927

1928
        if (p == NULL)
2,232✔
1929
        {
1930
            TIFFErrorExtR(tif, module, "Out of memory");
×
1931
            return (0);
×
1932
        }
1933

1934
        for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
5,934,430✔
1935
        {
1936
            if (*ma > 0xFFFF)
5,932,200✔
1937
            {
1938
                /* Should not happen normally given the check we did before */
1939
                TIFFErrorExtR(tif, module,
×
1940
                              "Attempt to write value larger than 0xFFFF in "
1941
                              "SHORT array.");
1942
                _TIFFfreeExt(tif, p);
×
1943
                return (0);
×
1944
            }
1945
            *q = (uint16_t)(*ma);
5,932,200✔
1946
        }
1947

1948
        o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
2,232✔
1949
                                                   p);
1950
        _TIFFfreeExt(tif, p);
2,232✔
1951
    }
1952

1953
    return (o);
146,191✔
1954
}
1955

1956
/************************************************************************/
1957
/*                 TIFFWriteDirectoryTagIfdIfd8Array()                  */
1958
/*                                                                      */
1959
/*      Write either IFD8 or IFD array depending on file type.          */
1960
/************************************************************************/
1961

1962
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
×
1963
                                             TIFFDirEntry *dir, uint16_t tag,
1964
                                             uint32_t count, uint64_t *value)
1965
{
1966
    static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
1967
    uint64_t *ma;
1968
    uint32_t mb;
1969
    uint32_t *p;
1970
    uint32_t *q;
1971
    int o;
1972

1973
    /* We always write IFD8 for BigTIFF, no checking needed. */
1974
    if (tif->tif_flags & TIFF_BIGTIFF)
×
1975
        return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count,
×
1976
                                                     value);
1977

1978
    /*
1979
    ** For classic tiff we want to verify everything is in range for IFD
1980
    ** and convert to long format.
1981
    */
1982

1983
    p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
×
1984
    if (p == NULL)
×
1985
    {
1986
        TIFFErrorExtR(tif, module, "Out of memory");
×
1987
        return (0);
×
1988
    }
1989

1990
    for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
×
1991
    {
1992
        if (*ma > 0xFFFFFFFF)
×
1993
        {
1994
            TIFFErrorExtR(tif, module,
×
1995
                          "Attempt to write value larger than 0xFFFFFFFF in "
1996
                          "Classic TIFF file.");
1997
            _TIFFfreeExt(tif, p);
×
1998
            return (0);
×
1999
        }
2000
        *q = (uint32_t)(*ma);
×
2001
    }
2002

2003
    o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
×
2004
    _TIFFfreeExt(tif, p);
×
2005

2006
    return (o);
×
2007
}
2008

2009
/*
2010
 * Auxiliary function to determine the IFD data size to be written to the file.
2011
 * The IFD data size is finally the size of the IFD tag entries plus the IFD
2012
 * data that is written directly after the IFD tag entries.
2013
 */
2014
static void EvaluateIFDdatasizeWrite(TIFF *tif, uint32_t count,
166,416✔
2015
                                     uint32_t typesize, uint32_t *ndir)
2016
{
2017
    uint64_t datalength = (uint64_t)count * typesize;
166,416✔
2018
    if (datalength > ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
166,416✔
2019
    {
2020
        /* LibTIFF increments write address to an even offset, thus datalenght
2021
         * written is also incremented. */
2022
        if (datalength & 1)
29,365✔
2023
            datalength++;
2,415✔
2024
        tif->tif_dir.td_dirdatasize_write += datalength;
29,365✔
2025
    }
2026
    (*ndir)++;
166,416✔
2027
}
166,416✔
2028

2029
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
122✔
2030
                                         TIFFDirEntry *dir)
2031
{
2032
    static const char module[] = "TIFFWriteDirectoryTagColormap";
2033
    uint32_t m;
2034
    uint16_t *n;
2035
    int o;
2036
    m = (1 << tif->tif_dir.td_bitspersample);
122✔
2037
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
122✔
2038
    {
2039
        EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir);
61✔
2040
        return 1;
61✔
2041
    }
2042

2043
    n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
61✔
2044
    if (n == NULL)
61✔
2045
    {
2046
        TIFFErrorExtR(tif, module, "Out of memory");
×
2047
        return (0);
×
2048
    }
2049
    _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
61✔
2050
    _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
61✔
2051
    _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
61✔
2052
    o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
61✔
2053
                                               3 * m, n);
2054
    _TIFFfreeExt(tif, n);
61✔
2055
    return (o);
61✔
2056
}
2057

2058
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
8✔
2059
                                                 TIFFDirEntry *dir)
2060
{
2061
    static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
2062
    uint32_t m;
2063
    uint16_t n;
2064
    uint16_t *o;
2065
    int p;
2066
    /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
2067
     *  (1 << BitsPerSample) * uint16_t values.
2068
     */
2069
    m = (1 << tif->tif_dir.td_bitspersample);
8✔
2070
    /* clang-format off */
2071
    n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
8✔
2072
    /* clang-format on */
2073

2074
    /* Check for proper number of transferfunctions */
2075
    for (int i = 0; i < n; i++)
32✔
2076
    {
2077
        if (tif->tif_dir.td_transferfunction[i] == NULL)
24✔
2078
        {
2079
            TIFFWarningExtR(tif, module,
×
2080
                            "Too few TransferFunctions provided. Tag "
2081
                            "not written to file");
2082
            return (1); /* Not an error; only tag is not written. */
×
2083
        }
2084
    }
2085
    /*
2086
     * Check if the table can be written as a single column,
2087
     * or if it must be written as 3 columns.  Note that we
2088
     * write a 3-column tag if there are 2 samples/pixel and
2089
     * a single column of data won't suffice--hmm.
2090
     */
2091
    if (n == 3)
8✔
2092
    {
2093
        if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
8✔
2094
                         tif->tif_dir.td_transferfunction[2],
8✔
2095
                         m * sizeof(uint16_t)) &&
8✔
2096
            !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
×
2097
                         tif->tif_dir.td_transferfunction[1],
×
2098
                         m * sizeof(uint16_t)))
×
2099
            n = 1;
×
2100
    }
2101
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
8✔
2102
    {
2103
        EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir);
4✔
2104
        return 1;
4✔
2105
    }
2106

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

2127
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
×
2128
                                       TIFFDirEntry *dir)
2129
{
2130
    static const char module[] = "TIFFWriteDirectoryTagSubifd";
2131
    uint64_t m;
2132
    int n;
2133
    if (tif->tif_dir.td_nsubifd == 0)
×
2134
        return (1);
×
2135
    m = tif->tif_dataoff;
×
2136
    if (!(tif->tif_flags & TIFF_BIGTIFF))
×
2137
    {
2138
        uint32_t *o;
2139
        uint64_t *pa;
2140
        uint32_t *pb;
2141
        uint16_t p;
2142
        o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
×
2143
        if (o == NULL)
×
2144
        {
2145
            TIFFErrorExtR(tif, module, "Out of memory");
×
2146
            return (0);
×
2147
        }
2148
        pa = tif->tif_dir.td_subifd;
×
2149
        pb = o;
×
2150
        for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
×
2151
        {
2152
            assert(pa != 0);
×
2153

2154
            /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
2155
             * is illegal) */
2156
            if (*pa > 0xFFFFFFFFUL)
×
2157
            {
2158
                TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
×
2159
                _TIFFfreeExt(tif, o);
×
2160
                return (0);
×
2161
            }
2162
            *pb++ = (uint32_t)(*pa++);
×
2163
        }
2164
        n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
×
2165
                                                 tif->tif_dir.td_nsubifd, o);
×
2166
        _TIFFfreeExt(tif, o);
×
2167
    }
2168
    else
2169
        n = TIFFWriteDirectoryTagCheckedIfd8Array(
×
2170
            tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
×
2171
            tif->tif_dir.td_subifd);
2172

2173
    if (dir == NULL)
×
2174
        /* Just have evaluated IFD data size and incremented ndir
2175
         * above in sub-functions. */
2176
        return (n);
×
2177

2178
    if (!n)
×
2179
        return (0);
×
2180
    /*
2181
     * Total hack: if this directory includes a SubIFD
2182
     * tag then force the next <n> directories to be
2183
     * written as ``sub directories'' of this one.  This
2184
     * is used to write things like thumbnails and
2185
     * image masks that one wants to keep out of the
2186
     * normal directory linkage access mechanism.
2187
     */
2188
    tif->tif_flags |= TIFF_INSUBIFD;
×
2189
    tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
×
2190
    if (tif->tif_dir.td_nsubifd == 1)
×
2191
        tif->tif_subifdoff = 0;
×
2192
    else
2193
        tif->tif_subifdoff = m;
×
2194
    return (1);
×
2195
}
2196

2197
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
7,492✔
2198
                                             TIFFDirEntry *dir, uint16_t tag,
2199
                                             uint32_t count, char *value)
2200
{
2201
    assert(sizeof(char) == 1);
2202
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
7,492✔
2203
    {
2204
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
3,761✔
2205
        return 1;
3,761✔
2206
    }
2207
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
3,731✔
2208
                                      count, value));
2209
}
2210

2211
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
4,536✔
2212
                                                      TIFFDirEntry *dir,
2213
                                                      uint16_t tag,
2214
                                                      uint32_t count,
2215
                                                      uint8_t *value)
2216
{
2217
    assert(sizeof(uint8_t) == 1);
2218
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
4,536✔
2219
    {
2220
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2,267✔
2221
        return 1;
2,267✔
2222
    }
2223
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
2,269✔
2224
                                      count, count, value));
2225
}
2226

2227
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
22✔
2228
                                                 TIFFDirEntry *dir,
2229
                                                 uint16_t tag, uint32_t count,
2230
                                                 uint8_t *value)
2231
{
2232
    assert(sizeof(uint8_t) == 1);
2233
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
22✔
2234
    {
2235
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
11✔
2236
        return 1;
11✔
2237
    }
2238
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
11✔
2239
                                      count, value));
2240
}
2241

2242
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
×
2243
                                                  TIFFDirEntry *dir,
2244
                                                  uint16_t tag, uint32_t count,
2245
                                                  int8_t *value)
2246
{
2247
    assert(sizeof(int8_t) == 1);
2248
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2249
    {
2250
        EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
×
2251
        return 1;
×
2252
    }
2253
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
×
2254
                                      count, value));
2255
}
2256

2257
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
522,999✔
2258
                                             TIFFDirEntry *dir, uint16_t tag,
2259
                                             uint16_t value)
2260
{
2261
    uint16_t m;
2262
    assert(sizeof(uint16_t) == 2);
2263
    if (dir == NULL)
522,999✔
2264
    {
2265
        /* No additional data to IFD data size just increment ndir. */
2266
        (*ndir)++;
261,487✔
2267
        return 1;
261,487✔
2268
    }
2269
    m = value;
261,512✔
2270
    if (tif->tif_flags & TIFF_SWAB)
261,512✔
2271
        TIFFSwabShort(&m);
951✔
2272
    return (
2273
        TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
261,512✔
2274
}
2275

2276
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
162,224✔
2277
                                                  TIFFDirEntry *dir,
2278
                                                  uint16_t tag, uint32_t count,
2279
                                                  uint16_t *value)
2280
{
2281
    assert(count < 0x80000000);
162,224✔
2282
    assert(sizeof(uint16_t) == 2);
2283
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
162,224✔
2284
    {
2285
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
81,087✔
2286
        return 1;
81,084✔
2287
    }
2288
    if (tif->tif_flags & TIFF_SWAB)
81,137✔
2289
        TIFFSwabArrayOfShort(value, count);
363✔
2290
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
81,137✔
2291
                                      count * 2, value));
2292
}
2293

2294
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
×
2295
                                                   TIFFDirEntry *dir,
2296
                                                   uint16_t tag, uint32_t count,
2297
                                                   int16_t *value)
2298
{
2299
    assert(count < 0x80000000);
×
2300
    assert(sizeof(int16_t) == 2);
2301
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2302
    {
2303
        EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
×
2304
        return 1;
×
2305
    }
2306
    if (tif->tif_flags & TIFF_SWAB)
×
2307
        TIFFSwabArrayOfShort((uint16_t *)value, count);
×
2308
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
×
2309
                                      count * 2, value));
2310
}
2311

2312
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
1,818✔
2313
                                            TIFFDirEntry *dir, uint16_t tag,
2314
                                            uint32_t value)
2315
{
2316
    uint32_t m;
2317
    assert(sizeof(uint32_t) == 4);
2318
    if (dir == NULL)
1,818✔
2319
    {
2320
        /* No additional data to IFD data size just increment ndir. */
2321
        (*ndir)++;
909✔
2322
        return 1;
909✔
2323
    }
2324
    m = value;
909✔
2325
    if (tif->tif_flags & TIFF_SWAB)
909✔
2326
        TIFFSwabLong(&m);
41✔
2327
    return (
2328
        TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
909✔
2329
}
2330

2331
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
144,360✔
2332
                                                 TIFFDirEntry *dir,
2333
                                                 uint16_t tag, uint32_t count,
2334
                                                 uint32_t *value)
2335
{
2336
    assert(count < 0x40000000);
144,360✔
2337
    assert(sizeof(uint32_t) == 4);
2338
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
144,360✔
2339
    {
2340
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
72,170✔
2341
        return 1;
72,167✔
2342
    }
2343
    if (tif->tif_flags & TIFF_SWAB)
72,190✔
2344
        TIFFSwabArrayOfLong(value, count);
218✔
2345
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
72,190✔
2346
                                      count * 4, value));
2347
}
2348

2349
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
×
2350
                                                  TIFFDirEntry *dir,
2351
                                                  uint16_t tag, uint32_t count,
2352
                                                  int32_t *value)
2353
{
2354
    assert(count < 0x40000000);
×
2355
    assert(sizeof(int32_t) == 4);
2356
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2357
    {
2358
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
×
2359
        return 1;
×
2360
    }
2361
    if (tif->tif_flags & TIFF_SWAB)
×
2362
        TIFFSwabArrayOfLong((uint32_t *)value, count);
×
2363
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
×
2364
                                      count * 4, value));
2365
}
2366

2367
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
332✔
2368
                                                  TIFFDirEntry *dir,
2369
                                                  uint16_t tag, uint32_t count,
2370
                                                  uint64_t *value)
2371
{
2372
    assert(count < 0x20000000);
332✔
2373
    assert(sizeof(uint64_t) == 8);
2374
    if (!(tif->tif_flags & TIFF_BIGTIFF))
332✔
2375
    {
2376
        TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
×
2377
                      "LONG8 not allowed for ClassicTIFF");
2378
        return (0);
×
2379
    }
2380
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
332✔
2381
    {
2382
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
166✔
2383
        return 1;
166✔
2384
    }
2385
    if (tif->tif_flags & TIFF_SWAB)
166✔
2386
        TIFFSwabArrayOfLong8(value, count);
4✔
2387
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
166✔
2388
                                      count * 8, value));
2389
}
2390

2391
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
×
2392
                                                   TIFFDirEntry *dir,
2393
                                                   uint16_t tag, uint32_t count,
2394
                                                   int64_t *value)
2395
{
2396
    assert(count < 0x20000000);
×
2397
    assert(sizeof(int64_t) == 8);
2398
    if (!(tif->tif_flags & TIFF_BIGTIFF))
×
2399
    {
2400
        TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
×
2401
                      "SLONG8 not allowed for ClassicTIFF");
2402
        return (0);
×
2403
    }
2404
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2405
    {
2406
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
×
2407
        return 1;
×
2408
    }
2409
    if (tif->tif_flags & TIFF_SWAB)
×
2410
        TIFFSwabArrayOfLong8((uint64_t *)value, count);
×
2411
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
×
2412
                                      count * 8, value));
2413
}
2414

2415
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
32✔
2416
                                                TIFFDirEntry *dir, uint16_t tag,
2417
                                                double value)
2418
{
2419
    static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2420
    uint32_t m[2];
2421
    assert(sizeof(uint32_t) == 4);
2422
    if (value < 0)
32✔
2423
    {
2424
        TIFFErrorExtR(tif, module, "Negative value is illegal");
×
2425
        return 0;
×
2426
    }
2427
    else if (value != value)
32✔
2428
    {
2429
        TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
×
2430
        return 0;
×
2431
    }
2432

2433
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
32✔
2434
    {
2435
        tif->tif_dir.td_dirdatasize_write +=
32✔
2436
            (tif->tif_flags & TIFF_BIGTIFF) ? 0 : 0x8U;
16✔
2437
        (*ndir)++;
16✔
2438
        return 1;
16✔
2439
    }
2440

2441
    DoubleToRational(value, &m[0], &m[1]);
16✔
2442

2443
    if (tif->tif_flags & TIFF_SWAB)
16✔
2444
    {
2445
        TIFFSwabLong(&m[0]);
×
2446
        TIFFSwabLong(&m[1]);
×
2447
    }
2448
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
16✔
2449
                                      &m[0]));
2450
}
2451

2452
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
1,686✔
2453
                                                     TIFFDirEntry *dir,
2454
                                                     uint16_t tag,
2455
                                                     uint32_t count,
2456
                                                     float *value)
2457
{
2458
    static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2459
    uint32_t *m;
2460
    float *na;
2461
    uint32_t *nb;
2462
    uint32_t nc;
2463
    int o;
2464
    assert(sizeof(uint32_t) == 4);
2465
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
1,686✔
2466
    {
2467
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
843✔
2468
        return 1;
843✔
2469
    }
2470
    m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
843✔
2471
    if (m == NULL)
843✔
2472
    {
2473
        TIFFErrorExtR(tif, module, "Out of memory");
×
2474
        return (0);
×
2475
    }
2476
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
5,881✔
2477
    {
2478
        DoubleToRational(*na, &nb[0], &nb[1]);
5,038✔
2479
    }
2480
    if (tif->tif_flags & TIFF_SWAB)
843✔
2481
        TIFFSwabArrayOfLong(m, count * 2);
10✔
2482
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
843✔
2483
                                  count * 8, &m[0]);
2484
    _TIFFfreeExt(tif, m);
843✔
2485
    return (o);
843✔
2486
}
2487

2488
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
×
2489
                                                      TIFFDirEntry *dir,
2490
                                                      uint16_t tag,
2491
                                                      uint32_t count,
2492
                                                      float *value)
2493
{
2494
    static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2495
    int32_t *m;
2496
    float *na;
2497
    int32_t *nb;
2498
    uint32_t nc;
2499
    int o;
2500
    assert(sizeof(int32_t) == 4);
2501
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2502
    {
2503
        EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
×
2504
        return 1;
×
2505
    }
2506
    m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
×
2507
    if (m == NULL)
×
2508
    {
2509
        TIFFErrorExtR(tif, module, "Out of memory");
×
2510
        return (0);
×
2511
    }
2512
    for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
×
2513
    {
2514
        DoubleToSrational(*na, &nb[0], &nb[1]);
×
2515
    }
2516
    if (tif->tif_flags & TIFF_SWAB)
×
2517
        TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
×
2518
    o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
×
2519
                                  count * 8, &m[0]);
2520
    _TIFFfreeExt(tif, m);
×
2521
    return (o);
×
2522
}
2523

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

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

2596
/** -----  Rational2Double: Double To Rational Conversion
2597
----------------------------------------------------------
2598
* There is a mathematical theorem to convert real numbers into a rational
2599
(integer fraction) number.
2600
* This is called "continuous fraction" which uses the Euclidean algorithm to
2601
find the greatest common divisor (GCD).
2602
*  (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
2603
https://en.wikipedia.org/wiki/Continued_fraction
2604
*             https://en.wikipedia.org/wiki/Euclidean_algorithm)
2605
* The following functions implement the
2606
* - ToRationalEuclideanGCD()                auxiliary function which mainly
2607
implements euclidean GCD
2608
* - DoubleToRational()                        conversion function for un-signed
2609
rationals
2610
* - DoubleToSrational()                        conversion function for signed rationals
2611
------------------------------------------------------------------------------------------------------------------*/
2612

2613
/**---- ToRationalEuclideanGCD() -----------------------------------------
2614
* Calculates the rational fractional of a double input value
2615
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2616
------------------------------------------------------------------------*/
2617
static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
76✔
2618
                                   int blnUseSmallRange, uint64_t *ullNum,
2619
                                   uint64_t *ullDenom)
2620
{
2621
    /* Internally, the integer variables can be bigger than the external ones,
2622
     * as long as the result will fit into the external variable size.
2623
     */
2624
    uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
76✔
2625
    uint64_t aux, bigNum, bigDenom;
2626
    uint64_t returnLimit;
2627
    int i;
2628
    uint64_t nMax;
2629
    double fMax;
2630
    unsigned long maxDenom;
2631
    /*-- nMax and fMax defines the initial accuracy of the starting fractional,
2632
     *   or better, the highest used integer numbers used within the starting
2633
     * fractional (bigNum/bigDenom). There are two approaches, which can
2634
     * accidentally lead to different accuracies just depending on the value.
2635
     *   Therefore, blnUseSmallRange steers this behavior.
2636
     *   For long long nMax = ((9223372036854775807-1)/2); for long nMax =
2637
     * ((2147483647-1)/2);
2638
     */
2639
    if (blnUseSmallRange)
76✔
2640
    {
2641
        nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
38✔
2642
    }
2643
    else
2644
    {
2645
        nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
38✔
2646
    }
2647
    fMax = (double)nMax;
76✔
2648

2649
    /*-- For the Euclidean GCD define the denominator range, so that it stays
2650
     * within size of unsigned long variables. maxDenom should be LONG_MAX for
2651
     * negative values and ULONG_MAX for positive ones. Also the final returned
2652
     * value of ullNum and ullDenom is limited according to signed- or
2653
     * unsigned-range.
2654
     */
2655
    if (blnUseSignedRange)
76✔
2656
    {
2657
        maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
×
2658
        returnLimit = maxDenom;
×
2659
    }
2660
    else
2661
    {
2662
        maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
76✔
2663
        returnLimit = maxDenom;
76✔
2664
    }
2665

2666
    /*-- First generate a rational fraction (bigNum/bigDenom) which represents
2667
     *the value as a rational number with the highest accuracy. Therefore,
2668
     *uint64_t (uint64_t) is needed. This rational fraction is then reduced
2669
     *using the Euclidean algorithm to find the greatest common divisor (GCD).
2670
     *   bigNum   = big numinator of value without fraction (or cut residual
2671
     *fraction) bigDenom = big denominator of value
2672
     *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
2673
     *and bigDenom has no overflow, and stop with enlargement of fraction when
2674
     *the double-value of it reaches an integer number without fractional part.
2675
     */
2676
    bigDenom = 1;
76✔
2677
    while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
1,902✔
2678
    {
2679
        bigDenom <<= 1;
1,826✔
2680
        value *= 2;
1,826✔
2681
    }
2682
    bigNum = (uint64_t)value;
76✔
2683

2684
    /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
2685
     */
2686
#define MAX_ITERATIONS 64
2687
    for (i = 0; i < MAX_ITERATIONS; i++)
778✔
2688
    {
2689
        uint64_t val;
2690
        /* if bigDenom is not zero, calculate integer part of fraction. */
2691
        if (bigDenom == 0)
778✔
2692
        {
2693
            break;
76✔
2694
        }
2695
        val = bigNum / bigDenom;
702✔
2696

2697
        /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
2698
         * denominator bigDenom. */
2699
        aux = bigNum;
702✔
2700
        bigNum = bigDenom;
702✔
2701
        bigDenom = aux % bigDenom;
702✔
2702

2703
        /* calculate next denominator and check for its given maximum */
2704
        aux = val;
702✔
2705
        if (denomSum[1] * val + denomSum[0] >= maxDenom)
702✔
2706
        {
2707
            aux = (maxDenom - denomSum[0]) / denomSum[1];
×
2708
            if (aux * 2 >= val || denomSum[1] >= maxDenom)
×
2709
                i = (MAX_ITERATIONS +
×
2710
                     1); /* exit but execute rest of for-loop */
2711
            else
2712
                break;
2713
        }
2714
        /* calculate next numerator to numSum2 and save previous one to numSum0;
2715
         * numSum1 just copy of numSum2. */
2716
        numSum[2] = aux * numSum[1] + numSum[0];
702✔
2717
        numSum[0] = numSum[1];
702✔
2718
        numSum[1] = numSum[2];
702✔
2719
        /* calculate next denominator to denomSum2 and save previous one to
2720
         * denomSum0; denomSum1 just copy of denomSum2. */
2721
        denomSum[2] = aux * denomSum[1] + denomSum[0];
702✔
2722
        denomSum[0] = denomSum[1];
702✔
2723
        denomSum[1] = denomSum[2];
702✔
2724
    }
2725

2726
    /*-- Check and adapt for final variable size and return values; reduces
2727
     * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
2728
    while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
76✔
2729
    {
2730
        numSum[1] = numSum[1] / 2;
×
2731
        denomSum[1] = denomSum[1] / 2;
×
2732
    }
2733

2734
    /* return values */
2735
    *ullNum = numSum[1];
76✔
2736
    *ullDenom = denomSum[1];
76✔
2737

2738
} /*-- ToRationalEuclideanGCD() -------------- */
76✔
2739

2740
/**---- DoubleToRational() -----------------------------------------------
2741
* Calculates the rational fractional of a double input value
2742
* for UN-SIGNED rationals,
2743
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2744
------------------------------------------------------------------------*/
2745
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
5,054✔
2746
{
2747
    /*---- UN-SIGNED RATIONAL ---- */
2748
    double dblDiff, dblDiff2;
2749
    uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2750

2751
    /*-- Check for negative values. If so it is an error. */
2752
    /* Test written that way to catch NaN */
2753
    if (!(value >= 0))
5,054✔
2754
    {
2755
        *num = *denom = 0;
×
2756
        TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
×
2757
                     " Negative Value for Unsigned Rational given.");
2758
        return;
5,016✔
2759
    }
2760

2761
    /*-- Check for too big numbers (> ULONG_MAX) -- */
2762
    if (value > 0xFFFFFFFFUL)
5,054✔
2763
    {
2764
        *num = 0xFFFFFFFFU;
×
2765
        *denom = 0;
×
2766
        return;
×
2767
    }
2768
    /*-- Check for easy integer numbers -- */
2769
    if (value == (uint32_t)(value))
5,054✔
2770
    {
2771
        *num = (uint32_t)value;
5,016✔
2772
        *denom = 1;
5,016✔
2773
        return;
5,016✔
2774
    }
2775
    /*-- Check for too small numbers for "unsigned long" type rationals -- */
2776
    if (value < 1.0 / (double)0xFFFFFFFFUL)
38✔
2777
    {
2778
        *num = 0;
×
2779
        *denom = 0xFFFFFFFFU;
×
2780
        return;
×
2781
    }
2782

2783
    /*-- There are two approaches using the Euclidean algorithm,
2784
     *   which can accidentally lead to different accuracies just depending on
2785
     * the value. Try both and define which one was better.
2786
     */
2787
    ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
38✔
2788
    ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
38✔
2789
    /*-- Double-Check, that returned values fit into ULONG :*/
2790
    if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
38✔
2791
        ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
38✔
2792
    {
2793
        TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
×
2794
                     " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
2795
                     ", denom=%12" PRIu64 " | num2=%12" PRIu64
2796
                     ", denom2=%12" PRIu64 "",
2797
                     value, ullNum, ullDenom, ullNum2, ullDenom2);
2798
        assert(0);
×
2799
    }
2800

2801
    /* Check, which one has higher accuracy and take that. */
2802
    dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
38✔
2803
    dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
38✔
2804
    if (dblDiff < dblDiff2)
38✔
2805
    {
2806
        *num = (uint32_t)ullNum;
×
2807
        *denom = (uint32_t)ullDenom;
×
2808
    }
2809
    else
2810
    {
2811
        *num = (uint32_t)ullNum2;
38✔
2812
        *denom = (uint32_t)ullDenom2;
38✔
2813
    }
2814
} /*-- DoubleToRational() -------------- */
2815

2816
/**---- DoubleToSrational() -----------------------------------------------
2817
* Calculates the rational fractional of a double input value
2818
* for SIGNED rationals,
2819
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2820
------------------------------------------------------------------------*/
2821
static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
×
2822
{
2823
    /*---- SIGNED RATIONAL ----*/
2824
    int neg = 1;
×
2825
    double dblDiff, dblDiff2;
2826
    uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2827

2828
    /*-- Check for negative values and use then the positive one for internal
2829
     * calculations, but take the sign into account before returning. */
2830
    if (value < 0)
×
2831
    {
2832
        neg = -1;
×
2833
        value = -value;
×
2834
    }
2835

2836
    /*-- Check for too big numbers (> LONG_MAX) -- */
2837
    if (value > 0x7FFFFFFFL)
×
2838
    {
2839
        *num = 0x7FFFFFFFL;
×
2840
        *denom = 0;
×
2841
        return;
×
2842
    }
2843
    /*-- Check for easy numbers -- */
2844
    if (value == (int32_t)(value))
×
2845
    {
2846
        *num = (int32_t)(neg * value);
×
2847
        *denom = 1;
×
2848
        return;
×
2849
    }
2850
    /*-- Check for too small numbers for "long" type rationals -- */
2851
    if (value < 1.0 / (double)0x7FFFFFFFL)
×
2852
    {
2853
        *num = 0;
×
2854
        *denom = 0x7FFFFFFFL;
×
2855
        return;
×
2856
    }
2857

2858
    /*-- There are two approaches using the Euclidean algorithm,
2859
     *   which can accidentally lead to different accuracies just depending on
2860
     * the value. Try both and define which one was better. Furthermore, set
2861
     * behavior of ToRationalEuclideanGCD() to the range of signed-long.
2862
     */
2863
    ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
×
2864
    ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
×
2865
    /*-- Double-Check, that returned values fit into LONG :*/
2866
    if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
×
2867
        ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
×
2868
    {
2869
        TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
×
2870
                     " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
2871
                     ", denom=%12" PRIu64 " | num2=%12" PRIu64
2872
                     ", denom2=%12" PRIu64 "",
2873
                     neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
2874
        assert(0);
×
2875
    }
2876

2877
    /* Check, which one has higher accuracy and take that. */
2878
    dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
×
2879
    dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
×
2880
    if (dblDiff < dblDiff2)
×
2881
    {
2882
        *num = (int32_t)(neg * (long)ullNum);
×
2883
        *denom = (int32_t)ullDenom;
×
2884
    }
2885
    else
2886
    {
2887
        *num = (int32_t)(neg * (long)ullNum2);
×
2888
        *denom = (int32_t)ullDenom2;
×
2889
    }
2890
} /*-- DoubleToSrational() --------------*/
2891

2892
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
×
2893
                                                  TIFFDirEntry *dir,
2894
                                                  uint16_t tag, uint32_t count,
2895
                                                  float *value)
2896
{
2897
    assert(count < 0x40000000);
×
2898
    assert(sizeof(float) == 4);
2899
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2900
    {
2901
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
×
2902
        return 1;
×
2903
    }
2904
    TIFFCvtNativeToIEEEFloat(tif, count, &value);
2905
    if (tif->tif_flags & TIFF_SWAB)
×
2906
        TIFFSwabArrayOfFloat(value, count);
×
2907
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
×
2908
                                      count * 4, value));
2909
}
2910

2911
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
12,022✔
2912
                                                   TIFFDirEntry *dir,
2913
                                                   uint16_t tag, uint32_t count,
2914
                                                   double *value)
2915
{
2916
    assert(count < 0x20000000);
12,022✔
2917
    assert(sizeof(double) == 8);
2918
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
12,022✔
2919
    {
2920
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
6,039✔
2921
        return 1;
6,039✔
2922
    }
2923
    TIFFCvtNativeToIEEEDouble(tif, count, &value);
2924
    if (tif->tif_flags & TIFF_SWAB)
5,983✔
2925
        TIFFSwabArrayOfDouble(value, count);
42✔
2926
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
5,983✔
2927
                                      count * 8, value));
2928
}
2929

2930
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
×
2931
                                                TIFFDirEntry *dir, uint16_t tag,
2932
                                                uint32_t count, uint32_t *value)
2933
{
2934
    assert(count < 0x40000000);
×
2935
    assert(sizeof(uint32_t) == 4);
2936
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2937
    {
2938
        EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
×
2939
        return 1;
×
2940
    }
2941
    if (tif->tif_flags & TIFF_SWAB)
×
2942
        TIFFSwabArrayOfLong(value, count);
×
2943
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
×
2944
                                      count * 4, value));
2945
}
2946

2947
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
×
2948
                                                 TIFFDirEntry *dir,
2949
                                                 uint16_t tag, uint32_t count,
2950
                                                 uint64_t *value)
2951
{
2952
    assert(count < 0x20000000);
×
2953
    assert(sizeof(uint64_t) == 8);
2954
    assert(tif->tif_flags & TIFF_BIGTIFF);
×
2955
    if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
×
2956
    {
2957
        EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
×
2958
        return 1;
×
2959
    }
2960
    if (tif->tif_flags & TIFF_SWAB)
×
2961
        TIFFSwabArrayOfLong8(value, count);
×
2962
    return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
×
2963
                                      count * 8, value));
2964
}
2965

2966
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
429,414✔
2967
                                     TIFFDirEntry *dir, uint16_t tag,
2968
                                     uint16_t datatype, uint32_t count,
2969
                                     uint32_t datalength, void *data)
2970
{
2971
    static const char module[] = "TIFFWriteDirectoryTagData";
2972
    uint32_t m;
2973
    m = 0;
429,414✔
2974
    while (m < (*ndir))
2,538,780✔
2975
    {
2976
        assert(dir[m].tdir_tag != tag);
2,194,240✔
2977
        if (dir[m].tdir_tag > tag)
2,194,240✔
2978
            break;
84,871✔
2979
        m++;
2,109,370✔
2980
    }
2981
    if (m < (*ndir))
429,414✔
2982
    {
2983
        uint32_t n;
2984
        for (n = *ndir; n > m; n--)
290,236✔
2985
            dir[n] = dir[n - 1];
205,366✔
2986
    }
2987
    dir[m].tdir_tag = tag;
429,414✔
2988
    dir[m].tdir_type = datatype;
429,414✔
2989
    dir[m].tdir_count = count;
429,414✔
2990
    dir[m].tdir_offset.toff_long8 = 0;
429,414✔
2991
    if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
429,414✔
2992
    {
2993
        if (data && datalength)
400,106✔
2994
        {
2995
            _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
399,466✔
2996
        }
2997
    }
2998
    else
2999
    {
3000
        uint64_t na, nb;
3001
        na = tif->tif_dataoff;
29,308✔
3002
        nb = na + datalength;
29,308✔
3003
        if (!(tif->tif_flags & TIFF_BIGTIFF))
29,308✔
3004
            nb = (uint32_t)nb;
29,012✔
3005
        if ((nb < na) || (nb < datalength))
29,308✔
3006
        {
3007
            TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
39✔
3008
            return (0);
×
3009
        }
3010
        if (!SeekOK(tif, na))
29,269✔
3011
        {
3012
            TIFFErrorExtR(tif, module, "IO error writing tag data");
1✔
3013
            return (0);
×
3014
        }
3015
        if (datalength >= 0x80000000UL)
29,274✔
3016
        {
3017
            TIFFErrorExtR(tif, module,
×
3018
                          "libtiff does not allow writing more than 2147483647 "
3019
                          "bytes in a tag");
3020
            return (0);
×
3021
        }
3022
        if (!WriteOK(tif, data, (tmsize_t)datalength))
29,274✔
3023
        {
3024
            TIFFErrorExtR(tif, module, "IO error writing tag data");
31✔
3025
            return (0);
30✔
3026
        }
3027
        tif->tif_dataoff = nb;
29,242✔
3028
        if (tif->tif_dataoff & 1)
29,242✔
3029
            tif->tif_dataoff++;
2,414✔
3030
        if (!(tif->tif_flags & TIFF_BIGTIFF))
29,242✔
3031
        {
3032
            uint32_t o;
3033
            o = (uint32_t)na;
28,983✔
3034
            if (tif->tif_flags & TIFF_SWAB)
28,983✔
3035
                TIFFSwabLong(&o);
390✔
3036
            _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
28,983✔
3037
        }
3038
        else
3039
        {
3040
            dir[m].tdir_offset.toff_long8 = na;
259✔
3041
            if (tif->tif_flags & TIFF_SWAB)
259✔
3042
                TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
8✔
3043
        }
3044
    }
3045
    (*ndir)++;
429,355✔
3046
    return (1);
429,355✔
3047
}
3048

3049
/*
3050
 * Link the current directory into the directory chain for the file.
3051
 */
3052
static int TIFFLinkDirectory(TIFF *tif)
36,941✔
3053
{
3054
    static const char module[] = "TIFFLinkDirectory";
3055

3056
    tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
36,941✔
3057

3058
    /*
3059
     * Handle SubIFDs
3060
     */
3061
    if (tif->tif_flags & TIFF_INSUBIFD)
36,939✔
3062
    {
3063
        if (!(tif->tif_flags & TIFF_BIGTIFF))
×
3064
        {
3065
            uint32_t m;
3066
            m = (uint32_t)tif->tif_diroff;
×
3067
            if (tif->tif_flags & TIFF_SWAB)
×
3068
                TIFFSwabLong(&m);
×
3069
            (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
×
3070
            if (!WriteOK(tif, &m, 4))
×
3071
            {
3072
                TIFFErrorExtR(tif, module,
×
3073
                              "Error writing SubIFD directory link");
3074
                return (0);
×
3075
            }
3076
            /*
3077
             * Advance to the next SubIFD or, if this is
3078
             * the last one configured, revert back to the
3079
             * normal directory linkage.
3080
             */
3081
            if (--tif->tif_nsubifd)
×
3082
                tif->tif_subifdoff += 4;
×
3083
            else
3084
                tif->tif_flags &= ~TIFF_INSUBIFD;
×
3085
            return (1);
×
3086
        }
3087
        else
3088
        {
3089
            uint64_t m;
3090
            m = tif->tif_diroff;
×
3091
            if (tif->tif_flags & TIFF_SWAB)
×
3092
                TIFFSwabLong8(&m);
×
3093
            (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
×
3094
            if (!WriteOK(tif, &m, 8))
×
3095
            {
3096
                TIFFErrorExtR(tif, module,
×
3097
                              "Error writing SubIFD directory link");
3098
                return (0);
×
3099
            }
3100
            /*
3101
             * Advance to the next SubIFD or, if this is
3102
             * the last one configured, revert back to the
3103
             * normal directory linkage.
3104
             */
3105
            if (--tif->tif_nsubifd)
×
3106
                tif->tif_subifdoff += 8;
×
3107
            else
3108
                tif->tif_flags &= ~TIFF_INSUBIFD;
×
3109
            return (1);
×
3110
        }
3111
    }
3112

3113
    if (!(tif->tif_flags & TIFF_BIGTIFF))
36,939✔
3114
    {
3115
        uint32_t m;
3116
        uint32_t nextdir;
3117
        m = (uint32_t)(tif->tif_diroff);
36,812✔
3118
        if (tif->tif_flags & TIFF_SWAB)
36,812✔
3119
            TIFFSwabLong(&m);
124✔
3120
        if (tif->tif_header.classic.tiff_diroff == 0)
36,802✔
3121
        {
3122
            /*
3123
             * First directory, overwrite offset in header.
3124
             */
3125
            tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff;
36,180✔
3126
            tif->tif_lastdiroff = tif->tif_diroff;
36,180✔
3127
            (void)TIFFSeekFile(tif, 4, SEEK_SET);
36,180✔
3128
            if (!WriteOK(tif, &m, 4))
36,183✔
3129
            {
3130
                TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
×
3131
                return (0);
36,188✔
3132
            }
3133
            return (1);
36,188✔
3134
        }
3135
        /*
3136
         * Not the first directory, search to the last and append.
3137
         */
3138
        if (tif->tif_lastdiroff != 0)
622✔
3139
        {
3140
            nextdir = (uint32_t)tif->tif_lastdiroff;
413✔
3141
        }
3142
        else
3143
        {
3144
            nextdir = tif->tif_header.classic.tiff_diroff;
209✔
3145
        }
3146

3147
        while (1)
3148
        {
31✔
3149
            uint16_t dircount;
3150
            uint32_t nextnextdir;
3151

3152
            if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
653✔
3153
            {
3154
                TIFFErrorExtR(tif, module, "Error fetching directory count");
×
3155
                return (0);
×
3156
            }
3157
            if (tif->tif_flags & TIFF_SWAB)
653✔
3158
                TIFFSwabShort(&dircount);
33✔
3159
            (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
653✔
3160
            if (!ReadOK(tif, &nextnextdir, 4))
653✔
3161
            {
3162
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
3163
                return (0);
×
3164
            }
3165
            if (tif->tif_flags & TIFF_SWAB)
653✔
3166
                TIFFSwabLong(&nextnextdir);
33✔
3167
            if (nextnextdir == 0)
653✔
3168
            {
3169
                (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
622✔
3170
                if (!WriteOK(tif, &m, 4))
622✔
3171
                {
3172
                    TIFFErrorExtR(tif, module, "Error writing directory link");
×
3173
                    return (0);
×
3174
                }
3175
                tif->tif_lastdiroff = tif->tif_diroff;
622✔
3176
                break;
622✔
3177
            }
3178
            nextdir = nextnextdir;
31✔
3179
        }
3180
    }
3181
    else
3182
    {
3183
        uint64_t m;
3184
        uint64_t nextdir;
3185
        m = tif->tif_diroff;
127✔
3186
        if (tif->tif_flags & TIFF_SWAB)
127✔
3187
            TIFFSwabLong8(&m);
4✔
3188
        if (tif->tif_header.big.tiff_diroff == 0)
133✔
3189
        {
3190
            /*
3191
             * First directory, overwrite offset in header.
3192
             */
3193
            tif->tif_header.big.tiff_diroff = tif->tif_diroff;
74✔
3194
            tif->tif_lastdiroff = tif->tif_diroff;
74✔
3195
            (void)TIFFSeekFile(tif, 8, SEEK_SET);
74✔
3196
            if (!WriteOK(tif, &m, 8))
74✔
3197
            {
3198
                TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
×
3199
                return (0);
74✔
3200
            }
3201
            return (1);
74✔
3202
        }
3203
        /*
3204
         * Not the first directory, search to the last and append.
3205
         */
3206
        if (tif->tif_lastdiroff != 0)
59✔
3207
        {
3208
            nextdir = tif->tif_lastdiroff;
55✔
3209
        }
3210
        else
3211
        {
3212
            nextdir = tif->tif_header.big.tiff_diroff;
4✔
3213
        }
3214
        while (1)
3215
        {
×
3216
            uint64_t dircount64;
3217
            uint16_t dircount;
3218
            uint64_t nextnextdir;
3219

3220
            if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
59✔
3221
            {
3222
                TIFFErrorExtR(tif, module, "Error fetching directory count");
×
3223
                return (0);
×
3224
            }
3225
            if (tif->tif_flags & TIFF_SWAB)
59✔
3226
                TIFFSwabLong8(&dircount64);
×
3227
            if (dircount64 > 0xFFFF)
59✔
3228
            {
3229
                TIFFErrorExtR(tif, module,
×
3230
                              "Sanity check on tag count failed, "
3231
                              "likely corrupt TIFF");
3232
                return (0);
×
3233
            }
3234
            dircount = (uint16_t)dircount64;
59✔
3235
            (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
59✔
3236
            if (!ReadOK(tif, &nextnextdir, 8))
59✔
3237
            {
3238
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
3239
                return (0);
×
3240
            }
3241
            if (tif->tif_flags & TIFF_SWAB)
59✔
3242
                TIFFSwabLong8(&nextnextdir);
×
3243
            if (nextnextdir == 0)
59✔
3244
            {
3245
                (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
59✔
3246
                if (!WriteOK(tif, &m, 8))
59✔
3247
                {
3248
                    TIFFErrorExtR(tif, module, "Error writing directory link");
×
3249
                    return (0);
×
3250
                }
3251
                tif->tif_lastdiroff = tif->tif_diroff;
59✔
3252
                break;
59✔
3253
            }
3254
            nextdir = nextnextdir;
×
3255
        }
3256
    }
3257
    return (1);
681✔
3258
}
3259

3260
/************************************************************************/
3261
/*                          TIFFRewriteField()                          */
3262
/*                                                                      */
3263
/*      Rewrite a field in the directory on disk without regard to      */
3264
/*      updating the TIFF directory structure in memory.  Currently     */
3265
/*      only supported for field that already exist in the on-disk      */
3266
/*      directory.  Mainly used for updating stripoffset /              */
3267
/*      stripbytecount values after the directory is already on         */
3268
/*      disk.                                                           */
3269
/*                                                                      */
3270
/*      Returns zero on failure, and one on success.                    */
3271
/************************************************************************/
3272

3273
int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
13,946✔
3274
                      tmsize_t count, void *data)
3275
{
3276
    static const char module[] = "TIFFResetField";
3277
    /* const TIFFField* fip = NULL; */
3278
    uint16_t dircount;
3279
    tmsize_t dirsize;
3280
    uint8_t direntry_raw[20];
3281
    uint16_t entry_tag = 0;
13,946✔
3282
    uint16_t entry_type = 0;
13,946✔
3283
    uint64_t entry_count = 0;
13,946✔
3284
    uint64_t entry_offset = 0;
13,946✔
3285
    int value_in_entry = 0;
13,946✔
3286
    uint64_t read_offset;
3287
    uint8_t *buf_to_write = NULL;
13,946✔
3288
    TIFFDataType datatype;
3289

3290
    /* -------------------------------------------------------------------- */
3291
    /*      Find field definition.                                          */
3292
    /* -------------------------------------------------------------------- */
3293
    /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
13,946✔
3294

3295
    /* -------------------------------------------------------------------- */
3296
    /*      Do some checking this is a straight forward case.               */
3297
    /* -------------------------------------------------------------------- */
3298
    if (isMapped(tif))
13,946✔
3299
    {
3300
        TIFFErrorExtR(tif, module,
×
3301
                      "Memory mapped files not currently supported for "
3302
                      "this operation.");
3303
        return 0;
×
3304
    }
3305

3306
    if (tif->tif_diroff == 0)
13,946✔
3307
    {
3308
        TIFFErrorExtR(
×
3309
            tif, module,
3310
            "Attempt to reset field on directory not already on disk.");
3311
        return 0;
×
3312
    }
3313

3314
    /* -------------------------------------------------------------------- */
3315
    /*      Read the directory entry count.                                 */
3316
    /* -------------------------------------------------------------------- */
3317
    if (!SeekOK(tif, tif->tif_diroff))
13,946✔
3318
    {
3319
        TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
×
3320
                      tif->tif_name);
3321
        return 0;
×
3322
    }
3323

3324
    read_offset = tif->tif_diroff;
13,946✔
3325

3326
    if (!(tif->tif_flags & TIFF_BIGTIFF))
13,946✔
3327
    {
3328
        if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
13,736✔
3329
        {
3330
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
×
3331
                          tif->tif_name);
3332
            return 0;
×
3333
        }
3334
        if (tif->tif_flags & TIFF_SWAB)
13,736✔
3335
            TIFFSwabShort(&dircount);
204✔
3336
        dirsize = 12;
13,736✔
3337
        read_offset += 2;
13,736✔
3338
    }
3339
    else
3340
    {
3341
        uint64_t dircount64;
3342
        if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
210✔
3343
        {
3344
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
×
3345
                          tif->tif_name);
3346
            return 0;
×
3347
        }
3348
        if (tif->tif_flags & TIFF_SWAB)
210✔
3349
            TIFFSwabLong8(&dircount64);
×
3350
        dircount = (uint16_t)dircount64;
210✔
3351
        dirsize = 20;
210✔
3352
        read_offset += 8;
210✔
3353
    }
3354

3355
    /* -------------------------------------------------------------------- */
3356
    /*      Read through directory to find target tag.                      */
3357
    /* -------------------------------------------------------------------- */
3358
    while (dircount > 0)
118,122✔
3359
    {
3360
        if (!ReadOK(tif, direntry_raw, dirsize))
118,122✔
3361
        {
3362
            TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
×
3363
                          tif->tif_name);
3364
            return 0;
×
3365
        }
3366

3367
        memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
118,122✔
3368
        if (tif->tif_flags & TIFF_SWAB)
118,122✔
3369
            TIFFSwabShort(&entry_tag);
1,882✔
3370

3371
        if (entry_tag == tag)
118,122✔
3372
            break;
13,946✔
3373

3374
        read_offset += dirsize;
104,176✔
3375
    }
3376

3377
    if (entry_tag != tag)
13,946✔
3378
    {
3379
        TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
×
3380
                      tif->tif_name, tag);
3381
        return 0;
×
3382
    }
3383

3384
    /* -------------------------------------------------------------------- */
3385
    /*      Extract the type, count and offset for this entry.              */
3386
    /* -------------------------------------------------------------------- */
3387
    memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
13,946✔
3388
    if (tif->tif_flags & TIFF_SWAB)
13,946✔
3389
        TIFFSwabShort(&entry_type);
204✔
3390

3391
    if (!(tif->tif_flags & TIFF_BIGTIFF))
13,946✔
3392
    {
3393
        uint32_t value;
3394

3395
        memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
13,736✔
3396
        if (tif->tif_flags & TIFF_SWAB)
13,736✔
3397
            TIFFSwabLong(&value);
204✔
3398
        entry_count = value;
13,736✔
3399

3400
        memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
13,736✔
3401
        if (tif->tif_flags & TIFF_SWAB)
13,736✔
3402
            TIFFSwabLong(&value);
204✔
3403
        entry_offset = value;
13,736✔
3404
    }
3405
    else
3406
    {
3407
        memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
210✔
3408
        if (tif->tif_flags & TIFF_SWAB)
210✔
3409
            TIFFSwabLong8(&entry_count);
×
3410

3411
        memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
210✔
3412
        if (tif->tif_flags & TIFF_SWAB)
210✔
3413
            TIFFSwabLong8(&entry_offset);
×
3414
    }
3415

3416
    /* -------------------------------------------------------------------- */
3417
    /*      When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
3418
    /* -------------------------------------------------------------------- */
3419
    if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
13,946✔
3420
    {
3421
        if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
624✔
3422
        {
3423
            entry_type =
312✔
3424
                (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
312✔
3425
        }
3426
        else
3427
        {
3428
            int write_aslong8 = 1;
312✔
3429
            if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
312✔
3430
            {
3431
                write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
10✔
3432
            }
3433
            else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
302✔
3434
            {
3435
                write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
94✔
3436
            }
3437
            if (write_aslong8)
312✔
3438
            {
3439
                entry_type = TIFF_LONG8;
208✔
3440
            }
3441
            else
3442
            {
3443
                int write_aslong4 = 1;
104✔
3444
                if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
104✔
3445
                {
3446
                    write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
10✔
3447
                }
3448
                else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
94✔
3449
                {
3450
                    write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
94✔
3451
                }
3452
                if (write_aslong4)
104✔
3453
                {
3454
                    entry_type = TIFF_LONG;
76✔
3455
                }
3456
                else
3457
                {
3458
                    entry_type = TIFF_SHORT;
28✔
3459
                }
3460
            }
3461
        }
3462
    }
3463

3464
    /* -------------------------------------------------------------------- */
3465
    /*      What data type do we want to write this as?                     */
3466
    /* -------------------------------------------------------------------- */
3467
    if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
13,946✔
3468
    {
3469
        if (in_datatype == TIFF_LONG8)
13,736✔
3470
            datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
13,736✔
3471
        else if (in_datatype == TIFF_SLONG8)
×
3472
            datatype = TIFF_SLONG;
×
3473
        else if (in_datatype == TIFF_IFD8)
×
3474
            datatype = TIFF_IFD;
×
3475
        else
3476
            datatype = in_datatype;
×
3477
    }
3478
    else
3479
    {
3480
        if (in_datatype == TIFF_LONG8 &&
210✔
3481
            (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
210✔
3482
             entry_type == TIFF_LONG8))
163✔
3483
            datatype = entry_type;
210✔
3484
        else if (in_datatype == TIFF_SLONG8 &&
×
3485
                 (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
×
3486
            datatype = entry_type;
×
3487
        else if (in_datatype == TIFF_IFD8 &&
×
3488
                 (entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
×
3489
            datatype = entry_type;
×
3490
        else
3491
            datatype = in_datatype;
×
3492
    }
3493

3494
    /* -------------------------------------------------------------------- */
3495
    /*      Prepare buffer of actual data to write.  This includes          */
3496
    /*      swabbing as needed.                                             */
3497
    /* -------------------------------------------------------------------- */
3498
    buf_to_write = (uint8_t *)_TIFFCheckMalloc(
13,946✔
3499
        tif, count, TIFFDataWidth(datatype), "for field buffer.");
13,946✔
3500
    if (!buf_to_write)
13,946✔
3501
        return 0;
×
3502

3503
    if (datatype == in_datatype)
13,946✔
3504
        memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
163✔
3505
    else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
13,783✔
3506
    {
×
3507
        tmsize_t i;
3508

3509
        for (i = 0; i < count; i++)
×
3510
        {
3511
            ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
×
3512
            if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
×
3513
            {
3514
                _TIFFfreeExt(tif, buf_to_write);
×
3515
                TIFFErrorExtR(tif, module,
×
3516
                              "Value exceeds 32bit range of output type.");
3517
                return 0;
×
3518
            }
3519
        }
3520
    }
3521
    else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
13,783✔
3522
             (datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
×
3523
    {
11,827✔
3524
        tmsize_t i;
3525

3526
        for (i = 0; i < count; i++)
3,474,190✔
3527
        {
3528
            ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
3,462,360✔
3529
            if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
3,462,360✔
3530
                ((uint64_t *)data)[i])
3,462,360✔
3531
            {
3532
                _TIFFfreeExt(tif, buf_to_write);
×
3533
                TIFFErrorExtR(tif, module,
×
3534
                              "Value exceeds 32bit range of output type.");
3535
                return 0;
×
3536
            }
3537
        }
3538
    }
3539
    else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
1,956✔
3540
    {
1,956✔
3541
        tmsize_t i;
3542

3543
        for (i = 0; i < count; i++)
3,273,910✔
3544
        {
3545
            ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
3,271,960✔
3546
            if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
3,271,960✔
3547
                ((uint64_t *)data)[i])
3,271,960✔
3548
            {
3549
                _TIFFfreeExt(tif, buf_to_write);
×
3550
                TIFFErrorExtR(tif, module,
×
3551
                              "Value exceeds 16bit range of output type.");
3552
                return 0;
×
3553
            }
3554
        }
3555
    }
3556
    else
3557
    {
3558
        TIFFErrorExtR(tif, module, "Unhandled type conversion.");
×
3559
        return 0;
×
3560
    }
3561

3562
    if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
13,946✔
3563
    {
3564
        if (TIFFDataWidth(datatype) == 2)
204✔
3565
            TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
36✔
3566
        else if (TIFFDataWidth(datatype) == 4)
168✔
3567
            TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
168✔
3568
        else if (TIFFDataWidth(datatype) == 8)
×
3569
            TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
×
3570
    }
3571

3572
    /* -------------------------------------------------------------------- */
3573
    /*      Is this a value that fits into the directory entry?             */
3574
    /* -------------------------------------------------------------------- */
3575
    if (!(tif->tif_flags & TIFF_BIGTIFF))
13,946✔
3576
    {
3577
        if (TIFFDataWidth(datatype) * count <= 4)
13,736✔
3578
        {
3579
            entry_offset = read_offset + 8;
8,860✔
3580
            value_in_entry = 1;
8,860✔
3581
        }
3582
    }
3583
    else
3584
    {
3585
        if (TIFFDataWidth(datatype) * count <= 8)
210✔
3586
        {
3587
            entry_offset = read_offset + 12;
121✔
3588
            value_in_entry = 1;
121✔
3589
        }
3590
    }
3591

3592
    if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
13,946✔
3593
        tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
6,973✔
3594
        tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
743✔
3595
        tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
743✔
3596
    {
3597
        tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
743✔
3598
        tif->tif_dir.td_stripoffset_entry.tdir_count = count;
743✔
3599
    }
3600
    else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
13,203✔
3601
              tag == TIFFTAG_STRIPBYTECOUNTS) &&
6,973✔
3602
             tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
6,973✔
3603
             tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
743✔
3604
             tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
743✔
3605
    {
3606
        tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
743✔
3607
        tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
743✔
3608
    }
3609

3610
    /* -------------------------------------------------------------------- */
3611
    /*      If the tag type, and count match, then we just write it out     */
3612
    /*      over the old values without altering the directory entry at     */
3613
    /*      all.                                                            */
3614
    /* -------------------------------------------------------------------- */
3615
    if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
13,946✔
3616
    {
3617
        if (!SeekOK(tif, entry_offset))
13,322✔
3618
        {
3619
            _TIFFfreeExt(tif, buf_to_write);
×
3620
            TIFFErrorExtR(tif, module,
×
3621
                          "%s: Seek error accessing TIFF directory",
3622
                          tif->tif_name);
3623
            return 0;
×
3624
        }
3625
        if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
13,322✔
3626
        {
3627
            _TIFFfreeExt(tif, buf_to_write);
×
3628
            TIFFErrorExtR(tif, module, "Error writing directory link");
×
3629
            return (0);
×
3630
        }
3631

3632
        _TIFFfreeExt(tif, buf_to_write);
13,322✔
3633
        return 1;
13,322✔
3634
    }
3635

3636
    /* -------------------------------------------------------------------- */
3637
    /*      Otherwise, we write the new tag data at the end of the file.    */
3638
    /* -------------------------------------------------------------------- */
3639
    if (!value_in_entry)
624✔
3640
    {
3641
        entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
203✔
3642

3643
        if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
203✔
3644
        {
3645
            _TIFFfreeExt(tif, buf_to_write);
×
3646
            TIFFErrorExtR(tif, module, "Error writing directory link");
×
3647
            return (0);
×
3648
        }
3649
    }
3650
    else
3651
    {
3652
        if (count * TIFFDataWidth(datatype) == 4)
421✔
3653
        {
3654
            uint32_t value;
3655
            memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
405✔
3656
            entry_offset = value;
405✔
3657
        }
3658
        else
3659
        {
3660
            memcpy(&entry_offset, buf_to_write,
16✔
3661
                   count * TIFFDataWidth(datatype));
16✔
3662
        }
3663
    }
3664

3665
    _TIFFfreeExt(tif, buf_to_write);
624✔
3666
    buf_to_write = 0;
624✔
3667

3668
    /* -------------------------------------------------------------------- */
3669
    /*      Adjust the directory entry.                                     */
3670
    /* -------------------------------------------------------------------- */
3671
    entry_type = datatype;
624✔
3672
    entry_count = (uint64_t)count;
624✔
3673
    memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
624✔
3674
    if (tif->tif_flags & TIFF_SWAB)
624✔
3675
        TIFFSwabShort((uint16_t *)(direntry_raw + 2));
×
3676

3677
    if (!(tif->tif_flags & TIFF_BIGTIFF))
624✔
3678
    {
3679
        uint32_t value;
3680

3681
        value = (uint32_t)entry_count;
592✔
3682
        memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
592✔
3683
        if (tif->tif_flags & TIFF_SWAB)
592✔
3684
            TIFFSwabLong((uint32_t *)(direntry_raw + 4));
×
3685

3686
        value = (uint32_t)entry_offset;
592✔
3687
        memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
592✔
3688
        if (tif->tif_flags & TIFF_SWAB)
592✔
3689
            TIFFSwabLong((uint32_t *)(direntry_raw + 8));
×
3690
    }
3691
    else
3692
    {
3693
        memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
32✔
3694
        if (tif->tif_flags & TIFF_SWAB)
32✔
3695
            TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
×
3696

3697
        memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
32✔
3698
        if (tif->tif_flags & TIFF_SWAB)
32✔
3699
            TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
×
3700
    }
3701

3702
    /* -------------------------------------------------------------------- */
3703
    /*      Write the directory entry out to disk.                          */
3704
    /* -------------------------------------------------------------------- */
3705
    if (!SeekOK(tif, read_offset))
624✔
3706
    {
3707
        TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
×
3708
                      tif->tif_name);
3709
        return 0;
×
3710
    }
3711

3712
    if (!WriteOK(tif, direntry_raw, dirsize))
624✔
3713
    {
3714
        TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
×
3715
                      tif->tif_name);
3716
        return 0;
×
3717
    }
3718

3719
    return 1;
624✔
3720
}
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