Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tiff/libtiff/tif_write.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
* Scanline-oriented Write Support
29
*/
30
#include "tiffiop.h"
31
#include <stdio.h>
32
33
#define STRIPINCR 20 /* expansion factor on strip array */
34
35
#define WRITECHECKSTRIPS(tif, module) \
36
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
37
#define WRITECHECKTILES(tif, module) \
38
(((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
39
#define BUFFERCHECK(tif) \
40
((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
41
TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
42
43
static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
44
static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
45
tmsize_t cc);
46
47
int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
48
{
49
static const char module[] = "TIFFWriteScanline";
50
register TIFFDirectory *td;
51
int status, imagegrew = 0;
52
uint32_t strip;
53
54
if (!WRITECHECKSTRIPS(tif, module))
55
return (-1);
56
/*
57
* Handle delayed allocation of data buffer. This
58
* permits it to be sized more intelligently (using
59
* directory information).
60
*/
61
if (!BUFFERCHECK(tif))
62
return (-1);
63
tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
64
65
td = &tif->tif_dir;
66
/*
67
* Extend image length if needed
68
* (but only for PlanarConfig=1).
69
*/
70
if (row >= td->td_imagelength)
71
{ /* extend image */
72
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
73
{
74
TIFFErrorExtR(
75
tif, module,
76
"Can not change \"ImageLength\" when using separate planes");
77
return (-1);
78
}
79
td->td_imagelength = row + 1;
80
imagegrew = 1;
81
}
82
/*
83
* Calculate strip and check for crossings.
84
*/
85
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
86
{
87
if (sample >= td->td_samplesperpixel)
88
{
89
TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
90
(unsigned long)sample,
91
(unsigned long)td->td_samplesperpixel);
92
return (-1);
93
}
94
strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
95
}
96
else
97
strip = row / td->td_rowsperstrip;
98
/*
99
* Check strip array to make sure there's space. We don't support
100
* dynamically growing files that have data organized in separate
101
* bitplanes because it's too painful. In that case we require that
102
* the imagelength be set properly before the first write (so that the
103
* strips array will be fully allocated above).
104
*/
105
if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
106
return (-1);
107
if (strip != tif->tif_curstrip)
108
{
109
/*
110
* Changing strips -- flush any data present.
111
*/
112
if (!TIFFFlushData(tif))
113
return (-1);
114
tif->tif_curstrip = strip;
115
/*
116
* Watch out for a growing image. The value of strips/image
117
* will initially be 1 (since it can't be deduced until the
118
* imagelength is known).
119
*/
120
if (strip >= td->td_stripsperimage && imagegrew)
121
td->td_stripsperimage =
122
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
123
if (td->td_stripsperimage == 0)
124
{
125
TIFFErrorExtR(tif, module, "Zero strips per image");
126
return (-1);
127
}
128
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
129
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
130
{
131
if (!(*tif->tif_setupencode)(tif))
132
return (-1);
133
tif->tif_flags |= TIFF_CODERSETUP;
134
}
135
136
tif->tif_rawcc = 0;
137
tif->tif_rawcp = tif->tif_rawdata;
138
139
/* this informs TIFFAppendToStrip() we have changed strip */
140
tif->tif_curoff = 0;
141
142
if (!(*tif->tif_preencode)(tif, sample))
143
return (-1);
144
tif->tif_flags |= TIFF_POSTENCODE;
145
}
146
/*
147
* Ensure the write is either sequential or at the
148
* beginning of a strip (or that we can randomly
149
* access the data -- i.e. no encoding).
150
*/
151
if (row != tif->tif_row)
152
{
153
if (row < tif->tif_row)
154
{
155
/*
156
* Moving backwards within the same strip:
157
* backup to the start and then decode
158
* forward (below).
159
*/
160
tif->tif_row =
161
(strip % td->td_stripsperimage) * td->td_rowsperstrip;
162
tif->tif_rawcp = tif->tif_rawdata;
163
}
164
/*
165
* Seek forward to the desired row.
166
*/
167
if (!(*tif->tif_seek)(tif, row - tif->tif_row))
168
return (-1);
169
tif->tif_row = row;
170
}
171
172
/* swab if needed - note that source buffer will be altered */
173
tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
174
175
status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
176
sample);
177
178
/* we are now poised at the beginning of the next row */
179
tif->tif_row = row + 1;
180
return (status);
181
}
182
183
/* Make sure that at the first attempt of rewriting a tile/strip, we will have
184
*/
185
/* more bytes available in the output buffer than the previous byte count, */
186
/* so that TIFFAppendToStrip() will detect the overflow when it is called the
187
* first */
188
/* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
189
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
190
{
191
TIFFDirectory *td = &tif->tif_dir;
192
if (td->td_stripbytecount_p[strip_or_tile] > 0)
193
{
194
/* The +1 is to ensure at least one extra bytes */
195
/* The +4 is because the LZW encoder flushes 4 bytes before the limit */
196
uint64_t safe_buffer_size =
197
(uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
198
if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size)
199
{
200
if (!(TIFFWriteBufferSetup(
201
tif, NULL,
202
(tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))))
203
return 0;
204
}
205
}
206
return 1;
207
}
208
209
/*
210
* Encode the supplied data and write it to the
211
* specified strip.
212
*
213
* NB: Image length must be setup before writing.
214
*/
215
tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
216
tmsize_t cc)
217
{
218
static const char module[] = "TIFFWriteEncodedStrip";
219
TIFFDirectory *td = &tif->tif_dir;
220
uint16_t sample;
221
222
if (!WRITECHECKSTRIPS(tif, module))
223
return ((tmsize_t)-1);
224
/*
225
* Check strip array to make sure there's space.
226
* We don't support dynamically growing files that
227
* have data organized in separate bitplanes because
228
* it's too painful. In that case we require that
229
* the imagelength be set properly before the first
230
* write (so that the strips array will be fully
231
* allocated above).
232
*/
233
if (strip >= td->td_nstrips)
234
{
235
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
236
{
237
TIFFErrorExtR(
238
tif, module,
239
"Can not grow image by strips when using separate planes");
240
return ((tmsize_t)-1);
241
}
242
if (!TIFFGrowStrips(tif, 1, module))
243
return ((tmsize_t)-1);
244
td->td_stripsperimage =
245
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
246
}
247
/*
248
* Handle delayed allocation of data buffer. This
249
* permits it to be sized according to the directory
250
* info.
251
*/
252
if (!BUFFERCHECK(tif))
253
return ((tmsize_t)-1);
254
255
tif->tif_flags |= TIFF_BUF4WRITE;
256
257
tif->tif_curstrip = strip;
258
259
/* this informs TIFFAppendToStrip() we have changed or reset strip */
260
tif->tif_curoff = 0;
261
262
if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip))
263
{
264
return ((tmsize_t)(-1));
265
}
266
267
tif->tif_rawcc = 0;
268
tif->tif_rawcp = tif->tif_rawdata;
269
270
if (td->td_stripsperimage == 0)
271
{
272
TIFFErrorExtR(tif, module, "Zero strips per image");
273
return ((tmsize_t)-1);
274
}
275
276
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
277
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
278
{
279
if (!(*tif->tif_setupencode)(tif))
280
return ((tmsize_t)-1);
281
tif->tif_flags |= TIFF_CODERSETUP;
282
}
283
284
tif->tif_flags &= ~TIFF_POSTENCODE;
285
286
/* shortcut to avoid an extra memcpy() */
287
if (td->td_compression == COMPRESSION_NONE)
288
{
289
/* swab if needed - note that source buffer will be altered */
290
tif->tif_postdecode(tif, (uint8_t *)data, cc);
291
292
if (!isFillOrder(tif, td->td_fillorder) &&
293
(tif->tif_flags & TIFF_NOBITREV) == 0)
294
TIFFReverseBits((uint8_t *)data, cc);
295
296
if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc))
297
return ((tmsize_t)-1);
298
return (cc);
299
}
300
301
sample = (uint16_t)(strip / td->td_stripsperimage);
302
if (!(*tif->tif_preencode)(tif, sample))
303
return ((tmsize_t)-1);
304
305
/* swab if needed - note that source buffer will be altered */
306
tif->tif_postdecode(tif, (uint8_t *)data, cc);
307
308
if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample))
309
return ((tmsize_t)-1);
310
if (!(*tif->tif_postencode)(tif))
311
return ((tmsize_t)-1);
312
if (!isFillOrder(tif, td->td_fillorder) &&
313
(tif->tif_flags & TIFF_NOBITREV) == 0)
314
TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
315
if (tif->tif_rawcc > 0 &&
316
!TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
317
return ((tmsize_t)-1);
318
tif->tif_rawcc = 0;
319
tif->tif_rawcp = tif->tif_rawdata;
320
return (cc);
321
}
322
323
/*
324
* Write the supplied data to the specified strip.
325
*
326
* NB: Image length must be setup before writing.
327
*/
328
tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
329
{
330
static const char module[] = "TIFFWriteRawStrip";
331
TIFFDirectory *td = &tif->tif_dir;
332
333
if (!WRITECHECKSTRIPS(tif, module))
334
return ((tmsize_t)-1);
335
/*
336
* Check strip array to make sure there's space.
337
* We don't support dynamically growing files that
338
* have data organized in separate bitplanes because
339
* it's too painful. In that case we require that
340
* the imagelength be set properly before the first
341
* write (so that the strips array will be fully
342
* allocated above).
343
*/
344
if (strip >= td->td_nstrips)
345
{
346
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
347
{
348
TIFFErrorExtR(
349
tif, module,
350
"Can not grow image by strips when using separate planes");
351
return ((tmsize_t)-1);
352
}
353
/*
354
* Watch out for a growing image. The value of
355
* strips/image will initially be 1 (since it
356
* can't be deduced until the imagelength is known).
357
*/
358
if (strip >= td->td_stripsperimage)
359
td->td_stripsperimage =
360
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
361
if (!TIFFGrowStrips(tif, 1, module))
362
return ((tmsize_t)-1);
363
}
364
365
if (tif->tif_curstrip != strip)
366
{
367
tif->tif_curstrip = strip;
368
369
/* this informs TIFFAppendToStrip() we have changed or reset strip */
370
tif->tif_curoff = 0;
371
}
372
373
if (td->td_stripsperimage == 0)
374
{
375
TIFFErrorExtR(tif, module, "Zero strips per image");
376
return ((tmsize_t)-1);
377
}
378
tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
379
return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
380
: (tmsize_t)-1);
381
}
382
383
/*
384
* Write and compress a tile of data. The
385
* tile is selected by the (x,y,z,s) coordinates.
386
*/
387
tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
388
uint16_t s)
389
{
390
if (!TIFFCheckTile(tif, x, y, z, s))
391
return ((tmsize_t)(-1));
392
/*
393
* NB: A tile size of -1 is used instead of tif_tilesize knowing
394
* that TIFFWriteEncodedTile will clamp this to the tile size.
395
* This is done because the tile size may not be defined until
396
* after the output buffer is setup in TIFFWriteBufferSetup.
397
*/
398
return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
399
(tmsize_t)(-1)));
400
}
401
402
/*
403
* Encode the supplied data and write it to the
404
* specified tile. There must be space for the
405
* data. The function clamps individual writes
406
* to a tile to the tile size, but does not (and
407
* can not) check that multiple writes to the same
408
* tile do not write more than tile size data.
409
*
410
* NB: Image length must be setup before writing; this
411
* interface does not support automatically growing
412
* the image on each write (as TIFFWriteScanline does).
413
*/
414
tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
415
{
416
static const char module[] = "TIFFWriteEncodedTile";
417
TIFFDirectory *td;
418
uint16_t sample;
419
uint32_t howmany32;
420
421
if (!WRITECHECKTILES(tif, module))
422
return ((tmsize_t)(-1));
423
td = &tif->tif_dir;
424
if (tile >= td->td_nstrips)
425
{
426
TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
427
(unsigned long)tile, (unsigned long)td->td_nstrips);
428
return ((tmsize_t)(-1));
429
}
430
/*
431
* Handle delayed allocation of data buffer. This
432
* permits it to be sized more intelligently (using
433
* directory information).
434
*/
435
if (!BUFFERCHECK(tif))
436
return ((tmsize_t)(-1));
437
438
tif->tif_flags |= TIFF_BUF4WRITE;
439
440
tif->tif_curtile = tile;
441
442
/* this informs TIFFAppendToStrip() we have changed or reset tile */
443
tif->tif_curoff = 0;
444
445
if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile))
446
{
447
return ((tmsize_t)(-1));
448
}
449
450
tif->tif_rawcc = 0;
451
tif->tif_rawcp = tif->tif_rawdata;
452
453
/*
454
* Compute tiles per row & per column to compute
455
* current row and column
456
*/
457
howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
458
if (howmany32 == 0)
459
{
460
TIFFErrorExtR(tif, module, "Zero tiles");
461
return ((tmsize_t)(-1));
462
}
463
tif->tif_row = (tile % howmany32) * td->td_tilelength;
464
howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
465
if (howmany32 == 0)
466
{
467
TIFFErrorExtR(tif, module, "Zero tiles");
468
return ((tmsize_t)(-1));
469
}
470
tif->tif_col = (tile % howmany32) * td->td_tilewidth;
471
472
if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
473
{
474
if (!(*tif->tif_setupencode)(tif))
475
return ((tmsize_t)(-1));
476
tif->tif_flags |= TIFF_CODERSETUP;
477
}
478
tif->tif_flags &= ~TIFF_POSTENCODE;
479
480
/*
481
* Clamp write amount to the tile size. This is mostly
482
* done so that callers can pass in some large number
483
* (e.g. -1) and have the tile size used instead.
484
*/
485
if (cc < 1 || cc > tif->tif_tilesize)
486
cc = tif->tif_tilesize;
487
488
/* shortcut to avoid an extra memcpy() */
489
if (td->td_compression == COMPRESSION_NONE)
490
{
491
/* swab if needed - note that source buffer will be altered */
492
tif->tif_postdecode(tif, (uint8_t *)data, cc);
493
494
if (!isFillOrder(tif, td->td_fillorder) &&
495
(tif->tif_flags & TIFF_NOBITREV) == 0)
496
TIFFReverseBits((uint8_t *)data, cc);
497
498
if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc))
499
return ((tmsize_t)-1);
500
return (cc);
501
}
502
503
sample = (uint16_t)(tile / td->td_stripsperimage);
504
if (!(*tif->tif_preencode)(tif, sample))
505
return ((tmsize_t)(-1));
506
/* swab if needed - note that source buffer will be altered */
507
tif->tif_postdecode(tif, (uint8_t *)data, cc);
508
509
if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample))
510
return ((tmsize_t)-1);
511
if (!(*tif->tif_postencode)(tif))
512
return ((tmsize_t)(-1));
513
if (!isFillOrder(tif, td->td_fillorder) &&
514
(tif->tif_flags & TIFF_NOBITREV) == 0)
515
TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
516
if (tif->tif_rawcc > 0 &&
517
!TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc))
518
return ((tmsize_t)(-1));
519
tif->tif_rawcc = 0;
520
tif->tif_rawcp = tif->tif_rawdata;
521
return (cc);
522
}
523
524
/*
525
* Write the supplied data to the specified strip.
526
* There must be space for the data; we don't check
527
* if strips overlap!
528
*
529
* NB: Image length must be setup before writing; this
530
* interface does not support automatically growing
531
* the image on each write (as TIFFWriteScanline does).
532
*/
533
tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
534
{
535
static const char module[] = "TIFFWriteRawTile";
536
537
if (!WRITECHECKTILES(tif, module))
538
return ((tmsize_t)(-1));
539
if (tile >= tif->tif_dir.td_nstrips)
540
{
541
TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
542
(unsigned long)tile,
543
(unsigned long)tif->tif_dir.td_nstrips);
544
return ((tmsize_t)(-1));
545
}
546
return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc
547
: (tmsize_t)(-1));
548
}
549
550
#define isUnspecified(tif, f) \
551
(TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
552
553
int TIFFSetupStrips(TIFF *tif)
554
{
555
TIFFDirectory *td = &tif->tif_dir;
556
557
if (isTiled(tif))
558
td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS)
559
? td->td_samplesperpixel
560
: TIFFNumberOfTiles(tif);
561
else
562
td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP)
563
? td->td_samplesperpixel
564
: TIFFNumberOfStrips(tif);
565
td->td_nstrips = td->td_stripsperimage;
566
/* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
567
if (td->td_nstrips >=
568
0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
569
{
570
TIFFErrorExtR(tif, "TIFFSetupStrips",
571
"Too large Strip/Tile Offsets/ByteCounts arrays");
572
return 0;
573
}
574
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
575
td->td_stripsperimage /= td->td_samplesperpixel;
576
td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
577
tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
578
td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
579
tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
580
if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
581
return (0);
582
/*
583
* Place data at the end-of-file
584
* (by setting offsets to zero).
585
*/
586
_TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
587
_TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
588
TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
589
TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
590
return (1);
591
}
592
#undef isUnspecified
593
594
/*
595
* Verify file is writable and that the directory
596
* information is setup properly. In doing the latter
597
* we also "freeze" the state of the directory so
598
* that important information is not changed.
599
*/
600
int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
601
{
602
if (tif->tif_mode == O_RDONLY)
603
{
604
TIFFErrorExtR(tif, module, "File not open for writing");
605
return (0);
606
}
607
if (tiles ^ isTiled(tif))
608
{
609
TIFFErrorExtR(tif, module,
610
tiles ? "Can not write tiles to a striped image"
611
: "Can not write scanlines to a tiled image");
612
return (0);
613
}
614
615
_TIFFFillStriles(tif);
616
617
/*
618
* On the first write verify all the required information
619
* has been setup and initialize any data structures that
620
* had to wait until directory information was set.
621
* Note that a lot of our work is assumed to remain valid
622
* because we disallow any of the important parameters
623
* from changing after we start writing (i.e. once
624
* TIFF_BEENWRITING is set, TIFFSetField will only allow
625
* the image's length to be changed).
626
*/
627
if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
628
{
629
TIFFErrorExtR(tif, module,
630
"Must set \"ImageWidth\" before writing data");
631
return (0);
632
}
633
if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
634
{
635
tif->tif_dir.td_nstrips = 0;
636
TIFFErrorExtR(tif, module, "No space for %s arrays",
637
isTiled(tif) ? "tile" : "strip");
638
return (0);
639
}
640
if (isTiled(tif))
641
{
642
tif->tif_tilesize = TIFFTileSize(tif);
643
if (tif->tif_tilesize == 0)
644
return (0);
645
}
646
else
647
tif->tif_tilesize = (tmsize_t)(-1);
648
tif->tif_scanlinesize = TIFFScanlineSize(tif);
649
if (tif->tif_scanlinesize == 0)
650
return (0);
651
tif->tif_flags |= TIFF_BEENWRITING;
652
653
if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
654
tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
655
tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
656
tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
657
tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
658
tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
659
tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
660
tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
661
!(tif->tif_flags & TIFF_DIRTYDIRECT))
662
{
663
TIFFForceStrileArrayWriting(tif);
664
}
665
666
return (1);
667
}
668
669
/*
670
* Setup the raw data buffer used for encoding.
671
*/
672
int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
673
{
674
static const char module[] = "TIFFWriteBufferSetup";
675
676
if (tif->tif_rawdata)
677
{
678
if (tif->tif_flags & TIFF_MYBUFFER)
679
{
680
_TIFFfreeExt(tif, tif->tif_rawdata);
681
tif->tif_flags &= ~TIFF_MYBUFFER;
682
}
683
tif->tif_rawdata = NULL;
684
}
685
if (size == (tmsize_t)(-1))
686
{
687
size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
688
689
/* Adds 10% margin for cases where compression would expand a bit */
690
if (size < TIFF_TMSIZE_T_MAX - size / 10)
691
size += size / 10;
692
/*
693
* Make raw data buffer at least 8K
694
*/
695
if (size < 8 * 1024)
696
size = 8 * 1024;
697
bp = NULL; /* NB: force malloc */
698
}
699
if (bp == NULL)
700
{
701
bp = _TIFFmallocExt(tif, size);
702
if (bp == NULL)
703
{
704
TIFFErrorExtR(tif, module, "No space for output buffer");
705
return (0);
706
}
707
tif->tif_flags |= TIFF_MYBUFFER;
708
}
709
else
710
tif->tif_flags &= ~TIFF_MYBUFFER;
711
tif->tif_rawdata = (uint8_t *)bp;
712
tif->tif_rawdatasize = size;
713
tif->tif_rawcc = 0;
714
tif->tif_rawcp = tif->tif_rawdata;
715
tif->tif_flags |= TIFF_BUFFERSETUP;
716
return (1);
717
}
718
719
/*
720
* Grow the strip data structures by delta strips.
721
*/
722
static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
723
{
724
TIFFDirectory *td = &tif->tif_dir;
725
uint64_t *new_stripoffset;
726
uint64_t *new_stripbytecount;
727
728
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
729
new_stripoffset = (uint64_t *)_TIFFreallocExt(
730
tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
731
new_stripbytecount = (uint64_t *)_TIFFreallocExt(
732
tif, td->td_stripbytecount_p,
733
(td->td_nstrips + delta) * sizeof(uint64_t));
734
if (new_stripoffset == NULL || new_stripbytecount == NULL)
735
{
736
if (new_stripoffset)
737
_TIFFfreeExt(tif, new_stripoffset);
738
if (new_stripbytecount)
739
_TIFFfreeExt(tif, new_stripbytecount);
740
td->td_nstrips = 0;
741
TIFFErrorExtR(tif, module, "No space to expand strip arrays");
742
return (0);
743
}
744
td->td_stripoffset_p = new_stripoffset;
745
td->td_stripbytecount_p = new_stripbytecount;
746
_TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
747
delta * sizeof(uint64_t));
748
_TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
749
delta * sizeof(uint64_t));
750
td->td_nstrips += delta;
751
tif->tif_flags |= TIFF_DIRTYDIRECT;
752
753
return (1);
754
}
755
756
/*
757
* Append the data to the specified strip.
758
*/
759
static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
760
tmsize_t cc)
761
{
762
static const char module[] = "TIFFAppendToStrip";
763
TIFFDirectory *td = &tif->tif_dir;
764
uint64_t m;
765
int64_t old_byte_count = -1;
766
767
if (tif->tif_curoff == 0)
768
tif->tif_lastvalidoff = 0;
769
770
if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0)
771
{
772
assert(td->td_nstrips > 0);
773
774
if (td->td_stripbytecount_p[strip] != 0 &&
775
td->td_stripoffset_p[strip] != 0 &&
776
td->td_stripbytecount_p[strip] >= (uint64_t)cc)
777
{
778
/*
779
* There is already tile data on disk, and the new tile
780
* data we have will fit in the same space. The only
781
* aspect of this that is risky is that there could be
782
* more data to append to this strip before we are done
783
* depending on how we are getting called.
784
*/
785
if (!SeekOK(tif, td->td_stripoffset_p[strip]))
786
{
787
TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
788
(unsigned long)tif->tif_row);
789
return (0);
790
}
791
792
tif->tif_lastvalidoff =
793
td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
794
}
795
else
796
{
797
/*
798
* Seek to end of file, and set that as our location to
799
* write this strip.
800
*/
801
td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
802
tif->tif_flags |= TIFF_DIRTYSTRIP;
803
}
804
805
tif->tif_curoff = td->td_stripoffset_p[strip];
806
807
/*
808
* We are starting a fresh strip/tile, so set the size to zero.
809
*/
810
old_byte_count = td->td_stripbytecount_p[strip];
811
td->td_stripbytecount_p[strip] = 0;
812
}
813
814
m = tif->tif_curoff + cc;
815
if (!(tif->tif_flags & TIFF_BIGTIFF))
816
m = (uint32_t)m;
817
if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
818
{
819
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
820
return (0);
821
}
822
823
if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff &&
824
td->td_stripbytecount_p[strip] > 0)
825
{
826
/* Ouch: we have detected that we are rewriting in place a strip/tile */
827
/* with several calls to TIFFAppendToStrip(). The first call was with */
828
/* a size smaller than the previous size of the strip/tile, so we */
829
/* opted to rewrite in place, but a following call causes us to go */
830
/* outsize of the strip/tile area, so we have to finally go for a */
831
/* append-at-end-of-file strategy, and start by moving what we already
832
*/
833
/* wrote. */
834
tmsize_t tempSize;
835
void *temp;
836
uint64_t offsetRead;
837
uint64_t offsetWrite;
838
uint64_t toCopy = td->td_stripbytecount_p[strip];
839
840
if (toCopy < 1024 * 1024)
841
tempSize = (tmsize_t)toCopy;
842
else
843
tempSize = 1024 * 1024;
844
845
offsetRead = td->td_stripoffset_p[strip];
846
offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
847
848
m = offsetWrite + toCopy + cc;
849
if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
850
{
851
TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
852
return (0);
853
}
854
855
temp = _TIFFmallocExt(tif, tempSize);
856
if (temp == NULL)
857
{
858
TIFFErrorExtR(tif, module, "No space for output buffer");
859
return (0);
860
}
861
862
tif->tif_flags |= TIFF_DIRTYSTRIP;
863
864
td->td_stripoffset_p[strip] = offsetWrite;
865
td->td_stripbytecount_p[strip] = 0;
866
867
/* Move data written by previous calls to us at end of file */
868
while (toCopy > 0)
869
{
870
if (!SeekOK(tif, offsetRead))
871
{
872
TIFFErrorExtR(tif, module, "Seek error");
873
_TIFFfreeExt(tif, temp);
874
return (0);
875
}
876
if (!ReadOK(tif, temp, tempSize))
877
{
878
TIFFErrorExtR(tif, module, "Cannot read");
879
_TIFFfreeExt(tif, temp);
880
return (0);
881
}
882
if (!SeekOK(tif, offsetWrite))
883
{
884
TIFFErrorExtR(tif, module, "Seek error");
885
_TIFFfreeExt(tif, temp);
886
return (0);
887
}
888
if (!WriteOK(tif, temp, tempSize))
889
{
890
TIFFErrorExtR(tif, module, "Cannot write");
891
_TIFFfreeExt(tif, temp);
892
return (0);
893
}
894
offsetRead += tempSize;
895
offsetWrite += tempSize;
896
td->td_stripbytecount_p[strip] += tempSize;
897
toCopy -= tempSize;
898
}
899
_TIFFfreeExt(tif, temp);
900
901
/* Append the data of this call */
902
offsetWrite += cc;
903
m = offsetWrite;
904
}
905
906
if (!WriteOK(tif, data, cc))
907
{
908
TIFFErrorExtR(tif, module, "Write error at scanline %lu",
909
(unsigned long)tif->tif_row);
910
return (0);
911
}
912
tif->tif_curoff = m;
913
td->td_stripbytecount_p[strip] += cc;
914
915
if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
916
tif->tif_flags |= TIFF_DIRTYSTRIP;
917
918
return (1);
919
}
920
921
/*
922
* Internal version of TIFFFlushData that can be
923
* called by ``encodestrip routines'' w/o concern
924
* for infinite recursion.
925
*/
926
int TIFFFlushData1(TIFF *tif)
927
{
928
if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE)
929
{
930
if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
931
(tif->tif_flags & TIFF_NOBITREV) == 0)
932
TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
933
if (!TIFFAppendToStrip(
934
tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
935
tif->tif_rawdata, tif->tif_rawcc))
936
{
937
/* We update those variables even in case of error since there's */
938
/* code that doesn't really check the return code of this */
939
/* function */
940
tif->tif_rawcc = 0;
941
tif->tif_rawcp = tif->tif_rawdata;
942
return (0);
943
}
944
tif->tif_rawcc = 0;
945
tif->tif_rawcp = tif->tif_rawdata;
946
}
947
return (1);
948
}
949
950
/*
951
* Set the current write offset. This should only be
952
* used to set the offset to a known previous location
953
* (very carefully), or to 0 so that the next write gets
954
* appended to the end of the file.
955
*/
956
void TIFFSetWriteOffset(TIFF *tif, toff_t off)
957
{
958
tif->tif_curoff = off;
959
tif->tif_lastvalidoff = 0;
960
}
961
962