1 /* $Id: tif_write.c,v 1.37 2012-08-13 22:10:17 fwarmerdam 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
32 #if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
36 #define STRIPINCR 20 /* expansion factor on strip array */
38 #define WRITECHECKSTRIPS(tif, module) \
39 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
40 #define WRITECHECKTILES(tif, module) \
41 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
42 #define BUFFERCHECK(tif) \
43 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
44 TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
46 static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
47 static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
50 TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
52 static const char module[] = "TIFFWriteScanline";
53 register TIFFDirectory *td;
54 int status, imagegrew = 0;
57 if (!WRITECHECKSTRIPS(tif, module))
60 * Handle delayed allocation of data buffer. This
61 * permits it to be sized more intelligently (using
62 * directory information).
64 if (!BUFFERCHECK(tif))
66 tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
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 TIFFErrorExt(tif->tif_clientdata, module,
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 TIFFErrorExt(tif->tif_clientdata, module,
88 "%lu: Sample out of range, max %lu",
89 (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
92 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
94 strip = row / td->td_rowsperstrip;
96 * Check strip array to make sure there's space. We don't support
97 * dynamically growing files that have data organized in separate
98 * bitplanes because it's too painful. In that case we require that
99 * the imagelength be set properly before the first write (so that the
100 * strips array will be fully allocated above).
102 if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
104 if (strip != tif->tif_curstrip) {
106 * Changing strips -- flush any data present.
108 if (!TIFFFlushData(tif))
110 tif->tif_curstrip = strip;
112 * Watch out for a growing image. The value of strips/image
113 * will initially be 1 (since it can't be deduced until the
114 * imagelength is known).
116 if (strip >= td->td_stripsperimage && imagegrew)
117 td->td_stripsperimage =
118 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
120 (strip % td->td_stripsperimage) * td->td_rowsperstrip;
121 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
122 if (!(*tif->tif_setupencode)(tif))
124 tif->tif_flags |= TIFF_CODERSETUP;
128 tif->tif_rawcp = tif->tif_rawdata;
130 if( td->td_stripbytecount[strip] > 0 )
132 /* if we are writing over existing tiles, zero length */
133 td->td_stripbytecount[strip] = 0;
135 /* this forces TIFFAppendToStrip() to do a seek */
139 if (!(*tif->tif_preencode)(tif, sample))
141 tif->tif_flags |= TIFF_POSTENCODE;
144 * Ensure the write is either sequential or at the
145 * beginning of a strip (or that we can randomly
146 * access the data -- i.e. no encoding).
148 if (row != tif->tif_row) {
149 if (row < tif->tif_row) {
151 * Moving backwards within the same strip:
152 * backup to the start and then decode
155 tif->tif_row = (strip % td->td_stripsperimage) *
157 tif->tif_rawcp = tif->tif_rawdata;
160 * Seek forward to the desired row.
162 if (!(*tif->tif_seek)(tif, row - tif->tif_row))
167 /* swab if needed - note that source buffer will be altered */
168 tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
170 status = (*tif->tif_encoderow)(tif, (uint8*) buf,
171 tif->tif_scanlinesize, sample);
173 /* we are now poised at the beginning of the next row */
174 tif->tif_row = row + 1;
179 * Encode the supplied data and write it to the
182 * NB: Image length must be setup before writing.
185 TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
187 static const char module[] = "TIFFWriteEncodedStrip";
188 TIFFDirectory *td = &tif->tif_dir;
191 if (!WRITECHECKSTRIPS(tif, module))
192 return ((tmsize_t) -1);
194 * Check strip array to make sure there's space.
195 * We don't support dynamically growing files that
196 * have data organized in separate bitplanes because
197 * it's too painful. In that case we require that
198 * the imagelength be set properly before the first
199 * write (so that the strips array will be fully
202 if (strip >= td->td_nstrips) {
203 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
204 TIFFErrorExt(tif->tif_clientdata, module,
205 "Can not grow image by strips when using separate planes");
206 return ((tmsize_t) -1);
208 if (!TIFFGrowStrips(tif, 1, module))
209 return ((tmsize_t) -1);
210 td->td_stripsperimage =
211 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
214 * Handle delayed allocation of data buffer. This
215 * permits it to be sized according to the directory
218 if (!BUFFERCHECK(tif))
219 return ((tmsize_t) -1);
221 tif->tif_flags |= TIFF_BUF4WRITE;
222 tif->tif_curstrip = strip;
224 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
225 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
226 if (!(*tif->tif_setupencode)(tif))
227 return ((tmsize_t) -1);
228 tif->tif_flags |= TIFF_CODERSETUP;
231 if( td->td_stripbytecount[strip] > 0 )
233 /* Make sure that at the first attempt of rewriting the tile, we will have */
234 /* more bytes available in the output buffer than the previous byte count, */
235 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
236 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
237 if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
239 if( !(TIFFWriteBufferSetup(tif, NULL,
240 (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
241 return ((tmsize_t)(-1));
244 /* Force TIFFAppendToStrip() to consider placing data at end
250 tif->tif_rawcp = tif->tif_rawdata;
252 tif->tif_flags &= ~TIFF_POSTENCODE;
253 sample = (uint16)(strip / td->td_stripsperimage);
254 if (!(*tif->tif_preencode)(tif, sample))
255 return ((tmsize_t) -1);
257 /* swab if needed - note that source buffer will be altered */
258 tif->tif_postdecode( tif, (uint8*) data, cc );
260 if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
262 if (!(*tif->tif_postencode)(tif))
263 return ((tmsize_t) -1);
264 if (!isFillOrder(tif, td->td_fillorder) &&
265 (tif->tif_flags & TIFF_NOBITREV) == 0)
266 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
267 if (tif->tif_rawcc > 0 &&
268 !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
269 return ((tmsize_t) -1);
271 tif->tif_rawcp = tif->tif_rawdata;
276 * Write the supplied data to the specified strip.
278 * NB: Image length must be setup before writing.
281 TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
283 static const char module[] = "TIFFWriteRawStrip";
284 TIFFDirectory *td = &tif->tif_dir;
286 if (!WRITECHECKSTRIPS(tif, module))
287 return ((tmsize_t) -1);
289 * Check strip array to make sure there's space.
290 * We don't support dynamically growing files that
291 * have data organized in separate bitplanes because
292 * it's too painful. In that case we require that
293 * the imagelength be set properly before the first
294 * write (so that the strips array will be fully
297 if (strip >= td->td_nstrips) {
298 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
299 TIFFErrorExt(tif->tif_clientdata, module,
300 "Can not grow image by strips when using separate planes");
301 return ((tmsize_t) -1);
304 * Watch out for a growing image. The value of
305 * strips/image will initially be 1 (since it
306 * can't be deduced until the imagelength is known).
308 if (strip >= td->td_stripsperimage)
309 td->td_stripsperimage =
310 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
311 if (!TIFFGrowStrips(tif, 1, module))
312 return ((tmsize_t) -1);
314 tif->tif_curstrip = strip;
315 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
316 return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
321 * Write and compress a tile of data. The
322 * tile is selected by the (x,y,z,s) coordinates.
325 TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
327 if (!TIFFCheckTile(tif, x, y, z, s))
328 return ((tmsize_t)(-1));
330 * NB: A tile size of -1 is used instead of tif_tilesize knowing
331 * that TIFFWriteEncodedTile will clamp this to the tile size.
332 * This is done because the tile size may not be defined until
333 * after the output buffer is setup in TIFFWriteBufferSetup.
335 return (TIFFWriteEncodedTile(tif,
336 TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
340 * Encode the supplied data and write it to the
341 * specified tile. There must be space for the
342 * data. The function clamps individual writes
343 * to a tile to the tile size, but does not (and
344 * can not) check that multiple writes to the same
345 * tile do not write more than tile size data.
347 * NB: Image length must be setup before writing; this
348 * interface does not support automatically growing
349 * the image on each write (as TIFFWriteScanline does).
352 TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
354 static const char module[] = "TIFFWriteEncodedTile";
358 if (!WRITECHECKTILES(tif, module))
359 return ((tmsize_t)(-1));
361 if (tile >= td->td_nstrips) {
362 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
363 (unsigned long) tile, (unsigned long) td->td_nstrips);
364 return ((tmsize_t)(-1));
367 * Handle delayed allocation of data buffer. This
368 * permits it to be sized more intelligently (using
369 * directory information).
371 if (!BUFFERCHECK(tif))
372 return ((tmsize_t)(-1));
374 tif->tif_flags |= TIFF_BUF4WRITE;
375 tif->tif_curtile = tile;
377 if( td->td_stripbytecount[tile] > 0 )
379 /* Make sure that at the first attempt of rewriting the tile, we will have */
380 /* more bytes available in the output buffer than the previous byte count, */
381 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
382 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
383 if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[tile] )
385 if( !(TIFFWriteBufferSetup(tif, NULL,
386 (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
387 return ((tmsize_t)(-1));
390 /* Force TIFFAppendToStrip() to consider placing data at end
396 tif->tif_rawcp = tif->tif_rawdata;
399 * Compute tiles per row & per column to compute
400 * current row and column
402 tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
404 tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
407 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
408 if (!(*tif->tif_setupencode)(tif))
409 return ((tmsize_t)(-1));
410 tif->tif_flags |= TIFF_CODERSETUP;
412 tif->tif_flags &= ~TIFF_POSTENCODE;
413 sample = (uint16)(tile/td->td_stripsperimage);
414 if (!(*tif->tif_preencode)(tif, sample))
415 return ((tmsize_t)(-1));
417 * Clamp write amount to the tile size. This is mostly
418 * done so that callers can pass in some large number
419 * (e.g. -1) and have the tile size used instead.
421 if ( cc < 1 || cc > tif->tif_tilesize)
422 cc = tif->tif_tilesize;
424 /* swab if needed - note that source buffer will be altered */
425 tif->tif_postdecode( tif, (uint8*) data, cc );
427 if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
429 if (!(*tif->tif_postencode)(tif))
430 return ((tmsize_t)(-1));
431 if (!isFillOrder(tif, td->td_fillorder) &&
432 (tif->tif_flags & TIFF_NOBITREV) == 0)
433 TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
434 if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
435 tif->tif_rawdata, tif->tif_rawcc))
436 return ((tmsize_t)(-1));
438 tif->tif_rawcp = tif->tif_rawdata;
443 * Write the supplied data to the specified strip.
444 * There must be space for the data; we don't check
447 * NB: Image length must be setup before writing; this
448 * interface does not support automatically growing
449 * the image on each write (as TIFFWriteScanline does).
452 TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
454 static const char module[] = "TIFFWriteRawTile";
456 if (!WRITECHECKTILES(tif, module))
457 return ((tmsize_t)(-1));
458 if (tile >= tif->tif_dir.td_nstrips) {
459 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
460 (unsigned long) tile,
461 (unsigned long) tif->tif_dir.td_nstrips);
462 return ((tmsize_t)(-1));
464 return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
465 cc : (tmsize_t)(-1));
468 #define isUnspecified(tif, f) \
469 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
472 TIFFSetupStrips(TIFF* tif)
474 TIFFDirectory* td = &tif->tif_dir;
477 td->td_stripsperimage =
478 isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
479 td->td_samplesperpixel : TIFFNumberOfTiles(tif);
481 td->td_stripsperimage =
482 isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
483 td->td_samplesperpixel : TIFFNumberOfStrips(tif);
484 td->td_nstrips = td->td_stripsperimage;
485 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
486 td->td_stripsperimage /= td->td_samplesperpixel;
487 td->td_stripoffset = (uint64 *)
488 _TIFFmalloc(td->td_nstrips * sizeof (uint64));
489 td->td_stripbytecount = (uint64 *)
490 _TIFFmalloc(td->td_nstrips * sizeof (uint64));
491 if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
494 * Place data at the end-of-file
495 * (by setting offsets to zero).
497 _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
498 _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
499 TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
500 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
506 * Verify file is writable and that the directory
507 * information is setup properly. In doing the latter
508 * we also "freeze" the state of the directory so
509 * that important information is not changed.
512 TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
514 if (tif->tif_mode == O_RDONLY) {
515 TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
518 if (tiles ^ isTiled(tif)) {
519 TIFFErrorExt(tif->tif_clientdata, module, tiles ?
520 "Can not write tiles to a stripped image" :
521 "Can not write scanlines to a tiled image");
525 _TIFFFillStriles( tif );
528 * On the first write verify all the required information
529 * has been setup and initialize any data structures that
530 * had to wait until directory information was set.
531 * Note that a lot of our work is assumed to remain valid
532 * because we disallow any of the important parameters
533 * from changing after we start writing (i.e. once
534 * TIFF_BEENWRITING is set, TIFFSetField will only allow
535 * the image's length to be changed).
537 if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
538 TIFFErrorExt(tif->tif_clientdata, module,
539 "Must set \"ImageWidth\" before writing data");
542 if (tif->tif_dir.td_samplesperpixel == 1) {
544 * Planarconfiguration is irrelevant in case of single band
545 * images and need not be included. We will set it anyway,
546 * because this field is used in other parts of library even
547 * in the single band case.
549 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
550 tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
552 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
553 TIFFErrorExt(tif->tif_clientdata, module,
554 "Must set \"PlanarConfiguration\" before writing data");
558 if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
559 tif->tif_dir.td_nstrips = 0;
560 TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
561 isTiled(tif) ? "tile" : "strip");
566 tif->tif_tilesize = TIFFTileSize(tif);
567 if (tif->tif_tilesize == 0)
571 tif->tif_tilesize = (tmsize_t)(-1);
572 tif->tif_scanlinesize = TIFFScanlineSize(tif);
573 if (tif->tif_scanlinesize == 0)
575 tif->tif_flags |= TIFF_BEENWRITING;
580 * Setup the raw data buffer used for encoding.
583 TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
585 static const char module[] = "TIFFWriteBufferSetup";
587 if (tif->tif_rawdata) {
588 if (tif->tif_flags & TIFF_MYBUFFER) {
589 _TIFFfree(tif->tif_rawdata);
590 tif->tif_flags &= ~TIFF_MYBUFFER;
592 tif->tif_rawdata = NULL;
594 if (size == (tmsize_t)(-1)) {
595 size = (isTiled(tif) ?
596 tif->tif_tilesize : TIFFStripSize(tif));
598 * Make raw data buffer at least 8K
602 bp = NULL; /* NB: force malloc */
605 bp = _TIFFmalloc(size);
607 TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
610 tif->tif_flags |= TIFF_MYBUFFER;
612 tif->tif_flags &= ~TIFF_MYBUFFER;
613 tif->tif_rawdata = (uint8*) bp;
614 tif->tif_rawdatasize = size;
616 tif->tif_rawcp = tif->tif_rawdata;
617 tif->tif_flags |= TIFF_BUFFERSETUP;
622 * Grow the strip data structures by delta strips.
625 TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
627 TIFFDirectory *td = &tif->tif_dir;
628 uint64* new_stripoffset;
629 uint64* new_stripbytecount;
631 assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
632 new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
633 (td->td_nstrips + delta) * sizeof (uint64));
634 new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
635 (td->td_nstrips + delta) * sizeof (uint64));
636 if (new_stripoffset == NULL || new_stripbytecount == NULL) {
638 _TIFFfree(new_stripoffset);
639 if (new_stripbytecount)
640 _TIFFfree(new_stripbytecount);
642 TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
645 td->td_stripoffset = new_stripoffset;
646 td->td_stripbytecount = new_stripbytecount;
647 _TIFFmemset(td->td_stripoffset + td->td_nstrips,
648 0, delta*sizeof (uint64));
649 _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
650 0, delta*sizeof (uint64));
651 td->td_nstrips += delta;
652 tif->tif_flags |= TIFF_DIRTYDIRECT;
658 * Append the data to the specified strip.
661 TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
663 static const char module[] = "TIFFAppendToStrip";
664 TIFFDirectory *td = &tif->tif_dir;
666 int64 old_byte_count = -1;
668 if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
669 assert(td->td_nstrips > 0);
671 if( td->td_stripbytecount[strip] != 0
672 && td->td_stripoffset[strip] != 0
673 && td->td_stripbytecount[strip] >= (uint64) cc )
676 * There is already tile data on disk, and the new tile
677 * data we have will fit in the same space. The only
678 * aspect of this that is risky is that there could be
679 * more data to append to this strip before we are done
680 * depending on how we are getting called.
682 if (!SeekOK(tif, td->td_stripoffset[strip])) {
683 TIFFErrorExt(tif->tif_clientdata, module,
684 "Seek error at scanline %lu",
685 (unsigned long)tif->tif_row);
692 * Seek to end of file, and set that as our location to
695 td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
696 tif->tif_flags |= TIFF_DIRTYSTRIP;
699 tif->tif_curoff = td->td_stripoffset[strip];
702 * We are starting a fresh strip/tile, so set the size to zero.
704 old_byte_count = td->td_stripbytecount[strip];
705 td->td_stripbytecount[strip] = 0;
708 m = tif->tif_curoff+cc;
709 if (!(tif->tif_flags&TIFF_BIGTIFF))
711 if ((m<tif->tif_curoff)||(m<(uint64)cc))
713 TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
716 if (!WriteOK(tif, data, cc)) {
717 TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
718 (unsigned long) tif->tif_row);
722 td->td_stripbytecount[strip] += cc;
724 if( (int64) td->td_stripbytecount[strip] != old_byte_count )
725 tif->tif_flags |= TIFF_DIRTYSTRIP;
731 * Internal version of TIFFFlushData that can be
732 * called by ``encodestrip routines'' w/o concern
733 * for infinite recursion.
736 TIFFFlushData1(TIFF* tif)
738 if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
739 if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
740 (tif->tif_flags & TIFF_NOBITREV) == 0)
741 TIFFReverseBits((uint8*)tif->tif_rawdata,
743 if (!TIFFAppendToStrip(tif,
744 isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
745 tif->tif_rawdata, tif->tif_rawcc))
748 tif->tif_rawcp = tif->tif_rawdata;
754 * Set the current write offset. This should only be
755 * used to set the offset to a known previous location
756 * (very carefully), or to 0 so that the next write gets
757 * appended to the end of the file.
760 TIFFSetWriteOffset(TIFF* tif, toff_t off)
762 tif->tif_curoff = off;
765 /* vim: set ts=8 sts=8 sw=8 noet: */