]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/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
38 #define STRIPINCR 20 /* expansion factor on strip array */
40 #define WRITECHECKSTRIPS(tif, module) \
41 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
42 #define WRITECHECKTILES(tif, module) \
43 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
44 #define BUFFERCHECK(tif) \
45 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
46 TIFFWriteBufferSetup((tif), NULL, (tsize_t) -1))
48 static int TIFFGrowStrips(TIFF
*, int, const char*);
49 static int TIFFAppendToStrip(TIFF
*, tstrip_t
, tidata_t
, tsize_t
);
52 TIFFWriteScanline(TIFF
* tif
, tdata_t buf
, uint32 row
, tsample_t sample
)
54 static const char module[] = "TIFFWriteScanline";
55 register TIFFDirectory
*td
;
56 int status
, imagegrew
= 0;
59 if (!WRITECHECKSTRIPS(tif
, module))
62 * Handle delayed allocation of data buffer. This
63 * permits it to be sized more intelligently (using
64 * directory information).
66 if (!BUFFERCHECK(tif
))
70 * Extend image length if needed
71 * (but only for PlanarConfig=1).
73 if (row
>= td
->td_imagelength
) { /* extend image */
74 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
75 TIFFError(tif
->tif_name
,
76 "Can not change \"ImageLength\" when using separate planes");
79 td
->td_imagelength
= row
+1;
83 * Calculate strip and check for crossings.
85 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
86 if (sample
>= td
->td_samplesperpixel
) {
87 TIFFError(tif
->tif_name
,
88 "%d: Sample out of range, max %d",
89 sample
, td
->td_samplesperpixel
);
92 strip
= sample
*td
->td_stripsperimage
+ row
/td
->td_rowsperstrip
;
94 strip
= row
/ td
->td_rowsperstrip
;
95 if (strip
!= tif
->tif_curstrip
) {
97 * Changing strips -- flush any data present.
99 if (!TIFFFlushData(tif
))
101 tif
->tif_curstrip
= strip
;
103 * Watch out for a growing image. The value of
104 * strips/image will initially be 1 (since it
105 * can't be deduced until the imagelength is known).
107 if (strip
>= td
->td_stripsperimage
&& imagegrew
)
108 td
->td_stripsperimage
=
109 TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
);
111 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
112 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
113 if (!(*tif
->tif_setupencode
)(tif
))
115 tif
->tif_flags
|= TIFF_CODERSETUP
;
117 if (!(*tif
->tif_preencode
)(tif
, sample
))
119 tif
->tif_flags
|= TIFF_POSTENCODE
;
122 * Check strip array to make sure there's space.
123 * We don't support dynamically growing files that
124 * have data organized in separate bitplanes because
125 * it's too painful. In that case we require that
126 * the imagelength be set properly before the first
127 * write (so that the strips array will be fully
130 if (strip
>= td
->td_nstrips
&& !TIFFGrowStrips(tif
, 1, module))
133 * Ensure the write is either sequential or at the
134 * beginning of a strip (or that we can randomly
135 * access the data -- i.e. no encoding).
137 if (row
!= tif
->tif_row
) {
138 if (row
< tif
->tif_row
) {
140 * Moving backwards within the same strip:
141 * backup to the start and then decode
144 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
146 tif
->tif_rawcp
= tif
->tif_rawdata
;
149 * Seek forward to the desired row.
151 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
156 /* swab if needed - note that source buffer will be altered */
157 tif
->tif_postdecode( tif
, (tidata_t
) buf
, tif
->tif_scanlinesize
);
159 status
= (*tif
->tif_encoderow
)(tif
, (tidata_t
) buf
,
160 tif
->tif_scanlinesize
, sample
);
162 /* we are now poised at the beginning of the next row */
163 tif
->tif_row
= row
+ 1;
168 * Encode the supplied data and write it to the
169 * specified strip. There must be space for the
170 * data; we don't check if strips overlap!
172 * NB: Image length must be setup before writing.
175 TIFFWriteEncodedStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
177 static const char module[] = "TIFFWriteEncodedStrip";
178 TIFFDirectory
*td
= &tif
->tif_dir
;
181 if (!WRITECHECKSTRIPS(tif
, module))
182 return ((tsize_t
) -1);
184 * Check strip array to make sure there's space.
185 * We don't support dynamically growing files that
186 * have data organized in separate bitplanes because
187 * it's too painful. In that case we require that
188 * the imagelength be set properly before the first
189 * write (so that the strips array will be fully
192 if (strip
>= td
->td_nstrips
) {
193 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
194 TIFFError(tif
->tif_name
,
195 "Can not grow image by strips when using separate planes");
196 return ((tsize_t
) -1);
198 if (!TIFFGrowStrips(tif
, 1, module))
199 return ((tsize_t
) -1);
200 td
->td_stripsperimage
=
201 TIFFhowmany(td
->td_imagelength
, td
->td_rowsperstrip
);
204 * Handle delayed allocation of data buffer. This
205 * permits it to be sized according to the directory
208 if (!BUFFERCHECK(tif
))
209 return ((tsize_t
) -1);
210 tif
->tif_curstrip
= strip
;
211 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
212 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
213 if (!(*tif
->tif_setupencode
)(tif
))
214 return ((tsize_t
) -1);
215 tif
->tif_flags
|= TIFF_CODERSETUP
;
220 tif
->tif_rawcp
= tif
->tif_rawdata
;
222 if( td
->td_stripbytecount
[strip
] > 0 )
224 /* if we are writing over existing tiles, zero length. */
225 td
->td_stripbytecount
[strip
] = 0;
227 /* this forces TIFFAppendToStrip() to do a seek */
232 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
233 sample
= (tsample_t
)(strip
/ td
->td_stripsperimage
);
234 if (!(*tif
->tif_preencode
)(tif
, sample
))
235 return ((tsize_t
) -1);
237 /* swab if needed - note that source buffer will be altered */
238 tif
->tif_postdecode( tif
, (tidata_t
) data
, cc
);
240 if (!(*tif
->tif_encodestrip
)(tif
, (tidata_t
) data
, cc
, sample
))
241 return ((tsize_t
) 0);
242 if (!(*tif
->tif_postencode
)(tif
))
243 return ((tsize_t
) -1);
244 if (!isFillOrder(tif
, td
->td_fillorder
) &&
245 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
246 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
247 if (tif
->tif_rawcc
> 0 &&
248 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
249 return ((tsize_t
) -1);
251 tif
->tif_rawcp
= tif
->tif_rawdata
;
256 * Write the supplied data to the specified strip.
257 * There must be space for the data; we don't check
260 * NB: Image length must be setup before writing.
263 TIFFWriteRawStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
265 static const char module[] = "TIFFWriteRawStrip";
266 TIFFDirectory
*td
= &tif
->tif_dir
;
268 if (!WRITECHECKSTRIPS(tif
, module))
269 return ((tsize_t
) -1);
271 * Check strip array to make sure there's space.
272 * We don't support dynamically growing files that
273 * have data organized in separate bitplanes because
274 * it's too painful. In that case we require that
275 * the imagelength be set properly before the first
276 * write (so that the strips array will be fully
279 if (strip
>= td
->td_nstrips
) {
280 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
281 TIFFError(tif
->tif_name
,
282 "Can not grow image by strips when using separate planes");
283 return ((tsize_t
) -1);
286 * Watch out for a growing image. The value of
287 * strips/image will initially be 1 (since it
288 * can't be deduced until the imagelength is known).
290 if (strip
>= td
->td_stripsperimage
)
291 td
->td_stripsperimage
=
292 TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
);
293 if (!TIFFGrowStrips(tif
, 1, module))
294 return ((tsize_t
) -1);
296 tif
->tif_curstrip
= strip
;
297 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
298 return (TIFFAppendToStrip(tif
, strip
, (tidata_t
) data
, cc
) ?
303 * Write and compress a tile of data. The
304 * tile is selected by the (x,y,z,s) coordinates.
307 TIFFWriteTile(TIFF
* tif
,
308 tdata_t buf
, uint32 x
, uint32 y
, uint32 z
, tsample_t s
)
310 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
313 * NB: A tile size of -1 is used instead of tif_tilesize knowing
314 * that TIFFWriteEncodedTile will clamp this to the tile size.
315 * This is done because the tile size may not be defined until
316 * after the output buffer is setup in TIFFWriteBufferSetup.
318 return (TIFFWriteEncodedTile(tif
,
319 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tsize_t
) -1));
323 * Encode the supplied data and write it to the
324 * specified tile. There must be space for the
325 * data. The function clamps individual writes
326 * to a tile to the tile size, but does not (and
327 * can not) check that multiple writes to the same
328 * tile do not write more than tile size data.
330 * NB: Image length must be setup before writing; this
331 * interface does not support automatically growing
332 * the image on each write (as TIFFWriteScanline does).
335 TIFFWriteEncodedTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
337 static const char module[] = "TIFFWriteEncodedTile";
341 if (!WRITECHECKTILES(tif
, module))
342 return ((tsize_t
) -1);
344 if (tile
>= td
->td_nstrips
) {
345 TIFFError(module, "%s: Tile %lu out of range, max %lu",
346 tif
->tif_name
, (u_long
) tile
, (u_long
) td
->td_nstrips
);
347 return ((tsize_t
) -1);
350 * Handle delayed allocation of data buffer. This
351 * permits it to be sized more intelligently (using
352 * directory information).
354 if (!BUFFERCHECK(tif
))
355 return ((tsize_t
) -1);
356 tif
->tif_curtile
= tile
;
360 tif
->tif_rawcp
= tif
->tif_rawdata
;
362 if( td
->td_stripbytecount
[tile
] > 0 )
364 /* if we are writing over existing tiles, zero length. */
365 td
->td_stripbytecount
[tile
] = 0;
367 /* this forces TIFFAppendToStrip() to do a seek */
373 * Compute tiles per row & per column to compute
374 * current row and column
376 tif
->tif_row
= (tile
% TIFFhowmany(td
->td_imagelength
, td
->td_tilelength
))
378 tif
->tif_col
= (tile
% TIFFhowmany(td
->td_imagewidth
, td
->td_tilewidth
))
381 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
382 if (!(*tif
->tif_setupencode
)(tif
))
383 return ((tsize_t
) -1);
384 tif
->tif_flags
|= TIFF_CODERSETUP
;
386 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
387 sample
= (tsample_t
)(tile
/td
->td_stripsperimage
);
388 if (!(*tif
->tif_preencode
)(tif
, sample
))
389 return ((tsize_t
) -1);
391 * Clamp write amount to the tile size. This is mostly
392 * done so that callers can pass in some large number
393 * (e.g. -1) and have the tile size used instead.
395 if ( cc
< 1 || cc
> tif
->tif_tilesize
)
396 cc
= tif
->tif_tilesize
;
398 /* swab if needed - note that source buffer will be altered */
399 tif
->tif_postdecode( tif
, (tidata_t
) data
, cc
);
401 if (!(*tif
->tif_encodetile
)(tif
, (tidata_t
) data
, cc
, sample
))
402 return ((tsize_t
) 0);
403 if (!(*tif
->tif_postencode
)(tif
))
404 return ((tsize_t
) -1);
405 if (!isFillOrder(tif
, td
->td_fillorder
) &&
406 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
407 TIFFReverseBits((u_char
*)tif
->tif_rawdata
, tif
->tif_rawcc
);
408 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
409 tif
->tif_rawdata
, tif
->tif_rawcc
))
410 return ((tsize_t
) -1);
412 tif
->tif_rawcp
= tif
->tif_rawdata
;
417 * Write the supplied data to the specified strip.
418 * There must be space for the data; we don't check
421 * NB: Image length must be setup before writing; this
422 * interface does not support automatically growing
423 * the image on each write (as TIFFWriteScanline does).
426 TIFFWriteRawTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
428 static const char module[] = "TIFFWriteRawTile";
430 if (!WRITECHECKTILES(tif
, module))
431 return ((tsize_t
) -1);
432 if (tile
>= tif
->tif_dir
.td_nstrips
) {
433 TIFFError(module, "%s: Tile %lu out of range, max %lu",
434 tif
->tif_name
, (u_long
) tile
,
435 (u_long
) tif
->tif_dir
.td_nstrips
);
436 return ((tsize_t
) -1);
438 return (TIFFAppendToStrip(tif
, tile
, (tidata_t
) data
, cc
) ?
442 #define isUnspecified(tif, f) \
443 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
446 TIFFSetupStrips(TIFF
* tif
)
448 TIFFDirectory
* td
= &tif
->tif_dir
;
451 td
->td_stripsperimage
=
452 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
453 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
455 td
->td_stripsperimage
=
456 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
457 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
458 td
->td_nstrips
= td
->td_stripsperimage
;
459 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
460 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
461 td
->td_stripoffset
= (uint32
*)
462 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
463 td
->td_stripbytecount
= (uint32
*)
464 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
465 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
468 * Place data at the end-of-file
469 * (by setting offsets to zero).
471 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint32
));
472 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint32
));
473 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
474 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
480 * Verify file is writable and that the directory
481 * information is setup properly. In doing the latter
482 * we also "freeze" the state of the directory so
483 * that important information is not changed.
486 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module)
488 if (tif
->tif_mode
== O_RDONLY
) {
489 TIFFError(module, "%s: File not open for writing",
493 if (tiles
^ isTiled(tif
)) {
494 TIFFError(tif
->tif_name
, tiles
?
495 "Can not write tiles to a stripped image" :
496 "Can not write scanlines to a tiled image");
501 * While we allow compressed TIFF files to be opened in update mode,
502 * we don't allow writing any image blocks in an existing compressed
503 * image. Eventually we could do so, by moving blocks that grow
504 * to the end of the file, but we don't for now.
506 if (tif
->tif_dir
.td_stripoffset
!= NULL
507 && tif
->tif_dir
.td_compression
!= COMPRESSION_NONE
)
511 "In place update to compressed TIFF images not "
518 * On the first write verify all the required information
519 * has been setup and initialize any data structures that
520 * had to wait until directory information was set.
521 * Note that a lot of our work is assumed to remain valid
522 * because we disallow any of the important parameters
523 * from changing after we start writing (i.e. once
524 * TIFF_BEENWRITING is set, TIFFSetField will only allow
525 * the image's length to be changed).
527 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
529 "%s: Must set \"ImageWidth\" before writing data",
533 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
535 "%s: Must set \"PlanarConfiguration\" before writing data",
539 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
540 tif
->tif_dir
.td_nstrips
= 0;
541 TIFFError(module, "%s: No space for %s arrays",
542 tif
->tif_name
, isTiled(tif
) ? "tile" : "strip");
546 tif
->tif_tilesize
= TIFFTileSize(tif
);
548 tif
->tif_tilesize
= (tsize_t
) -1;
550 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
551 tif
->tif_flags
|= TIFF_BEENWRITING
;
556 * Setup the raw data buffer used for encoding.
559 TIFFWriteBufferSetup(TIFF
* tif
, tdata_t bp
, tsize_t size
)
561 static const char module[] = "TIFFWriteBufferSetup";
563 if (tif
->tif_rawdata
) {
564 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
565 _TIFFfree(tif
->tif_rawdata
);
566 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
568 tif
->tif_rawdata
= NULL
;
570 if (size
== (tsize_t
) -1) {
571 size
= (isTiled(tif
) ?
572 tif
->tif_tilesize
: tif
->tif_scanlinesize
);
574 * Make raw data buffer at least 8K
578 bp
= NULL
; /* NB: force malloc */
581 bp
= _TIFFmalloc(size
);
583 TIFFError(module, "%s: No space for output buffer",
587 tif
->tif_flags
|= TIFF_MYBUFFER
;
589 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
590 tif
->tif_rawdata
= (tidata_t
) bp
;
591 tif
->tif_rawdatasize
= size
;
593 tif
->tif_rawcp
= tif
->tif_rawdata
;
594 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
599 * Grow the strip data structures by delta strips.
602 TIFFGrowStrips(TIFF
* tif
, int delta
, const char* module)
604 TIFFDirectory
*td
= &tif
->tif_dir
;
605 uint32
*new_stripoffset
, *new_stripbytecount
;
607 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
608 new_stripoffset
= (uint32
*)_TIFFrealloc(td
->td_stripoffset
,
609 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
610 new_stripbytecount
= (uint32
*)_TIFFrealloc(td
->td_stripbytecount
,
611 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
612 if (new_stripoffset
== NULL
|| new_stripbytecount
== NULL
) {
614 _TIFFfree(new_stripoffset
);
615 if (new_stripbytecount
)
616 _TIFFfree(new_stripbytecount
);
618 TIFFError(module, "%s: No space to expand strip arrays",
622 td
->td_stripoffset
= new_stripoffset
;
623 td
->td_stripbytecount
= new_stripbytecount
;
624 _TIFFmemset(td
->td_stripoffset
+ td
->td_nstrips
,
625 0, delta
*sizeof (uint32
));
626 _TIFFmemset(td
->td_stripbytecount
+ td
->td_nstrips
,
627 0, delta
*sizeof (uint32
));
628 td
->td_nstrips
+= delta
;
633 * Append the data to the specified strip.
635 * NB: We don't check that there's space in the
636 * file (i.e. that strips do not overlap).
639 TIFFAppendToStrip(TIFF
* tif
, tstrip_t strip
, tidata_t data
, tsize_t cc
)
641 TIFFDirectory
*td
= &tif
->tif_dir
;
642 static const char module[] = "TIFFAppendToStrip";
644 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
646 * No current offset, set the current strip.
648 if (td
->td_stripoffset
[strip
] != 0) {
649 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
651 "%s: Seek error at scanline %lu",
652 tif
->tif_name
, (u_long
) tif
->tif_row
);
656 td
->td_stripoffset
[strip
] =
657 TIFFSeekFile(tif
, (toff_t
) 0, SEEK_END
);
658 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
660 if (!WriteOK(tif
, data
, cc
)) {
661 TIFFError(module, "%s: Write error at scanline %lu",
662 tif
->tif_name
, (u_long
) tif
->tif_row
);
665 tif
->tif_curoff
+= cc
;
666 td
->td_stripbytecount
[strip
] += cc
;
671 * Internal version of TIFFFlushData that can be
672 * called by ``encodestrip routines'' w/o concern
673 * for infinite recursion.
676 TIFFFlushData1(TIFF
* tif
)
678 if (tif
->tif_rawcc
> 0) {
679 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
680 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
681 TIFFReverseBits((u_char
*)tif
->tif_rawdata
,
683 if (!TIFFAppendToStrip(tif
,
684 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
685 tif
->tif_rawdata
, tif
->tif_rawcc
))
688 tif
->tif_rawcp
= tif
->tif_rawdata
;
694 * Set the current write offset. This should only be
695 * used to set the offset to a known previous location
696 * (very carefully), or to 0 so that the next write gets
697 * appended to the end of the file.
700 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
702 tif
->tif_curoff
= off
;