2 * Copyright (c) 1988-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
28 * Scanline-oriented Write Support
33 #define STRIPINCR 20 /* expansion factor on strip array */
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))
43 static int TIFFGrowStrips(TIFF
*tif
, uint32_t delta
, const char *module
);
44 static int TIFFAppendToStrip(TIFF
*tif
, uint32_t strip
, uint8_t *data
,
47 int TIFFWriteScanline(TIFF
*tif
, void *buf
, uint32_t row
, uint16_t sample
)
49 static const char module
[] = "TIFFWriteScanline";
50 register TIFFDirectory
*td
;
51 int status
, imagegrew
= 0;
54 if (!WRITECHECKSTRIPS(tif
, module
))
57 * Handle delayed allocation of data buffer. This
58 * permits it to be sized more intelligently (using
59 * directory information).
61 if (!BUFFERCHECK(tif
))
63 tif
->tif_flags
|= TIFF_BUF4WRITE
; /* not strictly sure this is right*/
67 * Extend image length if needed
68 * (but only for PlanarConfig=1).
70 if (row
>= td
->td_imagelength
)
72 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
76 "Can not change \"ImageLength\" when using separate planes");
79 td
->td_imagelength
= row
+ 1;
83 * Calculate strip and check for crossings.
85 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
87 if (sample
>= td
->td_samplesperpixel
)
89 TIFFErrorExtR(tif
, module
, "%lu: Sample out of range, max %lu",
90 (unsigned long)sample
,
91 (unsigned long)td
->td_samplesperpixel
);
94 strip
= sample
* td
->td_stripsperimage
+ row
/ td
->td_rowsperstrip
;
97 strip
= row
/ td
->td_rowsperstrip
;
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).
105 if (strip
>= td
->td_nstrips
&& !TIFFGrowStrips(tif
, 1, module
))
107 if (strip
!= tif
->tif_curstrip
)
110 * Changing strips -- flush any data present.
112 if (!TIFFFlushData(tif
))
114 tif
->tif_curstrip
= strip
;
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).
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)
125 TIFFErrorExtR(tif
, module
, "Zero strips per image");
128 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
129 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0)
131 if (!(*tif
->tif_setupencode
)(tif
))
133 tif
->tif_flags
|= TIFF_CODERSETUP
;
137 tif
->tif_rawcp
= tif
->tif_rawdata
;
139 /* this informs TIFFAppendToStrip() we have changed strip */
142 if (!(*tif
->tif_preencode
)(tif
, sample
))
144 tif
->tif_flags
|= TIFF_POSTENCODE
;
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).
151 if (row
!= tif
->tif_row
)
153 if (row
< tif
->tif_row
)
156 * Moving backwards within the same strip:
157 * backup to the start and then decode
161 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
162 tif
->tif_rawcp
= tif
->tif_rawdata
;
165 * Seek forward to the desired row.
167 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
172 /* swab if needed - note that source buffer will be altered */
173 tif
->tif_postdecode(tif
, (uint8_t *)buf
, tif
->tif_scanlinesize
);
175 status
= (*tif
->tif_encoderow
)(tif
, (uint8_t *)buf
, tif
->tif_scanlinesize
,
178 /* we are now poised at the beginning of the next row */
179 tif
->tif_row
= row
+ 1;
183 /* Make sure that at the first attempt of rewriting a tile/strip, we will have
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
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
)
191 TIFFDirectory
*td
= &tif
->tif_dir
;
192 if (td
->td_stripbytecount_p
[strip_or_tile
] > 0)
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
)
200 if (!(TIFFWriteBufferSetup(
202 (tmsize_t
)TIFFroundup_64(safe_buffer_size
, 1024))))
210 * Encode the supplied data and write it to the
213 * NB: Image length must be setup before writing.
215 tmsize_t
TIFFWriteEncodedStrip(TIFF
*tif
, uint32_t strip
, void *data
,
218 static const char module
[] = "TIFFWriteEncodedStrip";
219 TIFFDirectory
*td
= &tif
->tif_dir
;
222 if (!WRITECHECKSTRIPS(tif
, module
))
223 return ((tmsize_t
)-1);
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
233 if (strip
>= td
->td_nstrips
)
235 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
239 "Can not grow image by strips when using separate planes");
240 return ((tmsize_t
)-1);
242 if (!TIFFGrowStrips(tif
, 1, module
))
243 return ((tmsize_t
)-1);
244 td
->td_stripsperimage
=
245 TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
);
248 * Handle delayed allocation of data buffer. This
249 * permits it to be sized according to the directory
252 if (!BUFFERCHECK(tif
))
253 return ((tmsize_t
)-1);
255 tif
->tif_flags
|= TIFF_BUF4WRITE
;
257 tif
->tif_curstrip
= strip
;
259 /* this informs TIFFAppendToStrip() we have changed or reset strip */
262 if (!_TIFFReserveLargeEnoughWriteBuffer(tif
, strip
))
264 return ((tmsize_t
)(-1));
268 tif
->tif_rawcp
= tif
->tif_rawdata
;
270 if (td
->td_stripsperimage
== 0)
272 TIFFErrorExtR(tif
, module
, "Zero strips per image");
273 return ((tmsize_t
)-1);
276 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
277 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0)
279 if (!(*tif
->tif_setupencode
)(tif
))
280 return ((tmsize_t
)-1);
281 tif
->tif_flags
|= TIFF_CODERSETUP
;
284 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
286 /* shortcut to avoid an extra memcpy() */
287 if (td
->td_compression
== COMPRESSION_NONE
)
289 /* swab if needed - note that source buffer will be altered */
290 tif
->tif_postdecode(tif
, (uint8_t *)data
, cc
);
292 if (!isFillOrder(tif
, td
->td_fillorder
) &&
293 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
294 TIFFReverseBits((uint8_t *)data
, cc
);
296 if (cc
> 0 && !TIFFAppendToStrip(tif
, strip
, (uint8_t *)data
, cc
))
297 return ((tmsize_t
)-1);
301 sample
= (uint16_t)(strip
/ td
->td_stripsperimage
);
302 if (!(*tif
->tif_preencode
)(tif
, sample
))
303 return ((tmsize_t
)-1);
305 /* swab if needed - note that source buffer will be altered */
306 tif
->tif_postdecode(tif
, (uint8_t *)data
, cc
);
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);
319 tif
->tif_rawcp
= tif
->tif_rawdata
;
324 * Write the supplied data to the specified strip.
326 * NB: Image length must be setup before writing.
328 tmsize_t
TIFFWriteRawStrip(TIFF
*tif
, uint32_t strip
, void *data
, tmsize_t cc
)
330 static const char module
[] = "TIFFWriteRawStrip";
331 TIFFDirectory
*td
= &tif
->tif_dir
;
333 if (!WRITECHECKSTRIPS(tif
, module
))
334 return ((tmsize_t
)-1);
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
344 if (strip
>= td
->td_nstrips
)
346 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
350 "Can not grow image by strips when using separate planes");
351 return ((tmsize_t
)-1);
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).
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);
365 if (tif
->tif_curstrip
!= strip
)
367 tif
->tif_curstrip
= strip
;
369 /* this informs TIFFAppendToStrip() we have changed or reset strip */
373 if (td
->td_stripsperimage
== 0)
375 TIFFErrorExtR(tif
, module
, "Zero strips per image");
376 return ((tmsize_t
)-1);
378 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
379 return (TIFFAppendToStrip(tif
, strip
, (uint8_t *)data
, cc
) ? cc
384 * Write and compress a tile of data. The
385 * tile is selected by the (x,y,z,s) coordinates.
387 tmsize_t
TIFFWriteTile(TIFF
*tif
, void *buf
, uint32_t x
, uint32_t y
, uint32_t z
,
390 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
391 return ((tmsize_t
)(-1));
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.
398 return (TIFFWriteEncodedTile(tif
, TIFFComputeTile(tif
, x
, y
, z
, s
), buf
,
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.
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).
414 tmsize_t
TIFFWriteEncodedTile(TIFF
*tif
, uint32_t tile
, void *data
, tmsize_t cc
)
416 static const char module
[] = "TIFFWriteEncodedTile";
421 if (!WRITECHECKTILES(tif
, module
))
422 return ((tmsize_t
)(-1));
424 if (tile
>= td
->td_nstrips
)
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));
431 * Handle delayed allocation of data buffer. This
432 * permits it to be sized more intelligently (using
433 * directory information).
435 if (!BUFFERCHECK(tif
))
436 return ((tmsize_t
)(-1));
438 tif
->tif_flags
|= TIFF_BUF4WRITE
;
440 tif
->tif_curtile
= tile
;
442 /* this informs TIFFAppendToStrip() we have changed or reset tile */
445 if (!_TIFFReserveLargeEnoughWriteBuffer(tif
, tile
))
447 return ((tmsize_t
)(-1));
451 tif
->tif_rawcp
= tif
->tif_rawdata
;
454 * Compute tiles per row & per column to compute
455 * current row and column
457 howmany32
= TIFFhowmany_32(td
->td_imagelength
, td
->td_tilelength
);
460 TIFFErrorExtR(tif
, module
, "Zero tiles");
461 return ((tmsize_t
)(-1));
463 tif
->tif_row
= (tile
% howmany32
) * td
->td_tilelength
;
464 howmany32
= TIFFhowmany_32(td
->td_imagewidth
, td
->td_tilewidth
);
467 TIFFErrorExtR(tif
, module
, "Zero tiles");
468 return ((tmsize_t
)(-1));
470 tif
->tif_col
= (tile
% howmany32
) * td
->td_tilewidth
;
472 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0)
474 if (!(*tif
->tif_setupencode
)(tif
))
475 return ((tmsize_t
)(-1));
476 tif
->tif_flags
|= TIFF_CODERSETUP
;
478 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
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.
485 if (cc
< 1 || cc
> tif
->tif_tilesize
)
486 cc
= tif
->tif_tilesize
;
488 /* shortcut to avoid an extra memcpy() */
489 if (td
->td_compression
== COMPRESSION_NONE
)
491 /* swab if needed - note that source buffer will be altered */
492 tif
->tif_postdecode(tif
, (uint8_t *)data
, cc
);
494 if (!isFillOrder(tif
, td
->td_fillorder
) &&
495 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
496 TIFFReverseBits((uint8_t *)data
, cc
);
498 if (cc
> 0 && !TIFFAppendToStrip(tif
, tile
, (uint8_t *)data
, cc
))
499 return ((tmsize_t
)-1);
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
);
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));
520 tif
->tif_rawcp
= tif
->tif_rawdata
;
525 * Write the supplied data to the specified strip.
526 * There must be space for the data; we don't check
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).
533 tmsize_t
TIFFWriteRawTile(TIFF
*tif
, uint32_t tile
, void *data
, tmsize_t cc
)
535 static const char module
[] = "TIFFWriteRawTile";
537 if (!WRITECHECKTILES(tif
, module
))
538 return ((tmsize_t
)(-1));
539 if (tile
>= tif
->tif_dir
.td_nstrips
)
541 TIFFErrorExtR(tif
, module
, "Tile %lu out of range, max %lu",
543 (unsigned long)tif
->tif_dir
.td_nstrips
);
544 return ((tmsize_t
)(-1));
546 return (TIFFAppendToStrip(tif
, tile
, (uint8_t *)data
, cc
) ? cc
550 #define isUnspecified(tif, f) \
551 (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
553 int TIFFSetupStrips(TIFF
*tif
)
555 TIFFDirectory
*td
= &tif
->tif_dir
;
558 td
->td_stripsperimage
= isUnspecified(tif
, FIELD_TILEDIMENSIONS
)
559 ? td
->td_samplesperpixel
560 : TIFFNumberOfTiles(tif
);
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
))
570 TIFFErrorExtR(tif
, "TIFFSetupStrips",
571 "Too large Strip/Tile Offsets/ByteCounts arrays");
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
)
583 * Place data at the end-of-file
584 * (by setting offsets to zero).
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
);
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.
600 int TIFFWriteCheck(TIFF
*tif
, int tiles
, const char *module
)
602 if (tif
->tif_mode
== O_RDONLY
)
604 TIFFErrorExtR(tif
, module
, "File not open for writing");
607 if (tiles
^ isTiled(tif
))
609 TIFFErrorExtR(tif
, module
,
610 tiles
? "Can not write tiles to a striped image"
611 : "Can not write scanlines to a tiled image");
615 _TIFFFillStriles(tif
);
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).
627 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
))
629 TIFFErrorExtR(tif
, module
,
630 "Must set \"ImageWidth\" before writing data");
633 if (tif
->tif_dir
.td_stripoffset_p
== NULL
&& !TIFFSetupStrips(tif
))
635 tif
->tif_dir
.td_nstrips
= 0;
636 TIFFErrorExtR(tif
, module
, "No space for %s arrays",
637 isTiled(tif
) ? "tile" : "strip");
642 tif
->tif_tilesize
= TIFFTileSize(tif
);
643 if (tif
->tif_tilesize
== 0)
647 tif
->tif_tilesize
= (tmsize_t
)(-1);
648 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
649 if (tif
->tif_scanlinesize
== 0)
651 tif
->tif_flags
|= TIFF_BEENWRITING
;
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
))
663 TIFFForceStrileArrayWriting(tif
);
670 * Setup the raw data buffer used for encoding.
672 int TIFFWriteBufferSetup(TIFF
*tif
, void *bp
, tmsize_t size
)
674 static const char module
[] = "TIFFWriteBufferSetup";
676 if (tif
->tif_rawdata
)
678 if (tif
->tif_flags
& TIFF_MYBUFFER
)
680 _TIFFfreeExt(tif
, tif
->tif_rawdata
);
681 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
683 tif
->tif_rawdata
= NULL
;
685 if (size
== (tmsize_t
)(-1))
687 size
= (isTiled(tif
) ? tif
->tif_tilesize
: TIFFStripSize(tif
));
689 /* Adds 10% margin for cases where compression would expand a bit */
690 if (size
< TIFF_TMSIZE_T_MAX
- size
/ 10)
693 * Make raw data buffer at least 8K
697 bp
= NULL
; /* NB: force malloc */
701 bp
= _TIFFmallocExt(tif
, size
);
704 TIFFErrorExtR(tif
, module
, "No space for output buffer");
707 tif
->tif_flags
|= TIFF_MYBUFFER
;
710 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
711 tif
->tif_rawdata
= (uint8_t *)bp
;
712 tif
->tif_rawdatasize
= size
;
714 tif
->tif_rawcp
= tif
->tif_rawdata
;
715 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
720 * Grow the strip data structures by delta strips.
722 static int TIFFGrowStrips(TIFF
*tif
, uint32_t delta
, const char *module
)
724 TIFFDirectory
*td
= &tif
->tif_dir
;
725 uint64_t *new_stripoffset
;
726 uint64_t *new_stripbytecount
;
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
)
737 _TIFFfreeExt(tif
, new_stripoffset
);
738 if (new_stripbytecount
)
739 _TIFFfreeExt(tif
, new_stripbytecount
);
741 TIFFErrorExtR(tif
, module
, "No space to expand strip arrays");
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
;
757 * Append the data to the specified strip.
759 static int TIFFAppendToStrip(TIFF
*tif
, uint32_t strip
, uint8_t *data
,
762 static const char module
[] = "TIFFAppendToStrip";
763 TIFFDirectory
*td
= &tif
->tif_dir
;
765 int64_t old_byte_count
= -1;
767 if (tif
->tif_curoff
== 0)
768 tif
->tif_lastvalidoff
= 0;
770 if (td
->td_stripoffset_p
[strip
] == 0 || tif
->tif_curoff
== 0)
772 assert(td
->td_nstrips
> 0);
774 if (td
->td_stripbytecount_p
[strip
] != 0 &&
775 td
->td_stripoffset_p
[strip
] != 0 &&
776 td
->td_stripbytecount_p
[strip
] >= (uint64_t)cc
)
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.
785 if (!SeekOK(tif
, td
->td_stripoffset_p
[strip
]))
787 TIFFErrorExtR(tif
, module
, "Seek error at scanline %lu",
788 (unsigned long)tif
->tif_row
);
792 tif
->tif_lastvalidoff
=
793 td
->td_stripoffset_p
[strip
] + td
->td_stripbytecount_p
[strip
];
798 * Seek to end of file, and set that as our location to
801 td
->td_stripoffset_p
[strip
] = TIFFSeekFile(tif
, 0, SEEK_END
);
802 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
805 tif
->tif_curoff
= td
->td_stripoffset_p
[strip
];
808 * We are starting a fresh strip/tile, so set the size to zero.
810 old_byte_count
= td
->td_stripbytecount_p
[strip
];
811 td
->td_stripbytecount_p
[strip
] = 0;
814 m
= tif
->tif_curoff
+ cc
;
815 if (!(tif
->tif_flags
& TIFF_BIGTIFF
))
817 if ((m
< tif
->tif_curoff
) || (m
< (uint64_t)cc
))
819 TIFFErrorExtR(tif
, module
, "Maximum TIFF file size exceeded");
823 if (tif
->tif_lastvalidoff
!= 0 && m
> tif
->tif_lastvalidoff
&&
824 td
->td_stripbytecount_p
[strip
] > 0)
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
837 uint64_t offsetWrite
;
838 uint64_t toCopy
= td
->td_stripbytecount_p
[strip
];
840 if (toCopy
< 1024 * 1024)
841 tempSize
= (tmsize_t
)toCopy
;
843 tempSize
= 1024 * 1024;
845 offsetRead
= td
->td_stripoffset_p
[strip
];
846 offsetWrite
= TIFFSeekFile(tif
, 0, SEEK_END
);
848 m
= offsetWrite
+ toCopy
+ cc
;
849 if (!(tif
->tif_flags
& TIFF_BIGTIFF
) && m
!= (uint32_t)m
)
851 TIFFErrorExtR(tif
, module
, "Maximum TIFF file size exceeded");
855 temp
= _TIFFmallocExt(tif
, tempSize
);
858 TIFFErrorExtR(tif
, module
, "No space for output buffer");
862 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
864 td
->td_stripoffset_p
[strip
] = offsetWrite
;
865 td
->td_stripbytecount_p
[strip
] = 0;
867 /* Move data written by previous calls to us at end of file */
870 if (!SeekOK(tif
, offsetRead
))
872 TIFFErrorExtR(tif
, module
, "Seek error");
873 _TIFFfreeExt(tif
, temp
);
876 if (!ReadOK(tif
, temp
, tempSize
))
878 TIFFErrorExtR(tif
, module
, "Cannot read");
879 _TIFFfreeExt(tif
, temp
);
882 if (!SeekOK(tif
, offsetWrite
))
884 TIFFErrorExtR(tif
, module
, "Seek error");
885 _TIFFfreeExt(tif
, temp
);
888 if (!WriteOK(tif
, temp
, tempSize
))
890 TIFFErrorExtR(tif
, module
, "Cannot write");
891 _TIFFfreeExt(tif
, temp
);
894 offsetRead
+= tempSize
;
895 offsetWrite
+= tempSize
;
896 td
->td_stripbytecount_p
[strip
] += tempSize
;
899 _TIFFfreeExt(tif
, temp
);
901 /* Append the data of this call */
906 if (!WriteOK(tif
, data
, cc
))
908 TIFFErrorExtR(tif
, module
, "Write error at scanline %lu",
909 (unsigned long)tif
->tif_row
);
913 td
->td_stripbytecount_p
[strip
] += cc
;
915 if ((int64_t)td
->td_stripbytecount_p
[strip
] != old_byte_count
)
916 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
922 * Internal version of TIFFFlushData that can be
923 * called by ``encodestrip routines'' w/o concern
924 * for infinite recursion.
926 int TIFFFlushData1(TIFF
*tif
)
928 if (tif
->tif_rawcc
> 0 && tif
->tif_flags
& TIFF_BUF4WRITE
)
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
))
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 */
941 tif
->tif_rawcp
= tif
->tif_rawdata
;
945 tif
->tif_rawcp
= tif
->tif_rawdata
;
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.
956 void TIFFSetWriteOffset(TIFF
*tif
, toff_t off
)
958 tif
->tif_curoff
= off
;
959 tif
->tif_lastvalidoff
= 0;