include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / libs / tiff / libtiff / tif_write.c
blob6631a782fd3c2fbed0decdac640ee8e164b92b88
1 /*
2 * Copyright (c) 1988-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that (i) the above copyright notices and this permission notice appear in
8 * all copies of the software and related documentation, and (ii) the names of
9 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 * publicity relating to the software without the specific, prior written
11 * permission of Sam Leffler and Silicon Graphics.
13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 * OF THIS SOFTWARE.
26 * TIFF Library.
28 * Scanline-oriented Write Support
30 #include "tiffiop.h"
31 #include <stdio.h>
33 #define STRIPINCR 20 /* expansion factor on strip array */
35 #define WRITECHECKSTRIPS(tif, module) \
36 (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
37 #define WRITECHECKTILES(tif, module) \
38 (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
39 #define BUFFERCHECK(tif) \
40 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
41 TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
43 static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
44 static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
45 tmsize_t cc);
47 int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
49 static const char module[] = "TIFFWriteScanline";
50 register TIFFDirectory *td;
51 int status, imagegrew = 0;
52 uint32_t strip;
54 if (!WRITECHECKSTRIPS(tif, module))
55 return (-1);
57 * Handle delayed allocation of data buffer. This
58 * permits it to be sized more intelligently (using
59 * directory information).
61 if (!BUFFERCHECK(tif))
62 return (-1);
63 tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
65 td = &tif->tif_dir;
67 * Extend image length if needed
68 * (but only for PlanarConfig=1).
70 if (row >= td->td_imagelength)
71 { /* extend image */
72 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
74 TIFFErrorExtR(
75 tif, module,
76 "Can not change \"ImageLength\" when using separate planes");
77 return (-1);
79 td->td_imagelength = row + 1;
80 imagegrew = 1;
83 * Calculate strip and check for crossings.
85 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
87 if (sample >= td->td_samplesperpixel)
89 TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
90 (unsigned long)sample,
91 (unsigned long)td->td_samplesperpixel);
92 return (-1);
94 strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
96 else
97 strip = row / td->td_rowsperstrip;
99 * Check strip array to make sure there's space. We don't support
100 * dynamically growing files that have data organized in separate
101 * bitplanes because it's too painful. In that case we require that
102 * the imagelength be set properly before the first write (so that the
103 * strips array will be fully allocated above).
105 if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
106 return (-1);
107 if (strip != tif->tif_curstrip)
110 * Changing strips -- flush any data present.
112 if (!TIFFFlushData(tif))
113 return (-1);
114 tif->tif_curstrip = strip;
116 * Watch out for a growing image. The value of strips/image
117 * will initially be 1 (since it can't be deduced until the
118 * imagelength is known).
120 if (strip >= td->td_stripsperimage && imagegrew)
121 td->td_stripsperimage =
122 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
123 if (td->td_stripsperimage == 0)
125 TIFFErrorExtR(tif, module, "Zero strips per image");
126 return (-1);
128 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
129 if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
131 if (!(*tif->tif_setupencode)(tif))
132 return (-1);
133 tif->tif_flags |= TIFF_CODERSETUP;
136 tif->tif_rawcc = 0;
137 tif->tif_rawcp = tif->tif_rawdata;
139 /* this informs TIFFAppendToStrip() we have changed strip */
140 tif->tif_curoff = 0;
142 if (!(*tif->tif_preencode)(tif, sample))
143 return (-1);
144 tif->tif_flags |= TIFF_POSTENCODE;
147 * Ensure the write is either sequential or at the
148 * beginning of a strip (or that we can randomly
149 * access the data -- i.e. no encoding).
151 if (row != tif->tif_row)
153 if (row < tif->tif_row)
156 * Moving backwards within the same strip:
157 * backup to the start and then decode
158 * forward (below).
160 tif->tif_row =
161 (strip % td->td_stripsperimage) * td->td_rowsperstrip;
162 tif->tif_rawcp = tif->tif_rawdata;
165 * Seek forward to the desired row.
167 if (!(*tif->tif_seek)(tif, row - tif->tif_row))
168 return (-1);
169 tif->tif_row = row;
172 /* swab if needed - note that source buffer will be altered */
173 tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
175 status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
176 sample);
178 /* we are now poised at the beginning of the next row */
179 tif->tif_row = row + 1;
180 return (status);
183 /* Make sure that at the first attempt of rewriting a tile/strip, we will have
185 /* more bytes available in the output buffer than the previous byte count, */
186 /* so that TIFFAppendToStrip() will detect the overflow when it is called the
187 * first */
188 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
189 static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
191 TIFFDirectory *td = &tif->tif_dir;
192 if (td->td_stripbytecount_p[strip_or_tile] > 0)
194 /* The +1 is to ensure at least one extra bytes */
195 /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
196 uint64_t safe_buffer_size =
197 (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
198 if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size)
200 if (!(TIFFWriteBufferSetup(
201 tif, NULL,
202 (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))))
203 return 0;
206 return 1;
210 * Encode the supplied data and write it to the
211 * specified strip.
213 * NB: Image length must be setup before writing.
215 tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
216 tmsize_t cc)
218 static const char module[] = "TIFFWriteEncodedStrip";
219 TIFFDirectory *td = &tif->tif_dir;
220 uint16_t sample;
222 if (!WRITECHECKSTRIPS(tif, module))
223 return ((tmsize_t)-1);
225 * Check strip array to make sure there's space.
226 * We don't support dynamically growing files that
227 * have data organized in separate bitplanes because
228 * it's too painful. In that case we require that
229 * the imagelength be set properly before the first
230 * write (so that the strips array will be fully
231 * allocated above).
233 if (strip >= td->td_nstrips)
235 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
237 TIFFErrorExtR(
238 tif, module,
239 "Can not grow image by strips when using separate planes");
240 return ((tmsize_t)-1);
242 if (!TIFFGrowStrips(tif, 1, module))
243 return ((tmsize_t)-1);
244 td->td_stripsperimage =
245 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
248 * Handle delayed allocation of data buffer. This
249 * permits it to be sized according to the directory
250 * info.
252 if (!BUFFERCHECK(tif))
253 return ((tmsize_t)-1);
255 tif->tif_flags |= TIFF_BUF4WRITE;
257 tif->tif_curstrip = strip;
259 /* this informs TIFFAppendToStrip() we have changed or reset strip */
260 tif->tif_curoff = 0;
262 if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip))
264 return ((tmsize_t)(-1));
267 tif->tif_rawcc = 0;
268 tif->tif_rawcp = tif->tif_rawdata;
270 if (td->td_stripsperimage == 0)
272 TIFFErrorExtR(tif, module, "Zero strips per image");
273 return ((tmsize_t)-1);
276 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
277 if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
279 if (!(*tif->tif_setupencode)(tif))
280 return ((tmsize_t)-1);
281 tif->tif_flags |= TIFF_CODERSETUP;
284 tif->tif_flags &= ~TIFF_POSTENCODE;
286 /* shortcut to avoid an extra memcpy() */
287 if (td->td_compression == COMPRESSION_NONE)
289 /* swab if needed - note that source buffer will be altered */
290 tif->tif_postdecode(tif, (uint8_t *)data, cc);
292 if (!isFillOrder(tif, td->td_fillorder) &&
293 (tif->tif_flags & TIFF_NOBITREV) == 0)
294 TIFFReverseBits((uint8_t *)data, cc);
296 if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc))
297 return ((tmsize_t)-1);
298 return (cc);
301 sample = (uint16_t)(strip / td->td_stripsperimage);
302 if (!(*tif->tif_preencode)(tif, sample))
303 return ((tmsize_t)-1);
305 /* swab if needed - note that source buffer will be altered */
306 tif->tif_postdecode(tif, (uint8_t *)data, cc);
308 if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample))
309 return ((tmsize_t)-1);
310 if (!(*tif->tif_postencode)(tif))
311 return ((tmsize_t)-1);
312 if (!isFillOrder(tif, td->td_fillorder) &&
313 (tif->tif_flags & TIFF_NOBITREV) == 0)
314 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
315 if (tif->tif_rawcc > 0 &&
316 !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
317 return ((tmsize_t)-1);
318 tif->tif_rawcc = 0;
319 tif->tif_rawcp = tif->tif_rawdata;
320 return (cc);
324 * Write the supplied data to the specified strip.
326 * NB: Image length must be setup before writing.
328 tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
330 static const char module[] = "TIFFWriteRawStrip";
331 TIFFDirectory *td = &tif->tif_dir;
333 if (!WRITECHECKSTRIPS(tif, module))
334 return ((tmsize_t)-1);
336 * Check strip array to make sure there's space.
337 * We don't support dynamically growing files that
338 * have data organized in separate bitplanes because
339 * it's too painful. In that case we require that
340 * the imagelength be set properly before the first
341 * write (so that the strips array will be fully
342 * allocated above).
344 if (strip >= td->td_nstrips)
346 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
348 TIFFErrorExtR(
349 tif, module,
350 "Can not grow image by strips when using separate planes");
351 return ((tmsize_t)-1);
354 * Watch out for a growing image. The value of
355 * strips/image will initially be 1 (since it
356 * can't be deduced until the imagelength is known).
358 if (strip >= td->td_stripsperimage)
359 td->td_stripsperimage =
360 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
361 if (!TIFFGrowStrips(tif, 1, module))
362 return ((tmsize_t)-1);
365 if (tif->tif_curstrip != strip)
367 tif->tif_curstrip = strip;
369 /* this informs TIFFAppendToStrip() we have changed or reset strip */
370 tif->tif_curoff = 0;
373 if (td->td_stripsperimage == 0)
375 TIFFErrorExtR(tif, module, "Zero strips per image");
376 return ((tmsize_t)-1);
378 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
379 return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
380 : (tmsize_t)-1);
384 * Write and compress a tile of data. The
385 * tile is selected by the (x,y,z,s) coordinates.
387 tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
388 uint16_t s)
390 if (!TIFFCheckTile(tif, x, y, z, s))
391 return ((tmsize_t)(-1));
393 * NB: A tile size of -1 is used instead of tif_tilesize knowing
394 * that TIFFWriteEncodedTile will clamp this to the tile size.
395 * This is done because the tile size may not be defined until
396 * after the output buffer is setup in TIFFWriteBufferSetup.
398 return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
399 (tmsize_t)(-1)));
403 * Encode the supplied data and write it to the
404 * specified tile. There must be space for the
405 * data. The function clamps individual writes
406 * to a tile to the tile size, but does not (and
407 * can not) check that multiple writes to the same
408 * tile do not write more than tile size data.
410 * NB: Image length must be setup before writing; this
411 * interface does not support automatically growing
412 * the image on each write (as TIFFWriteScanline does).
414 tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
416 static const char module[] = "TIFFWriteEncodedTile";
417 TIFFDirectory *td;
418 uint16_t sample;
419 uint32_t howmany32;
421 if (!WRITECHECKTILES(tif, module))
422 return ((tmsize_t)(-1));
423 td = &tif->tif_dir;
424 if (tile >= td->td_nstrips)
426 TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
427 (unsigned long)tile, (unsigned long)td->td_nstrips);
428 return ((tmsize_t)(-1));
431 * Handle delayed allocation of data buffer. This
432 * permits it to be sized more intelligently (using
433 * directory information).
435 if (!BUFFERCHECK(tif))
436 return ((tmsize_t)(-1));
438 tif->tif_flags |= TIFF_BUF4WRITE;
440 tif->tif_curtile = tile;
442 /* this informs TIFFAppendToStrip() we have changed or reset tile */
443 tif->tif_curoff = 0;
445 if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile))
447 return ((tmsize_t)(-1));
450 tif->tif_rawcc = 0;
451 tif->tif_rawcp = tif->tif_rawdata;
454 * Compute tiles per row & per column to compute
455 * current row and column
457 howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
458 if (howmany32 == 0)
460 TIFFErrorExtR(tif, module, "Zero tiles");
461 return ((tmsize_t)(-1));
463 tif->tif_row = (tile % howmany32) * td->td_tilelength;
464 howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
465 if (howmany32 == 0)
467 TIFFErrorExtR(tif, module, "Zero tiles");
468 return ((tmsize_t)(-1));
470 tif->tif_col = (tile % howmany32) * td->td_tilewidth;
472 if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
474 if (!(*tif->tif_setupencode)(tif))
475 return ((tmsize_t)(-1));
476 tif->tif_flags |= TIFF_CODERSETUP;
478 tif->tif_flags &= ~TIFF_POSTENCODE;
481 * Clamp write amount to the tile size. This is mostly
482 * done so that callers can pass in some large number
483 * (e.g. -1) and have the tile size used instead.
485 if (cc < 1 || cc > tif->tif_tilesize)
486 cc = tif->tif_tilesize;
488 /* shortcut to avoid an extra memcpy() */
489 if (td->td_compression == COMPRESSION_NONE)
491 /* swab if needed - note that source buffer will be altered */
492 tif->tif_postdecode(tif, (uint8_t *)data, cc);
494 if (!isFillOrder(tif, td->td_fillorder) &&
495 (tif->tif_flags & TIFF_NOBITREV) == 0)
496 TIFFReverseBits((uint8_t *)data, cc);
498 if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc))
499 return ((tmsize_t)-1);
500 return (cc);
503 sample = (uint16_t)(tile / td->td_stripsperimage);
504 if (!(*tif->tif_preencode)(tif, sample))
505 return ((tmsize_t)(-1));
506 /* swab if needed - note that source buffer will be altered */
507 tif->tif_postdecode(tif, (uint8_t *)data, cc);
509 if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample))
510 return ((tmsize_t)-1);
511 if (!(*tif->tif_postencode)(tif))
512 return ((tmsize_t)(-1));
513 if (!isFillOrder(tif, td->td_fillorder) &&
514 (tif->tif_flags & TIFF_NOBITREV) == 0)
515 TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
516 if (tif->tif_rawcc > 0 &&
517 !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc))
518 return ((tmsize_t)(-1));
519 tif->tif_rawcc = 0;
520 tif->tif_rawcp = tif->tif_rawdata;
521 return (cc);
525 * Write the supplied data to the specified strip.
526 * There must be space for the data; we don't check
527 * if strips overlap!
529 * NB: Image length must be setup before writing; this
530 * interface does not support automatically growing
531 * the image on each write (as TIFFWriteScanline does).
533 tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
535 static const char module[] = "TIFFWriteRawTile";
537 if (!WRITECHECKTILES(tif, module))
538 return ((tmsize_t)(-1));
539 if (tile >= tif->tif_dir.td_nstrips)
541 TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
542 (unsigned long)tile,
543 (unsigned long)tif->tif_dir.td_nstrips);
544 return ((tmsize_t)(-1));
546 return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc
547 : (tmsize_t)(-1));
550 #define isUnspecified(tif, f) \
551 (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
553 int TIFFSetupStrips(TIFF *tif)
555 TIFFDirectory *td = &tif->tif_dir;
557 if (isTiled(tif))
558 td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS)
559 ? td->td_samplesperpixel
560 : TIFFNumberOfTiles(tif);
561 else
562 td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP)
563 ? td->td_samplesperpixel
564 : TIFFNumberOfStrips(tif);
565 td->td_nstrips = td->td_stripsperimage;
566 /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
567 if (td->td_nstrips >=
568 0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
570 TIFFErrorExtR(tif, "TIFFSetupStrips",
571 "Too large Strip/Tile Offsets/ByteCounts arrays");
572 return 0;
574 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
575 td->td_stripsperimage /= td->td_samplesperpixel;
576 td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
577 tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
578 td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
579 tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
580 if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
581 return (0);
583 * Place data at the end-of-file
584 * (by setting offsets to zero).
586 _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
587 _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
588 TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
589 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
590 return (1);
592 #undef isUnspecified
595 * Verify file is writable and that the directory
596 * information is setup properly. In doing the latter
597 * we also "freeze" the state of the directory so
598 * that important information is not changed.
600 int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
602 if (tif->tif_mode == O_RDONLY)
604 TIFFErrorExtR(tif, module, "File not open for writing");
605 return (0);
607 if (tiles ^ isTiled(tif))
609 TIFFErrorExtR(tif, module,
610 tiles ? "Can not write tiles to a striped image"
611 : "Can not write scanlines to a tiled image");
612 return (0);
615 _TIFFFillStriles(tif);
618 * On the first write verify all the required information
619 * has been setup and initialize any data structures that
620 * had to wait until directory information was set.
621 * Note that a lot of our work is assumed to remain valid
622 * because we disallow any of the important parameters
623 * from changing after we start writing (i.e. once
624 * TIFF_BEENWRITING is set, TIFFSetField will only allow
625 * the image's length to be changed).
627 if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
629 TIFFErrorExtR(tif, module,
630 "Must set \"ImageWidth\" before writing data");
631 return (0);
633 if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
635 tif->tif_dir.td_nstrips = 0;
636 TIFFErrorExtR(tif, module, "No space for %s arrays",
637 isTiled(tif) ? "tile" : "strip");
638 return (0);
640 if (isTiled(tif))
642 tif->tif_tilesize = TIFFTileSize(tif);
643 if (tif->tif_tilesize == 0)
644 return (0);
646 else
647 tif->tif_tilesize = (tmsize_t)(-1);
648 tif->tif_scanlinesize = TIFFScanlineSize(tif);
649 if (tif->tif_scanlinesize == 0)
650 return (0);
651 tif->tif_flags |= TIFF_BEENWRITING;
653 if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
654 tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
655 tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
656 tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
657 tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
658 tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
659 tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
660 tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
661 !(tif->tif_flags & TIFF_DIRTYDIRECT))
663 TIFFForceStrileArrayWriting(tif);
666 return (1);
670 * Setup the raw data buffer used for encoding.
672 int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
674 static const char module[] = "TIFFWriteBufferSetup";
676 if (tif->tif_rawdata)
678 if (tif->tif_flags & TIFF_MYBUFFER)
680 _TIFFfreeExt(tif, tif->tif_rawdata);
681 tif->tif_flags &= ~TIFF_MYBUFFER;
683 tif->tif_rawdata = NULL;
685 if (size == (tmsize_t)(-1))
687 size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
689 /* Adds 10% margin for cases where compression would expand a bit */
690 if (size < TIFF_TMSIZE_T_MAX - size / 10)
691 size += size / 10;
693 * Make raw data buffer at least 8K
695 if (size < 8 * 1024)
696 size = 8 * 1024;
697 bp = NULL; /* NB: force malloc */
699 if (bp == NULL)
701 bp = _TIFFmallocExt(tif, size);
702 if (bp == NULL)
704 TIFFErrorExtR(tif, module, "No space for output buffer");
705 return (0);
707 tif->tif_flags |= TIFF_MYBUFFER;
709 else
710 tif->tif_flags &= ~TIFF_MYBUFFER;
711 tif->tif_rawdata = (uint8_t *)bp;
712 tif->tif_rawdatasize = size;
713 tif->tif_rawcc = 0;
714 tif->tif_rawcp = tif->tif_rawdata;
715 tif->tif_flags |= TIFF_BUFFERSETUP;
716 return (1);
720 * Grow the strip data structures by delta strips.
722 static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
724 TIFFDirectory *td = &tif->tif_dir;
725 uint64_t *new_stripoffset;
726 uint64_t *new_stripbytecount;
728 assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
729 new_stripoffset = (uint64_t *)_TIFFreallocExt(
730 tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
731 new_stripbytecount = (uint64_t *)_TIFFreallocExt(
732 tif, td->td_stripbytecount_p,
733 (td->td_nstrips + delta) * sizeof(uint64_t));
734 if (new_stripoffset == NULL || new_stripbytecount == NULL)
736 if (new_stripoffset)
737 _TIFFfreeExt(tif, new_stripoffset);
738 if (new_stripbytecount)
739 _TIFFfreeExt(tif, new_stripbytecount);
740 td->td_nstrips = 0;
741 TIFFErrorExtR(tif, module, "No space to expand strip arrays");
742 return (0);
744 td->td_stripoffset_p = new_stripoffset;
745 td->td_stripbytecount_p = new_stripbytecount;
746 _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
747 delta * sizeof(uint64_t));
748 _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
749 delta * sizeof(uint64_t));
750 td->td_nstrips += delta;
751 tif->tif_flags |= TIFF_DIRTYDIRECT;
753 return (1);
757 * Append the data to the specified strip.
759 static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
760 tmsize_t cc)
762 static const char module[] = "TIFFAppendToStrip";
763 TIFFDirectory *td = &tif->tif_dir;
764 uint64_t m;
765 int64_t old_byte_count = -1;
767 if (tif->tif_curoff == 0)
768 tif->tif_lastvalidoff = 0;
770 if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0)
772 assert(td->td_nstrips > 0);
774 if (td->td_stripbytecount_p[strip] != 0 &&
775 td->td_stripoffset_p[strip] != 0 &&
776 td->td_stripbytecount_p[strip] >= (uint64_t)cc)
779 * There is already tile data on disk, and the new tile
780 * data we have will fit in the same space. The only
781 * aspect of this that is risky is that there could be
782 * more data to append to this strip before we are done
783 * depending on how we are getting called.
785 if (!SeekOK(tif, td->td_stripoffset_p[strip]))
787 TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
788 (unsigned long)tif->tif_row);
789 return (0);
792 tif->tif_lastvalidoff =
793 td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
795 else
798 * Seek to end of file, and set that as our location to
799 * write this strip.
801 td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
802 tif->tif_flags |= TIFF_DIRTYSTRIP;
805 tif->tif_curoff = td->td_stripoffset_p[strip];
808 * We are starting a fresh strip/tile, so set the size to zero.
810 old_byte_count = td->td_stripbytecount_p[strip];
811 td->td_stripbytecount_p[strip] = 0;
814 m = tif->tif_curoff + cc;
815 if (!(tif->tif_flags & TIFF_BIGTIFF))
816 m = (uint32_t)m;
817 if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
819 TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
820 return (0);
823 if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff &&
824 td->td_stripbytecount_p[strip] > 0)
826 /* Ouch: we have detected that we are rewriting in place a strip/tile */
827 /* with several calls to TIFFAppendToStrip(). The first call was with */
828 /* a size smaller than the previous size of the strip/tile, so we */
829 /* opted to rewrite in place, but a following call causes us to go */
830 /* outsize of the strip/tile area, so we have to finally go for a */
831 /* append-at-end-of-file strategy, and start by moving what we already
833 /* wrote. */
834 tmsize_t tempSize;
835 void *temp;
836 uint64_t offsetRead;
837 uint64_t offsetWrite;
838 uint64_t toCopy = td->td_stripbytecount_p[strip];
840 if (toCopy < 1024 * 1024)
841 tempSize = (tmsize_t)toCopy;
842 else
843 tempSize = 1024 * 1024;
845 offsetRead = td->td_stripoffset_p[strip];
846 offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
848 m = offsetWrite + toCopy + cc;
849 if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
851 TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
852 return (0);
855 temp = _TIFFmallocExt(tif, tempSize);
856 if (temp == NULL)
858 TIFFErrorExtR(tif, module, "No space for output buffer");
859 return (0);
862 tif->tif_flags |= TIFF_DIRTYSTRIP;
864 td->td_stripoffset_p[strip] = offsetWrite;
865 td->td_stripbytecount_p[strip] = 0;
867 /* Move data written by previous calls to us at end of file */
868 while (toCopy > 0)
870 if (!SeekOK(tif, offsetRead))
872 TIFFErrorExtR(tif, module, "Seek error");
873 _TIFFfreeExt(tif, temp);
874 return (0);
876 if (!ReadOK(tif, temp, tempSize))
878 TIFFErrorExtR(tif, module, "Cannot read");
879 _TIFFfreeExt(tif, temp);
880 return (0);
882 if (!SeekOK(tif, offsetWrite))
884 TIFFErrorExtR(tif, module, "Seek error");
885 _TIFFfreeExt(tif, temp);
886 return (0);
888 if (!WriteOK(tif, temp, tempSize))
890 TIFFErrorExtR(tif, module, "Cannot write");
891 _TIFFfreeExt(tif, temp);
892 return (0);
894 offsetRead += tempSize;
895 offsetWrite += tempSize;
896 td->td_stripbytecount_p[strip] += tempSize;
897 toCopy -= tempSize;
899 _TIFFfreeExt(tif, temp);
901 /* Append the data of this call */
902 offsetWrite += cc;
903 m = offsetWrite;
906 if (!WriteOK(tif, data, cc))
908 TIFFErrorExtR(tif, module, "Write error at scanline %lu",
909 (unsigned long)tif->tif_row);
910 return (0);
912 tif->tif_curoff = m;
913 td->td_stripbytecount_p[strip] += cc;
915 if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
916 tif->tif_flags |= TIFF_DIRTYSTRIP;
918 return (1);
922 * Internal version of TIFFFlushData that can be
923 * called by ``encodestrip routines'' w/o concern
924 * for infinite recursion.
926 int TIFFFlushData1(TIFF *tif)
928 if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE)
930 if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
931 (tif->tif_flags & TIFF_NOBITREV) == 0)
932 TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
933 if (!TIFFAppendToStrip(
934 tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
935 tif->tif_rawdata, tif->tif_rawcc))
937 /* We update those variables even in case of error since there's */
938 /* code that doesn't really check the return code of this */
939 /* function */
940 tif->tif_rawcc = 0;
941 tif->tif_rawcp = tif->tif_rawdata;
942 return (0);
944 tif->tif_rawcc = 0;
945 tif->tif_rawcp = tif->tif_rawdata;
947 return (1);
951 * Set the current write offset. This should only be
952 * used to set the offset to a known previous location
953 * (very carefully), or to 0 so that the next write gets
954 * appended to the end of the file.
956 void TIFFSetWriteOffset(TIFF *tif, toff_t off)
958 tif->tif_curoff = off;
959 tif->tif_lastvalidoff = 0;