]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/libtiff/tif_write.c
3 * Copyright (c) 1988-1997 Sam Leffler
4 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29 * 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
);
118 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
119 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
120 if (!(*tif
->tif_setupencode
)(tif
))
122 tif
->tif_flags
|= TIFF_CODERSETUP
;
126 tif
->tif_rawcp
= tif
->tif_rawdata
;
128 if( td
->td_stripbytecount
[strip
] > 0 )
130 /* if we are writing over existing tiles, zero length */
131 td
->td_stripbytecount
[strip
] = 0;
133 /* this forces TIFFAppendToStrip() to do a seek */
137 if (!(*tif
->tif_preencode
)(tif
, sample
))
139 tif
->tif_flags
|= TIFF_POSTENCODE
;
142 * Ensure the write is either sequential or at the
143 * beginning of a strip (or that we can randomly
144 * access the data -- i.e. no encoding).
146 if (row
!= tif
->tif_row
) {
147 if (row
< tif
->tif_row
) {
149 * Moving backwards within the same strip:
150 * backup to the start and then decode
153 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
155 tif
->tif_rawcp
= tif
->tif_rawdata
;
158 * Seek forward to the desired row.
160 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
165 /* swab if needed - note that source buffer will be altered */
166 tif
->tif_postdecode( tif
, (uint8
*) buf
, tif
->tif_scanlinesize
);
168 status
= (*tif
->tif_encoderow
)(tif
, (uint8
*) buf
,
169 tif
->tif_scanlinesize
, sample
);
171 /* we are now poised at the beginning of the next row */
172 tif
->tif_row
= row
+ 1;
177 * Encode the supplied data and write it to the
180 * NB: Image length must be setup before writing.
183 TIFFWriteEncodedStrip(TIFF
* tif
, uint32 strip
, void* data
, tmsize_t cc
)
185 static const char module[] = "TIFFWriteEncodedStrip";
186 TIFFDirectory
*td
= &tif
->tif_dir
;
189 if (!WRITECHECKSTRIPS(tif
, module))
190 return ((tmsize_t
) -1);
192 * Check strip array to make sure there's space.
193 * We don't support dynamically growing files that
194 * have data organized in separate bitplanes because
195 * it's too painful. In that case we require that
196 * the imagelength be set properly before the first
197 * write (so that the strips array will be fully
200 if (strip
>= td
->td_nstrips
) {
201 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
202 TIFFErrorExt(tif
->tif_clientdata
, module,
203 "Can not grow image by strips when using separate planes");
204 return ((tmsize_t
) -1);
206 if (!TIFFGrowStrips(tif
, 1, module))
207 return ((tmsize_t
) -1);
208 td
->td_stripsperimage
=
209 TIFFhowmany_32(td
->td_imagelength
, td
->td_rowsperstrip
);
212 * Handle delayed allocation of data buffer. This
213 * permits it to be sized according to the directory
216 if (!BUFFERCHECK(tif
))
217 return ((tmsize_t
) -1);
219 tif
->tif_flags
|= TIFF_BUF4WRITE
;
220 tif
->tif_curstrip
= strip
;
222 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
223 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
224 if (!(*tif
->tif_setupencode
)(tif
))
225 return ((tmsize_t
) -1);
226 tif
->tif_flags
|= TIFF_CODERSETUP
;
229 if( td
->td_stripbytecount
[strip
] > 0 )
231 /* Make sure that at the first attempt of rewriting the tile, we will have */
232 /* more bytes available in the output buffer than the previous byte count, */
233 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
234 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
235 if( tif
->tif_rawdatasize
<= td
->td_stripbytecount
[strip
] )
237 if( !(TIFFWriteBufferSetup(tif
, NULL
,
238 (tmsize_t
)TIFFroundup_64((uint64
)(td
->td_stripbytecount
[strip
] + 1), 1024))) )
239 return ((tmsize_t
)(-1));
242 /* Force TIFFAppendToStrip() to consider placing data at end
248 tif
->tif_rawcp
= tif
->tif_rawdata
;
250 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
251 sample
= (uint16
)(strip
/ td
->td_stripsperimage
);
252 if (!(*tif
->tif_preencode
)(tif
, sample
))
253 return ((tmsize_t
) -1);
255 /* swab if needed - note that source buffer will be altered */
256 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
258 if (!(*tif
->tif_encodestrip
)(tif
, (uint8
*) data
, cc
, sample
))
260 if (!(*tif
->tif_postencode
)(tif
))
261 return ((tmsize_t
) -1);
262 if (!isFillOrder(tif
, td
->td_fillorder
) &&
263 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
264 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
265 if (tif
->tif_rawcc
> 0 &&
266 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
267 return ((tmsize_t
) -1);
269 tif
->tif_rawcp
= tif
->tif_rawdata
;
274 * Write the supplied data to the specified strip.
276 * NB: Image length must be setup before writing.
279 TIFFWriteRawStrip(TIFF
* tif
, uint32 strip
, void* data
, tmsize_t cc
)
281 static const char module[] = "TIFFWriteRawStrip";
282 TIFFDirectory
*td
= &tif
->tif_dir
;
284 if (!WRITECHECKSTRIPS(tif
, module))
285 return ((tmsize_t
) -1);
287 * Check strip array to make sure there's space.
288 * We don't support dynamically growing files that
289 * have data organized in separate bitplanes because
290 * it's too painful. In that case we require that
291 * the imagelength be set properly before the first
292 * write (so that the strips array will be fully
295 if (strip
>= td
->td_nstrips
) {
296 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
297 TIFFErrorExt(tif
->tif_clientdata
, module,
298 "Can not grow image by strips when using separate planes");
299 return ((tmsize_t
) -1);
302 * Watch out for a growing image. The value of
303 * strips/image will initially be 1 (since it
304 * can't be deduced until the imagelength is known).
306 if (strip
>= td
->td_stripsperimage
)
307 td
->td_stripsperimage
=
308 TIFFhowmany_32(td
->td_imagelength
,td
->td_rowsperstrip
);
309 if (!TIFFGrowStrips(tif
, 1, module))
310 return ((tmsize_t
) -1);
312 tif
->tif_curstrip
= strip
;
313 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
314 return (TIFFAppendToStrip(tif
, strip
, (uint8
*) data
, cc
) ?
319 * Write and compress a tile of data. The
320 * tile is selected by the (x,y,z,s) coordinates.
323 TIFFWriteTile(TIFF
* tif
, void* buf
, uint32 x
, uint32 y
, uint32 z
, uint16 s
)
325 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
326 return ((tmsize_t
)(-1));
328 * NB: A tile size of -1 is used instead of tif_tilesize knowing
329 * that TIFFWriteEncodedTile will clamp this to the tile size.
330 * This is done because the tile size may not be defined until
331 * after the output buffer is setup in TIFFWriteBufferSetup.
333 return (TIFFWriteEncodedTile(tif
,
334 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tmsize_t
)(-1)));
338 * Encode the supplied data and write it to the
339 * specified tile. There must be space for the
340 * data. The function clamps individual writes
341 * to a tile to the tile size, but does not (and
342 * can not) check that multiple writes to the same
343 * tile do not write more than tile size data.
345 * NB: Image length must be setup before writing; this
346 * interface does not support automatically growing
347 * the image on each write (as TIFFWriteScanline does).
350 TIFFWriteEncodedTile(TIFF
* tif
, uint32 tile
, void* data
, tmsize_t cc
)
352 static const char module[] = "TIFFWriteEncodedTile";
356 if (!WRITECHECKTILES(tif
, module))
357 return ((tmsize_t
)(-1));
359 if (tile
>= td
->td_nstrips
) {
360 TIFFErrorExt(tif
->tif_clientdata
, module, "Tile %lu out of range, max %lu",
361 (unsigned long) tile
, (unsigned long) td
->td_nstrips
);
362 return ((tmsize_t
)(-1));
365 * Handle delayed allocation of data buffer. This
366 * permits it to be sized more intelligently (using
367 * directory information).
369 if (!BUFFERCHECK(tif
))
370 return ((tmsize_t
)(-1));
372 tif
->tif_flags
|= TIFF_BUF4WRITE
;
373 tif
->tif_curtile
= tile
;
375 if( td
->td_stripbytecount
[tile
] > 0 )
377 /* Make sure that at the first attempt of rewriting the tile, we will have */
378 /* more bytes available in the output buffer than the previous byte count, */
379 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
380 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
381 if( tif
->tif_rawdatasize
<= td
->td_stripbytecount
[tile
] )
383 if( !(TIFFWriteBufferSetup(tif
, NULL
,
384 (tmsize_t
)TIFFroundup_64((uint64
)(td
->td_stripbytecount
[tile
] + 1), 1024))) )
385 return ((tmsize_t
)(-1));
388 /* Force TIFFAppendToStrip() to consider placing data at end
394 tif
->tif_rawcp
= tif
->tif_rawdata
;
397 * Compute tiles per row & per column to compute
398 * current row and column
400 tif
->tif_row
= (tile
% TIFFhowmany_32(td
->td_imagelength
, td
->td_tilelength
))
402 tif
->tif_col
= (tile
% TIFFhowmany_32(td
->td_imagewidth
, td
->td_tilewidth
))
405 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
406 if (!(*tif
->tif_setupencode
)(tif
))
407 return ((tmsize_t
)(-1));
408 tif
->tif_flags
|= TIFF_CODERSETUP
;
410 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
411 sample
= (uint16
)(tile
/td
->td_stripsperimage
);
412 if (!(*tif
->tif_preencode
)(tif
, sample
))
413 return ((tmsize_t
)(-1));
415 * Clamp write amount to the tile size. This is mostly
416 * done so that callers can pass in some large number
417 * (e.g. -1) and have the tile size used instead.
419 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
420 cc
= tif
->tif_tilesize
;
422 /* swab if needed - note that source buffer will be altered */
423 tif
->tif_postdecode( tif
, (uint8
*) data
, cc
);
425 if (!(*tif
->tif_encodetile
)(tif
, (uint8
*) data
, cc
, sample
))
427 if (!(*tif
->tif_postencode
)(tif
))
428 return ((tmsize_t
)(-1));
429 if (!isFillOrder(tif
, td
->td_fillorder
) &&
430 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
431 TIFFReverseBits((uint8
*)tif
->tif_rawdata
, tif
->tif_rawcc
);
432 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
433 tif
->tif_rawdata
, tif
->tif_rawcc
))
434 return ((tmsize_t
)(-1));
436 tif
->tif_rawcp
= tif
->tif_rawdata
;
441 * Write the supplied data to the specified strip.
442 * There must be space for the data; we don't check
445 * NB: Image length must be setup before writing; this
446 * interface does not support automatically growing
447 * the image on each write (as TIFFWriteScanline does).
450 TIFFWriteRawTile(TIFF
* tif
, uint32 tile
, void* data
, tmsize_t cc
)
452 static const char module[] = "TIFFWriteRawTile";
454 if (!WRITECHECKTILES(tif
, module))
455 return ((tmsize_t
)(-1));
456 if (tile
>= tif
->tif_dir
.td_nstrips
) {
457 TIFFErrorExt(tif
->tif_clientdata
, module, "Tile %lu out of range, max %lu",
458 (unsigned long) tile
,
459 (unsigned long) tif
->tif_dir
.td_nstrips
);
460 return ((tmsize_t
)(-1));
462 return (TIFFAppendToStrip(tif
, tile
, (uint8
*) data
, cc
) ?
463 cc
: (tmsize_t
)(-1));
466 #define isUnspecified(tif, f) \
467 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
470 TIFFSetupStrips(TIFF
* tif
)
472 TIFFDirectory
* td
= &tif
->tif_dir
;
475 td
->td_stripsperimage
=
476 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
477 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
479 td
->td_stripsperimage
=
480 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
481 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
482 td
->td_nstrips
= td
->td_stripsperimage
;
483 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
484 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
485 td
->td_stripoffset
= (uint64
*)
486 _TIFFmalloc(td
->td_nstrips
* sizeof (uint64
));
487 td
->td_stripbytecount
= (uint64
*)
488 _TIFFmalloc(td
->td_nstrips
* sizeof (uint64
));
489 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
492 * Place data at the end-of-file
493 * (by setting offsets to zero).
495 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint64
));
496 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint64
));
497 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
498 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
504 * Verify file is writable and that the directory
505 * information is setup properly. In doing the latter
506 * we also "freeze" the state of the directory so
507 * that important information is not changed.
510 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module)
512 if (tif
->tif_mode
== O_RDONLY
) {
513 TIFFErrorExt(tif
->tif_clientdata
, module, "File not open for writing");
516 if (tiles
^ isTiled(tif
)) {
517 TIFFErrorExt(tif
->tif_clientdata
, module, tiles
?
518 "Can not write tiles to a stripped image" :
519 "Can not write scanlines to a tiled image");
523 _TIFFFillStriles( tif
);
526 * On the first write verify all the required information
527 * has been setup and initialize any data structures that
528 * had to wait until directory information was set.
529 * Note that a lot of our work is assumed to remain valid
530 * because we disallow any of the important parameters
531 * from changing after we start writing (i.e. once
532 * TIFF_BEENWRITING is set, TIFFSetField will only allow
533 * the image's length to be changed).
535 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
536 TIFFErrorExt(tif
->tif_clientdata
, module,
537 "Must set \"ImageWidth\" before writing data");
540 if (tif
->tif_dir
.td_samplesperpixel
== 1) {
542 * Planarconfiguration is irrelevant in case of single band
543 * images and need not be included. We will set it anyway,
544 * because this field is used in other parts of library even
545 * in the single band case.
547 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
))
548 tif
->tif_dir
.td_planarconfig
= PLANARCONFIG_CONTIG
;
550 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
551 TIFFErrorExt(tif
->tif_clientdata
, module,
552 "Must set \"PlanarConfiguration\" before writing data");
556 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
557 tif
->tif_dir
.td_nstrips
= 0;
558 TIFFErrorExt(tif
->tif_clientdata
, module, "No space for %s arrays",
559 isTiled(tif
) ? "tile" : "strip");
564 tif
->tif_tilesize
= TIFFTileSize(tif
);
565 if (tif
->tif_tilesize
== 0)
569 tif
->tif_tilesize
= (tmsize_t
)(-1);
570 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
571 if (tif
->tif_scanlinesize
== 0)
573 tif
->tif_flags
|= TIFF_BEENWRITING
;
578 * Setup the raw data buffer used for encoding.
581 TIFFWriteBufferSetup(TIFF
* tif
, void* bp
, tmsize_t size
)
583 static const char module[] = "TIFFWriteBufferSetup";
585 if (tif
->tif_rawdata
) {
586 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
587 _TIFFfree(tif
->tif_rawdata
);
588 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
590 tif
->tif_rawdata
= NULL
;
592 if (size
== (tmsize_t
)(-1)) {
593 size
= (isTiled(tif
) ?
594 tif
->tif_tilesize
: TIFFStripSize(tif
));
596 * Make raw data buffer at least 8K
600 bp
= NULL
; /* NB: force malloc */
603 bp
= _TIFFmalloc(size
);
605 TIFFErrorExt(tif
->tif_clientdata
, module, "No space for output buffer");
608 tif
->tif_flags
|= TIFF_MYBUFFER
;
610 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
611 tif
->tif_rawdata
= (uint8
*) bp
;
612 tif
->tif_rawdatasize
= size
;
614 tif
->tif_rawcp
= tif
->tif_rawdata
;
615 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
620 * Grow the strip data structures by delta strips.
623 TIFFGrowStrips(TIFF
* tif
, uint32 delta
, const char* module)
625 TIFFDirectory
*td
= &tif
->tif_dir
;
626 uint64
* new_stripoffset
;
627 uint64
* new_stripbytecount
;
629 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
630 new_stripoffset
= (uint64
*)_TIFFrealloc(td
->td_stripoffset
,
631 (td
->td_nstrips
+ delta
) * sizeof (uint64
));
632 new_stripbytecount
= (uint64
*)_TIFFrealloc(td
->td_stripbytecount
,
633 (td
->td_nstrips
+ delta
) * sizeof (uint64
));
634 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
636 _TIFFfree(new_stripoffset
);
637 if (new_stripbytecount
)
638 _TIFFfree(new_stripbytecount
);
640 TIFFErrorExt(tif
->tif_clientdata
, module, "No space to expand strip arrays");
643 td
->td_stripoffset
= new_stripoffset
;
644 td
->td_stripbytecount
= new_stripbytecount
;
645 _TIFFmemset(td
->td_stripoffset
+ td
->td_nstrips
,
646 0, delta
*sizeof (uint64
));
647 _TIFFmemset(td
->td_stripbytecount
+ td
->td_nstrips
,
648 0, delta
*sizeof (uint64
));
649 td
->td_nstrips
+= delta
;
650 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
656 * Append the data to the specified strip.
659 TIFFAppendToStrip(TIFF
* tif
, uint32 strip
, uint8
* data
, tmsize_t cc
)
661 static const char module[] = "TIFFAppendToStrip";
662 TIFFDirectory
*td
= &tif
->tif_dir
;
664 int64 old_byte_count
= -1;
666 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
667 assert(td
->td_nstrips
> 0);
669 if( td
->td_stripbytecount
[strip
] != 0
670 && td
->td_stripoffset
[strip
] != 0
671 && td
->td_stripbytecount
[strip
] >= (uint64
) cc
)
674 * There is already tile data on disk, and the new tile
675 * data we have will fit in the same space. The only
676 * aspect of this that is risky is that there could be
677 * more data to append to this strip before we are done
678 * depending on how we are getting called.
680 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
681 TIFFErrorExt(tif
->tif_clientdata
, module,
682 "Seek error at scanline %lu",
683 (unsigned long)tif
->tif_row
);
690 * Seek to end of file, and set that as our location to
693 td
->td_stripoffset
[strip
] = TIFFSeekFile(tif
, 0, SEEK_END
);
694 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
697 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
700 * We are starting a fresh strip/tile, so set the size to zero.
702 old_byte_count
= td
->td_stripbytecount
[strip
];
703 td
->td_stripbytecount
[strip
] = 0;
706 m
= tif
->tif_curoff
+cc
;
707 if (!(tif
->tif_flags
&TIFF_BIGTIFF
))
709 if ((m
<tif
->tif_curoff
)||(m
<(uint64
)cc
))
711 TIFFErrorExt(tif
->tif_clientdata
, module, "Maximum TIFF file size exceeded");
714 if (!WriteOK(tif
, data
, cc
)) {
715 TIFFErrorExt(tif
->tif_clientdata
, module, "Write error at scanline %lu",
716 (unsigned long) tif
->tif_row
);
720 td
->td_stripbytecount
[strip
] += cc
;
722 if( (int64
) td
->td_stripbytecount
[strip
] != old_byte_count
)
723 tif
->tif_flags
|= TIFF_DIRTYSTRIP
;
729 * Internal version of TIFFFlushData that can be
730 * called by ``encodestrip routines'' w/o concern
731 * for infinite recursion.
734 TIFFFlushData1(TIFF
* tif
)
736 if (tif
->tif_rawcc
> 0 && tif
->tif_flags
& TIFF_BUF4WRITE
) {
737 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
738 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
739 TIFFReverseBits((uint8
*)tif
->tif_rawdata
,
741 if (!TIFFAppendToStrip(tif
,
742 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
743 tif
->tif_rawdata
, tif
->tif_rawcc
))
746 tif
->tif_rawcp
= tif
->tif_rawdata
;
752 * Set the current write offset. This should only be
753 * used to set the offset to a known previous location
754 * (very carefully), or to 0 so that the next write gets
755 * appended to the end of the file.
758 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
760 tif
->tif_curoff
= off
;
763 /* vim: set ts=8 sts=8 sw=8 noet: */