]>
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, (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 /* if we are writing over existing tiles, zero length. */
231 td
->td_stripbytecount
[strip
] = 0;
233 /* this forces TIFFAppendToStrip() to do a seek */
237 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
238 sample
= (tsample_t
)(strip
/ td
->td_stripsperimage
);
239 if (!(*tif
->tif_preencode
)(tif
, sample
))
240 return ((tsize_t
) -1);
242 /* swab if needed - note that source buffer will be altered */
243 tif
->tif_postdecode( tif
, (tidata_t
) data
, cc
);
245 if (!(*tif
->tif_encodestrip
)(tif
, (tidata_t
) data
, cc
, sample
))
246 return ((tsize_t
) 0);
247 if (!(*tif
->tif_postencode
)(tif
))
248 return ((tsize_t
) -1);
249 if (!isFillOrder(tif
, td
->td_fillorder
) &&
250 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
251 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
252 if (tif
->tif_rawcc
> 0 &&
253 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
254 return ((tsize_t
) -1);
256 tif
->tif_rawcp
= tif
->tif_rawdata
;
261 * Write the supplied data to the specified strip.
263 * NB: Image length must be setup before writing.
266 TIFFWriteRawStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
268 static const char module[] = "TIFFWriteRawStrip";
269 TIFFDirectory
*td
= &tif
->tif_dir
;
271 if (!WRITECHECKSTRIPS(tif
, module))
272 return ((tsize_t
) -1);
274 * Check strip array to make sure there's space.
275 * We don't support dynamically growing files that
276 * have data organized in separate bitplanes because
277 * it's too painful. In that case we require that
278 * the imagelength be set properly before the first
279 * write (so that the strips array will be fully
282 if (strip
>= td
->td_nstrips
) {
283 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
284 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
,
285 "Can not grow image by strips when using separate planes");
286 return ((tsize_t
) -1);
289 * Watch out for a growing image. The value of
290 * strips/image will initially be 1 (since it
291 * can't be deduced until the imagelength is known).
293 if (strip
>= td
->td_stripsperimage
)
294 td
->td_stripsperimage
=
295 TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
);
296 if (!TIFFGrowStrips(tif
, 1, module))
297 return ((tsize_t
) -1);
299 tif
->tif_curstrip
= strip
;
300 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
301 return (TIFFAppendToStrip(tif
, strip
, (tidata_t
) data
, cc
) ?
306 * Write and compress a tile of data. The
307 * tile is selected by the (x,y,z,s) coordinates.
310 TIFFWriteTile(TIFF
* tif
,
311 tdata_t buf
, uint32 x
, uint32 y
, uint32 z
, tsample_t s
)
313 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
316 * NB: A tile size of -1 is used instead of tif_tilesize knowing
317 * that TIFFWriteEncodedTile will clamp this to the tile size.
318 * This is done because the tile size may not be defined until
319 * after the output buffer is setup in TIFFWriteBufferSetup.
321 return (TIFFWriteEncodedTile(tif
,
322 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tsize_t
) -1));
326 * Encode the supplied data and write it to the
327 * specified tile. There must be space for the
328 * data. The function clamps individual writes
329 * to a tile to the tile size, but does not (and
330 * can not) check that multiple writes to the same
331 * tile do not write more than tile size data.
333 * NB: Image length must be setup before writing; this
334 * interface does not support automatically growing
335 * the image on each write (as TIFFWriteScanline does).
338 TIFFWriteEncodedTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
340 static const char module[] = "TIFFWriteEncodedTile";
344 if (!WRITECHECKTILES(tif
, module))
345 return ((tsize_t
) -1);
347 if (tile
>= td
->td_nstrips
) {
348 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Tile %lu out of range, max %lu",
349 tif
->tif_name
, (unsigned long) tile
, (unsigned long) td
->td_nstrips
);
350 return ((tsize_t
) -1);
353 * Handle delayed allocation of data buffer. This
354 * permits it to be sized more intelligently (using
355 * directory information).
357 if (!BUFFERCHECK(tif
))
358 return ((tsize_t
) -1);
359 tif
->tif_curtile
= tile
;
362 tif
->tif_rawcp
= tif
->tif_rawdata
;
364 if( td
->td_stripbytecount
[tile
] > 0 )
366 /* if we are writing over existing tiles, zero length. */
367 td
->td_stripbytecount
[tile
] = 0;
369 /* this forces TIFFAppendToStrip() to do a seek */
374 * Compute tiles per row & per column to compute
375 * current row and column
377 tif
->tif_row
= (tile
% TIFFhowmany(td
->td_imagelength
, td
->td_tilelength
))
379 tif
->tif_col
= (tile
% TIFFhowmany(td
->td_imagewidth
, td
->td_tilewidth
))
382 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
383 if (!(*tif
->tif_setupencode
)(tif
))
384 return ((tsize_t
) -1);
385 tif
->tif_flags
|= TIFF_CODERSETUP
;
387 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
388 sample
= (tsample_t
)(tile
/td
->td_stripsperimage
);
389 if (!(*tif
->tif_preencode
)(tif
, sample
))
390 return ((tsize_t
) -1);
392 * Clamp write amount to the tile size. This is mostly
393 * done so that callers can pass in some large number
394 * (e.g. -1) and have the tile size used instead.
396 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
397 cc
= tif
->tif_tilesize
;
399 /* swab if needed - note that source buffer will be altered */
400 tif
->tif_postdecode( tif
, (tidata_t
) data
, cc
);
402 if (!(*tif
->tif_encodetile
)(tif
, (tidata_t
) data
, cc
, sample
))
403 return ((tsize_t
) 0);
404 if (!(*tif
->tif_postencode
)(tif
))
405 return ((tsize_t
) -1);
406 if (!isFillOrder(tif
, td
->td_fillorder
) &&
407 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
408 TIFFReverseBits((unsigned char *)tif
->tif_rawdata
, tif
->tif_rawcc
);
409 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
410 tif
->tif_rawdata
, tif
->tif_rawcc
))
411 return ((tsize_t
) -1);
413 tif
->tif_rawcp
= tif
->tif_rawdata
;
418 * Write the supplied data to the specified strip.
419 * There must be space for the data; we don't check
422 * NB: Image length must be setup before writing; this
423 * interface does not support automatically growing
424 * the image on each write (as TIFFWriteScanline does).
427 TIFFWriteRawTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
429 static const char module[] = "TIFFWriteRawTile";
431 if (!WRITECHECKTILES(tif
, module))
432 return ((tsize_t
) -1);
433 if (tile
>= tif
->tif_dir
.td_nstrips
) {
434 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Tile %lu out of range, max %lu",
435 tif
->tif_name
, (unsigned long) tile
,
436 (unsigned long) tif
->tif_dir
.td_nstrips
);
437 return ((tsize_t
) -1);
439 return (TIFFAppendToStrip(tif
, tile
, (tidata_t
) data
, cc
) ?
443 #define isUnspecified(tif, f) \
444 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
447 TIFFSetupStrips(TIFF
* tif
)
449 TIFFDirectory
* td
= &tif
->tif_dir
;
452 td
->td_stripsperimage
=
453 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
454 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
456 td
->td_stripsperimage
=
457 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
458 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
459 td
->td_nstrips
= td
->td_stripsperimage
;
460 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
461 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
462 td
->td_stripoffset
= (uint32
*)
463 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
464 td
->td_stripbytecount
= (uint32
*)
465 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
466 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
469 * Place data at the end-of-file
470 * (by setting offsets to zero).
472 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint32
));
473 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint32
));
474 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
475 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
481 * Verify file is writable and that the directory
482 * information is setup properly. In doing the latter
483 * we also "freeze" the state of the directory so
484 * that important information is not changed.
487 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module)
489 if (tif
->tif_mode
== O_RDONLY
) {
490 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: File not open for writing",
494 if (tiles
^ isTiled(tif
)) {
495 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, tiles
?
496 "Can not write tiles to a stripped image" :
497 "Can not write scanlines to a tiled image");
502 * On the first write verify all the required information
503 * has been setup and initialize any data structures that
504 * had to wait until directory information was set.
505 * Note that a lot of our work is assumed to remain valid
506 * because we disallow any of the important parameters
507 * from changing after we start writing (i.e. once
508 * TIFF_BEENWRITING is set, TIFFSetField will only allow
509 * the image's length to be changed).
511 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
512 TIFFErrorExt(tif
->tif_clientdata
, module,
513 "%s: Must set \"ImageWidth\" before writing data",
517 if (tif
->tif_dir
.td_samplesperpixel
== 1) {
519 * Planarconfiguration is irrelevant in case of single band
520 * images and need not be included. We will set it anyway,
521 * because this field is used in other parts of library even
522 * in the single band case.
524 tif
->tif_dir
.td_planarconfig
= PLANARCONFIG_CONTIG
;
526 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
527 TIFFErrorExt(tif
->tif_clientdata
, module,
528 "%s: Must set \"PlanarConfiguration\" before writing data",
533 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
534 tif
->tif_dir
.td_nstrips
= 0;
535 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: No space for %s arrays",
536 tif
->tif_name
, isTiled(tif
) ? "tile" : "strip");
539 tif
->tif_tilesize
= isTiled(tif
) ? TIFFTileSize(tif
) : (tsize_t
) -1;
540 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
541 tif
->tif_flags
|= TIFF_BEENWRITING
;
546 * Setup the raw data buffer used for encoding.
549 TIFFWriteBufferSetup(TIFF
* tif
, tdata_t bp
, tsize_t size
)
551 static const char module[] = "TIFFWriteBufferSetup";
553 if (tif
->tif_rawdata
) {
554 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
555 _TIFFfree(tif
->tif_rawdata
);
556 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
558 tif
->tif_rawdata
= NULL
;
560 if (size
== (tsize_t
) -1) {
561 size
= (isTiled(tif
) ?
562 tif
->tif_tilesize
: TIFFStripSize(tif
));
564 * Make raw data buffer at least 8K
568 bp
= NULL
; /* NB: force malloc */
571 bp
= _TIFFmalloc(size
);
573 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: No space for output buffer",
577 tif
->tif_flags
|= TIFF_MYBUFFER
;
579 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
580 tif
->tif_rawdata
= (tidata_t
) bp
;
581 tif
->tif_rawdatasize
= size
;
583 tif
->tif_rawcp
= tif
->tif_rawdata
;
584 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
589 * Grow the strip data structures by delta strips.
592 TIFFGrowStrips(TIFF
* tif
, int delta
, const char* module)
594 TIFFDirectory
*td
= &tif
->tif_dir
;
595 uint32
*new_stripoffset
, *new_stripbytecount
;
597 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
598 new_stripoffset
= (uint32
*)_TIFFrealloc(td
->td_stripoffset
,
599 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
600 new_stripbytecount
= (uint32
*)_TIFFrealloc(td
->td_stripbytecount
,
601 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
602 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
604 _TIFFfree(new_stripoffset
);
605 if (new_stripbytecount
)
606 _TIFFfree(new_stripbytecount
);
608 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: No space to expand strip arrays",
612 td
->td_stripoffset
= new_stripoffset
;
613 td
->td_stripbytecount
= new_stripbytecount
;
614 _TIFFmemset(td
->td_stripoffset
+ td
->td_nstrips
,
615 0, delta
*sizeof (uint32
));
616 _TIFFmemset(td
->td_stripbytecount
+ td
->td_nstrips
,
617 0, delta
*sizeof (uint32
));
618 td
->td_nstrips
+= delta
;
623 * Append the data to the specified strip.
626 TIFFAppendToStrip(TIFF
* tif
, tstrip_t strip
, tidata_t data
, tsize_t cc
)
628 TIFFDirectory
*td
= &tif
->tif_dir
;
629 static const char module[] = "TIFFAppendToStrip";
631 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
633 * No current offset, set the current strip.
635 assert(td
->td_nstrips
> 0);
636 if (td
->td_stripoffset
[strip
] != 0) {
638 * Prevent overlapping of the data chunks. We need
639 * this to enable in place updating of the compressed
640 * images. Larger blocks will be moved at the end of
641 * the file without any optimization of the spare
642 * space, so such scheme is not too much effective.
644 if (td
->td_stripbytecountsorted
) {
645 if (strip
== td
->td_nstrips
- 1
646 || td
->td_stripoffset
[strip
+ 1] <
647 td
->td_stripoffset
[strip
] + cc
) {
648 td
->td_stripoffset
[strip
] =
649 TIFFSeekFile(tif
, (toff_t
)0,
654 for (i
= 0; i
< td
->td_nstrips
; i
++) {
655 if (td
->td_stripoffset
[i
] >
656 td
->td_stripoffset
[strip
]
657 && td
->td_stripoffset
[i
] <
658 td
->td_stripoffset
[strip
] + cc
) {
659 td
->td_stripoffset
[strip
] =
667 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
668 TIFFErrorExt(tif
->tif_clientdata
, module,
669 "%s: Seek error at scanline %lu",
671 (unsigned long)tif
->tif_row
);
675 td
->td_stripoffset
[strip
] =
676 TIFFSeekFile(tif
, (toff_t
) 0, SEEK_END
);
677 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
680 if (!WriteOK(tif
, data
, cc
)) {
681 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Write error at scanline %lu",
682 tif
->tif_name
, (unsigned long) tif
->tif_row
);
685 tif
->tif_curoff
+= cc
;
686 td
->td_stripbytecount
[strip
] += cc
;
691 * Internal version of TIFFFlushData that can be
692 * called by ``encodestrip routines'' w/o concern
693 * for infinite recursion.
696 TIFFFlushData1(TIFF
* tif
)
698 if (tif
->tif_rawcc
> 0) {
699 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
700 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
701 TIFFReverseBits((unsigned char *)tif
->tif_rawdata
,
703 if (!TIFFAppendToStrip(tif
,
704 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
705 tif
->tif_rawdata
, tif
->tif_rawcc
))
708 tif
->tif_rawcp
= tif
->tif_rawdata
;
714 * Set the current write offset. This should only be
715 * used to set the offset to a known previous location
716 * (very carefully), or to 0 so that the next write gets
717 * appended to the end of the file.
720 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
722 tif
->tif_curoff
= off
;
725 /* vim: set ts=8 sts=8 sw=8 noet: */