Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tiff/libtiff/tif_dirwrite.c
4391 views
1
/*
2
* Copyright (c) 1988-1997 Sam Leffler
3
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
4
*
5
* Permission to use, copy, modify, distribute, and sell this software and
6
* its documentation for any purpose is hereby granted without fee, provided
7
* that (i) the above copyright notices and this permission notice appear in
8
* all copies of the software and related documentation, and (ii) the names of
9
* Sam Leffler and Silicon Graphics may not be used in any advertising or
10
* publicity relating to the software without the specific, prior written
11
* permission of Sam Leffler and Silicon Graphics.
12
*
13
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
*
17
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
* OF THIS SOFTWARE.
23
*/
24
25
/*
26
* TIFF Library.
27
*
28
* Directory Write Support Routines.
29
*/
30
#include "tiffiop.h"
31
#include <float.h> /*--: for Rational2Double */
32
#include <math.h> /*--: for Rational2Double */
33
34
#ifdef HAVE_IEEEFP
35
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
36
#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
37
#else
38
extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
39
extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
40
#endif
41
42
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
43
uint64_t *pdiroff);
44
45
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
46
TIFFDirEntry *dir,
47
uint16_t tag, uint32_t count,
48
double *value);
49
50
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
51
TIFFDirEntry *dir, uint16_t tag,
52
uint32_t count, char *value);
53
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
54
TIFFDirEntry *dir, uint16_t tag,
55
uint32_t count, uint8_t *value);
56
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
57
TIFFDirEntry *dir, uint16_t tag,
58
uint32_t count, uint8_t *value);
59
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
60
TIFFDirEntry *dir, uint16_t tag,
61
uint32_t count, int8_t *value);
62
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
63
TIFFDirEntry *dir, uint16_t tag,
64
uint16_t value);
65
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
66
TIFFDirEntry *dir, uint16_t tag,
67
uint32_t count, uint16_t *value);
68
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
69
TIFFDirEntry *dir, uint16_t tag,
70
uint16_t value);
71
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
72
TIFFDirEntry *dir, uint16_t tag,
73
uint32_t count, int16_t *value);
74
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
75
TIFFDirEntry *dir, uint16_t tag,
76
uint32_t value);
77
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
78
TIFFDirEntry *dir, uint16_t tag,
79
uint32_t count, uint32_t *value);
80
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
81
TIFFDirEntry *dir, uint16_t tag,
82
uint32_t count, int32_t *value);
83
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
84
TIFFDirEntry *dir, uint16_t tag,
85
uint32_t count, uint64_t *value);
86
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
87
TIFFDirEntry *dir, uint16_t tag,
88
uint32_t count, int64_t *value);
89
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
90
TIFFDirEntry *dir, uint16_t tag,
91
double value);
92
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
93
TIFFDirEntry *dir, uint16_t tag,
94
uint32_t count, float *value);
95
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
96
TIFFDirEntry *dir, uint16_t tag,
97
uint32_t count, float *value);
98
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
99
TIFFDirEntry *dir, uint16_t tag,
100
uint32_t count, float *value);
101
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
102
TIFFDirEntry *dir, uint16_t tag,
103
uint32_t count, double *value);
104
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
105
TIFFDirEntry *dir, uint16_t tag,
106
uint32_t count, uint32_t *value);
107
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
108
TIFFDirEntry *dir, uint16_t tag,
109
uint32_t value);
110
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
111
TIFFDirEntry *dir, uint16_t tag,
112
uint32_t count, uint64_t *value);
113
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
114
TIFFDirEntry *dir, uint16_t tag,
115
uint32_t count, uint64_t *value);
116
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
117
TIFFDirEntry *dir);
118
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
119
TIFFDirEntry *dir);
120
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
121
TIFFDirEntry *dir);
122
123
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
124
TIFFDirEntry *dir, uint16_t tag,
125
uint32_t count, char *value);
126
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
127
TIFFDirEntry *dir,
128
uint16_t tag,
129
uint32_t count,
130
uint8_t *value);
131
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
132
TIFFDirEntry *dir,
133
uint16_t tag, uint32_t count,
134
uint8_t *value);
135
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
136
TIFFDirEntry *dir,
137
uint16_t tag, uint32_t count,
138
int8_t *value);
139
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
140
TIFFDirEntry *dir, uint16_t tag,
141
uint16_t value);
142
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
143
TIFFDirEntry *dir,
144
uint16_t tag, uint32_t count,
145
uint16_t *value);
146
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
147
TIFFDirEntry *dir,
148
uint16_t tag, uint32_t count,
149
int16_t *value);
150
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
151
TIFFDirEntry *dir, uint16_t tag,
152
uint32_t value);
153
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
154
TIFFDirEntry *dir,
155
uint16_t tag, uint32_t count,
156
uint32_t *value);
157
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
158
TIFFDirEntry *dir,
159
uint16_t tag, uint32_t count,
160
int32_t *value);
161
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
162
TIFFDirEntry *dir,
163
uint16_t tag, uint32_t count,
164
uint64_t *value);
165
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
166
TIFFDirEntry *dir,
167
uint16_t tag, uint32_t count,
168
int64_t *value);
169
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
170
TIFFDirEntry *dir, uint16_t tag,
171
double value);
172
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
173
TIFFDirEntry *dir,
174
uint16_t tag,
175
uint32_t count,
176
float *value);
177
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
178
TIFFDirEntry *dir,
179
uint16_t tag,
180
uint32_t count,
181
float *value);
182
183
/*--: Rational2Double: New functions to support true double-precision for custom
184
* rational tag types. */
185
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
186
TIFFDirEntry *dir,
187
uint16_t tag,
188
uint32_t count,
189
double *value);
190
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
191
TIFFDirEntry *dir,
192
uint16_t tag,
193
uint32_t count,
194
double *value);
195
static int
196
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
197
TIFFDirEntry *dir, uint16_t tag,
198
uint32_t count, double *value);
199
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
200
TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
201
double *value);
202
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom);
203
static void DoubleToSrational(double value, int32_t *num, int32_t *denom);
204
205
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
206
TIFFDirEntry *dir,
207
uint16_t tag, uint32_t count,
208
float *value);
209
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
210
TIFFDirEntry *dir,
211
uint16_t tag, uint32_t count,
212
double *value);
213
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
214
TIFFDirEntry *dir, uint16_t tag,
215
uint32_t count,
216
uint32_t *value);
217
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
218
TIFFDirEntry *dir,
219
uint16_t tag, uint32_t count,
220
uint64_t *value);
221
222
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
223
TIFFDirEntry *dir, uint16_t tag,
224
uint16_t datatype, uint32_t count,
225
uint32_t datalength, void *data);
226
227
static int TIFFLinkDirectory(TIFF *);
228
229
/*
230
* Write the contents of the current directory
231
* to the specified file. This routine doesn't
232
* handle overwriting a directory with auxiliary
233
* storage that's been changed.
234
*/
235
int TIFFWriteDirectory(TIFF *tif)
236
{
237
return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
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)
266
{
267
static const char module[] = "TIFFDeferStrileArrayWriting";
268
if (tif->tif_mode == O_RDONLY)
269
{
270
TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
271
return 0;
272
}
273
if (tif->tif_diroff != 0)
274
{
275
TIFFErrorExtR(tif, module, "Directory has already been written");
276
return 0;
277
}
278
279
tif->tif_dir.td_deferstrilearraywriting = TRUE;
280
return 1;
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,
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)
319
return TIFFWriteDirectory(tif);
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;
326
327
if (!(tif->tif_flags & TIFF_BIGTIFF))
328
{
329
if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
330
{
331
tif->tif_header.classic.tiff_diroff = 0;
332
tif->tif_diroff = 0;
333
334
TIFFSeekFile(tif, 4, SEEK_SET);
335
if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
336
{
337
TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
338
return (0);
339
}
340
}
341
else if (tif->tif_diroff > 0xFFFFFFFFU)
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;
352
while (1)
353
{
354
uint16_t dircount;
355
uint32_t nextnextdir;
356
357
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
358
{
359
TIFFErrorExtR(tif, module,
360
"Error fetching directory count");
361
return (0);
362
}
363
if (tif->tif_flags & TIFF_SWAB)
364
TIFFSwabShort(&dircount);
365
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
366
if (!ReadOK(tif, &nextnextdir, 4))
367
{
368
TIFFErrorExtR(tif, module, "Error fetching directory link");
369
return (0);
370
}
371
if (tif->tif_flags & TIFF_SWAB)
372
TIFFSwabLong(&nextnextdir);
373
if (nextnextdir == tif->tif_diroff)
374
{
375
uint32_t m;
376
m = 0;
377
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
378
SEEK_SET);
379
if (!WriteOK(tif, &m, 4))
380
{
381
TIFFErrorExtR(tif, module,
382
"Error writing directory link");
383
return (0);
384
}
385
tif->tif_diroff = 0;
386
/* Force a full-traversal to reach the zeroed pointer */
387
tif->tif_lastdiroff = 0;
388
break;
389
}
390
nextdir = nextnextdir;
391
}
392
}
393
/* Remove skipped offset from IFD loop directory list. */
394
_TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
395
}
396
else
397
{
398
if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
399
{
400
tif->tif_header.big.tiff_diroff = 0;
401
tif->tif_diroff = 0;
402
403
TIFFSeekFile(tif, 8, SEEK_SET);
404
if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8))
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;
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))
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);
466
}
467
468
/*
469
* Now use TIFFWriteDirectorySec() normally.
470
*/
471
return TIFFWriteDirectorySec(tif, isimage, imagedone, pdiroff);
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)
481
{
482
return TIFFRewriteDirectorySec(tif, TRUE, TRUE, NULL);
483
}
484
485
static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
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)
495
return (1);
496
497
_TIFFFillStriles(tif);
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)
505
{
506
if (tif->tif_flags & TIFF_POSTENCODE)
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 */
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)
525
{
526
if (!TIFFFlushData1(tif))
527
{
528
TIFFErrorExtR(tif, module,
529
"Error flushing data before directory write");
530
return (0);
531
}
532
}
533
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
534
{
535
_TIFFfreeExt(tif, tif->tif_rawdata);
536
tif->tif_rawdata = NULL;
537
tif->tif_rawcc = 0;
538
tif->tif_rawdatasize = 0;
539
tif->tif_rawdataoff = 0;
540
tif->tif_rawdataloaded = 0;
541
}
542
tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
543
}
544
545
if (TIFFFieldSet(tif, FIELD_COMPRESSION) &&
546
(tif->tif_dir.td_compression == COMPRESSION_DEFLATE))
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;
553
dirmem = NULL;
554
dirsize = 0;
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;
561
if (dir == NULL)
562
tif->tif_dir.td_dirdatasize_write = 0;
563
if (isimage)
564
{
565
if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
566
{
567
if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
568
TIFFTAG_IMAGEWIDTH,
569
tif->tif_dir.td_imagewidth))
570
goto bad;
571
if (!TIFFWriteDirectoryTagShortLong(
572
tif, &ndir, dir, TIFFTAG_IMAGELENGTH,
573
tif->tif_dir.td_imagelength))
574
goto bad;
575
}
576
if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
577
{
578
if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
579
TIFFTAG_TILEWIDTH,
580
tif->tif_dir.td_tilewidth))
581
goto bad;
582
if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
583
TIFFTAG_TILELENGTH,
584
tif->tif_dir.td_tilelength))
585
goto bad;
586
}
587
if (TIFFFieldSet(tif, FIELD_RESOLUTION))
588
{
589
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
590
TIFFTAG_XRESOLUTION,
591
tif->tif_dir.td_xresolution))
592
goto bad;
593
if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir,
594
TIFFTAG_YRESOLUTION,
595
tif->tif_dir.td_yresolution))
596
goto bad;
597
}
598
if (TIFFFieldSet(tif, FIELD_POSITION))
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))
610
{
611
if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
612
TIFFTAG_SUBFILETYPE,
613
tif->tif_dir.td_subfiletype))
614
goto bad;
615
}
616
if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
617
{
618
if (!TIFFWriteDirectoryTagShortPerSample(
619
tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE,
620
tif->tif_dir.td_bitspersample))
621
goto bad;
622
}
623
if (TIFFFieldSet(tif, FIELD_COMPRESSION))
624
{
625
if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
626
TIFFTAG_COMPRESSION,
627
tif->tif_dir.td_compression))
628
goto bad;
629
}
630
if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
631
{
632
if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
633
TIFFTAG_PHOTOMETRIC,
634
tif->tif_dir.td_photometric))
635
goto bad;
636
}
637
if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
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))
645
{
646
if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
647
TIFFTAG_FILLORDER,
648
tif->tif_dir.td_fillorder))
649
goto bad;
650
}
651
if (TIFFFieldSet(tif, FIELD_ORIENTATION))
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))
659
{
660
if (!TIFFWriteDirectoryTagShort(
661
tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL,
662
tif->tif_dir.td_samplesperpixel))
663
goto bad;
664
}
665
if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
666
{
667
if (!TIFFWriteDirectoryTagShortLong(
668
tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP,
669
tif->tif_dir.td_rowsperstrip))
670
goto bad;
671
}
672
if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
673
{
674
if (!TIFFWriteDirectoryTagShortPerSample(
675
tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE,
676
tif->tif_dir.td_minsamplevalue))
677
goto bad;
678
}
679
if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
680
{
681
if (!TIFFWriteDirectoryTagShortPerSample(
682
tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE,
683
tif->tif_dir.td_maxsamplevalue))
684
goto bad;
685
}
686
if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
687
{
688
if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
689
TIFFTAG_PLANARCONFIG,
690
tif->tif_dir.td_planarconfig))
691
goto bad;
692
}
693
if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
694
{
695
if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
696
TIFFTAG_RESOLUTIONUNIT,
697
tif->tif_dir.td_resolutionunit))
698
goto bad;
699
}
700
if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
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))
708
{
709
if (!isTiled(tif))
710
{
711
if (!TIFFWriteDirectoryTagLongLong8Array(
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(
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))
727
{
728
if (!isTiled(tif))
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 &&
742
!TIFFWriteDirectoryTagLongLong8Array(
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(
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))
758
{
759
if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir))
760
goto bad;
761
}
762
if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES))
763
{
764
if (tif->tif_dir.td_extrasamples)
765
{
766
uint16_t na;
767
uint16_t *nb;
768
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb);
769
if (!TIFFWriteDirectoryTagShortArray(
770
tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb))
771
goto bad;
772
}
773
}
774
if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
775
{
776
if (!TIFFWriteDirectoryTagShortPerSample(
777
tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT,
778
tif->tif_dir.td_sampleformat))
779
goto bad;
780
}
781
if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
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))
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))
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))
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))
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))
819
{
820
if (!TIFFWriteDirectoryTagShortArray(
821
tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2,
822
&tif->tif_dir.td_ycbcrsubsampling[0]))
823
goto bad;
824
}
825
if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
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))
833
{
834
if (!TIFFWriteDirectoryTagRationalArray(
835
tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6,
836
tif->tif_dir.td_refblackwhite))
837
goto bad;
838
}
839
if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
840
{
841
if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir))
842
goto bad;
843
}
844
if (TIFFFieldSet(tif, FIELD_INKNAMES))
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))
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))
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++)
866
{
867
const TIFFField *o;
868
o = tif->tif_fields[n];
869
if ((o->field_bit >= FIELD_CODEC) &&
870
(TIFFFieldSet(tif, o->field_bit)))
871
{
872
switch (o->set_field_type)
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:
890
{
891
uint16_t p;
892
assert(o->field_type == TIFF_SHORT);
893
assert(o->field_readcount == 1);
894
assert(o->field_passcount == 0);
895
TIFFGetField(tif, o->field_tag, &p);
896
if (!TIFFWriteDirectoryTagShort(
897
tif, &ndir, dir, (uint16_t)o->field_tag,
898
p))
899
goto bad;
900
}
901
break;
902
case TIFF_SETGET_UINT32:
903
{
904
uint32_t p;
905
assert(o->field_type == TIFF_LONG);
906
assert(o->field_readcount == 1);
907
assert(o->field_passcount == 0);
908
TIFFGetField(tif, o->field_tag, &p);
909
if (!TIFFWriteDirectoryTagLong(
910
tif, &ndir, dir, (uint16_t)o->field_tag,
911
p))
912
goto bad;
913
}
914
break;
915
case TIFF_SETGET_C32_UINT8:
916
{
917
uint32_t pa;
918
void *pb;
919
assert(o->field_type == TIFF_UNDEFINED);
920
assert(o->field_readcount == TIFF_VARIABLE2);
921
assert(o->field_passcount == 1);
922
TIFFGetField(tif, o->field_tag, &pa, &pb);
923
if (!TIFFWriteDirectoryTagUndefinedArray(
924
tif, &ndir, dir, (uint16_t)o->field_tag,
925
pa, pb))
926
goto bad;
927
}
928
break;
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
}
938
}
939
}
940
}
941
for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
942
{
943
uint16_t tag =
944
(uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
945
uint32_t count = tif->tif_dir.td_customValues[m].count;
946
switch (tif->tif_dir.td_customValues[m].info->field_type)
947
{
948
case TIFF_ASCII:
949
if (!TIFFWriteDirectoryTagAscii(
950
tif, &ndir, dir, tag, count,
951
tif->tif_dir.td_customValues[m].value))
952
goto bad;
953
break;
954
case TIFF_UNDEFINED:
955
if (!TIFFWriteDirectoryTagUndefinedArray(
956
tif, &ndir, dir, tag, count,
957
tif->tif_dir.td_customValues[m].value))
958
goto bad;
959
break;
960
case TIFF_BYTE:
961
if (!TIFFWriteDirectoryTagByteArray(
962
tif, &ndir, dir, tag, count,
963
tif->tif_dir.td_customValues[m].value))
964
goto bad;
965
break;
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:
973
if (!TIFFWriteDirectoryTagShortArray(
974
tif, &ndir, dir, tag, count,
975
tif->tif_dir.td_customValues[m].value))
976
goto bad;
977
break;
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:
985
if (!TIFFWriteDirectoryTagLongArray(
986
tif, &ndir, dir, tag, count,
987
tif->tif_dir.td_customValues[m].value))
988
goto bad;
989
break;
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:
1009
{
1010
/*-- Rational2Double: For Rationals evaluate
1011
* "set_field_type" to determine internal storage size. */
1012
int tv_size;
1013
tv_size = TIFFFieldSetGetSize(
1014
tif->tif_dir.td_customValues[m].info);
1015
if (tv_size == 8)
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(
1026
tif, &ndir, dir, tag, count,
1027
tif->tif_dir.td_customValues[m].value))
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)
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;
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:
1083
if (!TIFFWriteDirectoryTagDoubleArray(
1084
tif, &ndir, dir, tag, count,
1085
tif->tif_dir.td_customValues[m].value))
1086
goto bad;
1087
break;
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)
1107
break;
1108
1109
/* Evaluate IFD data size: Finally, add the size of the IFD tag entries
1110
* themselves. */
1111
if (!(tif->tif_flags & TIFF_BIGTIFF))
1112
tif->tif_dir.td_dirdatasize_write += 2 + ndir * 12 + 4;
1113
else
1114
tif->tif_dir.td_dirdatasize_write += 8 + ndir * 20 + 8;
1115
1116
/* Setup a new directory within first pass. */
1117
dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
1118
if (dir == NULL)
1119
{
1120
TIFFErrorExtR(tif, module, "Out of memory");
1121
goto bad;
1122
}
1123
if (isimage)
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)
1134
{
1135
if (!TIFFLinkDirectory(tif))
1136
goto bad;
1137
}
1138
else if (tif->tif_dir.td_dirdatasize_write >
1139
tif->tif_dir.td_dirdatasize_read)
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));
1164
}
1165
}
1166
/* Return IFD offset */
1167
if (pdiroff != NULL)
1168
*pdiroff = tif->tif_diroff;
1169
if (!(tif->tif_flags & TIFF_BIGTIFF))
1170
dirsize = 2 + ndir * 12 + 4;
1171
else
1172
dirsize = 8 + ndir * 20 + 8;
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;
1178
if (!(tif->tif_flags & TIFF_BIGTIFF))
1179
tif->tif_dataoff = (uint32_t)tif->tif_dataoff;
1180
if ((tif->tif_dataoff < tif->tif_diroff) ||
1181
(tif->tif_dataoff < (uint64_t)dirsize))
1182
{
1183
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
1184
goto bad;
1185
}
1186
if (tif->tif_dataoff & 1)
1187
tif->tif_dataoff++;
1188
} /* while() */
1189
if (isimage)
1190
{
1191
/* For SubIFDs remember offset of SubIFD tag within main IFD.
1192
* However, might be already done in TIFFWriteDirectoryTagSubifd() if
1193
* there are more than one SubIFD. */
1194
if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
1195
{
1196
uint32_t na;
1197
TIFFDirEntry *nb;
1198
for (na = 0, nb = dir;; na++, nb++)
1199
{
1200
if (na == ndir)
1201
{
1202
TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
1203
goto bad;
1204
}
1205
if (nb->tdir_tag == TIFFTAG_SUBIFD)
1206
break;
1207
}
1208
if (!(tif->tif_flags & TIFF_BIGTIFF))
1209
tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8;
1210
else
1211
tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12;
1212
}
1213
}
1214
/* Copy/swab IFD entries from "dir" into "dirmem",
1215
* which is then written to file. */
1216
dirmem = _TIFFmallocExt(tif, dirsize);
1217
if (dirmem == NULL)
1218
{
1219
TIFFErrorExtR(tif, module, "Out of memory");
1220
goto bad;
1221
}
1222
if (!(tif->tif_flags & TIFF_BIGTIFF))
1223
{
1224
uint8_t *n;
1225
uint32_t nTmp;
1226
TIFFDirEntry *o;
1227
n = dirmem;
1228
*(uint16_t *)n = (uint16_t)ndir;
1229
if (tif->tif_flags & TIFF_SWAB)
1230
TIFFSwabShort((uint16_t *)n);
1231
n += 2;
1232
o = dir;
1233
for (m = 0; m < ndir; m++)
1234
{
1235
*(uint16_t *)n = o->tdir_tag;
1236
if (tif->tif_flags & TIFF_SWAB)
1237
TIFFSwabShort((uint16_t *)n);
1238
n += 2;
1239
*(uint16_t *)n = o->tdir_type;
1240
if (tif->tif_flags & TIFF_SWAB)
1241
TIFFSwabShort((uint16_t *)n);
1242
n += 2;
1243
nTmp = (uint32_t)o->tdir_count;
1244
_TIFFmemcpy(n, &nTmp, 4);
1245
if (tif->tif_flags & TIFF_SWAB)
1246
TIFFSwabLong((uint32_t *)n);
1247
n += 4;
1248
/* This is correct. The data has been */
1249
/* swabbed previously in TIFFWriteDirectoryTagData */
1250
_TIFFmemcpy(n, &o->tdir_offset, 4);
1251
n += 4;
1252
o++;
1253
}
1254
nTmp = (uint32_t)tif->tif_nextdiroff;
1255
if (tif->tif_flags & TIFF_SWAB)
1256
TIFFSwabLong(&nTmp);
1257
_TIFFmemcpy(n, &nTmp, 4);
1258
}
1259
else
1260
{
1261
uint8_t *n;
1262
TIFFDirEntry *o;
1263
n = dirmem;
1264
*(uint64_t *)n = ndir;
1265
if (tif->tif_flags & TIFF_SWAB)
1266
TIFFSwabLong8((uint64_t *)n);
1267
n += 8;
1268
o = dir;
1269
for (m = 0; m < ndir; m++)
1270
{
1271
*(uint16_t *)n = o->tdir_tag;
1272
if (tif->tif_flags & TIFF_SWAB)
1273
TIFFSwabShort((uint16_t *)n);
1274
n += 2;
1275
*(uint16_t *)n = o->tdir_type;
1276
if (tif->tif_flags & TIFF_SWAB)
1277
TIFFSwabShort((uint16_t *)n);
1278
n += 2;
1279
_TIFFmemcpy(n, &o->tdir_count, 8);
1280
if (tif->tif_flags & TIFF_SWAB)
1281
TIFFSwabLong8((uint64_t *)n);
1282
n += 8;
1283
_TIFFmemcpy(n, &o->tdir_offset, 8);
1284
n += 8;
1285
o++;
1286
}
1287
_TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
1288
if (tif->tif_flags & TIFF_SWAB)
1289
TIFFSwabLong8((uint64_t *)n);
1290
}
1291
_TIFFfreeExt(tif, dir);
1292
dir = NULL;
1293
if (!SeekOK(tif, tif->tif_diroff))
1294
{
1295
TIFFErrorExtR(tif, module,
1296
"IO error writing directory at seek to offset");
1297
goto bad;
1298
}
1299
if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
1300
{
1301
TIFFErrorExtR(tif, module, "IO error writing directory");
1302
goto bad;
1303
}
1304
_TIFFfreeExt(tif, dirmem);
1305
1306
/* Increment tif_curdir if IFD wasn't already written to file and no error
1307
* occurred during IFD writing above. */
1308
if (isimage && !tif->tif_dir.td_iswrittentofile)
1309
{
1310
if (!((tif->tif_flags & TIFF_INSUBIFD) &&
1311
!(TIFFFieldSet(tif, FIELD_SUBIFD))))
1312
{
1313
/*-- Normal main-IFD case --*/
1314
if (tif->tif_curdircount != TIFF_NON_EXISTENT_DIR_NUMBER)
1315
{
1316
tif->tif_curdir = tif->tif_curdircount;
1317
}
1318
else
1319
{
1320
/*ToDo SU: NEW_IFD_CURDIR_INCREMENTING: Delete this
1321
* unexpected case after some testing time. */
1322
/* Attention: tif->tif_curdircount is already set within
1323
* TIFFNumberOfDirectories() */
1324
tif->tif_curdircount = TIFFNumberOfDirectories(tif);
1325
tif->tif_curdir = tif->tif_curdircount;
1326
TIFFErrorExtR(
1327
tif, module,
1328
"tif_curdircount is TIFF_NON_EXISTENT_DIR_NUMBER, "
1329
"not expected !! Line %d",
1330
__LINE__);
1331
goto bad;
1332
}
1333
}
1334
else
1335
{
1336
/*-- SubIFD case -- */
1337
/* tif_curdir is always set to 0 for all SubIFDs. */
1338
tif->tif_curdir = 0;
1339
}
1340
}
1341
/* Increment tif_curdircount only if main-IFD of an image was not already
1342
* present on file. */
1343
/* Check in combination with (... && !(TIFFFieldSet(tif, FIELD_SUBIFD)))
1344
* is necessary here because TIFF_INSUBIFD was already set above for the
1345
* next SubIFD when this main-IFD (with FIELD_SUBIFD) is currently being
1346
* written. */
1347
if (isimage && !tif->tif_dir.td_iswrittentofile &&
1348
!((tif->tif_flags & TIFF_INSUBIFD) &&
1349
!(TIFFFieldSet(tif, FIELD_SUBIFD))))
1350
tif->tif_curdircount++;
1351
1352
tif->tif_dir.td_iswrittentofile = TRUE;
1353
1354
/* Reset SubIFD writing stage after last SubIFD has been written. */
1355
if (imagedone && (tif->tif_flags & TIFF_INSUBIFD) && tif->tif_nsubifd == 0)
1356
tif->tif_flags &= ~TIFF_INSUBIFD;
1357
1358
/* Add or update this directory to the IFD list. */
1359
if (!_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, tif->tif_diroff))
1360
{
1361
TIFFErrorExtR(tif, module,
1362
"Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1363
") might cause an IFD loop",
1364
tif->tif_curdir, tif->tif_diroff, tif->tif_diroff);
1365
}
1366
1367
if (imagedone)
1368
{
1369
TIFFFreeDirectory(tif);
1370
tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1371
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
1372
(*tif->tif_cleanup)(tif);
1373
/* Reset directory-related state for subsequent directories. */
1374
TIFFCreateDirectory(tif);
1375
}
1376
else
1377
{
1378
/* IFD is only checkpointed to file (or a custom IFD like EXIF is
1379
* written), thus set IFD data size written to file. */
1380
tif->tif_dir.td_dirdatasize_read = tif->tif_dir.td_dirdatasize_write;
1381
}
1382
return (1);
1383
bad:
1384
if (dir != NULL)
1385
_TIFFfreeExt(tif, dir);
1386
if (dirmem != NULL)
1387
_TIFFfreeExt(tif, dirmem);
1388
return (0);
1389
}
1390
1391
static int8_t TIFFClampDoubleToInt8(double val)
1392
{
1393
if (val > 127)
1394
return 127;
1395
if (val < -128 || val != val)
1396
return -128;
1397
return (int8_t)val;
1398
}
1399
1400
static int16_t TIFFClampDoubleToInt16(double val)
1401
{
1402
if (val > 32767)
1403
return 32767;
1404
if (val < -32768 || val != val)
1405
return -32768;
1406
return (int16_t)val;
1407
}
1408
1409
static int32_t TIFFClampDoubleToInt32(double val)
1410
{
1411
if (val > 0x7FFFFFFF)
1412
return 0x7FFFFFFF;
1413
if (val < -0x7FFFFFFF - 1 || val != val)
1414
return -0x7FFFFFFF - 1;
1415
return (int32_t)val;
1416
}
1417
1418
static uint8_t TIFFClampDoubleToUInt8(double val)
1419
{
1420
if (val < 0)
1421
return 0;
1422
if (val > 255 || val != val)
1423
return 255;
1424
return (uint8_t)val;
1425
}
1426
1427
static uint16_t TIFFClampDoubleToUInt16(double val)
1428
{
1429
if (val < 0)
1430
return 0;
1431
if (val > 65535 || val != val)
1432
return 65535;
1433
return (uint16_t)val;
1434
}
1435
1436
static uint32_t TIFFClampDoubleToUInt32(double val)
1437
{
1438
if (val < 0)
1439
return 0;
1440
if (val > 0xFFFFFFFFU || val != val)
1441
return 0xFFFFFFFFU;
1442
return (uint32_t)val;
1443
}
1444
1445
static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
1446
TIFFDirEntry *dir,
1447
uint16_t tag, uint32_t count,
1448
double *value)
1449
{
1450
static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
1451
void *conv;
1452
uint32_t i;
1453
int ok;
1454
conv = _TIFFmallocExt(tif, count * sizeof(double));
1455
if (conv == NULL)
1456
{
1457
TIFFErrorExtR(tif, module, "Out of memory");
1458
return (0);
1459
}
1460
1461
switch (tif->tif_dir.td_sampleformat)
1462
{
1463
case SAMPLEFORMAT_IEEEFP:
1464
if (tif->tif_dir.td_bitspersample <= 32)
1465
{
1466
for (i = 0; i < count; ++i)
1467
((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
1468
ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count,
1469
(float *)conv);
1470
}
1471
else
1472
{
1473
ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
1474
count, value);
1475
}
1476
break;
1477
case SAMPLEFORMAT_INT:
1478
if (tif->tif_dir.td_bitspersample <= 8)
1479
{
1480
for (i = 0; i < count; ++i)
1481
((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]);
1482
ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count,
1483
(int8_t *)conv);
1484
}
1485
else if (tif->tif_dir.td_bitspersample <= 16)
1486
{
1487
for (i = 0; i < count; ++i)
1488
((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]);
1489
ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag,
1490
count, (int16_t *)conv);
1491
}
1492
else
1493
{
1494
for (i = 0; i < count; ++i)
1495
((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]);
1496
ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count,
1497
(int32_t *)conv);
1498
}
1499
break;
1500
case SAMPLEFORMAT_UINT:
1501
if (tif->tif_dir.td_bitspersample <= 8)
1502
{
1503
for (i = 0; i < count; ++i)
1504
((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
1505
ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count,
1506
(uint8_t *)conv);
1507
}
1508
else if (tif->tif_dir.td_bitspersample <= 16)
1509
{
1510
for (i = 0; i < count; ++i)
1511
((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
1512
ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count,
1513
(uint16_t *)conv);
1514
}
1515
else
1516
{
1517
for (i = 0; i < count; ++i)
1518
((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
1519
ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count,
1520
(uint32_t *)conv);
1521
}
1522
break;
1523
default:
1524
ok = 0;
1525
}
1526
1527
_TIFFfreeExt(tif, conv);
1528
return (ok);
1529
}
1530
1531
static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
1532
TIFFDirEntry *dir, uint16_t tag,
1533
uint32_t count, char *value)
1534
{
1535
return (
1536
TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
1537
}
1538
1539
static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
1540
TIFFDirEntry *dir, uint16_t tag,
1541
uint32_t count, uint8_t *value)
1542
{
1543
return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
1544
count, value));
1545
}
1546
1547
static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
1548
TIFFDirEntry *dir, uint16_t tag,
1549
uint32_t count, uint8_t *value)
1550
{
1551
return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
1552
value));
1553
}
1554
1555
static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
1556
TIFFDirEntry *dir, uint16_t tag,
1557
uint32_t count, int8_t *value)
1558
{
1559
return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
1560
value));
1561
}
1562
1563
static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
1564
TIFFDirEntry *dir, uint16_t tag,
1565
uint16_t value)
1566
{
1567
return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
1568
}
1569
1570
static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
1571
TIFFDirEntry *dir, uint16_t tag,
1572
uint32_t count, uint16_t *value)
1573
{
1574
return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1575
value));
1576
}
1577
1578
static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
1579
TIFFDirEntry *dir, uint16_t tag,
1580
uint16_t value)
1581
{
1582
static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1583
uint16_t *m;
1584
uint16_t *na;
1585
uint16_t nb;
1586
int o;
1587
if (dir == NULL)
1588
{
1589
/* only evaluate IFD data size and inc. ndir */
1590
return (TIFFWriteDirectoryTagCheckedShortArray(
1591
tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, NULL));
1592
}
1593
m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
1594
if (m == NULL)
1595
{
1596
TIFFErrorExtR(tif, module, "Out of memory");
1597
return (0);
1598
}
1599
for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++)
1600
*na = value;
1601
o = TIFFWriteDirectoryTagCheckedShortArray(
1602
tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m);
1603
_TIFFfreeExt(tif, m);
1604
return (o);
1605
}
1606
1607
static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
1608
TIFFDirEntry *dir, uint16_t tag,
1609
uint32_t count, int16_t *value)
1610
{
1611
return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
1612
value));
1613
}
1614
1615
static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
1616
TIFFDirEntry *dir, uint16_t tag,
1617
uint32_t value)
1618
{
1619
return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1620
}
1621
1622
static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
1623
TIFFDirEntry *dir, uint16_t tag,
1624
uint32_t count, uint32_t *value)
1625
{
1626
return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1627
value));
1628
}
1629
1630
static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
1631
TIFFDirEntry *dir, uint16_t tag,
1632
uint32_t count, int32_t *value)
1633
{
1634
return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
1635
value));
1636
}
1637
1638
/************************************************************************/
1639
/* TIFFWriteDirectoryTagLong8Array() */
1640
/* */
1641
/* Write either Long8 or Long array depending on file type. */
1642
/************************************************************************/
1643
static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
1644
TIFFDirEntry *dir, uint16_t tag,
1645
uint32_t count, uint64_t *value)
1646
{
1647
static const char module[] = "TIFFWriteDirectoryTagLong8Array";
1648
uint64_t *ma;
1649
uint32_t mb;
1650
uint32_t *p;
1651
uint32_t *q;
1652
int o;
1653
1654
/* is this just a counting pass? */
1655
if (dir == NULL)
1656
{
1657
/* only evaluate IFD data size and inc. ndir */
1658
return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1659
count, value));
1660
}
1661
1662
/* We always write Long8 for BigTIFF, no checking needed. */
1663
if (tif->tif_flags & TIFF_BIGTIFF)
1664
return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1665
count, value));
1666
1667
/*
1668
** For classic tiff we want to verify everything is in range for long
1669
** and convert to long format.
1670
*/
1671
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1672
if (p == NULL)
1673
{
1674
TIFFErrorExtR(tif, module, "Out of memory");
1675
return (0);
1676
}
1677
1678
for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1679
{
1680
if (*ma > 0xFFFFFFFF)
1681
{
1682
TIFFErrorExtR(tif, module,
1683
"Attempt to write unsigned long value %" PRIu64
1684
" larger than 0xFFFFFFFF for tag %d in Classic TIFF "
1685
"file. TIFF file writing aborted",
1686
*ma, tag);
1687
_TIFFfreeExt(tif, p);
1688
return (0);
1689
}
1690
*q = (uint32_t)(*ma);
1691
}
1692
1693
o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
1694
_TIFFfreeExt(tif, p);
1695
1696
return (o);
1697
}
1698
1699
/************************************************************************/
1700
/* TIFFWriteDirectoryTagSlong8Array() */
1701
/* */
1702
/* Write either SLong8 or SLong array depending on file type. */
1703
/************************************************************************/
1704
static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
1705
TIFFDirEntry *dir, uint16_t tag,
1706
uint32_t count, int64_t *value)
1707
{
1708
static const char module[] = "TIFFWriteDirectoryTagSlong8Array";
1709
int64_t *ma;
1710
uint32_t mb;
1711
int32_t *p;
1712
int32_t *q;
1713
int o;
1714
1715
/* is this just a counting pass? */
1716
if (dir == NULL)
1717
{
1718
/* only evaluate IFD data size and inc. ndir */
1719
return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
1720
count, value));
1721
}
1722
/* We always write SLong8 for BigTIFF, no checking needed. */
1723
if (tif->tif_flags & TIFF_BIGTIFF)
1724
return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag,
1725
count, value));
1726
1727
/*
1728
** For classic tiff we want to verify everything is in range for signed-long
1729
** and convert to signed-long format.
1730
*/
1731
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1732
if (p == NULL)
1733
{
1734
TIFFErrorExtR(tif, module, "Out of memory");
1735
return (0);
1736
}
1737
1738
for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1739
{
1740
if (*ma > (2147483647))
1741
{
1742
TIFFErrorExtR(tif, module,
1743
"Attempt to write signed long value %" PRIi64
1744
" larger than 0x7FFFFFFF (2147483647) for tag %d in "
1745
"Classic TIFF file. TIFF writing to file aborted",
1746
*ma, tag);
1747
_TIFFfreeExt(tif, p);
1748
return (0);
1749
}
1750
else if (*ma < (-2147483647 - 1))
1751
{
1752
TIFFErrorExtR(tif, module,
1753
"Attempt to write signed long value %" PRIi64
1754
" smaller than 0x80000000 (-2147483648) for tag %d "
1755
"in Classic TIFF file. TIFF writing to file aborted",
1756
*ma, tag);
1757
_TIFFfreeExt(tif, p);
1758
return (0);
1759
}
1760
*q = (int32_t)(*ma);
1761
}
1762
1763
o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p);
1764
_TIFFfreeExt(tif, p);
1765
1766
return (o);
1767
}
1768
1769
static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
1770
TIFFDirEntry *dir, uint16_t tag,
1771
double value)
1772
{
1773
return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
1774
}
1775
1776
static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
1777
TIFFDirEntry *dir, uint16_t tag,
1778
uint32_t count, float *value)
1779
{
1780
return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
1781
count, value));
1782
}
1783
1784
static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
1785
TIFFDirEntry *dir, uint16_t tag,
1786
uint32_t count, float *value)
1787
{
1788
return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
1789
count, value));
1790
}
1791
1792
/*-- Rational2Double: additional write functions */
1793
static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
1794
TIFFDirEntry *dir,
1795
uint16_t tag,
1796
uint32_t count,
1797
double *value)
1798
{
1799
return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
1800
count, value));
1801
}
1802
1803
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
1804
TIFFDirEntry *dir,
1805
uint16_t tag,
1806
uint32_t count,
1807
double *value)
1808
{
1809
return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
1810
tif, ndir, dir, tag, count, value));
1811
}
1812
1813
static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
1814
TIFFDirEntry *dir, uint16_t tag,
1815
uint32_t count, float *value)
1816
{
1817
return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
1818
value));
1819
}
1820
1821
static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
1822
TIFFDirEntry *dir, uint16_t tag,
1823
uint32_t count, double *value)
1824
{
1825
return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
1826
value));
1827
}
1828
1829
static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
1830
TIFFDirEntry *dir, uint16_t tag,
1831
uint32_t count, uint32_t *value)
1832
{
1833
return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
1834
value));
1835
}
1836
1837
static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
1838
TIFFDirEntry *dir, uint16_t tag,
1839
uint32_t value)
1840
{
1841
if (value <= 0xFFFF)
1842
return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag,
1843
(uint16_t)value));
1844
else
1845
return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1846
}
1847
1848
static int _WriteAsType(TIFF *tif, uint64_t strile_size,
1849
uint64_t uncompressed_threshold)
1850
{
1851
const uint16_t compression = tif->tif_dir.td_compression;
1852
if (compression == COMPRESSION_NONE)
1853
{
1854
return strile_size > uncompressed_threshold;
1855
}
1856
else if (compression == COMPRESSION_JPEG ||
1857
compression == COMPRESSION_LZW ||
1858
compression == COMPRESSION_ADOBE_DEFLATE ||
1859
compression == COMPRESSION_DEFLATE ||
1860
compression == COMPRESSION_LZMA ||
1861
compression == COMPRESSION_LERC ||
1862
compression == COMPRESSION_ZSTD ||
1863
compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL)
1864
{
1865
/* For a few select compression types, we assume that in the worst */
1866
/* case the compressed size will be 10 times the uncompressed size. */
1867
/* This is overly pessismistic ! */
1868
return strile_size >= uncompressed_threshold / 10;
1869
}
1870
return 1;
1871
}
1872
1873
static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
1874
{
1875
return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
1876
}
1877
1878
static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
1879
{
1880
return _WriteAsType(tif, strile_size, 0xFFFFU);
1881
}
1882
1883
/************************************************************************/
1884
/* TIFFWriteDirectoryTagLongLong8Array() */
1885
/* */
1886
/* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */
1887
/* on strile size and Classic/BigTIFF mode. */
1888
/************************************************************************/
1889
1890
static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
1891
TIFFDirEntry *dir, uint16_t tag,
1892
uint32_t count, uint64_t *value)
1893
{
1894
static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1895
int o;
1896
int write_aslong4;
1897
1898
if (tif->tif_dir.td_deferstrilearraywriting)
1899
{
1900
if (dir == NULL)
1901
{
1902
/* This is just a counting pass to count IFD entries.
1903
* For deferstrilearraywriting no extra bytes will be written
1904
* into IFD space. */
1905
(*ndir)++;
1906
return 1;
1907
}
1908
return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
1909
NULL);
1910
}
1911
1912
if (tif->tif_flags & TIFF_BIGTIFF)
1913
{
1914
int write_aslong8 = 1;
1915
/* In the case of ByteCounts array, we may be able to write them on LONG
1916
* if the strip/tilesize is not too big. Also do that for count > 1 in
1917
* the case someone would want to create a single-strip file with a
1918
* growing height, in which case using LONG8 will be safer. */
1919
if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1920
{
1921
write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
1922
}
1923
else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1924
{
1925
write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
1926
}
1927
if (write_aslong8)
1928
{
1929
return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1930
count, value);
1931
}
1932
}
1933
1934
write_aslong4 = 1;
1935
if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1936
{
1937
write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
1938
}
1939
else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1940
{
1941
write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1942
}
1943
if (write_aslong4)
1944
{
1945
/*
1946
** For classic tiff we want to verify everything is in range for LONG
1947
** and convert to long format.
1948
*/
1949
1950
uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1951
uint32_t *q;
1952
uint64_t *ma;
1953
uint32_t mb;
1954
1955
if (p == NULL)
1956
{
1957
TIFFErrorExtR(tif, module, "Out of memory");
1958
return (0);
1959
}
1960
1961
for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1962
{
1963
if (*ma > 0xFFFFFFFF)
1964
{
1965
TIFFErrorExtR(tif, module,
1966
"Attempt to write value larger than 0xFFFFFFFF "
1967
"in LONG array.");
1968
_TIFFfreeExt(tif, p);
1969
return (0);
1970
}
1971
*q = (uint32_t)(*ma);
1972
}
1973
1974
o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1975
p);
1976
_TIFFfreeExt(tif, p);
1977
}
1978
else
1979
{
1980
uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
1981
uint16_t *q;
1982
uint64_t *ma;
1983
uint32_t mb;
1984
1985
if (p == NULL)
1986
{
1987
TIFFErrorExtR(tif, module, "Out of memory");
1988
return (0);
1989
}
1990
1991
for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1992
{
1993
if (*ma > 0xFFFF)
1994
{
1995
/* Should not happen normally given the check we did before */
1996
TIFFErrorExtR(tif, module,
1997
"Attempt to write value larger than 0xFFFF in "
1998
"SHORT array.");
1999
_TIFFfreeExt(tif, p);
2000
return (0);
2001
}
2002
*q = (uint16_t)(*ma);
2003
}
2004
2005
o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
2006
p);
2007
_TIFFfreeExt(tif, p);
2008
}
2009
2010
return (o);
2011
}
2012
2013
/************************************************************************/
2014
/* TIFFWriteDirectoryTagIfdIfd8Array() */
2015
/* */
2016
/* Write either IFD8 or IFD array depending on file type. */
2017
/************************************************************************/
2018
2019
static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
2020
TIFFDirEntry *dir, uint16_t tag,
2021
uint32_t count, uint64_t *value)
2022
{
2023
static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
2024
uint64_t *ma;
2025
uint32_t mb;
2026
uint32_t *p;
2027
uint32_t *q;
2028
int o;
2029
2030
/* We always write IFD8 for BigTIFF, no checking needed. */
2031
if (tif->tif_flags & TIFF_BIGTIFF)
2032
return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count,
2033
value);
2034
2035
/*
2036
** For classic tiff we want to verify everything is in range for IFD
2037
** and convert to long format.
2038
*/
2039
2040
p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
2041
if (p == NULL)
2042
{
2043
TIFFErrorExtR(tif, module, "Out of memory");
2044
return (0);
2045
}
2046
2047
for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
2048
{
2049
if (*ma > 0xFFFFFFFF)
2050
{
2051
TIFFErrorExtR(tif, module,
2052
"Attempt to write value larger than 0xFFFFFFFF in "
2053
"Classic TIFF file.");
2054
_TIFFfreeExt(tif, p);
2055
return (0);
2056
}
2057
*q = (uint32_t)(*ma);
2058
}
2059
2060
o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
2061
_TIFFfreeExt(tif, p);
2062
2063
return (o);
2064
}
2065
2066
/*
2067
* Auxiliary function to determine the IFD data size to be written to the file.
2068
* The IFD data size is finally the size of the IFD tag entries plus the IFD
2069
* data that is written directly after the IFD tag entries.
2070
*/
2071
static void EvaluateIFDdatasizeWrite(TIFF *tif, uint32_t count,
2072
uint32_t typesize, uint32_t *ndir)
2073
{
2074
uint64_t datalength = (uint64_t)count * typesize;
2075
if (datalength > ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
2076
{
2077
/* LibTIFF increments write address to an even offset, thus datalength
2078
* written is also incremented. */
2079
if (datalength & 1)
2080
datalength++;
2081
tif->tif_dir.td_dirdatasize_write += datalength;
2082
}
2083
(*ndir)++;
2084
}
2085
2086
static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
2087
TIFFDirEntry *dir)
2088
{
2089
static const char module[] = "TIFFWriteDirectoryTagColormap";
2090
uint32_t m;
2091
uint16_t *n;
2092
int o;
2093
m = (1 << tif->tif_dir.td_bitspersample);
2094
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2095
{
2096
EvaluateIFDdatasizeWrite(tif, 3 * m, sizeof(uint16_t), ndir);
2097
return 1;
2098
}
2099
2100
n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
2101
if (n == NULL)
2102
{
2103
TIFFErrorExtR(tif, module, "Out of memory");
2104
return (0);
2105
}
2106
_TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t));
2107
_TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t));
2108
_TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t));
2109
o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP,
2110
3 * m, n);
2111
_TIFFfreeExt(tif, n);
2112
return (o);
2113
}
2114
2115
static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
2116
TIFFDirEntry *dir)
2117
{
2118
static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
2119
uint32_t m;
2120
uint16_t n;
2121
uint16_t *o;
2122
int p;
2123
/* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
2124
* (1 << BitsPerSample) * uint16_t values.
2125
*/
2126
m = (1 << tif->tif_dir.td_bitspersample);
2127
/* clang-format off */
2128
n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
2129
/* clang-format on */
2130
2131
/* Check for proper number of transferfunctions */
2132
for (int i = 0; i < n; i++)
2133
{
2134
if (tif->tif_dir.td_transferfunction[i] == NULL)
2135
{
2136
TIFFWarningExtR(tif, module,
2137
"Too few TransferFunctions provided. Tag "
2138
"not written to file");
2139
return (1); /* Not an error; only tag is not written. */
2140
}
2141
}
2142
/*
2143
* Check if the table can be written as a single column,
2144
* or if it must be written as 3 columns. Note that we
2145
* write a 3-column tag if there are 2 samples/pixel and
2146
* a single column of data won't suffice--hmm.
2147
*/
2148
if (n == 3)
2149
{
2150
if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2151
tif->tif_dir.td_transferfunction[2],
2152
m * sizeof(uint16_t)) &&
2153
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2154
tif->tif_dir.td_transferfunction[1],
2155
m * sizeof(uint16_t)))
2156
n = 1;
2157
}
2158
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2159
{
2160
EvaluateIFDdatasizeWrite(tif, n * m, 2, ndir);
2161
return 1;
2162
}
2163
2164
o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
2165
if (o == NULL)
2166
{
2167
TIFFErrorExtR(tif, module, "Out of memory");
2168
return (0);
2169
}
2170
_TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
2171
m * sizeof(uint16_t));
2172
if (n > 1)
2173
_TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
2174
m * sizeof(uint16_t));
2175
if (n > 2)
2176
_TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
2177
m * sizeof(uint16_t));
2178
p = TIFFWriteDirectoryTagCheckedShortArray(
2179
tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
2180
_TIFFfreeExt(tif, o);
2181
return (p);
2182
}
2183
2184
static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
2185
TIFFDirEntry *dir)
2186
{
2187
static const char module[] = "TIFFWriteDirectoryTagSubifd";
2188
uint64_t m;
2189
int n;
2190
if (tif->tif_dir.td_nsubifd == 0)
2191
return (1);
2192
m = tif->tif_dataoff;
2193
if (!(tif->tif_flags & TIFF_BIGTIFF))
2194
{
2195
uint32_t *o;
2196
uint64_t *pa;
2197
uint32_t *pb;
2198
uint16_t p;
2199
o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
2200
if (o == NULL)
2201
{
2202
TIFFErrorExtR(tif, module, "Out of memory");
2203
return (0);
2204
}
2205
pa = tif->tif_dir.td_subifd;
2206
pb = o;
2207
for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
2208
{
2209
assert(pa != 0);
2210
2211
/* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
2212
* is illegal) */
2213
if (*pa > 0xFFFFFFFFUL)
2214
{
2215
TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
2216
_TIFFfreeExt(tif, o);
2217
return (0);
2218
}
2219
*pb++ = (uint32_t)(*pa++);
2220
}
2221
n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
2222
tif->tif_dir.td_nsubifd, o);
2223
_TIFFfreeExt(tif, o);
2224
}
2225
else
2226
n = TIFFWriteDirectoryTagCheckedIfd8Array(
2227
tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
2228
tif->tif_dir.td_subifd);
2229
2230
if (dir == NULL)
2231
/* Just have evaluated IFD data size and incremented ndir
2232
* above in sub-functions. */
2233
return (n);
2234
2235
if (!n)
2236
return (0);
2237
/*
2238
* Total hack: if this directory includes a SubIFD
2239
* tag then force the next <n> directories to be
2240
* written as ``sub directories'' of this one. This
2241
* is used to write things like thumbnails and
2242
* image masks that one wants to keep out of the
2243
* normal directory linkage access mechanism.
2244
*/
2245
tif->tif_flags |= TIFF_INSUBIFD;
2246
tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
2247
if (tif->tif_dir.td_nsubifd == 1)
2248
tif->tif_subifdoff = 0;
2249
else
2250
tif->tif_subifdoff = m;
2251
return (1);
2252
}
2253
2254
static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
2255
TIFFDirEntry *dir, uint16_t tag,
2256
uint32_t count, char *value)
2257
{
2258
assert(sizeof(char) == 1);
2259
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2260
{
2261
EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2262
return 1;
2263
}
2264
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
2265
count, value));
2266
}
2267
2268
static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
2269
TIFFDirEntry *dir,
2270
uint16_t tag,
2271
uint32_t count,
2272
uint8_t *value)
2273
{
2274
assert(sizeof(uint8_t) == 1);
2275
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2276
{
2277
EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2278
return 1;
2279
}
2280
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
2281
count, count, value));
2282
}
2283
2284
static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
2285
TIFFDirEntry *dir,
2286
uint16_t tag, uint32_t count,
2287
uint8_t *value)
2288
{
2289
assert(sizeof(uint8_t) == 1);
2290
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2291
{
2292
EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2293
return 1;
2294
}
2295
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
2296
count, value));
2297
}
2298
2299
static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
2300
TIFFDirEntry *dir,
2301
uint16_t tag, uint32_t count,
2302
int8_t *value)
2303
{
2304
assert(sizeof(int8_t) == 1);
2305
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2306
{
2307
EvaluateIFDdatasizeWrite(tif, count, 1, ndir);
2308
return 1;
2309
}
2310
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
2311
count, value));
2312
}
2313
2314
static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
2315
TIFFDirEntry *dir, uint16_t tag,
2316
uint16_t value)
2317
{
2318
uint16_t m;
2319
assert(sizeof(uint16_t) == 2);
2320
if (dir == NULL)
2321
{
2322
/* No additional data to IFD data size just increment ndir. */
2323
(*ndir)++;
2324
return 1;
2325
}
2326
m = value;
2327
if (tif->tif_flags & TIFF_SWAB)
2328
TIFFSwabShort(&m);
2329
return (
2330
TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
2331
}
2332
2333
static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
2334
TIFFDirEntry *dir,
2335
uint16_t tag, uint32_t count,
2336
uint16_t *value)
2337
{
2338
assert(count < 0x80000000);
2339
assert(sizeof(uint16_t) == 2);
2340
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2341
{
2342
EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
2343
return 1;
2344
}
2345
if (tif->tif_flags & TIFF_SWAB)
2346
TIFFSwabArrayOfShort(value, count);
2347
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
2348
count * 2, value));
2349
}
2350
2351
static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
2352
TIFFDirEntry *dir,
2353
uint16_t tag, uint32_t count,
2354
int16_t *value)
2355
{
2356
assert(count < 0x80000000);
2357
assert(sizeof(int16_t) == 2);
2358
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2359
{
2360
EvaluateIFDdatasizeWrite(tif, count, 2, ndir);
2361
return 1;
2362
}
2363
if (tif->tif_flags & TIFF_SWAB)
2364
TIFFSwabArrayOfShort((uint16_t *)value, count);
2365
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
2366
count * 2, value));
2367
}
2368
2369
static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
2370
TIFFDirEntry *dir, uint16_t tag,
2371
uint32_t value)
2372
{
2373
uint32_t m;
2374
assert(sizeof(uint32_t) == 4);
2375
if (dir == NULL)
2376
{
2377
/* No additional data to IFD data size just increment ndir. */
2378
(*ndir)++;
2379
return 1;
2380
}
2381
m = value;
2382
if (tif->tif_flags & TIFF_SWAB)
2383
TIFFSwabLong(&m);
2384
return (
2385
TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
2386
}
2387
2388
static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
2389
TIFFDirEntry *dir,
2390
uint16_t tag, uint32_t count,
2391
uint32_t *value)
2392
{
2393
assert(count < 0x40000000);
2394
assert(sizeof(uint32_t) == 4);
2395
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2396
{
2397
EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2398
return 1;
2399
}
2400
if (tif->tif_flags & TIFF_SWAB)
2401
TIFFSwabArrayOfLong(value, count);
2402
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
2403
count * 4, value));
2404
}
2405
2406
static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
2407
TIFFDirEntry *dir,
2408
uint16_t tag, uint32_t count,
2409
int32_t *value)
2410
{
2411
assert(count < 0x40000000);
2412
assert(sizeof(int32_t) == 4);
2413
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2414
{
2415
EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2416
return 1;
2417
}
2418
if (tif->tif_flags & TIFF_SWAB)
2419
TIFFSwabArrayOfLong((uint32_t *)value, count);
2420
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
2421
count * 4, value));
2422
}
2423
2424
static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
2425
TIFFDirEntry *dir,
2426
uint16_t tag, uint32_t count,
2427
uint64_t *value)
2428
{
2429
assert(count < 0x20000000);
2430
assert(sizeof(uint64_t) == 8);
2431
if (!(tif->tif_flags & TIFF_BIGTIFF))
2432
{
2433
TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
2434
"LONG8 not allowed for ClassicTIFF");
2435
return (0);
2436
}
2437
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2438
{
2439
EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2440
return 1;
2441
}
2442
if (tif->tif_flags & TIFF_SWAB)
2443
TIFFSwabArrayOfLong8(value, count);
2444
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
2445
count * 8, value));
2446
}
2447
2448
static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
2449
TIFFDirEntry *dir,
2450
uint16_t tag, uint32_t count,
2451
int64_t *value)
2452
{
2453
assert(count < 0x20000000);
2454
assert(sizeof(int64_t) == 8);
2455
if (!(tif->tif_flags & TIFF_BIGTIFF))
2456
{
2457
TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
2458
"SLONG8 not allowed for ClassicTIFF");
2459
return (0);
2460
}
2461
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2462
{
2463
EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2464
return 1;
2465
}
2466
if (tif->tif_flags & TIFF_SWAB)
2467
TIFFSwabArrayOfLong8((uint64_t *)value, count);
2468
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
2469
count * 8, value));
2470
}
2471
2472
static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
2473
TIFFDirEntry *dir, uint16_t tag,
2474
double value)
2475
{
2476
static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2477
uint32_t m[2];
2478
assert(sizeof(uint32_t) == 4);
2479
if (value < 0)
2480
{
2481
TIFFErrorExtR(tif, module, "Negative value is illegal");
2482
return 0;
2483
}
2484
else if (value != value)
2485
{
2486
TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
2487
return 0;
2488
}
2489
2490
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2491
{
2492
tif->tif_dir.td_dirdatasize_write +=
2493
(tif->tif_flags & TIFF_BIGTIFF) ? 0 : 0x8U;
2494
(*ndir)++;
2495
return 1;
2496
}
2497
2498
DoubleToRational(value, &m[0], &m[1]);
2499
2500
if (tif->tif_flags & TIFF_SWAB)
2501
{
2502
TIFFSwabLong(&m[0]);
2503
TIFFSwabLong(&m[1]);
2504
}
2505
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
2506
&m[0]));
2507
}
2508
2509
static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
2510
TIFFDirEntry *dir,
2511
uint16_t tag,
2512
uint32_t count,
2513
float *value)
2514
{
2515
static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2516
uint32_t *m;
2517
float *na;
2518
uint32_t *nb;
2519
uint32_t nc;
2520
int o;
2521
assert(sizeof(uint32_t) == 4);
2522
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2523
{
2524
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
2525
return 1;
2526
}
2527
m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2528
if (m == NULL)
2529
{
2530
TIFFErrorExtR(tif, module, "Out of memory");
2531
return (0);
2532
}
2533
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2534
{
2535
DoubleToRational(*na, &nb[0], &nb[1]);
2536
}
2537
if (tif->tif_flags & TIFF_SWAB)
2538
TIFFSwabArrayOfLong(m, count * 2);
2539
o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2540
count * 8, &m[0]);
2541
_TIFFfreeExt(tif, m);
2542
return (o);
2543
}
2544
2545
static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
2546
TIFFDirEntry *dir,
2547
uint16_t tag,
2548
uint32_t count,
2549
float *value)
2550
{
2551
static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2552
int32_t *m;
2553
float *na;
2554
int32_t *nb;
2555
uint32_t nc;
2556
int o;
2557
assert(sizeof(int32_t) == 4);
2558
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2559
{
2560
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
2561
return 1;
2562
}
2563
m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2564
if (m == NULL)
2565
{
2566
TIFFErrorExtR(tif, module, "Out of memory");
2567
return (0);
2568
}
2569
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2570
{
2571
DoubleToSrational(*na, &nb[0], &nb[1]);
2572
}
2573
if (tif->tif_flags & TIFF_SWAB)
2574
TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2575
o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2576
count * 8, &m[0]);
2577
_TIFFfreeExt(tif, m);
2578
return (o);
2579
}
2580
2581
/*-- Rational2Double: additional write functions for double arrays */
2582
static int
2583
TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
2584
TIFFDirEntry *dir, uint16_t tag,
2585
uint32_t count, double *value)
2586
{
2587
static const char module[] =
2588
"TIFFWriteDirectoryTagCheckedRationalDoubleArray";
2589
uint32_t *m;
2590
double *na;
2591
uint32_t *nb;
2592
uint32_t nc;
2593
int o;
2594
assert(sizeof(uint32_t) == 4);
2595
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2596
{
2597
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(uint32_t), ndir);
2598
return 1;
2599
}
2600
m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2601
if (m == NULL)
2602
{
2603
TIFFErrorExtR(tif, module, "Out of memory");
2604
return (0);
2605
}
2606
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2607
{
2608
DoubleToRational(*na, &nb[0], &nb[1]);
2609
}
2610
if (tif->tif_flags & TIFF_SWAB)
2611
TIFFSwabArrayOfLong(m, count * 2);
2612
o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2613
count * 8, &m[0]);
2614
_TIFFfreeExt(tif, m);
2615
return (o);
2616
} /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
2617
2618
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
2619
TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
2620
double *value)
2621
{
2622
static const char module[] =
2623
"TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
2624
int32_t *m;
2625
double *na;
2626
int32_t *nb;
2627
uint32_t nc;
2628
int o;
2629
assert(sizeof(int32_t) == 4);
2630
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2631
{
2632
EvaluateIFDdatasizeWrite(tif, count * 2, sizeof(int32_t), ndir);
2633
return 1;
2634
}
2635
m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2636
if (m == NULL)
2637
{
2638
TIFFErrorExtR(tif, module, "Out of memory");
2639
return (0);
2640
}
2641
for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2642
{
2643
DoubleToSrational(*na, &nb[0], &nb[1]);
2644
}
2645
if (tif->tif_flags & TIFF_SWAB)
2646
TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2647
o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2648
count * 8, &m[0]);
2649
_TIFFfreeExt(tif, m);
2650
return (o);
2651
} /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
2652
2653
/** ----- Rational2Double: Double To Rational Conversion
2654
----------------------------------------------------------
2655
* There is a mathematical theorem to convert real numbers into a rational
2656
(integer fraction) number.
2657
* This is called "continuous fraction" which uses the Euclidean algorithm to
2658
find the greatest common divisor (GCD).
2659
* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
2660
https://en.wikipedia.org/wiki/Continued_fraction
2661
* https://en.wikipedia.org/wiki/Euclidean_algorithm)
2662
* The following functions implement the
2663
* - ToRationalEuclideanGCD() auxiliary function which mainly
2664
implements euclidean GCD
2665
* - DoubleToRational() conversion function for un-signed
2666
rationals
2667
* - DoubleToSrational() conversion function for signed rationals
2668
------------------------------------------------------------------------------------------------------------------*/
2669
2670
/**---- ToRationalEuclideanGCD() -----------------------------------------
2671
* Calculates the rational fractional of a double input value
2672
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2673
------------------------------------------------------------------------*/
2674
static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
2675
int blnUseSmallRange, uint64_t *ullNum,
2676
uint64_t *ullDenom)
2677
{
2678
/* Internally, the integer variables can be bigger than the external ones,
2679
* as long as the result will fit into the external variable size.
2680
*/
2681
uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
2682
uint64_t aux, bigNum, bigDenom;
2683
uint64_t returnLimit;
2684
int i;
2685
uint64_t nMax;
2686
double fMax;
2687
unsigned long maxDenom;
2688
/*-- nMax and fMax defines the initial accuracy of the starting fractional,
2689
* or better, the highest used integer numbers used within the starting
2690
* fractional (bigNum/bigDenom). There are two approaches, which can
2691
* accidentally lead to different accuracies just depending on the value.
2692
* Therefore, blnUseSmallRange steers this behavior.
2693
* For long long nMax = ((9223372036854775807-1)/2); for long nMax =
2694
* ((2147483647-1)/2);
2695
*/
2696
if (blnUseSmallRange)
2697
{
2698
nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
2699
}
2700
else
2701
{
2702
nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
2703
}
2704
fMax = (double)nMax;
2705
2706
/*-- For the Euclidean GCD define the denominator range, so that it stays
2707
* within size of unsigned long variables. maxDenom should be LONG_MAX for
2708
* negative values and ULONG_MAX for positive ones. Also the final returned
2709
* value of ullNum and ullDenom is limited according to signed- or
2710
* unsigned-range.
2711
*/
2712
if (blnUseSignedRange)
2713
{
2714
maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
2715
returnLimit = maxDenom;
2716
}
2717
else
2718
{
2719
maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
2720
returnLimit = maxDenom;
2721
}
2722
2723
/*-- First generate a rational fraction (bigNum/bigDenom) which represents
2724
*the value as a rational number with the highest accuracy. Therefore,
2725
*uint64_t (uint64_t) is needed. This rational fraction is then reduced
2726
*using the Euclidean algorithm to find the greatest common divisor (GCD).
2727
* bigNum = big numinator of value without fraction (or cut residual
2728
*fraction) bigDenom = big denominator of value
2729
*-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
2730
*and bigDenom has no overflow, and stop with enlargement of fraction when
2731
*the double-value of it reaches an integer number without fractional part.
2732
*/
2733
bigDenom = 1;
2734
while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
2735
{
2736
bigDenom <<= 1;
2737
value *= 2;
2738
}
2739
bigNum = (uint64_t)value;
2740
2741
/*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
2742
*/
2743
#define MAX_ITERATIONS 64
2744
for (i = 0; i < MAX_ITERATIONS; i++)
2745
{
2746
uint64_t val;
2747
/* if bigDenom is not zero, calculate integer part of fraction. */
2748
if (bigDenom == 0)
2749
{
2750
break;
2751
}
2752
val = bigNum / bigDenom;
2753
2754
/* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
2755
* denominator bigDenom. */
2756
aux = bigNum;
2757
bigNum = bigDenom;
2758
bigDenom = aux % bigDenom;
2759
2760
/* calculate next denominator and check for its given maximum */
2761
aux = val;
2762
if (denomSum[1] * val + denomSum[0] >= maxDenom)
2763
{
2764
aux = (maxDenom - denomSum[0]) / denomSum[1];
2765
if (aux * 2 >= val || denomSum[1] >= maxDenom)
2766
i = (MAX_ITERATIONS +
2767
1); /* exit but execute rest of for-loop */
2768
else
2769
break;
2770
}
2771
/* calculate next numerator to numSum2 and save previous one to numSum0;
2772
* numSum1 just copy of numSum2. */
2773
numSum[2] = aux * numSum[1] + numSum[0];
2774
numSum[0] = numSum[1];
2775
numSum[1] = numSum[2];
2776
/* calculate next denominator to denomSum2 and save previous one to
2777
* denomSum0; denomSum1 just copy of denomSum2. */
2778
denomSum[2] = aux * denomSum[1] + denomSum[0];
2779
denomSum[0] = denomSum[1];
2780
denomSum[1] = denomSum[2];
2781
}
2782
2783
/*-- Check and adapt for final variable size and return values; reduces
2784
* internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
2785
while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
2786
{
2787
numSum[1] = numSum[1] / 2;
2788
denomSum[1] = denomSum[1] / 2;
2789
}
2790
2791
/* return values */
2792
*ullNum = numSum[1];
2793
*ullDenom = denomSum[1];
2794
2795
} /*-- ToRationalEuclideanGCD() -------------- */
2796
2797
/**---- DoubleToRational() -----------------------------------------------
2798
* Calculates the rational fractional of a double input value
2799
* for UN-SIGNED rationals,
2800
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2801
------------------------------------------------------------------------*/
2802
static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
2803
{
2804
/*---- UN-SIGNED RATIONAL ---- */
2805
double dblDiff, dblDiff2;
2806
uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2807
2808
/*-- Check for negative values. If so it is an error. */
2809
/* Test written that way to catch NaN */
2810
if (!(value >= 0))
2811
{
2812
*num = *denom = 0;
2813
TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2814
" Negative Value for Unsigned Rational given.");
2815
return;
2816
}
2817
2818
/*-- Check for too big numbers (> ULONG_MAX) -- */
2819
if (value > 0xFFFFFFFFUL)
2820
{
2821
*num = 0xFFFFFFFFU;
2822
*denom = 0;
2823
return;
2824
}
2825
/*-- Check for easy integer numbers -- */
2826
if (value == (uint32_t)(value))
2827
{
2828
*num = (uint32_t)value;
2829
*denom = 1;
2830
return;
2831
}
2832
/*-- Check for too small numbers for "unsigned long" type rationals -- */
2833
if (value < 1.0 / (double)0xFFFFFFFFUL)
2834
{
2835
*num = 0;
2836
*denom = 0xFFFFFFFFU;
2837
return;
2838
}
2839
2840
/*-- There are two approaches using the Euclidean algorithm,
2841
* which can accidentally lead to different accuracies just depending on
2842
* the value. Try both and define which one was better.
2843
*/
2844
ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
2845
ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
2846
/*-- Double-Check, that returned values fit into ULONG :*/
2847
if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
2848
ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
2849
{
2850
TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2851
" Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
2852
", denom=%12" PRIu64 " | num2=%12" PRIu64
2853
", denom2=%12" PRIu64 "",
2854
value, ullNum, ullDenom, ullNum2, ullDenom2);
2855
assert(0);
2856
}
2857
2858
/* Check, which one has higher accuracy and take that. */
2859
dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2860
dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2861
if (dblDiff < dblDiff2)
2862
{
2863
*num = (uint32_t)ullNum;
2864
*denom = (uint32_t)ullDenom;
2865
}
2866
else
2867
{
2868
*num = (uint32_t)ullNum2;
2869
*denom = (uint32_t)ullDenom2;
2870
}
2871
} /*-- DoubleToRational() -------------- */
2872
2873
/**---- DoubleToSrational() -----------------------------------------------
2874
* Calculates the rational fractional of a double input value
2875
* for SIGNED rationals,
2876
* using the Euclidean algorithm to find the greatest common divisor (GCD)
2877
------------------------------------------------------------------------*/
2878
static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
2879
{
2880
/*---- SIGNED RATIONAL ----*/
2881
int neg = 1;
2882
double dblDiff, dblDiff2;
2883
uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2884
2885
/*-- Check for negative values and use then the positive one for internal
2886
* calculations, but take the sign into account before returning. */
2887
if (value < 0)
2888
{
2889
neg = -1;
2890
value = -value;
2891
}
2892
2893
/*-- Check for too big numbers (> LONG_MAX) -- */
2894
if (value > 0x7FFFFFFFL)
2895
{
2896
*num = 0x7FFFFFFFL;
2897
*denom = 0;
2898
return;
2899
}
2900
/*-- Check for easy numbers -- */
2901
if (value == (int32_t)(value))
2902
{
2903
*num = (int32_t)(neg * value);
2904
*denom = 1;
2905
return;
2906
}
2907
/*-- Check for too small numbers for "long" type rationals -- */
2908
if (value < 1.0 / (double)0x7FFFFFFFL)
2909
{
2910
*num = 0;
2911
*denom = 0x7FFFFFFFL;
2912
return;
2913
}
2914
2915
/*-- There are two approaches using the Euclidean algorithm,
2916
* which can accidentally lead to different accuracies just depending on
2917
* the value. Try both and define which one was better. Furthermore, set
2918
* behavior of ToRationalEuclideanGCD() to the range of signed-long.
2919
*/
2920
ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
2921
ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
2922
/*-- Double-Check, that returned values fit into LONG :*/
2923
if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
2924
ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
2925
{
2926
TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
2927
" Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
2928
", denom=%12" PRIu64 " | num2=%12" PRIu64
2929
", denom2=%12" PRIu64 "",
2930
neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
2931
assert(0);
2932
}
2933
2934
/* Check, which one has higher accuracy and take that. */
2935
dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2936
dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2937
if (dblDiff < dblDiff2)
2938
{
2939
*num = (int32_t)(neg * (long)ullNum);
2940
*denom = (int32_t)ullDenom;
2941
}
2942
else
2943
{
2944
*num = (int32_t)(neg * (long)ullNum2);
2945
*denom = (int32_t)ullDenom2;
2946
}
2947
} /*-- DoubleToSrational() --------------*/
2948
2949
static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
2950
TIFFDirEntry *dir,
2951
uint16_t tag, uint32_t count,
2952
float *value)
2953
{
2954
assert(count < 0x40000000);
2955
assert(sizeof(float) == 4);
2956
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2957
{
2958
EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2959
return 1;
2960
}
2961
TIFFCvtNativeToIEEEFloat(tif, count, &value);
2962
if (tif->tif_flags & TIFF_SWAB)
2963
TIFFSwabArrayOfFloat(value, count);
2964
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
2965
count * 4, value));
2966
}
2967
2968
static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
2969
TIFFDirEntry *dir,
2970
uint16_t tag, uint32_t count,
2971
double *value)
2972
{
2973
assert(count < 0x20000000);
2974
assert(sizeof(double) == 8);
2975
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2976
{
2977
EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
2978
return 1;
2979
}
2980
TIFFCvtNativeToIEEEDouble(tif, count, &value);
2981
if (tif->tif_flags & TIFF_SWAB)
2982
TIFFSwabArrayOfDouble(value, count);
2983
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
2984
count * 8, value));
2985
}
2986
2987
static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
2988
TIFFDirEntry *dir, uint16_t tag,
2989
uint32_t count, uint32_t *value)
2990
{
2991
assert(count < 0x40000000);
2992
assert(sizeof(uint32_t) == 4);
2993
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
2994
{
2995
EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
2996
return 1;
2997
}
2998
if (tif->tif_flags & TIFF_SWAB)
2999
TIFFSwabArrayOfLong(value, count);
3000
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
3001
count * 4, value));
3002
}
3003
3004
static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
3005
TIFFDirEntry *dir,
3006
uint16_t tag, uint32_t count,
3007
uint64_t *value)
3008
{
3009
assert(count < 0x20000000);
3010
assert(sizeof(uint64_t) == 8);
3011
assert(tif->tif_flags & TIFF_BIGTIFF);
3012
if (dir == NULL) /* Just evaluate IFD data size and increment ndir. */
3013
{
3014
EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
3015
return 1;
3016
}
3017
if (tif->tif_flags & TIFF_SWAB)
3018
TIFFSwabArrayOfLong8(value, count);
3019
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
3020
count * 8, value));
3021
}
3022
3023
static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
3024
TIFFDirEntry *dir, uint16_t tag,
3025
uint16_t datatype, uint32_t count,
3026
uint32_t datalength, void *data)
3027
{
3028
static const char module[] = "TIFFWriteDirectoryTagData";
3029
uint32_t m;
3030
m = 0;
3031
while (m < (*ndir))
3032
{
3033
assert(dir[m].tdir_tag != tag);
3034
if (dir[m].tdir_tag > tag)
3035
break;
3036
m++;
3037
}
3038
if (m < (*ndir))
3039
{
3040
uint32_t n;
3041
for (n = *ndir; n > m; n--)
3042
dir[n] = dir[n - 1];
3043
}
3044
dir[m].tdir_tag = tag;
3045
dir[m].tdir_type = datatype;
3046
dir[m].tdir_count = count;
3047
dir[m].tdir_offset.toff_long8 = 0;
3048
if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
3049
{
3050
if (data && datalength)
3051
{
3052
_TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
3053
}
3054
}
3055
else
3056
{
3057
uint64_t na, nb;
3058
na = tif->tif_dataoff;
3059
nb = na + datalength;
3060
if (!(tif->tif_flags & TIFF_BIGTIFF))
3061
nb = (uint32_t)nb;
3062
if ((nb < na) || (nb < datalength))
3063
{
3064
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
3065
return (0);
3066
}
3067
if (!SeekOK(tif, na))
3068
{
3069
TIFFErrorExtR(tif, module, "IO error writing tag data");
3070
return (0);
3071
}
3072
if (datalength >= 0x80000000UL)
3073
{
3074
TIFFErrorExtR(tif, module,
3075
"libtiff does not allow writing more than 2147483647 "
3076
"bytes in a tag");
3077
return (0);
3078
}
3079
if (!WriteOK(tif, data, (tmsize_t)datalength))
3080
{
3081
TIFFErrorExtR(tif, module, "IO error writing tag data");
3082
return (0);
3083
}
3084
tif->tif_dataoff = nb;
3085
if (tif->tif_dataoff & 1)
3086
tif->tif_dataoff++;
3087
if (!(tif->tif_flags & TIFF_BIGTIFF))
3088
{
3089
uint32_t o;
3090
o = (uint32_t)na;
3091
if (tif->tif_flags & TIFF_SWAB)
3092
TIFFSwabLong(&o);
3093
_TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
3094
}
3095
else
3096
{
3097
dir[m].tdir_offset.toff_long8 = na;
3098
if (tif->tif_flags & TIFF_SWAB)
3099
TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
3100
}
3101
}
3102
(*ndir)++;
3103
return (1);
3104
}
3105
3106
/*
3107
* Link the current directory into the directory chain for the file.
3108
*/
3109
static int TIFFLinkDirectory(TIFF *tif)
3110
{
3111
static const char module[] = "TIFFLinkDirectory";
3112
3113
tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
3114
3115
/*
3116
* Handle SubIFDs
3117
*/
3118
if (tif->tif_flags & TIFF_INSUBIFD)
3119
{
3120
if (!(tif->tif_flags & TIFF_BIGTIFF))
3121
{
3122
uint32_t m;
3123
m = (uint32_t)tif->tif_diroff;
3124
if (tif->tif_flags & TIFF_SWAB)
3125
TIFFSwabLong(&m);
3126
(void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
3127
if (!WriteOK(tif, &m, 4))
3128
{
3129
TIFFErrorExtR(tif, module,
3130
"Error writing SubIFD directory link");
3131
return (0);
3132
}
3133
3134
/*
3135
* Advance to the next SubIFD or, if this is
3136
* the last one configured, reverting back to the
3137
* normal directory linkage is done in TIFFWriteDirectorySec()
3138
* by tif->tif_flags &= ~TIFF_INSUBIFD;.
3139
*/
3140
if (--tif->tif_nsubifd)
3141
tif->tif_subifdoff += 4;
3142
return (1);
3143
}
3144
else
3145
{
3146
uint64_t m;
3147
m = tif->tif_diroff;
3148
if (tif->tif_flags & TIFF_SWAB)
3149
TIFFSwabLong8(&m);
3150
(void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
3151
if (!WriteOK(tif, &m, 8))
3152
{
3153
TIFFErrorExtR(tif, module,
3154
"Error writing SubIFD directory link");
3155
return (0);
3156
}
3157
3158
/*
3159
* Advance to the next SubIFD or, if this is
3160
* the last one configured, reverting back to the
3161
* normal directory linkage is done in TIFFWriteDirectorySec()
3162
* by tif->tif_flags &= ~TIFF_INSUBIFD;.
3163
*/
3164
if (--tif->tif_nsubifd)
3165
tif->tif_subifdoff += 8;
3166
return (1);
3167
}
3168
}
3169
3170
/*
3171
* Handle main-IFDs
3172
*/
3173
tdir_t ndir = 1; /* count current number of main-IFDs */
3174
if (!(tif->tif_flags & TIFF_BIGTIFF))
3175
{
3176
uint32_t m;
3177
uint32_t nextdir;
3178
m = (uint32_t)(tif->tif_diroff);
3179
if (tif->tif_flags & TIFF_SWAB)
3180
TIFFSwabLong(&m);
3181
if (tif->tif_header.classic.tiff_diroff == 0)
3182
{
3183
/*
3184
* First directory, overwrite offset in header.
3185
*/
3186
tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff;
3187
tif->tif_lastdiroff = tif->tif_diroff;
3188
(void)TIFFSeekFile(tif, 4, SEEK_SET);
3189
if (!WriteOK(tif, &m, 4))
3190
{
3191
TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3192
return (0);
3193
}
3194
if (!tif->tif_dir.td_iswrittentofile)
3195
tif->tif_curdircount = 0;
3196
return (1);
3197
}
3198
/*
3199
* Not the first directory, search to the last and append.
3200
*/
3201
tdir_t dirn = 0;
3202
if (tif->tif_lastdiroff != 0 &&
3203
_TIFFGetDirNumberFromOffset(tif, tif->tif_lastdiroff, &dirn))
3204
{
3205
/* Start searching from the lastely written IFD. Thus get its IFD
3206
* number. */
3207
nextdir = (uint32_t)tif->tif_lastdiroff;
3208
ndir = dirn + 1;
3209
}
3210
else
3211
{
3212
nextdir = tif->tif_header.classic.tiff_diroff;
3213
ndir = 1; /* start searching from the first IFD */
3214
}
3215
3216
while (1)
3217
{
3218
uint16_t dircount;
3219
uint32_t nextnextdir;
3220
3221
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
3222
{
3223
TIFFErrorExtR(tif, module, "Error fetching directory count");
3224
return (0);
3225
}
3226
if (tif->tif_flags & TIFF_SWAB)
3227
TIFFSwabShort(&dircount);
3228
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3229
if (!ReadOK(tif, &nextnextdir, 4))
3230
{
3231
TIFFErrorExtR(tif, module, "Error fetching directory link");
3232
return (0);
3233
}
3234
if (tif->tif_flags & TIFF_SWAB)
3235
TIFFSwabLong(&nextnextdir);
3236
if (nextnextdir == 0)
3237
{
3238
(void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3239
if (!WriteOK(tif, &m, 4))
3240
{
3241
TIFFErrorExtR(tif, module, "Error writing directory link");
3242
return (0);
3243
}
3244
tif->tif_lastdiroff = tif->tif_diroff;
3245
break;
3246
}
3247
nextdir = nextnextdir;
3248
ndir++;
3249
}
3250
}
3251
else
3252
{
3253
/*- BigTIFF -*/
3254
uint64_t m;
3255
uint64_t nextdir;
3256
m = tif->tif_diroff;
3257
if (tif->tif_flags & TIFF_SWAB)
3258
TIFFSwabLong8(&m);
3259
if (tif->tif_header.big.tiff_diroff == 0)
3260
{
3261
/*
3262
* First directory, overwrite offset in header.
3263
*/
3264
tif->tif_header.big.tiff_diroff = tif->tif_diroff;
3265
tif->tif_lastdiroff = tif->tif_diroff;
3266
(void)TIFFSeekFile(tif, 8, SEEK_SET);
3267
if (!WriteOK(tif, &m, 8))
3268
{
3269
TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3270
return (0);
3271
}
3272
if (!tif->tif_dir.td_iswrittentofile)
3273
tif->tif_curdircount = 0;
3274
return (1);
3275
}
3276
/*
3277
* Not the first directory, search to the last and append.
3278
*/
3279
tdir_t dirn = 0;
3280
if (tif->tif_lastdiroff != 0 &&
3281
_TIFFGetDirNumberFromOffset(tif, tif->tif_lastdiroff, &dirn))
3282
{
3283
/* Start searching from the lastely written IFD. Thus get its IFD
3284
* number. */
3285
nextdir = tif->tif_lastdiroff;
3286
ndir = dirn + 1;
3287
}
3288
else
3289
{
3290
nextdir = tif->tif_header.big.tiff_diroff;
3291
ndir = 1; /* start searching from the first IFD */
3292
}
3293
while (1)
3294
{
3295
uint64_t dircount64;
3296
uint16_t dircount;
3297
uint64_t nextnextdir;
3298
3299
if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
3300
{
3301
TIFFErrorExtR(tif, module, "Error fetching directory count");
3302
return (0);
3303
}
3304
if (tif->tif_flags & TIFF_SWAB)
3305
TIFFSwabLong8(&dircount64);
3306
if (dircount64 > 0xFFFF)
3307
{
3308
TIFFErrorExtR(tif, module,
3309
"Sanity check on tag count failed, "
3310
"likely corrupt TIFF");
3311
return (0);
3312
}
3313
dircount = (uint16_t)dircount64;
3314
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3315
if (!ReadOK(tif, &nextnextdir, 8))
3316
{
3317
TIFFErrorExtR(tif, module, "Error fetching directory link");
3318
return (0);
3319
}
3320
if (tif->tif_flags & TIFF_SWAB)
3321
TIFFSwabLong8(&nextnextdir);
3322
if (nextnextdir == 0)
3323
{
3324
(void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3325
if (!WriteOK(tif, &m, 8))
3326
{
3327
TIFFErrorExtR(tif, module, "Error writing directory link");
3328
return (0);
3329
}
3330
tif->tif_lastdiroff = tif->tif_diroff;
3331
break;
3332
}
3333
nextdir = nextnextdir;
3334
ndir++;
3335
}
3336
}
3337
/* Offset of next IFD is written to file.
3338
* Update number of main-IFDs in file.
3339
* However, tif_curdircount shall count only newly written main-IFDs with
3340
* entries and not only number of linked offsets! Thus, tif_curdircount is
3341
* incremented at the end of TIFFWriteDirectorySec().
3342
* TIFF_NON_EXISTENT_DIR_NUMBER means 'dont know number of IFDs'
3343
* 0 means 'empty file opened for writing, but no IFD written yet' */
3344
if (!tif->tif_dir.td_iswrittentofile && !(tif->tif_flags & TIFF_INSUBIFD))
3345
{
3346
tif->tif_curdircount = ndir;
3347
}
3348
return (1);
3349
}
3350
3351
/************************************************************************/
3352
/* TIFFRewriteField() */
3353
/* */
3354
/* Rewrite a field in the directory on disk without regard to */
3355
/* updating the TIFF directory structure in memory. Currently */
3356
/* only supported for field that already exist in the on-disk */
3357
/* directory. Mainly used for updating stripoffset / */
3358
/* stripbytecount values after the directory is already on */
3359
/* disk. */
3360
/* */
3361
/* Returns zero on failure, and one on success. */
3362
/************************************************************************/
3363
3364
int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
3365
tmsize_t count, void *data)
3366
{
3367
static const char module[] = "TIFFResetField";
3368
/* const TIFFField* fip = NULL; */
3369
uint16_t dircount;
3370
tmsize_t dirsize;
3371
uint8_t direntry_raw[20];
3372
uint16_t entry_tag = 0;
3373
uint16_t entry_type = 0;
3374
uint64_t entry_count = 0;
3375
uint64_t entry_offset = 0;
3376
int value_in_entry = 0;
3377
uint64_t read_offset;
3378
uint8_t *buf_to_write = NULL;
3379
TIFFDataType datatype;
3380
3381
/* -------------------------------------------------------------------- */
3382
/* Find field definition. */
3383
/* -------------------------------------------------------------------- */
3384
/*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
3385
3386
/* -------------------------------------------------------------------- */
3387
/* Do some checking this is a straight forward case. */
3388
/* -------------------------------------------------------------------- */
3389
if (isMapped(tif))
3390
{
3391
TIFFErrorExtR(tif, module,
3392
"Memory mapped files not currently supported for "
3393
"this operation.");
3394
return 0;
3395
}
3396
3397
if (tif->tif_diroff == 0)
3398
{
3399
TIFFErrorExtR(
3400
tif, module,
3401
"Attempt to reset field on directory not already on disk.");
3402
return 0;
3403
}
3404
3405
/* -------------------------------------------------------------------- */
3406
/* Read the directory entry count. */
3407
/* -------------------------------------------------------------------- */
3408
if (!SeekOK(tif, tif->tif_diroff))
3409
{
3410
TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3411
tif->tif_name);
3412
return 0;
3413
}
3414
3415
read_offset = tif->tif_diroff;
3416
3417
if (!(tif->tif_flags & TIFF_BIGTIFF))
3418
{
3419
if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
3420
{
3421
TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3422
tif->tif_name);
3423
return 0;
3424
}
3425
if (tif->tif_flags & TIFF_SWAB)
3426
TIFFSwabShort(&dircount);
3427
dirsize = 12;
3428
read_offset += 2;
3429
}
3430
else
3431
{
3432
uint64_t dircount64;
3433
if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
3434
{
3435
TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3436
tif->tif_name);
3437
return 0;
3438
}
3439
if (tif->tif_flags & TIFF_SWAB)
3440
TIFFSwabLong8(&dircount64);
3441
dircount = (uint16_t)dircount64;
3442
dirsize = 20;
3443
read_offset += 8;
3444
}
3445
3446
/* -------------------------------------------------------------------- */
3447
/* Read through directory to find target tag. */
3448
/* -------------------------------------------------------------------- */
3449
while (dircount > 0)
3450
{
3451
if (!ReadOK(tif, direntry_raw, dirsize))
3452
{
3453
TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
3454
tif->tif_name);
3455
return 0;
3456
}
3457
3458
memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
3459
if (tif->tif_flags & TIFF_SWAB)
3460
TIFFSwabShort(&entry_tag);
3461
3462
if (entry_tag == tag)
3463
break;
3464
3465
read_offset += dirsize;
3466
}
3467
3468
if (entry_tag != tag)
3469
{
3470
TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
3471
tif->tif_name, tag);
3472
return 0;
3473
}
3474
3475
/* -------------------------------------------------------------------- */
3476
/* Extract the type, count and offset for this entry. */
3477
/* -------------------------------------------------------------------- */
3478
memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
3479
if (tif->tif_flags & TIFF_SWAB)
3480
TIFFSwabShort(&entry_type);
3481
3482
if (!(tif->tif_flags & TIFF_BIGTIFF))
3483
{
3484
uint32_t value;
3485
3486
memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
3487
if (tif->tif_flags & TIFF_SWAB)
3488
TIFFSwabLong(&value);
3489
entry_count = value;
3490
3491
memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
3492
if (tif->tif_flags & TIFF_SWAB)
3493
TIFFSwabLong(&value);
3494
entry_offset = value;
3495
}
3496
else
3497
{
3498
memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
3499
if (tif->tif_flags & TIFF_SWAB)
3500
TIFFSwabLong8(&entry_count);
3501
3502
memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
3503
if (tif->tif_flags & TIFF_SWAB)
3504
TIFFSwabLong8(&entry_offset);
3505
}
3506
3507
/* -------------------------------------------------------------------- */
3508
/* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
3509
/* -------------------------------------------------------------------- */
3510
if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
3511
{
3512
if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
3513
{
3514
entry_type =
3515
(tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
3516
}
3517
else
3518
{
3519
int write_aslong8 = 1;
3520
if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3521
{
3522
write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
3523
}
3524
else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3525
{
3526
write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
3527
}
3528
if (write_aslong8)
3529
{
3530
entry_type = TIFF_LONG8;
3531
}
3532
else
3533
{
3534
int write_aslong4 = 1;
3535
if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3536
{
3537
write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
3538
}
3539
else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3540
{
3541
write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
3542
}
3543
if (write_aslong4)
3544
{
3545
entry_type = TIFF_LONG;
3546
}
3547
else
3548
{
3549
entry_type = TIFF_SHORT;
3550
}
3551
}
3552
}
3553
}
3554
3555
/* -------------------------------------------------------------------- */
3556
/* What data type do we want to write this as? */
3557
/* -------------------------------------------------------------------- */
3558
if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
3559
{
3560
if (in_datatype == TIFF_LONG8)
3561
datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
3562
else if (in_datatype == TIFF_SLONG8)
3563
datatype = TIFF_SLONG;
3564
else if (in_datatype == TIFF_IFD8)
3565
datatype = TIFF_IFD;
3566
else
3567
datatype = in_datatype;
3568
}
3569
else
3570
{
3571
if (in_datatype == TIFF_LONG8 &&
3572
(entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
3573
entry_type == TIFF_LONG8))
3574
datatype = entry_type;
3575
else if (in_datatype == TIFF_SLONG8 &&
3576
(entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
3577
datatype = entry_type;
3578
else if (in_datatype == TIFF_IFD8 &&
3579
(entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
3580
datatype = entry_type;
3581
else
3582
datatype = in_datatype;
3583
}
3584
3585
/* -------------------------------------------------------------------- */
3586
/* Prepare buffer of actual data to write. This includes */
3587
/* swabbing as needed. */
3588
/* -------------------------------------------------------------------- */
3589
buf_to_write = (uint8_t *)_TIFFCheckMalloc(
3590
tif, count, TIFFDataWidth(datatype), "for field buffer.");
3591
if (!buf_to_write)
3592
return 0;
3593
3594
if (datatype == in_datatype)
3595
memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
3596
else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
3597
{
3598
tmsize_t i;
3599
3600
for (i = 0; i < count; i++)
3601
{
3602
((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
3603
if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
3604
{
3605
_TIFFfreeExt(tif, buf_to_write);
3606
TIFFErrorExtR(tif, module,
3607
"Value exceeds 32bit range of output type.");
3608
return 0;
3609
}
3610
}
3611
}
3612
else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
3613
(datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
3614
{
3615
tmsize_t i;
3616
3617
for (i = 0; i < count; i++)
3618
{
3619
((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
3620
if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
3621
((uint64_t *)data)[i])
3622
{
3623
_TIFFfreeExt(tif, buf_to_write);
3624
TIFFErrorExtR(tif, module,
3625
"Value exceeds 32bit range of output type.");
3626
return 0;
3627
}
3628
}
3629
}
3630
else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
3631
{
3632
tmsize_t i;
3633
3634
for (i = 0; i < count; i++)
3635
{
3636
((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
3637
if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
3638
((uint64_t *)data)[i])
3639
{
3640
_TIFFfreeExt(tif, buf_to_write);
3641
TIFFErrorExtR(tif, module,
3642
"Value exceeds 16bit range of output type.");
3643
return 0;
3644
}
3645
}
3646
}
3647
else
3648
{
3649
TIFFErrorExtR(tif, module, "Unhandled type conversion.");
3650
return 0;
3651
}
3652
3653
if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
3654
{
3655
if (TIFFDataWidth(datatype) == 2)
3656
TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
3657
else if (TIFFDataWidth(datatype) == 4)
3658
TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
3659
else if (TIFFDataWidth(datatype) == 8)
3660
TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
3661
}
3662
3663
/* -------------------------------------------------------------------- */
3664
/* Is this a value that fits into the directory entry? */
3665
/* -------------------------------------------------------------------- */
3666
if (!(tif->tif_flags & TIFF_BIGTIFF))
3667
{
3668
if (TIFFDataWidth(datatype) * count <= 4)
3669
{
3670
entry_offset = read_offset + 8;
3671
value_in_entry = 1;
3672
}
3673
}
3674
else
3675
{
3676
if (TIFFDataWidth(datatype) * count <= 8)
3677
{
3678
entry_offset = read_offset + 12;
3679
value_in_entry = 1;
3680
}
3681
}
3682
3683
if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
3684
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
3685
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
3686
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
3687
{
3688
tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
3689
tif->tif_dir.td_stripoffset_entry.tdir_count = count;
3690
}
3691
else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
3692
tag == TIFFTAG_STRIPBYTECOUNTS) &&
3693
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
3694
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
3695
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
3696
{
3697
tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
3698
tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
3699
}
3700
3701
/* -------------------------------------------------------------------- */
3702
/* If the tag type, and count match, then we just write it out */
3703
/* over the old values without altering the directory entry at */
3704
/* all. */
3705
/* -------------------------------------------------------------------- */
3706
if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
3707
{
3708
if (!SeekOK(tif, entry_offset))
3709
{
3710
_TIFFfreeExt(tif, buf_to_write);
3711
TIFFErrorExtR(tif, module,
3712
"%s: Seek error accessing TIFF directory",
3713
tif->tif_name);
3714
return 0;
3715
}
3716
if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3717
{
3718
_TIFFfreeExt(tif, buf_to_write);
3719
TIFFErrorExtR(tif, module, "Error writing directory link");
3720
return (0);
3721
}
3722
3723
_TIFFfreeExt(tif, buf_to_write);
3724
return 1;
3725
}
3726
3727
/* -------------------------------------------------------------------- */
3728
/* Otherwise, we write the new tag data at the end of the file. */
3729
/* -------------------------------------------------------------------- */
3730
if (!value_in_entry)
3731
{
3732
entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
3733
3734
if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3735
{
3736
_TIFFfreeExt(tif, buf_to_write);
3737
TIFFErrorExtR(tif, module, "Error writing directory link");
3738
return (0);
3739
}
3740
}
3741
else
3742
{
3743
if (count * TIFFDataWidth(datatype) == 4)
3744
{
3745
uint32_t value;
3746
memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
3747
entry_offset = value;
3748
}
3749
else
3750
{
3751
memcpy(&entry_offset, buf_to_write,
3752
count * TIFFDataWidth(datatype));
3753
}
3754
}
3755
3756
_TIFFfreeExt(tif, buf_to_write);
3757
buf_to_write = 0;
3758
3759
/* -------------------------------------------------------------------- */
3760
/* Adjust the directory entry. */
3761
/* -------------------------------------------------------------------- */
3762
entry_type = datatype;
3763
entry_count = (uint64_t)count;
3764
memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
3765
if (tif->tif_flags & TIFF_SWAB)
3766
TIFFSwabShort((uint16_t *)(direntry_raw + 2));
3767
3768
if (!(tif->tif_flags & TIFF_BIGTIFF))
3769
{
3770
uint32_t value;
3771
3772
value = (uint32_t)entry_count;
3773
memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
3774
if (tif->tif_flags & TIFF_SWAB)
3775
TIFFSwabLong((uint32_t *)(direntry_raw + 4));
3776
3777
value = (uint32_t)entry_offset;
3778
memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
3779
if (tif->tif_flags & TIFF_SWAB)
3780
TIFFSwabLong((uint32_t *)(direntry_raw + 8));
3781
}
3782
else
3783
{
3784
memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
3785
if (tif->tif_flags & TIFF_SWAB)
3786
TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
3787
3788
memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
3789
if (tif->tif_flags & TIFF_SWAB)
3790
TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
3791
}
3792
3793
/* -------------------------------------------------------------------- */
3794
/* Write the directory entry out to disk. */
3795
/* -------------------------------------------------------------------- */
3796
if (!SeekOK(tif, read_offset))
3797
{
3798
TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3799
tif->tif_name);
3800
return 0;
3801
}
3802
3803
if (!WriteOK(tif, direntry_raw, dirsize))
3804
{
3805
TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
3806
tif->tif_name);
3807
return 0;
3808
}
3809
3810
return 1;
3811
}
3812
3813