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
34 #define STRIPINCR 20 /* expansion factor on strip array */
36 #define WRITECHECKSTRIPS(tif, module) \
37 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
38 #define WRITECHECKTILES(tif, module) \
39 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
40 #define BUFFERCHECK(tif) \
41 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
42 TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
44 static int TIFFGrowStrips(TIFF
* tif
, uint32 delta
, const char* module
);
45 static int TIFFAppendToStrip(TIFF
* tif
, uint32 strip
, uint8
* data
, tmsize_t cc
);
48 TIFFWriteScanline(TIFF
* tif
, void* buf
, uint32 row
, uint16 sample
)
50 static const char module
[] = "TIFFWriteScanline";
51 register TIFFDirectory
*td
;
52 int status
, imagegrew
= 0;
55 if (!WRITECHECKSTRIPS(tif
, module
))
58 * Handle delayed allocation of data buffer. This
59 * permits it to be sized more intelligently (using
60 * directory information).
62 if (!BUFFERCHECK(tif
))
64 tif
->tif_flags
|= TIFF_BUF4WRITE
; /* not strictly sure this is right*/
68 * Extend image length if needed
69 * (but only for PlanarConfig=1).
71 if (row
>= td
->td_imagelength
) { /* extend image */
72 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
73 TIFFErrorExt(tif
->tif_clientdata
, module
,
74 "Can not change \"ImageLength\" when using separate planes");
77 td
->td_imagelength
= row
+1;
81 * Calculate strip and check for crossings.
83 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
84 if (sample
>= td
->td_samplesperpixel
) {
85 TIFFErrorExt(tif
->tif_clientdata
, module
,
86 "%lu: Sample out of range, max %lu",
87 (unsigned long) sample
, (unsigned long) td
->td_samplesperpixel
);
90 strip
= sample
*td
->td_stripsperimage
+ row
/td
->td_rowsperstrip
;
92 strip
= row
/ td
->td_rowsperstrip
;
94 * Check strip array to make sure there's space. We don't support
95 * dynamically growing files that have data organized in separate
96 * bitplanes because it's too painful. In that case we require that
97 * the imagelength be set properly before the first write (so that the
98 * strips array will be fully allocated above).
100 if (strip
>= td
->td_nstrips
&& !TIFFGrowStrips(tif
, 1, module
))
102 if (strip
!= tif
->tif_curstrip
) {
104 * Changing strips -- flush any data present.
106 if (!TIFFFlushData(tif
))
108 tif
->tif_curstrip
= strip
;
110 * Watch out for a growing image. The value of strips/image
111 * will initially be 1 (since it can't be deduced until the
112 * imagelength is known).
114 if (strip
>= td
->td_stripsperimage
&& imagegrew
)
115 td
->td_stripsperimage
=
116 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
117 if (td
->td_stripsperimage
== 0) {
118 TIFFErrorExt(tif
->tif_clientdata
, module
, "Zero strips per image");
122 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
123 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
124 if (!(*tif
->tif_setupencode
)(tif
))
126 tif
->tif_flags
|= TIFF_CODERSETUP
;
130 tif
->tif_rawcp
= tif
->tif_rawdata
;
132 if( td
->td_stripbytecount
[strip
] > 0 )
134 /* if we are writing over existing tiles, zero length */
135 td
->td_stripbytecount
[strip
] = 0;
137 /* this forces TIFFAppendToStrip() to do a seek */
141 if (!(*tif
->tif_preencode
)(tif
, sample
))
143 tif
->tif_flags
|= TIFF_POSTENCODE
;
146 * Ensure the write is either sequential or at the
147 * beginning of a strip (or that we can randomly
148 * access the data -- i.e. no encoding).
150 if (row
!= tif
->tif_row
) {
151 if (row
< tif
->tif_row
) {
153 * Moving backwards within the same strip:
154 * backup to the start and then decode
157 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
159 tif
->tif_rawcp
= tif
->tif_rawdata
;
162 * Seek forward to the desired row.
164 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
169 /* swab if needed - note that source buffer will be altered */
170 tif
->tif_postdecode( tif
, (uint8
*) buf
, tif
->tif_scanlinesize
);
172 status
= (*tif
->tif_encoderow
)(tif
, (uint8
*) buf
,
173 tif
->tif_scanlinesize
, sample
);
175 /* we are now poised at the beginning of the next row */
176 tif
->tif_row
= row
+ 1;
181 * Encode the supplied data and write it to the
184 * NB: Image length must be setup before writing.
187 TIFFWriteEncodedStrip(TIFF
* tif
, uint32 strip
, void* data
, tmsize_t cc
)
189 static const char module
[] = "TIFFWriteEncodedStrip";
190 TIFFDirectory
*td
= &tif
->tif_dir
;
193 if (!WRITECHECKSTRIPS(tif
, module
))
194 return ((tmsize_t
) -1);
196 * Check strip array to make sure there's space.
197 * We don't support dynamically growing files that
198 * have data organized in separate bitplanes because
199 * it's too painful. In that case we require that
200 * the imagelength be set properly before the first
201 * write (so that the strips array will be fully
204 if (strip
>= td
->td_nstrips
) {
205 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
206 TIFFErrorExt(tif
->tif_clientdata
, module
,
207 "Can not grow image by strips when using separate planes");
208 return ((tmsize_t
) -1);
210 if (!TIFFGrowStrips(tif
, 1, module
))
211 return ((tmsize_t
) -1);
212 td
->td_stripsperimage
=
213 TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
);
216 * Handle delayed allocation of data buffer. This
217 * permits it to be sized according to the directory
220 if (!BUFFERCHECK(tif
))
221 return ((tmsize_t
) -1);
223 tif
->tif_flags
|= TIFF_BUF4WRITE
;
224 tif
->tif_curstrip
= strip
;
226 if (td
->td_stripsperimage
== 0) {
227 TIFFErrorExt(tif
->tif_clientdata
, module
, "Zero strips per image");
228 return ((tmsize_t
) -1);
231 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
232 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
233 if (!(*tif
->tif_setupencode
)(tif
))
234 return ((tmsize_t
) -1);
235 tif
->tif_flags
|= TIFF_CODERSETUP
;
238 if( td
->td_stripbytecount
[strip
] > 0 )
240 /* Make sure that at the first attempt of rewriting the tile, we will have */
241 /* more bytes available in the output buffer than the previous byte count, */
242 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
243 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
244 if( tif
->tif_rawdatasize
<= (tmsize_t
)td
->td_stripbytecount
[strip
] )
246 if( !(TIFFWriteBufferSetup(tif
, NULL
,
247 (tmsize_t
)TIFFroundup_64((uint64
)(td
->td_stripbytecount
[strip
] + 1), 1024))) )
248 return ((tmsize_t
)(-1));
251 /* Force TIFFAppendToStrip() to consider placing data at end
257 tif
->tif_rawcp
= tif
->tif_rawdata
;
259 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
261 /* shortcut to avoid an extra memcpy() */
262 if( td
->td_compression
== COMPRESSION_NONE
)
264 /* swab if needed - note that source buffer will be altered */
265 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
267 if (!isFillOrder(tif
, td
->td_fillorder
) &&
268 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
269 TIFFReverseBits((uint8
*) data
, cc
);
272 !TIFFAppendToStrip(tif
, strip
, (uint8
*) data
, cc
))
273 return ((tmsize_t
) -1);
277 sample
= (uint16
)(strip
/ td
->td_stripsperimage
);
278 if (!(*tif
->tif_preencode
)(tif
, sample
))
279 return ((tmsize_t
) -1);
281 /* swab if needed - note that source buffer will be altered */
282 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
284 if (!(*tif
->tif_encodestrip
)(tif
, (uint8
*) data
, cc
, sample
))
285 return ((tmsize_t
) -1);
286 if (!(*tif
->tif_postencode
)(tif
))
287 return ((tmsize_t
) -1);
288 if (!isFillOrder(tif
, td
->td_fillorder
) &&
289 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
290 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
291 if (tif
->tif_rawcc
> 0 &&
292 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
293 return ((tmsize_t
) -1);
295 tif
->tif_rawcp
= tif
->tif_rawdata
;
300 * Write the supplied data to the specified strip.
302 * NB: Image length must be setup before writing.
305 TIFFWriteRawStrip(TIFF
* tif
, uint32 strip
, void* data
, tmsize_t cc
)
307 static const char module
[] = "TIFFWriteRawStrip";
308 TIFFDirectory
*td
= &tif
->tif_dir
;
310 if (!WRITECHECKSTRIPS(tif
, module
))
311 return ((tmsize_t
) -1);
313 * Check strip array to make sure there's space.
314 * We don't support dynamically growing files that
315 * have data organized in separate bitplanes because
316 * it's too painful. In that case we require that
317 * the imagelength be set properly before the first
318 * write (so that the strips array will be fully
321 if (strip
>= td
->td_nstrips
) {
322 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
323 TIFFErrorExt(tif
->tif_clientdata
, module
,
324 "Can not grow image by strips when using separate planes");
325 return ((tmsize_t
) -1);
328 * Watch out for a growing image. The value of
329 * strips/image will initially be 1 (since it
330 * can't be deduced until the imagelength is known).
332 if (strip
>= td
->td_stripsperimage
)
333 td
->td_stripsperimage
=
334 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
335 if (!TIFFGrowStrips(tif
, 1, module
))
336 return ((tmsize_t
) -1);
338 tif
->tif_curstrip
= strip
;
339 if (td
->td_stripsperimage
== 0) {
340 TIFFErrorExt(tif
->tif_clientdata
, module
,"Zero strips per image");
341 return ((tmsize_t
) -1);
343 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
344 return (TIFFAppendToStrip(tif
, strip
, (uint8
*) data
, cc
) ?
349 * Write and compress a tile of data. The
350 * tile is selected by the (x,y,z,s) coordinates.
353 TIFFWriteTile(TIFF
* tif
, void* buf
, uint32 x
, uint32 y
, uint32 z
, uint16 s
)
355 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
356 return ((tmsize_t
)(-1));
358 * NB: A tile size of -1 is used instead of tif_tilesize knowing
359 * that TIFFWriteEncodedTile will clamp this to the tile size.
360 * This is done because the tile size may not be defined until
361 * after the output buffer is setup in TIFFWriteBufferSetup.
363 return (TIFFWriteEncodedTile(tif
,
364 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tmsize_t
)(-1)));
368 * Encode the supplied data and write it to the
369 * specified tile. There must be space for the
370 * data. The function clamps individual writes
371 * to a tile to the tile size, but does not (and
372 * can not) check that multiple writes to the same
373 * tile do not write more than tile size data.
375 * NB: Image length must be setup before writing; this
376 * interface does not support automatically growing
377 * the image on each write (as TIFFWriteScanline does).
380 TIFFWriteEncodedTile(TIFF
* tif
, uint32 tile
, void* data
, tmsize_t cc
)
382 static const char module
[] = "TIFFWriteEncodedTile";
387 if (!WRITECHECKTILES(tif
, module
))
388 return ((tmsize_t
)(-1));
390 if (tile
>= td
->td_nstrips
) {
391 TIFFErrorExt(tif
->tif_clientdata
, module
, "Tile %lu out of range, max %lu",
392 (unsigned long) tile
, (unsigned long) td
->td_nstrips
);
393 return ((tmsize_t
)(-1));
396 * Handle delayed allocation of data buffer. This
397 * permits it to be sized more intelligently (using
398 * directory information).
400 if (!BUFFERCHECK(tif
))
401 return ((tmsize_t
)(-1));
403 tif
->tif_flags
|= TIFF_BUF4WRITE
;
404 tif
->tif_curtile
= tile
;
406 if( td
->td_stripbytecount
[tile
] > 0 )
408 /* Make sure that at the first attempt of rewriting the tile, we will have */
409 /* more bytes available in the output buffer than the previous byte count, */
410 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
411 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
412 if( tif
->tif_rawdatasize
<= (tmsize_t
) td
->td_stripbytecount
[tile
] )
414 if( !(TIFFWriteBufferSetup(tif
, NULL
,
415 (tmsize_t
)TIFFroundup_64((uint64
)(td
->td_stripbytecount
[tile
] + 1), 1024))) )
416 return ((tmsize_t
)(-1));
419 /* Force TIFFAppendToStrip() to consider placing data at end
425 tif
->tif_rawcp
= tif
->tif_rawdata
;
428 * Compute tiles per row & per column to compute
429 * current row and column
431 howmany32
=TIFFhowmany_32(td
->td_imagelength
, td
->td_tilelength
);
432 if (howmany32
== 0) {
433 TIFFErrorExt(tif
->tif_clientdata
,module
,"Zero tiles");
434 return ((tmsize_t
)(-1));
436 tif
->tif_row
= (tile
% howmany32
) * td
->td_tilelength
;
437 howmany32
=TIFFhowmany_32(td
->td_imagewidth
, td
->td_tilewidth
);
438 if (howmany32
== 0) {
439 TIFFErrorExt(tif
->tif_clientdata
,module
,"Zero tiles");
440 return ((tmsize_t
)(-1));
442 tif
->tif_col
= (tile
% howmany32
) * td
->td_tilewidth
;
444 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
445 if (!(*tif
->tif_setupencode
)(tif
))
446 return ((tmsize_t
)(-1));
447 tif
->tif_flags
|= TIFF_CODERSETUP
;
449 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
452 * Clamp write amount to the tile size. This is mostly
453 * done so that callers can pass in some large number
454 * (e.g. -1) and have the tile size used instead.
456 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
457 cc
= tif
->tif_tilesize
;
459 /* shortcut to avoid an extra memcpy() */
460 if( td
->td_compression
== COMPRESSION_NONE
)
462 /* swab if needed - note that source buffer will be altered */
463 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
465 if (!isFillOrder(tif
, td
->td_fillorder
) &&
466 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
467 TIFFReverseBits((uint8
*) data
, cc
);
470 !TIFFAppendToStrip(tif
, tile
, (uint8
*) data
, cc
))
471 return ((tmsize_t
) -1);
475 sample
= (uint16
)(tile
/td
->td_stripsperimage
);
476 if (!(*tif
->tif_preencode
)(tif
, sample
))
477 return ((tmsize_t
)(-1));
478 /* swab if needed - note that source buffer will be altered */
479 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
481 if (!(*tif
->tif_encodetile
)(tif
, (uint8
*) data
, cc
, sample
))
482 return ((tmsize_t
) -1);
483 if (!(*tif
->tif_postencode
)(tif
))
484 return ((tmsize_t
)(-1));
485 if (!isFillOrder(tif
, td
->td_fillorder
) &&
486 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
487 TIFFReverseBits((uint8
*)tif
->tif_rawdata
, tif
->tif_rawcc
);
488 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
489 tif
->tif_rawdata
, tif
->tif_rawcc
))
490 return ((tmsize_t
)(-1));
492 tif
->tif_rawcp
= tif
->tif_rawdata
;
497 * Write the supplied data to the specified strip.
498 * There must be space for the data; we don't check
501 * NB: Image length must be setup before writing; this
502 * interface does not support automatically growing
503 * the image on each write (as TIFFWriteScanline does).
506 TIFFWriteRawTile(TIFF
* tif
, uint32 tile
, void* data
, tmsize_t cc
)
508 static const char module
[] = "TIFFWriteRawTile";
510 if (!WRITECHECKTILES(tif
, module
))
511 return ((tmsize_t
)(-1));
512 if (tile
>= tif
->tif_dir
.td_nstrips
) {
513 TIFFErrorExt(tif
->tif_clientdata
, module
, "Tile %lu out of range, max %lu",
514 (unsigned long) tile
,
515 (unsigned long) tif
->tif_dir
.td_nstrips
);
516 return ((tmsize_t
)(-1));
518 return (TIFFAppendToStrip(tif
, tile
, (uint8
*) data
, cc
) ?
519 cc
: (tmsize_t
)(-1));
522 #define isUnspecified(tif, f) \
523 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
526 TIFFSetupStrips(TIFF
* tif
)
528 TIFFDirectory
* td
= &tif
->tif_dir
;
531 td
->td_stripsperimage
=
532 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
533 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
535 td
->td_stripsperimage
=
536 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
537 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
538 td
->td_nstrips
= td
->td_stripsperimage
;
539 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
540 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
541 td
->td_stripoffset
= (uint64
*)
542 _TIFFCheckMalloc(tif
, td
->td_nstrips
, sizeof (uint64
),
543 "for \"StripOffsets\" array");
544 td
->td_stripbytecount
= (uint64
*)
545 _TIFFCheckMalloc(tif
, td
->td_nstrips
, sizeof (uint64
),
546 "for \"StripByteCounts\" array");
547 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
550 * Place data at the end-of-file
551 * (by setting offsets to zero).
553 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint64
));
554 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint64
));
555 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
556 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
562 * Verify file is writable and that the directory
563 * information is setup properly. In doing the latter
564 * we also "freeze" the state of the directory so
565 * that important information is not changed.
568 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module
)
570 if (tif
->tif_mode
== O_RDONLY
) {
571 TIFFErrorExt(tif
->tif_clientdata
, module
, "File not open for writing");
574 if (tiles
^ isTiled(tif
)) {
575 TIFFErrorExt(tif
->tif_clientdata
, module
, tiles
?
576 "Can not write tiles to a stripped image" :
577 "Can not write scanlines to a tiled image");
581 _TIFFFillStriles( tif
);
584 * On the first write verify all the required information
585 * has been setup and initialize any data structures that
586 * had to wait until directory information was set.
587 * Note that a lot of our work is assumed to remain valid
588 * because we disallow any of the important parameters
589 * from changing after we start writing (i.e. once
590 * TIFF_BEENWRITING is set, TIFFSetField will only allow
591 * the image's length to be changed).
593 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
594 TIFFErrorExt(tif
->tif_clientdata
, module
,
595 "Must set \"ImageWidth\" before writing data");
598 if (tif
->tif_dir
.td_samplesperpixel
== 1) {
600 * Planarconfiguration is irrelevant in case of single band
601 * images and need not be included. We will set it anyway,
602 * because this field is used in other parts of library even
603 * in the single band case.
605 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
))
606 tif
->tif_dir
.td_planarconfig
= PLANARCONFIG_CONTIG
;
608 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
609 TIFFErrorExt(tif
->tif_clientdata
, module
,
610 "Must set \"PlanarConfiguration\" before writing data");
614 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
615 tif
->tif_dir
.td_nstrips
= 0;
616 TIFFErrorExt(tif
->tif_clientdata
, module
, "No space for %s arrays",
617 isTiled(tif
) ? "tile" : "strip");
622 tif
->tif_tilesize
= TIFFTileSize(tif
);
623 if (tif
->tif_tilesize
== 0)
627 tif
->tif_tilesize
= (tmsize_t
)(-1);
628 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
629 if (tif
->tif_scanlinesize
== 0)
631 tif
->tif_flags
|= TIFF_BEENWRITING
;
636 * Setup the raw data buffer used for encoding.
639 TIFFWriteBufferSetup(TIFF
* tif
, void* bp
, tmsize_t size
)
641 static const char module
[] = "TIFFWriteBufferSetup";
643 if (tif
->tif_rawdata
) {
644 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
645 _TIFFfree(tif
->tif_rawdata
);
646 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
648 tif
->tif_rawdata
= NULL
;
650 if (size
== (tmsize_t
)(-1)) {
651 size
= (isTiled(tif
) ?
652 tif
->tif_tilesize
: TIFFStripSize(tif
));
654 * Make raw data buffer at least 8K
658 bp
= NULL
; /* NB: force malloc */
661 bp
= _TIFFmalloc(size
);
663 TIFFErrorExt(tif
->tif_clientdata
, module
, "No space for output buffer");
666 tif
->tif_flags
|= TIFF_MYBUFFER
;
668 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
669 tif
->tif_rawdata
= (uint8
*) bp
;
670 tif
->tif_rawdatasize
= size
;
672 tif
->tif_rawcp
= tif
->tif_rawdata
;
673 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
678 * Grow the strip data structures by delta strips.
681 TIFFGrowStrips(TIFF
* tif
, uint32 delta
, const char* module
)
683 TIFFDirectory
*td
= &tif
->tif_dir
;
684 uint64
* new_stripoffset
;
685 uint64
* new_stripbytecount
;
687 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
688 new_stripoffset
= (uint64
*)_TIFFrealloc(td
->td_stripoffset
,
689 (td
->td_nstrips
+ delta
) * sizeof (uint64
));
690 new_stripbytecount
= (uint64
*)_TIFFrealloc(td
->td_stripbytecount
,
691 (td
->td_nstrips
+ delta
) * sizeof (uint64
));
692 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
694 _TIFFfree(new_stripoffset
);
695 if (new_stripbytecount
)
696 _TIFFfree(new_stripbytecount
);
698 TIFFErrorExt(tif
->tif_clientdata
, module
, "No space to expand strip arrays");
701 td
->td_stripoffset
= new_stripoffset
;
702 td
->td_stripbytecount
= new_stripbytecount
;
703 _TIFFmemset(td
->td_stripoffset
+ td
->td_nstrips
,
704 0, delta
*sizeof (uint64
));
705 _TIFFmemset(td
->td_stripbytecount
+ td
->td_nstrips
,
706 0, delta
*sizeof (uint64
));
707 td
->td_nstrips
+= delta
;
708 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
714 * Append the data to the specified strip.
717 TIFFAppendToStrip(TIFF
* tif
, uint32 strip
, uint8
* data
, tmsize_t cc
)
719 static const char module
[] = "TIFFAppendToStrip";
720 TIFFDirectory
*td
= &tif
->tif_dir
;
722 int64 old_byte_count
= -1;
724 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
725 assert(td
->td_nstrips
> 0);
727 if( td
->td_stripbytecount
[strip
] != 0
728 && td
->td_stripoffset
[strip
] != 0
729 && td
->td_stripbytecount
[strip
] >= (uint64
) cc
)
732 * There is already tile data on disk, and the new tile
733 * data we have will fit in the same space. The only
734 * aspect of this that is risky is that there could be
735 * more data to append to this strip before we are done
736 * depending on how we are getting called.
738 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
739 TIFFErrorExt(tif
->tif_clientdata
, module
,
740 "Seek error at scanline %lu",
741 (unsigned long)tif
->tif_row
);
748 * Seek to end of file, and set that as our location to
751 td
->td_stripoffset
[strip
] = TIFFSeekFile(tif
, 0, SEEK_END
);
752 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
755 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
758 * We are starting a fresh strip/tile, so set the size to zero.
760 old_byte_count
= td
->td_stripbytecount
[strip
];
761 td
->td_stripbytecount
[strip
] = 0;
764 m
= tif
->tif_curoff
+cc
;
765 if (!(tif
->tif_flags
&TIFF_BIGTIFF
))
767 if ((m
<tif
->tif_curoff
)||(m
<(uint64
)cc
))
769 TIFFErrorExt(tif
->tif_clientdata
, module
, "Maximum TIFF file size exceeded");
772 if (!WriteOK(tif
, data
, cc
)) {
773 TIFFErrorExt(tif
->tif_clientdata
, module
, "Write error at scanline %lu",
774 (unsigned long) tif
->tif_row
);
778 td
->td_stripbytecount
[strip
] += cc
;
780 if( (int64
) td
->td_stripbytecount
[strip
] != old_byte_count
)
781 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
787 * Internal version of TIFFFlushData that can be
788 * called by ``encodestrip routines'' w/o concern
789 * for infinite recursion.
792 TIFFFlushData1(TIFF
* tif
)
794 if (tif
->tif_rawcc
> 0 && tif
->tif_flags
& TIFF_BUF4WRITE
) {
795 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
796 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
797 TIFFReverseBits((uint8
*)tif
->tif_rawdata
,
799 if (!TIFFAppendToStrip(tif
,
800 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
801 tif
->tif_rawdata
, tif
->tif_rawcc
))
803 /* We update those variables even in case of error since there's */
804 /* code that doesn't really check the return code of this */
807 tif
->tif_rawcp
= tif
->tif_rawdata
;
811 tif
->tif_rawcp
= tif
->tif_rawdata
;
817 * Set the current write offset. This should only be
818 * used to set the offset to a known previous location
819 * (very carefully), or to 0 so that the next write gets
820 * appended to the end of the file.
823 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
825 tif
->tif_curoff
= off
;
828 /* vim: set ts=8 sts=8 sw=8 noet: */