1 /* $Id: tif_write.c,v 1.22.2.5 2010-06-08 18:50:43 bfriesen Exp $ */
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, (tsize_t) -1))
45 static int TIFFGrowStrips(TIFF
*, int, const char*);
46 static int TIFFAppendToStrip(TIFF
*, tstrip_t
, tidata_t
, tsize_t
);
49 TIFFWriteScanline(TIFF
* tif
, tdata_t buf
, uint32 row
, tsample_t 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
))
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
, tif
->tif_name
,
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
, tif
->tif_name
,
85 "%d: Sample out of range, max %d",
86 sample
, 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(td
->td_imagelength
,td
->td_rowsperstrip
);
117 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
118 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
119 if (!(*tif
->tif_setupencode
)(tif
))
121 tif
->tif_flags
|= TIFF_CODERSETUP
;
125 tif
->tif_rawcp
= tif
->tif_rawdata
;
127 if( td
->td_stripbytecount
[strip
] > 0 )
129 /* if we are writing over existing tiles, zero length */
130 td
->td_stripbytecount
[strip
] = 0;
132 /* this forces TIFFAppendToStrip() to do a seek */
136 if (!(*tif
->tif_preencode
)(tif
, sample
))
138 tif
->tif_flags
|= TIFF_POSTENCODE
;
141 * Ensure the write is either sequential or at the
142 * beginning of a strip (or that we can randomly
143 * access the data -- i.e. no encoding).
145 if (row
!= tif
->tif_row
) {
146 if (row
< tif
->tif_row
) {
148 * Moving backwards within the same strip:
149 * backup to the start and then decode
152 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
154 tif
->tif_rawcp
= tif
->tif_rawdata
;
157 * Seek forward to the desired row.
159 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
164 /* swab if needed - note that source buffer will be altered */
165 tif
->tif_postdecode( tif
, (tidata_t
) buf
, tif
->tif_scanlinesize
);
167 status
= (*tif
->tif_encoderow
)(tif
, (tidata_t
) buf
,
168 tif
->tif_scanlinesize
, sample
);
170 /* we are now poised at the beginning of the next row */
171 tif
->tif_row
= row
+ 1;
176 * Encode the supplied data and write it to the
179 * NB: Image length must be setup before writing.
182 TIFFWriteEncodedStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
184 static const char module
[] = "TIFFWriteEncodedStrip";
185 TIFFDirectory
*td
= &tif
->tif_dir
;
188 if (!WRITECHECKSTRIPS(tif
, module
))
189 return ((tsize_t
) -1);
191 * Check strip array to make sure there's space.
192 * We don't support dynamically growing files that
193 * have data organized in separate bitplanes because
194 * it's too painful. In that case we require that
195 * the imagelength be set properly before the first
196 * write (so that the strips array will be fully
199 if (strip
>= td
->td_nstrips
) {
200 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
201 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
,
202 "Can not grow image by strips when using separate planes");
203 return ((tsize_t
) -1);
205 if (!TIFFGrowStrips(tif
, 1, module
))
206 return ((tsize_t
) -1);
207 td
->td_stripsperimage
=
208 TIFFhowmany(td
->td_imagelength
, td
->td_rowsperstrip
);
211 * Handle delayed allocation of data buffer. This
212 * permits it to be sized according to the directory
215 if (!BUFFERCHECK(tif
))
216 return ((tsize_t
) -1);
217 tif
->tif_curstrip
= strip
;
218 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
219 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
220 if (!(*tif
->tif_setupencode
)(tif
))
221 return ((tsize_t
) -1);
222 tif
->tif_flags
|= TIFF_CODERSETUP
;
226 tif
->tif_rawcp
= tif
->tif_rawdata
;
228 if( td
->td_stripbytecount
[strip
] > 0 )
230 /* Force TIFFAppendToStrip() to consider placing data at end
235 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
236 sample
= (tsample_t
)(strip
/ td
->td_stripsperimage
);
237 if (!(*tif
->tif_preencode
)(tif
, sample
))
238 return ((tsize_t
) -1);
240 /* swab if needed - note that source buffer will be altered */
241 tif
->tif_postdecode( tif
, (tidata_t
) data
, cc
);
243 if (!(*tif
->tif_encodestrip
)(tif
, (tidata_t
) data
, cc
, sample
))
244 return ((tsize_t
) 0);
245 if (!(*tif
->tif_postencode
)(tif
))
246 return ((tsize_t
) -1);
247 if (!isFillOrder(tif
, td
->td_fillorder
) &&
248 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
249 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
250 if (tif
->tif_rawcc
> 0 &&
251 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
252 return ((tsize_t
) -1);
254 tif
->tif_rawcp
= tif
->tif_rawdata
;
259 * Write the supplied data to the specified strip.
261 * NB: Image length must be setup before writing.
264 TIFFWriteRawStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
266 static const char module
[] = "TIFFWriteRawStrip";
267 TIFFDirectory
*td
= &tif
->tif_dir
;
269 if (!WRITECHECKSTRIPS(tif
, module
))
270 return ((tsize_t
) -1);
272 * Check strip array to make sure there's space.
273 * We don't support dynamically growing files that
274 * have data organized in separate bitplanes because
275 * it's too painful. In that case we require that
276 * the imagelength be set properly before the first
277 * write (so that the strips array will be fully
280 if (strip
>= td
->td_nstrips
) {
281 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
282 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
,
283 "Can not grow image by strips when using separate planes");
284 return ((tsize_t
) -1);
287 * Watch out for a growing image. The value of
288 * strips/image will initially be 1 (since it
289 * can't be deduced until the imagelength is known).
291 if (strip
>= td
->td_stripsperimage
)
292 td
->td_stripsperimage
=
293 TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
);
294 if (!TIFFGrowStrips(tif
, 1, module
))
295 return ((tsize_t
) -1);
297 tif
->tif_curstrip
= strip
;
298 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
299 return (TIFFAppendToStrip(tif
, strip
, (tidata_t
) data
, cc
) ?
304 * Write and compress a tile of data. The
305 * tile is selected by the (x,y,z,s) coordinates.
308 TIFFWriteTile(TIFF
* tif
,
309 tdata_t buf
, uint32 x
, uint32 y
, uint32 z
, tsample_t s
)
311 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
314 * NB: A tile size of -1 is used instead of tif_tilesize knowing
315 * that TIFFWriteEncodedTile will clamp this to the tile size.
316 * This is done because the tile size may not be defined until
317 * after the output buffer is setup in TIFFWriteBufferSetup.
319 return (TIFFWriteEncodedTile(tif
,
320 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tsize_t
) -1));
324 * Encode the supplied data and write it to the
325 * specified tile. There must be space for the
326 * data. The function clamps individual writes
327 * to a tile to the tile size, but does not (and
328 * can not) check that multiple writes to the same
329 * tile do not write more than tile size data.
331 * NB: Image length must be setup before writing; this
332 * interface does not support automatically growing
333 * the image on each write (as TIFFWriteScanline does).
336 TIFFWriteEncodedTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
338 static const char module
[] = "TIFFWriteEncodedTile";
342 if (!WRITECHECKTILES(tif
, module
))
343 return ((tsize_t
) -1);
345 if (tile
>= td
->td_nstrips
) {
346 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s: Tile %lu out of range, max %lu",
347 tif
->tif_name
, (unsigned long) tile
, (unsigned long) td
->td_nstrips
);
348 return ((tsize_t
) -1);
351 * Handle delayed allocation of data buffer. This
352 * permits it to be sized more intelligently (using
353 * directory information).
355 if (!BUFFERCHECK(tif
))
356 return ((tsize_t
) -1);
357 tif
->tif_curtile
= tile
;
360 tif
->tif_rawcp
= tif
->tif_rawdata
;
362 if( td
->td_stripbytecount
[tile
] > 0 )
364 /* Force TIFFAppendToStrip() to consider placing data at end
370 * Compute tiles per row & per column to compute
371 * current row and column
373 tif
->tif_row
= (tile
% TIFFhowmany(td
->td_imagelength
, td
->td_tilelength
))
375 tif
->tif_col
= (tile
% TIFFhowmany(td
->td_imagewidth
, td
->td_tilewidth
))
378 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
379 if (!(*tif
->tif_setupencode
)(tif
))
380 return ((tsize_t
) -1);
381 tif
->tif_flags
|= TIFF_CODERSETUP
;
383 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
384 sample
= (tsample_t
)(tile
/td
->td_stripsperimage
);
385 if (!(*tif
->tif_preencode
)(tif
, sample
))
386 return ((tsize_t
) -1);
388 * Clamp write amount to the tile size. This is mostly
389 * done so that callers can pass in some large number
390 * (e.g. -1) and have the tile size used instead.
392 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
393 cc
= tif
->tif_tilesize
;
395 /* swab if needed - note that source buffer will be altered */
396 tif
->tif_postdecode( tif
, (tidata_t
) data
, cc
);
398 if (!(*tif
->tif_encodetile
)(tif
, (tidata_t
) data
, cc
, sample
))
399 return ((tsize_t
) 0);
400 if (!(*tif
->tif_postencode
)(tif
))
401 return ((tsize_t
) -1);
402 if (!isFillOrder(tif
, td
->td_fillorder
) &&
403 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
404 TIFFReverseBits((unsigned char *)tif
->tif_rawdata
, tif
->tif_rawcc
);
405 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
406 tif
->tif_rawdata
, tif
->tif_rawcc
))
407 return ((tsize_t
) -1);
409 tif
->tif_rawcp
= tif
->tif_rawdata
;
414 * Write the supplied data to the specified strip.
415 * There must be space for the data; we don't check
418 * NB: Image length must be setup before writing; this
419 * interface does not support automatically growing
420 * the image on each write (as TIFFWriteScanline does).
423 TIFFWriteRawTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
425 static const char module
[] = "TIFFWriteRawTile";
427 if (!WRITECHECKTILES(tif
, module
))
428 return ((tsize_t
) -1);
429 if (tile
>= tif
->tif_dir
.td_nstrips
) {
430 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s: Tile %lu out of range, max %lu",
431 tif
->tif_name
, (unsigned long) tile
,
432 (unsigned long) tif
->tif_dir
.td_nstrips
);
433 return ((tsize_t
) -1);
435 return (TIFFAppendToStrip(tif
, tile
, (tidata_t
) data
, cc
) ?
439 #define isUnspecified(tif, f) \
440 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
443 TIFFSetupStrips(TIFF
* tif
)
445 TIFFDirectory
* td
= &tif
->tif_dir
;
448 td
->td_stripsperimage
=
449 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
450 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
452 td
->td_stripsperimage
=
453 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
454 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
455 td
->td_nstrips
= td
->td_stripsperimage
;
456 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
457 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
458 td
->td_stripoffset
= (uint32
*)
459 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
460 td
->td_stripbytecount
= (uint32
*)
461 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
462 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
465 * Place data at the end-of-file
466 * (by setting offsets to zero).
468 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint32
));
469 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint32
));
470 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
471 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
477 * Verify file is writable and that the directory
478 * information is setup properly. In doing the latter
479 * we also "freeze" the state of the directory so
480 * that important information is not changed.
483 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module
)
485 if (tif
->tif_mode
== O_RDONLY
) {
486 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s: File not open for writing",
490 if (tiles
^ isTiled(tif
)) {
491 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, tiles
?
492 "Can not write tiles to a stripped image" :
493 "Can not write scanlines to a tiled image");
498 * On the first write verify all the required information
499 * has been setup and initialize any data structures that
500 * had to wait until directory information was set.
501 * Note that a lot of our work is assumed to remain valid
502 * because we disallow any of the important parameters
503 * from changing after we start writing (i.e. once
504 * TIFF_BEENWRITING is set, TIFFSetField will only allow
505 * the image's length to be changed).
507 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
508 TIFFErrorExt(tif
->tif_clientdata
, module
,
509 "%s: Must set \"ImageWidth\" before writing data",
513 if (tif
->tif_dir
.td_samplesperpixel
== 1) {
515 * Planarconfiguration is irrelevant in case of single band
516 * images and need not be included. We will set it anyway,
517 * because this field is used in other parts of library even
518 * in the single band case.
520 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
))
521 tif
->tif_dir
.td_planarconfig
= PLANARCONFIG_CONTIG
;
523 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
524 TIFFErrorExt(tif
->tif_clientdata
, module
,
525 "%s: Must set \"PlanarConfiguration\" before writing data",
530 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
531 tif
->tif_dir
.td_nstrips
= 0;
532 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s: No space for %s arrays",
533 tif
->tif_name
, isTiled(tif
) ? "tile" : "strip");
536 tif
->tif_tilesize
= isTiled(tif
) ? TIFFTileSize(tif
) : (tsize_t
) -1;
537 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
538 tif
->tif_flags
|= TIFF_BEENWRITING
;
543 * Setup the raw data buffer used for encoding.
546 TIFFWriteBufferSetup(TIFF
* tif
, tdata_t bp
, tsize_t size
)
548 static const char module
[] = "TIFFWriteBufferSetup";
550 if (tif
->tif_rawdata
) {
551 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
552 _TIFFfree(tif
->tif_rawdata
);
553 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
555 tif
->tif_rawdata
= NULL
;
557 if (size
== (tsize_t
) -1) {
558 size
= (isTiled(tif
) ?
559 tif
->tif_tilesize
: TIFFStripSize(tif
));
561 * Make raw data buffer at least 8K
565 bp
= NULL
; /* NB: force malloc */
568 bp
= _TIFFmalloc(size
);
570 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s: No space for output buffer",
574 tif
->tif_flags
|= TIFF_MYBUFFER
;
576 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
577 tif
->tif_rawdata
= (tidata_t
) bp
;
578 tif
->tif_rawdatasize
= size
;
580 tif
->tif_rawcp
= tif
->tif_rawdata
;
581 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
586 * Grow the strip data structures by delta strips.
589 TIFFGrowStrips(TIFF
* tif
, int delta
, const char* module
)
591 TIFFDirectory
*td
= &tif
->tif_dir
;
592 uint32
*new_stripoffset
, *new_stripbytecount
;
594 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
595 new_stripoffset
= (uint32
*)_TIFFrealloc(td
->td_stripoffset
,
596 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
597 new_stripbytecount
= (uint32
*)_TIFFrealloc(td
->td_stripbytecount
,
598 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
599 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
601 _TIFFfree(new_stripoffset
);
602 if (new_stripbytecount
)
603 _TIFFfree(new_stripbytecount
);
605 TIFFErrorExt(tif
->tif_clientdata
, module
, "%s: No space to expand strip arrays",
609 td
->td_stripoffset
= new_stripoffset
;
610 td
->td_stripbytecount
= new_stripbytecount
;
611 _TIFFmemset(td
->td_stripoffset
+ td
->td_nstrips
,
612 0, delta
*sizeof (uint32
));
613 _TIFFmemset(td
->td_stripbytecount
+ td
->td_nstrips
,
614 0, delta
*sizeof (uint32
));
615 td
->td_nstrips
+= delta
;
620 * Append the data to the specified strip.
623 TIFFAppendToStrip(TIFF
* tif
, tstrip_t strip
, tidata_t data
, tsize_t cc
)
625 static const char module
[] = "TIFFAppendToStrip";
626 TIFFDirectory
*td
= &tif
->tif_dir
;
628 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
629 assert(td
->td_nstrips
> 0);
631 if( td
->td_stripbytecount
[strip
] != 0
632 && td
->td_stripoffset
[strip
] != 0
633 && td
->td_stripbytecount
[strip
] >= cc
)
636 * There is already tile data on disk, and the new tile
637 * data we have to will fit in the same space. The only
638 * aspect of this that is risky is that there could be
639 * more data to append to this strip before we are done
640 * depending on how we are getting called.
642 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
643 TIFFErrorExt(tif
->tif_clientdata
, module
,
644 "Seek error at scanline %lu",
645 (unsigned long)tif
->tif_row
);
652 * Seek to end of file, and set that as our location to
655 td
->td_stripoffset
[strip
] = TIFFSeekFile(tif
, 0, SEEK_END
);
658 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
661 * We are starting a fresh strip/tile, so set the size to zero.
663 td
->td_stripbytecount
[strip
] = 0;
666 if (!WriteOK(tif
, data
, cc
)) {
667 TIFFErrorExt(tif
->tif_clientdata
, module
, "Write error at scanline %lu",
668 (unsigned long) tif
->tif_row
);
671 tif
->tif_curoff
= tif
->tif_curoff
+cc
;
672 td
->td_stripbytecount
[strip
] += cc
;
677 * Internal version of TIFFFlushData that can be
678 * called by ``encodestrip routines'' w/o concern
679 * for infinite recursion.
682 TIFFFlushData1(TIFF
* tif
)
684 if (tif
->tif_rawcc
> 0) {
685 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
686 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
687 TIFFReverseBits((unsigned char *)tif
->tif_rawdata
,
689 if (!TIFFAppendToStrip(tif
,
690 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
691 tif
->tif_rawdata
, tif
->tif_rawcc
))
694 tif
->tif_rawcp
= tif
->tif_rawdata
;
700 * Set the current write offset. This should only be
701 * used to set the offset to a known previous location
702 * (very carefully), or to 0 so that the next write gets
703 * appended to the end of the file.
706 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
708 tif
->tif_curoff
= off
;
711 /* vim: set ts=8 sts=8 sw=8 noet: */