]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/libtiff/tif_write.c
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
30 * Scanline-oriented Write Support
35 #define STRIPINCR 20 /* expansion factor on strip array */
37 #define WRITECHECKSTRIPS(tif, module) \
38 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
39 #define WRITECHECKTILES(tif, module) \
40 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
41 #define BUFFERCHECK(tif) \
42 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
43 TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
45 static int TIFFGrowStrips(TIFF
* tif
, uint32 delta
, const char* module);
46 static int TIFFAppendToStrip(TIFF
* tif
, uint32 strip
, uint8
* data
, tmsize_t cc
);
49 TIFFWriteScanline(TIFF
* tif
, void* buf
, uint32 row
, uint16 sample
)
51 static const char module[] = "TIFFWriteScanline";
52 register TIFFDirectory
*td
;
53 int status
, imagegrew
= 0;
56 if (!WRITECHECKSTRIPS(tif
, module))
59 * Handle delayed allocation of data buffer. This
60 * permits it to be sized more intelligently (using
61 * directory information).
63 if (!BUFFERCHECK(tif
))
65 tif
->tif_flags
|= TIFF_BUF4WRITE
; /* not strictly sure this is right*/
69 * Extend image length if needed
70 * (but only for PlanarConfig=1).
72 if (row
>= td
->td_imagelength
) { /* extend image */
73 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
74 TIFFErrorExt(tif
->tif_clientdata
, module,
75 "Can not change \"ImageLength\" when using separate planes");
78 td
->td_imagelength
= row
+1;
82 * Calculate strip and check for crossings.
84 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
85 if (sample
>= td
->td_samplesperpixel
) {
86 TIFFErrorExt(tif
->tif_clientdata
, module,
87 "%lu: Sample out of range, max %lu",
88 (unsigned long) sample
, (unsigned long) td
->td_samplesperpixel
);
91 strip
= sample
*td
->td_stripsperimage
+ row
/td
->td_rowsperstrip
;
93 strip
= row
/ td
->td_rowsperstrip
;
95 * Check strip array to make sure there's space. We don't support
96 * dynamically growing files that have data organized in separate
97 * bitplanes because it's too painful. In that case we require that
98 * the imagelength be set properly before the first write (so that the
99 * strips array will be fully allocated above).
101 if (strip
>= td
->td_nstrips
&& !TIFFGrowStrips(tif
, 1, module))
103 if (strip
!= tif
->tif_curstrip
) {
105 * Changing strips -- flush any data present.
107 if (!TIFFFlushData(tif
))
109 tif
->tif_curstrip
= strip
;
111 * Watch out for a growing image. The value of strips/image
112 * will initially be 1 (since it can't be deduced until the
113 * imagelength is known).
115 if (strip
>= td
->td_stripsperimage
&& imagegrew
)
116 td
->td_stripsperimage
=
117 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
119 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
120 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
121 if (!(*tif
->tif_setupencode
)(tif
))
123 tif
->tif_flags
|= TIFF_CODERSETUP
;
127 tif
->tif_rawcp
= tif
->tif_rawdata
;
129 if( td
->td_stripbytecount
[strip
] > 0 )
131 /* if we are writing over existing tiles, zero length */
132 td
->td_stripbytecount
[strip
] = 0;
134 /* this forces TIFFAppendToStrip() to do a seek */
138 if (!(*tif
->tif_preencode
)(tif
, sample
))
140 tif
->tif_flags
|= TIFF_POSTENCODE
;
143 * Ensure the write is either sequential or at the
144 * beginning of a strip (or that we can randomly
145 * access the data -- i.e. no encoding).
147 if (row
!= tif
->tif_row
) {
148 if (row
< tif
->tif_row
) {
150 * Moving backwards within the same strip:
151 * backup to the start and then decode
154 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
156 tif
->tif_rawcp
= tif
->tif_rawdata
;
159 * Seek forward to the desired row.
161 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
166 /* swab if needed - note that source buffer will be altered */
167 tif
->tif_postdecode( tif
, (uint8
*) buf
, tif
->tif_scanlinesize
);
169 status
= (*tif
->tif_encoderow
)(tif
, (uint8
*) buf
,
170 tif
->tif_scanlinesize
, sample
);
172 /* we are now poised at the beginning of the next row */
173 tif
->tif_row
= row
+ 1;
178 * Encode the supplied data and write it to the
181 * NB: Image length must be setup before writing.
184 TIFFWriteEncodedStrip(TIFF
* tif
, uint32 strip
, void* data
, tmsize_t cc
)
186 static const char module[] = "TIFFWriteEncodedStrip";
187 TIFFDirectory
*td
= &tif
->tif_dir
;
190 if (!WRITECHECKSTRIPS(tif
, module))
191 return ((tmsize_t
) -1);
193 * Check strip array to make sure there's space.
194 * We don't support dynamically growing files that
195 * have data organized in separate bitplanes because
196 * it's too painful. In that case we require that
197 * the imagelength be set properly before the first
198 * write (so that the strips array will be fully
201 if (strip
>= td
->td_nstrips
) {
202 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
203 TIFFErrorExt(tif
->tif_clientdata
, module,
204 "Can not grow image by strips when using separate planes");
205 return ((tmsize_t
) -1);
207 if (!TIFFGrowStrips(tif
, 1, module))
208 return ((tmsize_t
) -1);
209 td
->td_stripsperimage
=
210 TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
);
213 * Handle delayed allocation of data buffer. This
214 * permits it to be sized according to the directory
217 if (!BUFFERCHECK(tif
))
218 return ((tmsize_t
) -1);
220 tif
->tif_flags
|= TIFF_BUF4WRITE
;
221 tif
->tif_curstrip
= strip
;
223 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
224 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
225 if (!(*tif
->tif_setupencode
)(tif
))
226 return ((tmsize_t
) -1);
227 tif
->tif_flags
|= TIFF_CODERSETUP
;
230 if( td
->td_stripbytecount
[strip
] > 0 )
232 /* Make sure that at the first attempt of rewriting the tile, we will have */
233 /* more bytes available in the output buffer than the previous byte count, */
234 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
235 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
236 if( tif
->tif_rawdatasize
<= td
->td_stripbytecount
[strip
] )
238 if( !(TIFFWriteBufferSetup(tif
, NULL
,
239 (tmsize_t
)TIFFroundup_64((uint64
)(td
->td_stripbytecount
[strip
] + 1), 1024))) )
240 return ((tmsize_t
)(-1));
243 /* Force TIFFAppendToStrip() to consider placing data at end
249 tif
->tif_rawcp
= tif
->tif_rawdata
;
251 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
252 sample
= (uint16
)(strip
/ td
->td_stripsperimage
);
253 if (!(*tif
->tif_preencode
)(tif
, sample
))
254 return ((tmsize_t
) -1);
256 /* swab if needed - note that source buffer will be altered */
257 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
259 if (!(*tif
->tif_encodestrip
)(tif
, (uint8
*) data
, cc
, sample
))
261 if (!(*tif
->tif_postencode
)(tif
))
262 return ((tmsize_t
) -1);
263 if (!isFillOrder(tif
, td
->td_fillorder
) &&
264 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
265 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
266 if (tif
->tif_rawcc
> 0 &&
267 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
268 return ((tmsize_t
) -1);
270 tif
->tif_rawcp
= tif
->tif_rawdata
;
275 * Write the supplied data to the specified strip.
277 * NB: Image length must be setup before writing.
280 TIFFWriteRawStrip(TIFF
* tif
, uint32 strip
, void* data
, tmsize_t cc
)
282 static const char module[] = "TIFFWriteRawStrip";
283 TIFFDirectory
*td
= &tif
->tif_dir
;
285 if (!WRITECHECKSTRIPS(tif
, module))
286 return ((tmsize_t
) -1);
288 * Check strip array to make sure there's space.
289 * We don't support dynamically growing files that
290 * have data organized in separate bitplanes because
291 * it's too painful. In that case we require that
292 * the imagelength be set properly before the first
293 * write (so that the strips array will be fully
296 if (strip
>= td
->td_nstrips
) {
297 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
298 TIFFErrorExt(tif
->tif_clientdata
, module,
299 "Can not grow image by strips when using separate planes");
300 return ((tmsize_t
) -1);
303 * Watch out for a growing image. The value of
304 * strips/image will initially be 1 (since it
305 * can't be deduced until the imagelength is known).
307 if (strip
>= td
->td_stripsperimage
)
308 td
->td_stripsperimage
=
309 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
310 if (!TIFFGrowStrips(tif
, 1, module))
311 return ((tmsize_t
) -1);
313 tif
->tif_curstrip
= strip
;
314 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
315 return (TIFFAppendToStrip(tif
, strip
, (uint8
*) data
, cc
) ?
320 * Write and compress a tile of data. The
321 * tile is selected by the (x,y,z,s) coordinates.
324 TIFFWriteTile(TIFF
* tif
, void* buf
, uint32 x
, uint32 y
, uint32 z
, uint16 s
)
326 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
327 return ((tmsize_t
)(-1));
329 * NB: A tile size of -1 is used instead of tif_tilesize knowing
330 * that TIFFWriteEncodedTile will clamp this to the tile size.
331 * This is done because the tile size may not be defined until
332 * after the output buffer is setup in TIFFWriteBufferSetup.
334 return (TIFFWriteEncodedTile(tif
,
335 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tmsize_t
)(-1)));
339 * Encode the supplied data and write it to the
340 * specified tile. There must be space for the
341 * data. The function clamps individual writes
342 * to a tile to the tile size, but does not (and
343 * can not) check that multiple writes to the same
344 * tile do not write more than tile size data.
346 * NB: Image length must be setup before writing; this
347 * interface does not support automatically growing
348 * the image on each write (as TIFFWriteScanline does).
351 TIFFWriteEncodedTile(TIFF
* tif
, uint32 tile
, void* data
, tmsize_t cc
)
353 static const char module[] = "TIFFWriteEncodedTile";
357 if (!WRITECHECKTILES(tif
, module))
358 return ((tmsize_t
)(-1));
360 if (tile
>= td
->td_nstrips
) {
361 TIFFErrorExt(tif
->tif_clientdata
, module, "Tile %lu out of range, max %lu",
362 (unsigned long) tile
, (unsigned long) td
->td_nstrips
);
363 return ((tmsize_t
)(-1));
366 * Handle delayed allocation of data buffer. This
367 * permits it to be sized more intelligently (using
368 * directory information).
370 if (!BUFFERCHECK(tif
))
371 return ((tmsize_t
)(-1));
373 tif
->tif_flags
|= TIFF_BUF4WRITE
;
374 tif
->tif_curtile
= tile
;
376 if( td
->td_stripbytecount
[tile
] > 0 )
378 /* Make sure that at the first attempt of rewriting the tile, we will have */
379 /* more bytes available in the output buffer than the previous byte count, */
380 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
381 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
382 if( tif
->tif_rawdatasize
<= td
->td_stripbytecount
[tile
] )
384 if( !(TIFFWriteBufferSetup(tif
, NULL
,
385 (tmsize_t
)TIFFroundup_64((uint64
)(td
->td_stripbytecount
[tile
] + 1), 1024))) )
386 return ((tmsize_t
)(-1));
389 /* Force TIFFAppendToStrip() to consider placing data at end
395 tif
->tif_rawcp
= tif
->tif_rawdata
;
398 * Compute tiles per row & per column to compute
399 * current row and column
401 tif
->tif_row
= (tile
% TIFFhowmany_32(td
->td_imagelength
, td
->td_tilelength
))
403 tif
->tif_col
= (tile
% TIFFhowmany_32(td
->td_imagewidth
, td
->td_tilewidth
))
406 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
407 if (!(*tif
->tif_setupencode
)(tif
))
408 return ((tmsize_t
)(-1));
409 tif
->tif_flags
|= TIFF_CODERSETUP
;
411 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
412 sample
= (uint16
)(tile
/td
->td_stripsperimage
);
413 if (!(*tif
->tif_preencode
)(tif
, sample
))
414 return ((tmsize_t
)(-1));
416 * Clamp write amount to the tile size. This is mostly
417 * done so that callers can pass in some large number
418 * (e.g. -1) and have the tile size used instead.
420 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
421 cc
= tif
->tif_tilesize
;
423 /* swab if needed - note that source buffer will be altered */
424 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
426 if (!(*tif
->tif_encodetile
)(tif
, (uint8
*) data
, cc
, sample
))
428 if (!(*tif
->tif_postencode
)(tif
))
429 return ((tmsize_t
)(-1));
430 if (!isFillOrder(tif
, td
->td_fillorder
) &&
431 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
432 TIFFReverseBits((uint8
*)tif
->tif_rawdata
, tif
->tif_rawcc
);
433 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
434 tif
->tif_rawdata
, tif
->tif_rawcc
))
435 return ((tmsize_t
)(-1));
437 tif
->tif_rawcp
= tif
->tif_rawdata
;
442 * Write the supplied data to the specified strip.
443 * There must be space for the data; we don't check
446 * NB: Image length must be setup before writing; this
447 * interface does not support automatically growing
448 * the image on each write (as TIFFWriteScanline does).
451 TIFFWriteRawTile(TIFF
* tif
, uint32 tile
, void* data
, tmsize_t cc
)
453 static const char module[] = "TIFFWriteRawTile";
455 if (!WRITECHECKTILES(tif
, module))
456 return ((tmsize_t
)(-1));
457 if (tile
>= tif
->tif_dir
.td_nstrips
) {
458 TIFFErrorExt(tif
->tif_clientdata
, module, "Tile %lu out of range, max %lu",
459 (unsigned long) tile
,
460 (unsigned long) tif
->tif_dir
.td_nstrips
);
461 return ((tmsize_t
)(-1));
463 return (TIFFAppendToStrip(tif
, tile
, (uint8
*) data
, cc
) ?
464 cc
: (tmsize_t
)(-1));
467 #define isUnspecified(tif, f) \
468 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
471 TIFFSetupStrips(TIFF
* tif
)
473 TIFFDirectory
* td
= &tif
->tif_dir
;
476 td
->td_stripsperimage
=
477 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
478 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
480 td
->td_stripsperimage
=
481 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
482 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
483 td
->td_nstrips
= td
->td_stripsperimage
;
484 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
485 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
486 td
->td_stripoffset
= (uint64
*)
487 _TIFFmalloc(td
->td_nstrips
* sizeof (uint64
));
488 td
->td_stripbytecount
= (uint64
*)
489 _TIFFmalloc(td
->td_nstrips
* sizeof (uint64
));
490 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
493 * Place data at the end-of-file
494 * (by setting offsets to zero).
496 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint64
));
497 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint64
));
498 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
499 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
505 * Verify file is writable and that the directory
506 * information is setup properly. In doing the latter
507 * we also "freeze" the state of the directory so
508 * that important information is not changed.
511 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module)
513 if (tif
->tif_mode
== O_RDONLY
) {
514 TIFFErrorExt(tif
->tif_clientdata
, module, "File not open for writing");
517 if (tiles
^ isTiled(tif
)) {
518 TIFFErrorExt(tif
->tif_clientdata
, module, tiles
?
519 "Can not write tiles to a stripped image" :
520 "Can not write scanlines to a tiled image");
524 _TIFFFillStriles( tif
);
527 * On the first write verify all the required information
528 * has been setup and initialize any data structures that
529 * had to wait until directory information was set.
530 * Note that a lot of our work is assumed to remain valid
531 * because we disallow any of the important parameters
532 * from changing after we start writing (i.e. once
533 * TIFF_BEENWRITING is set, TIFFSetField will only allow
534 * the image's length to be changed).
536 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
537 TIFFErrorExt(tif
->tif_clientdata
, module,
538 "Must set \"ImageWidth\" before writing data");
541 if (tif
->tif_dir
.td_samplesperpixel
== 1) {
543 * Planarconfiguration is irrelevant in case of single band
544 * images and need not be included. We will set it anyway,
545 * because this field is used in other parts of library even
546 * in the single band case.
548 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
))
549 tif
->tif_dir
.td_planarconfig
= PLANARCONFIG_CONTIG
;
551 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
552 TIFFErrorExt(tif
->tif_clientdata
, module,
553 "Must set \"PlanarConfiguration\" before writing data");
557 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
558 tif
->tif_dir
.td_nstrips
= 0;
559 TIFFErrorExt(tif
->tif_clientdata
, module, "No space for %s arrays",
560 isTiled(tif
) ? "tile" : "strip");
565 tif
->tif_tilesize
= TIFFTileSize(tif
);
566 if (tif
->tif_tilesize
== 0)
570 tif
->tif_tilesize
= (tmsize_t
)(-1);
571 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
572 if (tif
->tif_scanlinesize
== 0)
574 tif
->tif_flags
|= TIFF_BEENWRITING
;
579 * Setup the raw data buffer used for encoding.
582 TIFFWriteBufferSetup(TIFF
* tif
, void* bp
, tmsize_t size
)
584 static const char module[] = "TIFFWriteBufferSetup";
586 if (tif
->tif_rawdata
) {
587 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
588 _TIFFfree(tif
->tif_rawdata
);
589 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
591 tif
->tif_rawdata
= NULL
;
593 if (size
== (tmsize_t
)(-1)) {
594 size
= (isTiled(tif
) ?
595 tif
->tif_tilesize
: TIFFStripSize(tif
));
597 * Make raw data buffer at least 8K
601 bp
= NULL
; /* NB: force malloc */
604 bp
= _TIFFmalloc(size
);
606 TIFFErrorExt(tif
->tif_clientdata
, module, "No space for output buffer");
609 tif
->tif_flags
|= TIFF_MYBUFFER
;
611 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
612 tif
->tif_rawdata
= (uint8
*) bp
;
613 tif
->tif_rawdatasize
= size
;
615 tif
->tif_rawcp
= tif
->tif_rawdata
;
616 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
621 * Grow the strip data structures by delta strips.
624 TIFFGrowStrips(TIFF
* tif
, uint32 delta
, const char* module)
626 TIFFDirectory
*td
= &tif
->tif_dir
;
627 uint64
* new_stripoffset
;
628 uint64
* new_stripbytecount
;
630 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
631 new_stripoffset
= (uint64
*)_TIFFrealloc(td
->td_stripoffset
,
632 (td
->td_nstrips
+ delta
) * sizeof (uint64
));
633 new_stripbytecount
= (uint64
*)_TIFFrealloc(td
->td_stripbytecount
,
634 (td
->td_nstrips
+ delta
) * sizeof (uint64
));
635 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
637 _TIFFfree(new_stripoffset
);
638 if (new_stripbytecount
)
639 _TIFFfree(new_stripbytecount
);
641 TIFFErrorExt(tif
->tif_clientdata
, module, "No space to expand strip arrays");
644 td
->td_stripoffset
= new_stripoffset
;
645 td
->td_stripbytecount
= new_stripbytecount
;
646 _TIFFmemset(td
->td_stripoffset
+ td
->td_nstrips
,
647 0, delta
*sizeof (uint64
));
648 _TIFFmemset(td
->td_stripbytecount
+ td
->td_nstrips
,
649 0, delta
*sizeof (uint64
));
650 td
->td_nstrips
+= delta
;
651 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
657 * Append the data to the specified strip.
660 TIFFAppendToStrip(TIFF
* tif
, uint32 strip
, uint8
* data
, tmsize_t cc
)
662 static const char module[] = "TIFFAppendToStrip";
663 TIFFDirectory
*td
= &tif
->tif_dir
;
665 int64 old_byte_count
= -1;
667 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
668 assert(td
->td_nstrips
> 0);
670 if( td
->td_stripbytecount
[strip
] != 0
671 && td
->td_stripoffset
[strip
] != 0
672 && td
->td_stripbytecount
[strip
] >= (uint64
) cc
)
675 * There is already tile data on disk, and the new tile
676 * data we have will fit in the same space. The only
677 * aspect of this that is risky is that there could be
678 * more data to append to this strip before we are done
679 * depending on how we are getting called.
681 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
682 TIFFErrorExt(tif
->tif_clientdata
, module,
683 "Seek error at scanline %lu",
684 (unsigned long)tif
->tif_row
);
691 * Seek to end of file, and set that as our location to
694 td
->td_stripoffset
[strip
] = TIFFSeekFile(tif
, 0, SEEK_END
);
695 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
698 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
701 * We are starting a fresh strip/tile, so set the size to zero.
703 old_byte_count
= td
->td_stripbytecount
[strip
];
704 td
->td_stripbytecount
[strip
] = 0;
707 m
= tif
->tif_curoff
+cc
;
708 if (!(tif
->tif_flags
&TIFF_BIGTIFF
))
710 if ((m
<tif
->tif_curoff
)||(m
<(uint64
)cc
))
712 TIFFErrorExt(tif
->tif_clientdata
, module, "Maximum TIFF file size exceeded");
715 if (!WriteOK(tif
, data
, cc
)) {
716 TIFFErrorExt(tif
->tif_clientdata
, module, "Write error at scanline %lu",
717 (unsigned long) tif
->tif_row
);
721 td
->td_stripbytecount
[strip
] += cc
;
723 if( (int64
) td
->td_stripbytecount
[strip
] != old_byte_count
)
724 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
730 * Internal version of TIFFFlushData that can be
731 * called by ``encodestrip routines'' w/o concern
732 * for infinite recursion.
735 TIFFFlushData1(TIFF
* tif
)
737 if (tif
->tif_rawcc
> 0 && tif
->tif_flags
& TIFF_BUF4WRITE
) {
738 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
739 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
740 TIFFReverseBits((uint8
*)tif
->tif_rawdata
,
742 if (!TIFFAppendToStrip(tif
,
743 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
744 tif
->tif_rawdata
, tif
->tif_rawcc
))
747 tif
->tif_rawcp
= tif
->tif_rawdata
;
753 * Set the current write offset. This should only be
754 * used to set the offset to a known previous location
755 * (very carefully), or to 0 so that the next write gets
756 * appended to the end of the file.
759 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
761 tif
->tif_curoff
= off
;
764 /* vim: set ts=8 sts=8 sw=8 noet: */