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
, tmsize_t cc
);
47 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
) { /* extend image */
71 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
72 TIFFErrorExt(tif
->tif_clientdata
, module
,
73 "Can not change \"ImageLength\" when using separate planes");
76 td
->td_imagelength
= row
+1;
80 * Calculate strip and check for crossings.
82 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
83 if (sample
>= td
->td_samplesperpixel
) {
84 TIFFErrorExt(tif
->tif_clientdata
, module
,
85 "%lu: Sample out of range, max %lu",
86 (unsigned long) sample
, (unsigned long) td
->td_samplesperpixel
);
89 strip
= sample
*td
->td_stripsperimage
+ row
/td
->td_rowsperstrip
;
91 strip
= row
/ td
->td_rowsperstrip
;
93 * Check strip array to make sure there's space. We don't support
94 * dynamically growing files that have data organized in separate
95 * bitplanes because it's too painful. In that case we require that
96 * the imagelength be set properly before the first write (so that the
97 * strips array will be fully allocated above).
99 if (strip
>= td
->td_nstrips
&& !TIFFGrowStrips(tif
, 1, module
))
101 if (strip
!= tif
->tif_curstrip
) {
103 * Changing strips -- flush any data present.
105 if (!TIFFFlushData(tif
))
107 tif
->tif_curstrip
= strip
;
109 * Watch out for a growing image. The value of strips/image
110 * will initially be 1 (since it can't be deduced until the
111 * imagelength is known).
113 if (strip
>= td
->td_stripsperimage
&& imagegrew
)
114 td
->td_stripsperimage
=
115 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
116 if (td
->td_stripsperimage
== 0) {
117 TIFFErrorExt(tif
->tif_clientdata
, module
, "Zero strips per image");
121 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
122 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
123 if (!(*tif
->tif_setupencode
)(tif
))
125 tif
->tif_flags
|= TIFF_CODERSETUP
;
129 tif
->tif_rawcp
= tif
->tif_rawdata
;
131 if( td
->td_stripbytecount_p
[strip
] > 0 )
133 /* if we are writing over existing tiles, zero length */
134 td
->td_stripbytecount_p
[strip
] = 0;
136 /* this forces TIFFAppendToStrip() to do a seek */
140 if (!(*tif
->tif_preencode
)(tif
, sample
))
142 tif
->tif_flags
|= TIFF_POSTENCODE
;
145 * Ensure the write is either sequential or at the
146 * beginning of a strip (or that we can randomly
147 * access the data -- i.e. no encoding).
149 if (row
!= tif
->tif_row
) {
150 if (row
< tif
->tif_row
) {
152 * Moving backwards within the same strip:
153 * backup to the start and then decode
156 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
158 tif
->tif_rawcp
= tif
->tif_rawdata
;
161 * Seek forward to the desired row.
163 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
168 /* swab if needed - note that source buffer will be altered */
169 tif
->tif_postdecode(tif
, (uint8_t*) buf
, tif
->tif_scanlinesize
);
171 status
= (*tif
->tif_encoderow
)(tif
, (uint8_t*) buf
,
172 tif
->tif_scanlinesize
, sample
);
174 /* we are now poised at the beginning of the next row */
175 tif
->tif_row
= row
+ 1;
179 /* Make sure that at the first attempt of rewriting a tile/strip, we will have */
180 /* more bytes available in the output buffer than the previous byte count, */
181 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
182 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
183 static int _TIFFReserveLargeEnoughWriteBuffer(TIFF
* tif
, uint32_t strip_or_tile
)
185 TIFFDirectory
*td
= &tif
->tif_dir
;
186 if( td
->td_stripbytecount_p
[strip_or_tile
] > 0 )
188 /* The +1 is to ensure at least one extra bytes */
189 /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
190 uint64_t safe_buffer_size
= (uint64_t)(td
->td_stripbytecount_p
[strip_or_tile
] + 1 + 4);
191 if( tif
->tif_rawdatasize
<= (tmsize_t
)safe_buffer_size
)
193 if( !(TIFFWriteBufferSetup(tif
, NULL
,
194 (tmsize_t
)TIFFroundup_64(safe_buffer_size
, 1024))) )
198 /* Force TIFFAppendToStrip() to consider placing data at end
206 * Encode the supplied data and write it to the
209 * NB: Image length must be setup before writing.
212 TIFFWriteEncodedStrip(TIFF
* tif
, uint32_t strip
, void* data
, tmsize_t cc
)
214 static const char module
[] = "TIFFWriteEncodedStrip";
215 TIFFDirectory
*td
= &tif
->tif_dir
;
218 if (!WRITECHECKSTRIPS(tif
, module
))
219 return ((tmsize_t
) -1);
221 * Check strip array to make sure there's space.
222 * We don't support dynamically growing files that
223 * have data organized in separate bitplanes because
224 * it's too painful. In that case we require that
225 * the imagelength be set properly before the first
226 * write (so that the strips array will be fully
229 if (strip
>= td
->td_nstrips
) {
230 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
231 TIFFErrorExt(tif
->tif_clientdata
, module
,
232 "Can not grow image by strips when using separate planes");
233 return ((tmsize_t
) -1);
235 if (!TIFFGrowStrips(tif
, 1, module
))
236 return ((tmsize_t
) -1);
237 td
->td_stripsperimage
=
238 TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
);
241 * Handle delayed allocation of data buffer. This
242 * permits it to be sized according to the directory
245 if (!BUFFERCHECK(tif
))
246 return ((tmsize_t
) -1);
248 tif
->tif_flags
|= TIFF_BUF4WRITE
;
249 tif
->tif_curstrip
= strip
;
251 if( !_TIFFReserveLargeEnoughWriteBuffer(tif
, strip
) ) {
252 return ((tmsize_t
)(-1));
256 tif
->tif_rawcp
= tif
->tif_rawdata
;
258 if (td
->td_stripsperimage
== 0) {
259 TIFFErrorExt(tif
->tif_clientdata
, module
, "Zero strips per image");
260 return ((tmsize_t
) -1);
263 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
264 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
265 if (!(*tif
->tif_setupencode
)(tif
))
266 return ((tmsize_t
) -1);
267 tif
->tif_flags
|= TIFF_CODERSETUP
;
270 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
272 /* shortcut to avoid an extra memcpy() */
273 if( td
->td_compression
== COMPRESSION_NONE
)
275 /* swab if needed - note that source buffer will be altered */
276 tif
->tif_postdecode(tif
, (uint8_t*) data
, cc
);
278 if (!isFillOrder(tif
, td
->td_fillorder
) &&
279 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
280 TIFFReverseBits((uint8_t*) data
, cc
);
283 !TIFFAppendToStrip(tif
, strip
, (uint8_t*) data
, cc
))
284 return ((tmsize_t
) -1);
288 sample
= (uint16_t)(strip
/ td
->td_stripsperimage
);
289 if (!(*tif
->tif_preencode
)(tif
, sample
))
290 return ((tmsize_t
) -1);
292 /* swab if needed - note that source buffer will be altered */
293 tif
->tif_postdecode(tif
, (uint8_t*) data
, cc
);
295 if (!(*tif
->tif_encodestrip
)(tif
, (uint8_t*) data
, cc
, sample
))
296 return ((tmsize_t
) -1);
297 if (!(*tif
->tif_postencode
)(tif
))
298 return ((tmsize_t
) -1);
299 if (!isFillOrder(tif
, td
->td_fillorder
) &&
300 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
301 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
302 if (tif
->tif_rawcc
> 0 &&
303 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
304 return ((tmsize_t
) -1);
306 tif
->tif_rawcp
= tif
->tif_rawdata
;
311 * Write the supplied data to the specified strip.
313 * NB: Image length must be setup before writing.
316 TIFFWriteRawStrip(TIFF
* tif
, uint32_t strip
, void* data
, tmsize_t cc
)
318 static const char module
[] = "TIFFWriteRawStrip";
319 TIFFDirectory
*td
= &tif
->tif_dir
;
321 if (!WRITECHECKSTRIPS(tif
, module
))
322 return ((tmsize_t
) -1);
324 * Check strip array to make sure there's space.
325 * We don't support dynamically growing files that
326 * have data organized in separate bitplanes because
327 * it's too painful. In that case we require that
328 * the imagelength be set properly before the first
329 * write (so that the strips array will be fully
332 if (strip
>= td
->td_nstrips
) {
333 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
334 TIFFErrorExt(tif
->tif_clientdata
, module
,
335 "Can not grow image by strips when using separate planes");
336 return ((tmsize_t
) -1);
339 * Watch out for a growing image. The value of
340 * strips/image will initially be 1 (since it
341 * can't be deduced until the imagelength is known).
343 if (strip
>= td
->td_stripsperimage
)
344 td
->td_stripsperimage
=
345 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
346 if (!TIFFGrowStrips(tif
, 1, module
))
347 return ((tmsize_t
) -1);
349 tif
->tif_curstrip
= strip
;
350 if (td
->td_stripsperimage
== 0) {
351 TIFFErrorExt(tif
->tif_clientdata
, module
,"Zero strips per image");
352 return ((tmsize_t
) -1);
354 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
355 return (TIFFAppendToStrip(tif
, strip
, (uint8_t*) data
, cc
) ?
360 * Write and compress a tile of data. The
361 * tile is selected by the (x,y,z,s) coordinates.
364 TIFFWriteTile(TIFF
* tif
, void* buf
, uint32_t x
, uint32_t y
, uint32_t z
, uint16_t s
)
366 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
367 return ((tmsize_t
)(-1));
369 * NB: A tile size of -1 is used instead of tif_tilesize knowing
370 * that TIFFWriteEncodedTile will clamp this to the tile size.
371 * This is done because the tile size may not be defined until
372 * after the output buffer is setup in TIFFWriteBufferSetup.
374 return (TIFFWriteEncodedTile(tif
,
375 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tmsize_t
)(-1)));
379 * Encode the supplied data and write it to the
380 * specified tile. There must be space for the
381 * data. The function clamps individual writes
382 * to a tile to the tile size, but does not (and
383 * can not) check that multiple writes to the same
384 * tile do not write more than tile size data.
386 * NB: Image length must be setup before writing; this
387 * interface does not support automatically growing
388 * the image on each write (as TIFFWriteScanline does).
391 TIFFWriteEncodedTile(TIFF
* tif
, uint32_t tile
, void* data
, tmsize_t cc
)
393 static const char module
[] = "TIFFWriteEncodedTile";
398 if (!WRITECHECKTILES(tif
, module
))
399 return ((tmsize_t
)(-1));
401 if (tile
>= td
->td_nstrips
) {
402 TIFFErrorExt(tif
->tif_clientdata
, module
, "Tile %lu out of range, max %lu",
403 (unsigned long) tile
, (unsigned long) td
->td_nstrips
);
404 return ((tmsize_t
)(-1));
407 * Handle delayed allocation of data buffer. This
408 * permits it to be sized more intelligently (using
409 * directory information).
411 if (!BUFFERCHECK(tif
))
412 return ((tmsize_t
)(-1));
414 tif
->tif_flags
|= TIFF_BUF4WRITE
;
415 tif
->tif_curtile
= tile
;
417 if( !_TIFFReserveLargeEnoughWriteBuffer(tif
, tile
) ) {
418 return ((tmsize_t
)(-1));
422 tif
->tif_rawcp
= tif
->tif_rawdata
;
425 * Compute tiles per row & per column to compute
426 * current row and column
428 howmany32
=TIFFhowmany_32(td
->td_imagelength
, td
->td_tilelength
);
429 if (howmany32
== 0) {
430 TIFFErrorExt(tif
->tif_clientdata
,module
,"Zero tiles");
431 return ((tmsize_t
)(-1));
433 tif
->tif_row
= (tile
% howmany32
) * td
->td_tilelength
;
434 howmany32
=TIFFhowmany_32(td
->td_imagewidth
, td
->td_tilewidth
);
435 if (howmany32
== 0) {
436 TIFFErrorExt(tif
->tif_clientdata
,module
,"Zero tiles");
437 return ((tmsize_t
)(-1));
439 tif
->tif_col
= (tile
% howmany32
) * td
->td_tilewidth
;
441 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
442 if (!(*tif
->tif_setupencode
)(tif
))
443 return ((tmsize_t
)(-1));
444 tif
->tif_flags
|= TIFF_CODERSETUP
;
446 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
449 * Clamp write amount to the tile size. This is mostly
450 * done so that callers can pass in some large number
451 * (e.g. -1) and have the tile size used instead.
453 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
454 cc
= tif
->tif_tilesize
;
456 /* shortcut to avoid an extra memcpy() */
457 if( td
->td_compression
== COMPRESSION_NONE
)
459 /* swab if needed - note that source buffer will be altered */
460 tif
->tif_postdecode(tif
, (uint8_t*) data
, cc
);
462 if (!isFillOrder(tif
, td
->td_fillorder
) &&
463 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
464 TIFFReverseBits((uint8_t*) data
, cc
);
467 !TIFFAppendToStrip(tif
, tile
, (uint8_t*) data
, cc
))
468 return ((tmsize_t
) -1);
472 sample
= (uint16_t)(tile
/ td
->td_stripsperimage
);
473 if (!(*tif
->tif_preencode
)(tif
, sample
))
474 return ((tmsize_t
)(-1));
475 /* swab if needed - note that source buffer will be altered */
476 tif
->tif_postdecode(tif
, (uint8_t*) data
, cc
);
478 if (!(*tif
->tif_encodetile
)(tif
, (uint8_t*) data
, cc
, sample
))
479 return ((tmsize_t
) -1);
480 if (!(*tif
->tif_postencode
)(tif
))
481 return ((tmsize_t
)(-1));
482 if (!isFillOrder(tif
, td
->td_fillorder
) &&
483 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
484 TIFFReverseBits((uint8_t*)tif
->tif_rawdata
, tif
->tif_rawcc
);
485 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
486 tif
->tif_rawdata
, tif
->tif_rawcc
))
487 return ((tmsize_t
)(-1));
489 tif
->tif_rawcp
= tif
->tif_rawdata
;
494 * Write the supplied data to the specified strip.
495 * There must be space for the data; we don't check
498 * NB: Image length must be setup before writing; this
499 * interface does not support automatically growing
500 * the image on each write (as TIFFWriteScanline does).
503 TIFFWriteRawTile(TIFF
* tif
, uint32_t tile
, void* data
, tmsize_t cc
)
505 static const char module
[] = "TIFFWriteRawTile";
507 if (!WRITECHECKTILES(tif
, module
))
508 return ((tmsize_t
)(-1));
509 if (tile
>= tif
->tif_dir
.td_nstrips
) {
510 TIFFErrorExt(tif
->tif_clientdata
, module
, "Tile %lu out of range, max %lu",
511 (unsigned long) tile
,
512 (unsigned long) tif
->tif_dir
.td_nstrips
);
513 return ((tmsize_t
)(-1));
515 return (TIFFAppendToStrip(tif
, tile
, (uint8_t*) data
, cc
) ?
516 cc
: (tmsize_t
)(-1));
519 #define isUnspecified(tif, f) \
520 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
523 TIFFSetupStrips(TIFF
* tif
)
525 TIFFDirectory
* td
= &tif
->tif_dir
;
528 td
->td_stripsperimage
=
529 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
530 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
532 td
->td_stripsperimage
=
533 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
534 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
535 td
->td_nstrips
= td
->td_stripsperimage
;
536 /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
537 if( td
->td_nstrips
>= 0x80000000U
/ ((tif
->tif_flags
&TIFF_BIGTIFF
)?0x8U
:0x4U
) )
539 TIFFErrorExt(tif
->tif_clientdata
, "TIFFSetupStrips",
540 "Too large Strip/Tile Offsets/ByteCounts arrays");
543 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
544 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
545 td
->td_stripoffset_p
= (uint64_t *)
546 _TIFFCheckMalloc(tif
, td
->td_nstrips
, sizeof (uint64_t),
547 "for \"StripOffsets\" array");
548 td
->td_stripbytecount_p
= (uint64_t *)
549 _TIFFCheckMalloc(tif
, td
->td_nstrips
, sizeof (uint64_t),
550 "for \"StripByteCounts\" array");
551 if (td
->td_stripoffset_p
== NULL
|| td
->td_stripbytecount_p
== NULL
)
554 * Place data at the end-of-file
555 * (by setting offsets to zero).
557 _TIFFmemset(td
->td_stripoffset_p
, 0, td
->td_nstrips
*sizeof (uint64_t));
558 _TIFFmemset(td
->td_stripbytecount_p
, 0, td
->td_nstrips
*sizeof (uint64_t));
559 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
560 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
566 * Verify file is writable and that the directory
567 * information is setup properly. In doing the latter
568 * we also "freeze" the state of the directory so
569 * that important information is not changed.
572 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module
)
574 if (tif
->tif_mode
== O_RDONLY
) {
575 TIFFErrorExt(tif
->tif_clientdata
, module
, "File not open for writing");
578 if (tiles
^ isTiled(tif
)) {
579 TIFFErrorExt(tif
->tif_clientdata
, module
, tiles
?
580 "Can not write tiles to a striped image" :
581 "Can not write scanlines to a tiled image");
585 _TIFFFillStriles( tif
);
588 * On the first write verify all the required information
589 * has been setup and initialize any data structures that
590 * had to wait until directory information was set.
591 * Note that a lot of our work is assumed to remain valid
592 * because we disallow any of the important parameters
593 * from changing after we start writing (i.e. once
594 * TIFF_BEENWRITING is set, TIFFSetField will only allow
595 * the image's length to be changed).
597 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
598 TIFFErrorExt(tif
->tif_clientdata
, module
,
599 "Must set \"ImageWidth\" before writing data");
602 if (tif
->tif_dir
.td_samplesperpixel
== 1) {
604 * Planarconfiguration is irrelevant in case of single band
605 * images and need not be included. We will set it anyway,
606 * because this field is used in other parts of library even
607 * in the single band case.
609 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
))
610 tif
->tif_dir
.td_planarconfig
= PLANARCONFIG_CONTIG
;
612 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
613 TIFFErrorExt(tif
->tif_clientdata
, module
,
614 "Must set \"PlanarConfiguration\" before writing data");
618 if (tif
->tif_dir
.td_stripoffset_p
== NULL
&& !TIFFSetupStrips(tif
)) {
619 tif
->tif_dir
.td_nstrips
= 0;
620 TIFFErrorExt(tif
->tif_clientdata
, module
, "No space for %s arrays",
621 isTiled(tif
) ? "tile" : "strip");
626 tif
->tif_tilesize
= TIFFTileSize(tif
);
627 if (tif
->tif_tilesize
== 0)
631 tif
->tif_tilesize
= (tmsize_t
)(-1);
632 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
633 if (tif
->tif_scanlinesize
== 0)
635 tif
->tif_flags
|= TIFF_BEENWRITING
;
637 if( tif
->tif_dir
.td_stripoffset_entry
.tdir_tag
!= 0 &&
638 tif
->tif_dir
.td_stripoffset_entry
.tdir_count
== 0 &&
639 tif
->tif_dir
.td_stripoffset_entry
.tdir_type
== 0 &&
640 tif
->tif_dir
.td_stripoffset_entry
.tdir_offset
.toff_long8
== 0 &&
641 tif
->tif_dir
.td_stripbytecount_entry
.tdir_tag
!= 0 &&
642 tif
->tif_dir
.td_stripbytecount_entry
.tdir_count
== 0 &&
643 tif
->tif_dir
.td_stripbytecount_entry
.tdir_type
== 0 &&
644 tif
->tif_dir
.td_stripbytecount_entry
.tdir_offset
.toff_long8
== 0 &&
645 !(tif
->tif_flags
& TIFF_DIRTYDIRECT
) )
647 TIFFForceStrileArrayWriting(tif
);
654 * Setup the raw data buffer used for encoding.
657 TIFFWriteBufferSetup(TIFF
* tif
, void* bp
, tmsize_t size
)
659 static const char module
[] = "TIFFWriteBufferSetup";
661 if (tif
->tif_rawdata
) {
662 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
663 _TIFFfree(tif
->tif_rawdata
);
664 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
666 tif
->tif_rawdata
= NULL
;
668 if (size
== (tmsize_t
)(-1)) {
669 size
= (isTiled(tif
) ?
670 tif
->tif_tilesize
: TIFFStripSize(tif
));
672 /* Adds 10% margin for cases where compression would expand a bit */
673 if( size
< TIFF_TMSIZE_T_MAX
- size
/ 10 )
676 * Make raw data buffer at least 8K
680 bp
= NULL
; /* NB: force malloc */
683 bp
= _TIFFmalloc(size
);
685 TIFFErrorExt(tif
->tif_clientdata
, module
, "No space for output buffer");
688 tif
->tif_flags
|= TIFF_MYBUFFER
;
690 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
691 tif
->tif_rawdata
= (uint8_t*) bp
;
692 tif
->tif_rawdatasize
= size
;
694 tif
->tif_rawcp
= tif
->tif_rawdata
;
695 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
700 * Grow the strip data structures by delta strips.
703 TIFFGrowStrips(TIFF
* tif
, uint32_t delta
, const char* module
)
705 TIFFDirectory
*td
= &tif
->tif_dir
;
706 uint64_t* new_stripoffset
;
707 uint64_t* new_stripbytecount
;
709 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
710 new_stripoffset
= (uint64_t*)_TIFFrealloc(td
->td_stripoffset_p
,
711 (td
->td_nstrips
+ delta
) * sizeof (uint64_t));
712 new_stripbytecount
= (uint64_t*)_TIFFrealloc(td
->td_stripbytecount_p
,
713 (td
->td_nstrips
+ delta
) * sizeof (uint64_t));
714 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
716 _TIFFfree(new_stripoffset
);
717 if (new_stripbytecount
)
718 _TIFFfree(new_stripbytecount
);
720 TIFFErrorExt(tif
->tif_clientdata
, module
, "No space to expand strip arrays");
723 td
->td_stripoffset_p
= new_stripoffset
;
724 td
->td_stripbytecount_p
= new_stripbytecount
;
725 _TIFFmemset(td
->td_stripoffset_p
+ td
->td_nstrips
,
726 0, delta
*sizeof (uint64_t));
727 _TIFFmemset(td
->td_stripbytecount_p
+ td
->td_nstrips
,
728 0, delta
*sizeof (uint64_t));
729 td
->td_nstrips
+= delta
;
730 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
736 * Append the data to the specified strip.
739 TIFFAppendToStrip(TIFF
* tif
, uint32_t strip
, uint8_t* data
, tmsize_t cc
)
741 static const char module
[] = "TIFFAppendToStrip";
742 TIFFDirectory
*td
= &tif
->tif_dir
;
744 int64_t old_byte_count
= -1;
746 if (td
->td_stripoffset_p
[strip
] == 0 || tif
->tif_curoff
== 0) {
747 assert(td
->td_nstrips
> 0);
749 if( td
->td_stripbytecount_p
[strip
] != 0
750 && td
->td_stripoffset_p
[strip
] != 0
751 && td
->td_stripbytecount_p
[strip
] >= (uint64_t) cc
)
754 * There is already tile data on disk, and the new tile
755 * data we have will fit in the same space. The only
756 * aspect of this that is risky is that there could be
757 * more data to append to this strip before we are done
758 * depending on how we are getting called.
760 if (!SeekOK(tif
, td
->td_stripoffset_p
[strip
])) {
761 TIFFErrorExt(tif
->tif_clientdata
, module
,
762 "Seek error at scanline %lu",
763 (unsigned long)tif
->tif_row
);
770 * Seek to end of file, and set that as our location to
773 td
->td_stripoffset_p
[strip
] = TIFFSeekFile(tif
, 0, SEEK_END
);
774 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
777 tif
->tif_curoff
= td
->td_stripoffset_p
[strip
];
780 * We are starting a fresh strip/tile, so set the size to zero.
782 old_byte_count
= td
->td_stripbytecount_p
[strip
];
783 td
->td_stripbytecount_p
[strip
] = 0;
786 m
= tif
->tif_curoff
+cc
;
787 if (!(tif
->tif_flags
&TIFF_BIGTIFF
))
789 if ((m
<tif
->tif_curoff
)||(m
<(uint64_t)cc
))
791 TIFFErrorExt(tif
->tif_clientdata
, module
, "Maximum TIFF file size exceeded");
794 if (!WriteOK(tif
, data
, cc
)) {
795 TIFFErrorExt(tif
->tif_clientdata
, module
, "Write error at scanline %lu",
796 (unsigned long) tif
->tif_row
);
800 td
->td_stripbytecount_p
[strip
] += cc
;
802 if((int64_t) td
->td_stripbytecount_p
[strip
] != old_byte_count
)
803 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
809 * Internal version of TIFFFlushData that can be
810 * called by ``encodestrip routines'' w/o concern
811 * for infinite recursion.
814 TIFFFlushData1(TIFF
* tif
)
816 if (tif
->tif_rawcc
> 0 && tif
->tif_flags
& TIFF_BUF4WRITE
) {
817 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
818 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
819 TIFFReverseBits((uint8_t*)tif
->tif_rawdata
,
821 if (!TIFFAppendToStrip(tif
,
822 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
823 tif
->tif_rawdata
, tif
->tif_rawcc
))
825 /* We update those variables even in case of error since there's */
826 /* code that doesn't really check the return code of this */
829 tif
->tif_rawcp
= tif
->tif_rawdata
;
833 tif
->tif_rawcp
= tif
->tif_rawdata
;
839 * Set the current write offset. This should only be
840 * used to set the offset to a known previous location
841 * (very carefully), or to 0 so that the next write gets
842 * appended to the end of the file.
845 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
847 tif
->tif_curoff
= off
;
850 /* vim: set ts=8 sts=8 sw=8 noet: */