d2d1/effect: Create effect instance properties from builtin effect description.
[wine.git] / libs / tiff / libtiff / tif_write.c
blobb5ef21d0816ad21d93ae0a5c6d95334d29d8cf3f
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, tmsize_t cc);
46 int
47 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) { /* extend image */
71 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
72 TIFFErrorExt(tif->tif_clientdata, module,
73 "Can not change \"ImageLength\" when using separate planes");
74 return (-1);
76 td->td_imagelength = row+1;
77 imagegrew = 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, module,
85 "%lu: Sample out of range, max %lu",
86 (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
87 return (-1);
89 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
90 } else
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))
100 return (-1);
101 if (strip != tif->tif_curstrip) {
103 * Changing strips -- flush any data present.
105 if (!TIFFFlushData(tif))
106 return (-1);
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_32(td->td_imagelength,td->td_rowsperstrip);
116 if (td->td_stripsperimage == 0) {
117 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
118 return (-1);
120 tif->tif_row =
121 (strip % td->td_stripsperimage) * td->td_rowsperstrip;
122 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
123 if (!(*tif->tif_setupencode)(tif))
124 return (-1);
125 tif->tif_flags |= TIFF_CODERSETUP;
128 tif->tif_rawcc = 0;
129 tif->tif_rawcp = tif->tif_rawdata;
131 if( td->td_stripbytecount_p[strip] > 0 )
133 /* if we are writing over existing tiles, zero length */
134 td->td_stripbytecount_p[strip] = 0;
136 /* this forces TIFFAppendToStrip() to do a seek */
137 tif->tif_curoff = 0;
140 if (!(*tif->tif_preencode)(tif, sample))
141 return (-1);
142 tif->tif_flags |= TIFF_POSTENCODE;
145 * Ensure the write is either sequential or at the
146 * beginning of a strip (or that we can randomly
147 * access the data -- i.e. no encoding).
149 if (row != tif->tif_row) {
150 if (row < tif->tif_row) {
152 * Moving backwards within the same strip:
153 * backup to the start and then decode
154 * forward (below).
156 tif->tif_row = (strip % td->td_stripsperimage) *
157 td->td_rowsperstrip;
158 tif->tif_rawcp = tif->tif_rawdata;
161 * Seek forward to the desired row.
163 if (!(*tif->tif_seek)(tif, row - tif->tif_row))
164 return (-1);
165 tif->tif_row = row;
168 /* swab if needed - note that source buffer will be altered */
169 tif->tif_postdecode(tif, (uint8_t*) buf, tif->tif_scanlinesize );
171 status = (*tif->tif_encoderow)(tif, (uint8_t*) buf,
172 tif->tif_scanlinesize, sample);
174 /* we are now poised at the beginning of the next row */
175 tif->tif_row = row + 1;
176 return (status);
179 /* Make sure that at the first attempt of rewriting a tile/strip, we will have */
180 /* more bytes available in the output buffer than the previous byte count, */
181 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
182 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
183 static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile)
185 TIFFDirectory *td = &tif->tif_dir;
186 if( td->td_stripbytecount_p[strip_or_tile] > 0 )
188 /* The +1 is to ensure at least one extra bytes */
189 /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
190 uint64_t safe_buffer_size = (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
191 if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size )
193 if( !(TIFFWriteBufferSetup(tif, NULL,
194 (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
195 return 0;
198 /* Force TIFFAppendToStrip() to consider placing data at end
199 of file. */
200 tif->tif_curoff = 0;
202 return 1;
206 * Encode the supplied data and write it to the
207 * specified strip.
209 * NB: Image length must be setup before writing.
211 tmsize_t
212 TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
214 static const char module[] = "TIFFWriteEncodedStrip";
215 TIFFDirectory *td = &tif->tif_dir;
216 uint16_t sample;
218 if (!WRITECHECKSTRIPS(tif, module))
219 return ((tmsize_t) -1);
221 * Check strip array to make sure there's space.
222 * We don't support dynamically growing files that
223 * have data organized in separate bitplanes because
224 * it's too painful. In that case we require that
225 * the imagelength be set properly before the first
226 * write (so that the strips array will be fully
227 * allocated above).
229 if (strip >= td->td_nstrips) {
230 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
231 TIFFErrorExt(tif->tif_clientdata, module,
232 "Can not grow image by strips when using separate planes");
233 return ((tmsize_t) -1);
235 if (!TIFFGrowStrips(tif, 1, module))
236 return ((tmsize_t) -1);
237 td->td_stripsperimage =
238 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
241 * Handle delayed allocation of data buffer. This
242 * permits it to be sized according to the directory
243 * info.
245 if (!BUFFERCHECK(tif))
246 return ((tmsize_t) -1);
248 tif->tif_flags |= TIFF_BUF4WRITE;
249 tif->tif_curstrip = strip;
251 if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
252 return ((tmsize_t)(-1));
255 tif->tif_rawcc = 0;
256 tif->tif_rawcp = tif->tif_rawdata;
258 if (td->td_stripsperimage == 0) {
259 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
260 return ((tmsize_t) -1);
263 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
264 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
265 if (!(*tif->tif_setupencode)(tif))
266 return ((tmsize_t) -1);
267 tif->tif_flags |= TIFF_CODERSETUP;
270 tif->tif_flags &= ~TIFF_POSTENCODE;
272 /* shortcut to avoid an extra memcpy() */
273 if( td->td_compression == COMPRESSION_NONE )
275 /* swab if needed - note that source buffer will be altered */
276 tif->tif_postdecode(tif, (uint8_t*) data, cc );
278 if (!isFillOrder(tif, td->td_fillorder) &&
279 (tif->tif_flags & TIFF_NOBITREV) == 0)
280 TIFFReverseBits((uint8_t*) data, cc);
282 if (cc > 0 &&
283 !TIFFAppendToStrip(tif, strip, (uint8_t*) data, cc))
284 return ((tmsize_t) -1);
285 return (cc);
288 sample = (uint16_t)(strip / td->td_stripsperimage);
289 if (!(*tif->tif_preencode)(tif, sample))
290 return ((tmsize_t) -1);
292 /* swab if needed - note that source buffer will be altered */
293 tif->tif_postdecode(tif, (uint8_t*) data, cc );
295 if (!(*tif->tif_encodestrip)(tif, (uint8_t*) data, cc, sample))
296 return ((tmsize_t) -1);
297 if (!(*tif->tif_postencode)(tif))
298 return ((tmsize_t) -1);
299 if (!isFillOrder(tif, td->td_fillorder) &&
300 (tif->tif_flags & TIFF_NOBITREV) == 0)
301 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
302 if (tif->tif_rawcc > 0 &&
303 !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
304 return ((tmsize_t) -1);
305 tif->tif_rawcc = 0;
306 tif->tif_rawcp = tif->tif_rawdata;
307 return (cc);
311 * Write the supplied data to the specified strip.
313 * NB: Image length must be setup before writing.
315 tmsize_t
316 TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
318 static const char module[] = "TIFFWriteRawStrip";
319 TIFFDirectory *td = &tif->tif_dir;
321 if (!WRITECHECKSTRIPS(tif, module))
322 return ((tmsize_t) -1);
324 * Check strip array to make sure there's space.
325 * We don't support dynamically growing files that
326 * have data organized in separate bitplanes because
327 * it's too painful. In that case we require that
328 * the imagelength be set properly before the first
329 * write (so that the strips array will be fully
330 * allocated above).
332 if (strip >= td->td_nstrips) {
333 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
334 TIFFErrorExt(tif->tif_clientdata, module,
335 "Can not grow image by strips when using separate planes");
336 return ((tmsize_t) -1);
339 * Watch out for a growing image. The value of
340 * strips/image will initially be 1 (since it
341 * can't be deduced until the imagelength is known).
343 if (strip >= td->td_stripsperimage)
344 td->td_stripsperimage =
345 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
346 if (!TIFFGrowStrips(tif, 1, module))
347 return ((tmsize_t) -1);
349 tif->tif_curstrip = strip;
350 if (td->td_stripsperimage == 0) {
351 TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
352 return ((tmsize_t) -1);
354 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
355 return (TIFFAppendToStrip(tif, strip, (uint8_t*) data, cc) ?
356 cc : (tmsize_t) -1);
360 * Write and compress a tile of data. The
361 * tile is selected by the (x,y,z,s) coordinates.
363 tmsize_t
364 TIFFWriteTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t s)
366 if (!TIFFCheckTile(tif, x, y, z, s))
367 return ((tmsize_t)(-1));
369 * NB: A tile size of -1 is used instead of tif_tilesize knowing
370 * that TIFFWriteEncodedTile will clamp this to the tile size.
371 * This is done because the tile size may not be defined until
372 * after the output buffer is setup in TIFFWriteBufferSetup.
374 return (TIFFWriteEncodedTile(tif,
375 TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
379 * Encode the supplied data and write it to the
380 * specified tile. There must be space for the
381 * data. The function clamps individual writes
382 * to a tile to the tile size, but does not (and
383 * can not) check that multiple writes to the same
384 * tile do not write more than tile size data.
386 * NB: Image length must be setup before writing; this
387 * interface does not support automatically growing
388 * the image on each write (as TIFFWriteScanline does).
390 tmsize_t
391 TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
393 static const char module[] = "TIFFWriteEncodedTile";
394 TIFFDirectory *td;
395 uint16_t sample;
396 uint32_t howmany32;
398 if (!WRITECHECKTILES(tif, module))
399 return ((tmsize_t)(-1));
400 td = &tif->tif_dir;
401 if (tile >= td->td_nstrips) {
402 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
403 (unsigned long) tile, (unsigned long) td->td_nstrips);
404 return ((tmsize_t)(-1));
407 * Handle delayed allocation of data buffer. This
408 * permits it to be sized more intelligently (using
409 * directory information).
411 if (!BUFFERCHECK(tif))
412 return ((tmsize_t)(-1));
414 tif->tif_flags |= TIFF_BUF4WRITE;
415 tif->tif_curtile = tile;
417 if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
418 return ((tmsize_t)(-1));
421 tif->tif_rawcc = 0;
422 tif->tif_rawcp = tif->tif_rawdata;
425 * Compute tiles per row & per column to compute
426 * current row and column
428 howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
429 if (howmany32 == 0) {
430 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
431 return ((tmsize_t)(-1));
433 tif->tif_row = (tile % howmany32) * td->td_tilelength;
434 howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
435 if (howmany32 == 0) {
436 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
437 return ((tmsize_t)(-1));
439 tif->tif_col = (tile % howmany32) * td->td_tilewidth;
441 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
442 if (!(*tif->tif_setupencode)(tif))
443 return ((tmsize_t)(-1));
444 tif->tif_flags |= TIFF_CODERSETUP;
446 tif->tif_flags &= ~TIFF_POSTENCODE;
449 * Clamp write amount to the tile size. This is mostly
450 * done so that callers can pass in some large number
451 * (e.g. -1) and have the tile size used instead.
453 if ( cc < 1 || cc > tif->tif_tilesize)
454 cc = tif->tif_tilesize;
456 /* shortcut to avoid an extra memcpy() */
457 if( td->td_compression == COMPRESSION_NONE )
459 /* swab if needed - note that source buffer will be altered */
460 tif->tif_postdecode(tif, (uint8_t*) data, cc );
462 if (!isFillOrder(tif, td->td_fillorder) &&
463 (tif->tif_flags & TIFF_NOBITREV) == 0)
464 TIFFReverseBits((uint8_t*) data, cc);
466 if (cc > 0 &&
467 !TIFFAppendToStrip(tif, tile, (uint8_t*) data, cc))
468 return ((tmsize_t) -1);
469 return (cc);
472 sample = (uint16_t)(tile / td->td_stripsperimage);
473 if (!(*tif->tif_preencode)(tif, sample))
474 return ((tmsize_t)(-1));
475 /* swab if needed - note that source buffer will be altered */
476 tif->tif_postdecode(tif, (uint8_t*) data, cc );
478 if (!(*tif->tif_encodetile)(tif, (uint8_t*) data, cc, sample))
479 return ((tmsize_t) -1);
480 if (!(*tif->tif_postencode)(tif))
481 return ((tmsize_t)(-1));
482 if (!isFillOrder(tif, td->td_fillorder) &&
483 (tif->tif_flags & TIFF_NOBITREV) == 0)
484 TIFFReverseBits((uint8_t*)tif->tif_rawdata, tif->tif_rawcc);
485 if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
486 tif->tif_rawdata, tif->tif_rawcc))
487 return ((tmsize_t)(-1));
488 tif->tif_rawcc = 0;
489 tif->tif_rawcp = tif->tif_rawdata;
490 return (cc);
494 * Write the supplied data to the specified strip.
495 * There must be space for the data; we don't check
496 * if strips overlap!
498 * NB: Image length must be setup before writing; this
499 * interface does not support automatically growing
500 * the image on each write (as TIFFWriteScanline does).
502 tmsize_t
503 TIFFWriteRawTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
505 static const char module[] = "TIFFWriteRawTile";
507 if (!WRITECHECKTILES(tif, module))
508 return ((tmsize_t)(-1));
509 if (tile >= tif->tif_dir.td_nstrips) {
510 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
511 (unsigned long) tile,
512 (unsigned long) tif->tif_dir.td_nstrips);
513 return ((tmsize_t)(-1));
515 return (TIFFAppendToStrip(tif, tile, (uint8_t*) data, cc) ?
516 cc : (tmsize_t)(-1));
519 #define isUnspecified(tif, f) \
520 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
523 TIFFSetupStrips(TIFF* tif)
525 TIFFDirectory* td = &tif->tif_dir;
527 if (isTiled(tif))
528 td->td_stripsperimage =
529 isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
530 td->td_samplesperpixel : TIFFNumberOfTiles(tif);
531 else
532 td->td_stripsperimage =
533 isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
534 td->td_samplesperpixel : TIFFNumberOfStrips(tif);
535 td->td_nstrips = td->td_stripsperimage;
536 /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
537 if( td->td_nstrips >= 0x80000000U / ((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U) )
539 TIFFErrorExt(tif->tif_clientdata, "TIFFSetupStrips",
540 "Too large Strip/Tile Offsets/ByteCounts arrays");
541 return 0;
543 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
544 td->td_stripsperimage /= td->td_samplesperpixel;
545 td->td_stripoffset_p = (uint64_t *)
546 _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64_t),
547 "for \"StripOffsets\" array");
548 td->td_stripbytecount_p = (uint64_t *)
549 _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64_t),
550 "for \"StripByteCounts\" array");
551 if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
552 return (0);
554 * Place data at the end-of-file
555 * (by setting offsets to zero).
557 _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64_t));
558 _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64_t));
559 TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
560 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
561 return (1);
563 #undef isUnspecified
566 * Verify file is writable and that the directory
567 * information is setup properly. In doing the latter
568 * we also "freeze" the state of the directory so
569 * that important information is not changed.
572 TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
574 if (tif->tif_mode == O_RDONLY) {
575 TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
576 return (0);
578 if (tiles ^ isTiled(tif)) {
579 TIFFErrorExt(tif->tif_clientdata, module, tiles ?
580 "Can not write tiles to a striped image" :
581 "Can not write scanlines to a tiled image");
582 return (0);
585 _TIFFFillStriles( tif );
588 * On the first write verify all the required information
589 * has been setup and initialize any data structures that
590 * had to wait until directory information was set.
591 * Note that a lot of our work is assumed to remain valid
592 * because we disallow any of the important parameters
593 * from changing after we start writing (i.e. once
594 * TIFF_BEENWRITING is set, TIFFSetField will only allow
595 * the image's length to be changed).
597 if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
598 TIFFErrorExt(tif->tif_clientdata, module,
599 "Must set \"ImageWidth\" before writing data");
600 return (0);
602 if (tif->tif_dir.td_samplesperpixel == 1) {
604 * Planarconfiguration is irrelevant in case of single band
605 * images and need not be included. We will set it anyway,
606 * because this field is used in other parts of library even
607 * in the single band case.
609 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
610 tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
611 } else {
612 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
613 TIFFErrorExt(tif->tif_clientdata, module,
614 "Must set \"PlanarConfiguration\" before writing data");
615 return (0);
618 if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) {
619 tif->tif_dir.td_nstrips = 0;
620 TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
621 isTiled(tif) ? "tile" : "strip");
622 return (0);
624 if (isTiled(tif))
626 tif->tif_tilesize = TIFFTileSize(tif);
627 if (tif->tif_tilesize == 0)
628 return (0);
630 else
631 tif->tif_tilesize = (tmsize_t)(-1);
632 tif->tif_scanlinesize = TIFFScanlineSize(tif);
633 if (tif->tif_scanlinesize == 0)
634 return (0);
635 tif->tif_flags |= TIFF_BEENWRITING;
637 if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
638 tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
639 tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
640 tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
641 tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
642 tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
643 tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
644 tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
645 !(tif->tif_flags & TIFF_DIRTYDIRECT) )
647 TIFFForceStrileArrayWriting(tif);
650 return (1);
654 * Setup the raw data buffer used for encoding.
657 TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
659 static const char module[] = "TIFFWriteBufferSetup";
661 if (tif->tif_rawdata) {
662 if (tif->tif_flags & TIFF_MYBUFFER) {
663 _TIFFfree(tif->tif_rawdata);
664 tif->tif_flags &= ~TIFF_MYBUFFER;
666 tif->tif_rawdata = NULL;
668 if (size == (tmsize_t)(-1)) {
669 size = (isTiled(tif) ?
670 tif->tif_tilesize : TIFFStripSize(tif));
672 /* Adds 10% margin for cases where compression would expand a bit */
673 if( size < TIFF_TMSIZE_T_MAX - size / 10 )
674 size += size / 10;
676 * Make raw data buffer at least 8K
678 if (size < 8*1024)
679 size = 8*1024;
680 bp = NULL; /* NB: force malloc */
682 if (bp == NULL) {
683 bp = _TIFFmalloc(size);
684 if (bp == NULL) {
685 TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
686 return (0);
688 tif->tif_flags |= TIFF_MYBUFFER;
689 } else
690 tif->tif_flags &= ~TIFF_MYBUFFER;
691 tif->tif_rawdata = (uint8_t*) bp;
692 tif->tif_rawdatasize = size;
693 tif->tif_rawcc = 0;
694 tif->tif_rawcp = tif->tif_rawdata;
695 tif->tif_flags |= TIFF_BUFFERSETUP;
696 return (1);
700 * Grow the strip data structures by delta strips.
702 static int
703 TIFFGrowStrips(TIFF* tif, uint32_t delta, const char* module)
705 TIFFDirectory *td = &tif->tif_dir;
706 uint64_t* new_stripoffset;
707 uint64_t* new_stripbytecount;
709 assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
710 new_stripoffset = (uint64_t*)_TIFFrealloc(td->td_stripoffset_p,
711 (td->td_nstrips + delta) * sizeof (uint64_t));
712 new_stripbytecount = (uint64_t*)_TIFFrealloc(td->td_stripbytecount_p,
713 (td->td_nstrips + delta) * sizeof (uint64_t));
714 if (new_stripoffset == NULL || new_stripbytecount == NULL) {
715 if (new_stripoffset)
716 _TIFFfree(new_stripoffset);
717 if (new_stripbytecount)
718 _TIFFfree(new_stripbytecount);
719 td->td_nstrips = 0;
720 TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
721 return (0);
723 td->td_stripoffset_p = new_stripoffset;
724 td->td_stripbytecount_p = new_stripbytecount;
725 _TIFFmemset(td->td_stripoffset_p + td->td_nstrips,
726 0, delta*sizeof (uint64_t));
727 _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips,
728 0, delta*sizeof (uint64_t));
729 td->td_nstrips += delta;
730 tif->tif_flags |= TIFF_DIRTYDIRECT;
732 return (1);
736 * Append the data to the specified strip.
738 static int
739 TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
741 static const char module[] = "TIFFAppendToStrip";
742 TIFFDirectory *td = &tif->tif_dir;
743 uint64_t m;
744 int64_t old_byte_count = -1;
746 if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
747 assert(td->td_nstrips > 0);
749 if( td->td_stripbytecount_p[strip] != 0
750 && td->td_stripoffset_p[strip] != 0
751 && td->td_stripbytecount_p[strip] >= (uint64_t) cc )
754 * There is already tile data on disk, and the new tile
755 * data we have will fit in the same space. The only
756 * aspect of this that is risky is that there could be
757 * more data to append to this strip before we are done
758 * depending on how we are getting called.
760 if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
761 TIFFErrorExt(tif->tif_clientdata, module,
762 "Seek error at scanline %lu",
763 (unsigned long)tif->tif_row);
764 return (0);
767 else
770 * Seek to end of file, and set that as our location to
771 * write this strip.
773 td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
774 tif->tif_flags |= TIFF_DIRTYSTRIP;
777 tif->tif_curoff = td->td_stripoffset_p[strip];
780 * We are starting a fresh strip/tile, so set the size to zero.
782 old_byte_count = td->td_stripbytecount_p[strip];
783 td->td_stripbytecount_p[strip] = 0;
786 m = tif->tif_curoff+cc;
787 if (!(tif->tif_flags&TIFF_BIGTIFF))
788 m = (uint32_t)m;
789 if ((m<tif->tif_curoff)||(m<(uint64_t)cc))
791 TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
792 return (0);
794 if (!WriteOK(tif, data, cc)) {
795 TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
796 (unsigned long) tif->tif_row);
797 return (0);
799 tif->tif_curoff = m;
800 td->td_stripbytecount_p[strip] += cc;
802 if((int64_t) td->td_stripbytecount_p[strip] != old_byte_count )
803 tif->tif_flags |= TIFF_DIRTYSTRIP;
805 return (1);
809 * Internal version of TIFFFlushData that can be
810 * called by ``encodestrip routines'' w/o concern
811 * for infinite recursion.
814 TIFFFlushData1(TIFF* tif)
816 if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
817 if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
818 (tif->tif_flags & TIFF_NOBITREV) == 0)
819 TIFFReverseBits((uint8_t*)tif->tif_rawdata,
820 tif->tif_rawcc);
821 if (!TIFFAppendToStrip(tif,
822 isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
823 tif->tif_rawdata, tif->tif_rawcc))
825 /* We update those variables even in case of error since there's */
826 /* code that doesn't really check the return code of this */
827 /* function */
828 tif->tif_rawcc = 0;
829 tif->tif_rawcp = tif->tif_rawdata;
830 return (0);
832 tif->tif_rawcc = 0;
833 tif->tif_rawcp = tif->tif_rawdata;
835 return (1);
839 * Set the current write offset. This should only be
840 * used to set the offset to a known previous location
841 * (very carefully), or to 0 so that the next write gets
842 * appended to the end of the file.
844 void
845 TIFFSetWriteOffset(TIFF* tif, toff_t off)
847 tif->tif_curoff = off;
850 /* vim: set ts=8 sts=8 sw=8 noet: */
852 * Local Variables:
853 * mode: c
854 * c-basic-offset: 8
855 * fill-column: 78
856 * End: