ReactOS 0.4.16-dev-336-gb667d82
tif_write.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 1988-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4 *
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.
12 *
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.
16 *
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.
23 */
24
25/*
26 * TIFF Library.
27 *
28 * Scanline-oriented Write Support
29 */
30#include <precomp.h>
31//#include <stdio.h>
32
33#define STRIPINCR 20 /* expansion factor on strip array */
34
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))
42
43static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
44static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
45
46int
48{
49 static const char module[] = "TIFFWriteScanline";
50 register TIFFDirectory *td;
51 int status, imagegrew = 0;
52 uint32 strip;
53
54 if (!WRITECHECKSTRIPS(tif, module))
55 return (-1);
56 /*
57 * Handle delayed allocation of data buffer. This
58 * permits it to be sized more intelligently (using
59 * directory information).
60 */
61 if (!BUFFERCHECK(tif))
62 return (-1);
63 tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
64
65 td = &tif->tif_dir;
66 /*
67 * Extend image length if needed
68 * (but only for PlanarConfig=1).
69 */
70 if (row >= td->td_imagelength) { /* extend image */
73 "Can not change \"ImageLength\" when using separate planes");
74 return (-1);
75 }
76 td->td_imagelength = row+1;
77 imagegrew = 1;
78 }
79 /*
80 * Calculate strip and check for crossings.
81 */
83 if (sample >= td->td_samplesperpixel) {
85 "%lu: Sample out of range, max %lu",
86 (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
87 return (-1);
88 }
89 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
90 } else
91 strip = row / td->td_rowsperstrip;
92 /*
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).
98 */
99 if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
100 return (-1);
101 if (strip != tif->tif_curstrip) {
102 /*
103 * Changing strips -- flush any data present.
104 */
105 if (!TIFFFlushData(tif))
106 return (-1);
107 tif->tif_curstrip = strip;
108 /*
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).
112 */
113 if (strip >= td->td_stripsperimage && imagegrew)
116 if (td->td_stripsperimage == 0) {
117 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
118 return (-1);
119 }
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);
126 }
127
128 tif->tif_rawcc = 0;
129 tif->tif_rawcp = tif->tif_rawdata;
130
131 if( td->td_stripbytecount_p[strip] > 0 )
132 {
133 /* if we are writing over existing tiles, zero length */
134 td->td_stripbytecount_p[strip] = 0;
135
136 /* this forces TIFFAppendToStrip() to do a seek */
137 tif->tif_curoff = 0;
138 }
139
140 if (!(*tif->tif_preencode)(tif, sample))
141 return (-1);
143 }
144 /*
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).
148 */
149 if (row != tif->tif_row) {
150 if (row < tif->tif_row) {
151 /*
152 * Moving backwards within the same strip:
153 * backup to the start and then decode
154 * forward (below).
155 */
156 tif->tif_row = (strip % td->td_stripsperimage) *
157 td->td_rowsperstrip;
158 tif->tif_rawcp = tif->tif_rawdata;
159 }
160 /*
161 * Seek forward to the desired row.
162 */
163 if (!(*tif->tif_seek)(tif, row - tif->tif_row))
164 return (-1);
165 tif->tif_row = row;
166 }
167
168 /* swab if needed - note that source buffer will be altered */
169 tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
170
171 status = (*tif->tif_encoderow)(tif, (uint8*) buf,
172 tif->tif_scanlinesize, sample);
173
174 /* we are now poised at the beginning of the next row */
175 tif->tif_row = row + 1;
176 return (status);
177}
178
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) */
183static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32 strip_or_tile)
184{
185 TIFFDirectory *td = &tif->tif_dir;
186 if( td->td_stripbytecount_p[strip_or_tile] > 0 )
187 {
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 safe_buffer_size = (uint64)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
191 if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size )
192 {
193 if( !(TIFFWriteBufferSetup(tif, NULL,
194 (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) )
195 return 0;
196 }
197
198 /* Force TIFFAppendToStrip() to consider placing data at end
199 of file. */
200 tif->tif_curoff = 0;
201 }
202 return 1;
203}
204
205/*
206 * Encode the supplied data and write it to the
207 * specified strip.
208 *
209 * NB: Image length must be setup before writing.
210 */
213{
214 static const char module[] = "TIFFWriteEncodedStrip";
215 TIFFDirectory *td = &tif->tif_dir;
216 uint16 sample;
217
218 if (!WRITECHECKSTRIPS(tif, module))
219 return ((tmsize_t) -1);
220 /*
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).
228 */
229 if (strip >= td->td_nstrips) {
232 "Can not grow image by strips when using separate planes");
233 return ((tmsize_t) -1);
234 }
235 if (!TIFFGrowStrips(tif, 1, module))
236 return ((tmsize_t) -1);
239 }
240 /*
241 * Handle delayed allocation of data buffer. This
242 * permits it to be sized according to the directory
243 * info.
244 */
245 if (!BUFFERCHECK(tif))
246 return ((tmsize_t) -1);
247
249 tif->tif_curstrip = strip;
250
251 if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) {
252 return ((tmsize_t)(-1));
253 }
254
255 tif->tif_rawcc = 0;
256 tif->tif_rawcp = tif->tif_rawdata;
257
258 if (td->td_stripsperimage == 0) {
259 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
260 return ((tmsize_t) -1);
261 }
262
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);
268 }
269
270 tif->tif_flags &= ~TIFF_POSTENCODE;
271
272 /* shortcut to avoid an extra memcpy() */
274 {
275 /* swab if needed - note that source buffer will be altered */
276 tif->tif_postdecode( tif, (uint8*) data, cc );
277
278 if (!isFillOrder(tif, td->td_fillorder) &&
279 (tif->tif_flags & TIFF_NOBITREV) == 0)
281
282 if (cc > 0 &&
283 !TIFFAppendToStrip(tif, strip, (uint8*) data, cc))
284 return ((tmsize_t) -1);
285 return (cc);
286 }
287
288 sample = (uint16)(strip / td->td_stripsperimage);
289 if (!(*tif->tif_preencode)(tif, sample))
290 return ((tmsize_t) -1);
291
292 /* swab if needed - note that source buffer will be altered */
293 tif->tif_postdecode( tif, (uint8*) data, cc );
294
295 if (!(*tif->tif_encodestrip)(tif, (uint8*) 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)
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);
308}
309
310/*
311 * Write the supplied data to the specified strip.
312 *
313 * NB: Image length must be setup before writing.
314 */
317{
318 static const char module[] = "TIFFWriteRawStrip";
319 TIFFDirectory *td = &tif->tif_dir;
320
321 if (!WRITECHECKSTRIPS(tif, module))
322 return ((tmsize_t) -1);
323 /*
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).
331 */
332 if (strip >= td->td_nstrips) {
335 "Can not grow image by strips when using separate planes");
336 return ((tmsize_t) -1);
337 }
338 /*
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).
342 */
343 if (strip >= td->td_stripsperimage)
346 if (!TIFFGrowStrips(tif, 1, module))
347 return ((tmsize_t) -1);
348 }
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);
353 }
354 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
355 return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
356 cc : (tmsize_t) -1);
357}
358
359/*
360 * Write and compress a tile of data. The
361 * tile is selected by the (x,y,z,s) coordinates.
362 */
365{
366 if (!TIFFCheckTile(tif, x, y, z, s))
367 return ((tmsize_t)(-1));
368 /*
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.
373 */
374 return (TIFFWriteEncodedTile(tif,
375 TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
376}
377
378/*
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.
385 *
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).
389 */
392{
393 static const char module[] = "TIFFWriteEncodedTile";
394 TIFFDirectory *td;
395 uint16 sample;
396 uint32 howmany32;
397
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));
405 }
406 /*
407 * Handle delayed allocation of data buffer. This
408 * permits it to be sized more intelligently (using
409 * directory information).
410 */
411 if (!BUFFERCHECK(tif))
412 return ((tmsize_t)(-1));
413
415 tif->tif_curtile = tile;
416
417 if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) {
418 return ((tmsize_t)(-1));
419 }
420
421 tif->tif_rawcc = 0;
422 tif->tif_rawcp = tif->tif_rawdata;
423
424 /*
425 * Compute tiles per row & per column to compute
426 * current row and column
427 */
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));
432 }
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));
438 }
439 tif->tif_col = (tile % howmany32) * td->td_tilewidth;
440
441 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
442 if (!(*tif->tif_setupencode)(tif))
443 return ((tmsize_t)(-1));
445 }
446 tif->tif_flags &= ~TIFF_POSTENCODE;
447
448 /*
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.
452 */
453 if ( cc < 1 || cc > tif->tif_tilesize)
454 cc = tif->tif_tilesize;
455
456 /* shortcut to avoid an extra memcpy() */
458 {
459 /* swab if needed - note that source buffer will be altered */
460 tif->tif_postdecode( tif, (uint8*) data, cc );
461
462 if (!isFillOrder(tif, td->td_fillorder) &&
463 (tif->tif_flags & TIFF_NOBITREV) == 0)
465
466 if (cc > 0 &&
467 !TIFFAppendToStrip(tif, tile, (uint8*) data, cc))
468 return ((tmsize_t) -1);
469 return (cc);
470 }
471
472 sample = (uint16)(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*) data, cc );
477
478 if (!(*tif->tif_encodetile)(tif, (uint8*) 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)
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);
491}
492
493/*
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!
497 *
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).
501 */
504{
505 static const char module[] = "TIFFWriteRawTile";
506
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));
514 }
515 return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
516 cc : (tmsize_t)(-1));
517}
518
519#define isUnspecified(tif, f) \
520 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
521
522int
524{
525 TIFFDirectory* td = &tif->tif_dir;
526
527 if (isTiled(tif))
531 else
538 td->td_stripoffset_p = (uint64 *)
540 "for \"StripOffsets\" array");
543 "for \"StripByteCounts\" array");
544 if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
545 return (0);
546 /*
547 * Place data at the end-of-file
548 * (by setting offsets to zero).
549 */
554 return (1);
555}
556#undef isUnspecified
557
558/*
559 * Verify file is writable and that the directory
560 * information is setup properly. In doing the latter
561 * we also "freeze" the state of the directory so
562 * that important information is not changed.
563 */
564int
565TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
566{
567 if (tif->tif_mode == O_RDONLY) {
568 TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
569 return (0);
570 }
571 if (tiles ^ isTiled(tif)) {
572 TIFFErrorExt(tif->tif_clientdata, module, tiles ?
573 "Can not write tiles to a striped image" :
574 "Can not write scanlines to a tiled image");
575 return (0);
576 }
577
578 _TIFFFillStriles( tif );
579
580 /*
581 * On the first write verify all the required information
582 * has been setup and initialize any data structures that
583 * had to wait until directory information was set.
584 * Note that a lot of our work is assumed to remain valid
585 * because we disallow any of the important parameters
586 * from changing after we start writing (i.e. once
587 * TIFF_BEENWRITING is set, TIFFSetField will only allow
588 * the image's length to be changed).
589 */
592 "Must set \"ImageWidth\" before writing data");
593 return (0);
594 }
595 if (tif->tif_dir.td_samplesperpixel == 1) {
596 /*
597 * Planarconfiguration is irrelevant in case of single band
598 * images and need not be included. We will set it anyway,
599 * because this field is used in other parts of library even
600 * in the single band case.
601 */
604 } else {
605 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
607 "Must set \"PlanarConfiguration\" before writing data");
608 return (0);
609 }
610 }
611 if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) {
612 tif->tif_dir.td_nstrips = 0;
613 TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
614 isTiled(tif) ? "tile" : "strip");
615 return (0);
616 }
617 if (isTiled(tif))
618 {
619 tif->tif_tilesize = TIFFTileSize(tif);
620 if (tif->tif_tilesize == 0)
621 return (0);
622 }
623 else
624 tif->tif_tilesize = (tmsize_t)(-1);
626 if (tif->tif_scanlinesize == 0)
627 return (0);
629
630 if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
638 !(tif->tif_flags & TIFF_DIRTYDIRECT) )
639 {
641 }
642
643 return (1);
644}
645
646/*
647 * Setup the raw data buffer used for encoding.
648 */
649int
651{
652 static const char module[] = "TIFFWriteBufferSetup";
653
654 if (tif->tif_rawdata) {
655 if (tif->tif_flags & TIFF_MYBUFFER) {
657 tif->tif_flags &= ~TIFF_MYBUFFER;
658 }
659 tif->tif_rawdata = NULL;
660 }
661 if (size == (tmsize_t)(-1)) {
662 size = (isTiled(tif) ?
663 tif->tif_tilesize : TIFFStripSize(tif));
664 /*
665 * Make raw data buffer at least 8K
666 */
667 if (size < 8*1024)
668 size = 8*1024;
669 bp = NULL; /* NB: force malloc */
670 }
671 if (bp == NULL) {
672 bp = _TIFFmalloc(size);
673 if (bp == NULL) {
674 TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
675 return (0);
676 }
677 tif->tif_flags |= TIFF_MYBUFFER;
678 } else
679 tif->tif_flags &= ~TIFF_MYBUFFER;
680 tif->tif_rawdata = (uint8*) bp;
681 tif->tif_rawdatasize = size;
682 tif->tif_rawcc = 0;
683 tif->tif_rawcp = tif->tif_rawdata;
685 return (1);
686}
687
688/*
689 * Grow the strip data structures by delta strips.
690 */
691static int
692TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
693{
694 TIFFDirectory *td = &tif->tif_dir;
695 uint64* new_stripoffset;
696 uint64* new_stripbytecount;
697
699 new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset_p,
700 (td->td_nstrips + delta) * sizeof (uint64));
701 new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount_p,
702 (td->td_nstrips + delta) * sizeof (uint64));
703 if (new_stripoffset == NULL || new_stripbytecount == NULL) {
704 if (new_stripoffset)
705 _TIFFfree(new_stripoffset);
706 if (new_stripbytecount)
707 _TIFFfree(new_stripbytecount);
708 td->td_nstrips = 0;
709 TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
710 return (0);
711 }
712 td->td_stripoffset_p = new_stripoffset;
713 td->td_stripbytecount_p = new_stripbytecount;
715 0, delta*sizeof (uint64));
717 0, delta*sizeof (uint64));
718 td->td_nstrips += delta;
720
721 return (1);
722}
723
724/*
725 * Append the data to the specified strip.
726 */
727static int
729{
730 static const char module[] = "TIFFAppendToStrip";
731 TIFFDirectory *td = &tif->tif_dir;
732 uint64 m;
733 int64 old_byte_count = -1;
734
735 if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
736 assert(td->td_nstrips > 0);
737
738 if( td->td_stripbytecount_p[strip] != 0
739 && td->td_stripoffset_p[strip] != 0
740 && td->td_stripbytecount_p[strip] >= (uint64) cc )
741 {
742 /*
743 * There is already tile data on disk, and the new tile
744 * data we have will fit in the same space. The only
745 * aspect of this that is risky is that there could be
746 * more data to append to this strip before we are done
747 * depending on how we are getting called.
748 */
749 if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
751 "Seek error at scanline %lu",
752 (unsigned long)tif->tif_row);
753 return (0);
754 }
755 }
756 else
757 {
758 /*
759 * Seek to end of file, and set that as our location to
760 * write this strip.
761 */
762 td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
764 }
765
766 tif->tif_curoff = td->td_stripoffset_p[strip];
767
768 /*
769 * We are starting a fresh strip/tile, so set the size to zero.
770 */
771 old_byte_count = td->td_stripbytecount_p[strip];
772 td->td_stripbytecount_p[strip] = 0;
773 }
774
775 m = tif->tif_curoff+cc;
776 if (!(tif->tif_flags&TIFF_BIGTIFF))
777 m = (uint32)m;
778 if ((m<tif->tif_curoff)||(m<(uint64)cc))
779 {
780 TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
781 return (0);
782 }
783 if (!WriteOK(tif, data, cc)) {
784 TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
785 (unsigned long) tif->tif_row);
786 return (0);
787 }
788 tif->tif_curoff = m;
789 td->td_stripbytecount_p[strip] += cc;
790
791 if( (int64) td->td_stripbytecount_p[strip] != old_byte_count )
793
794 return (1);
795}
796
797/*
798 * Internal version of TIFFFlushData that can be
799 * called by ``encodestrip routines'' w/o concern
800 * for infinite recursion.
801 */
802int
804{
805 if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
806 if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
807 (tif->tif_flags & TIFF_NOBITREV) == 0)
809 tif->tif_rawcc);
810 if (!TIFFAppendToStrip(tif,
811 isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
812 tif->tif_rawdata, tif->tif_rawcc))
813 {
814 /* We update those variables even in case of error since there's */
815 /* code that doesn't really check the return code of this */
816 /* function */
817 tif->tif_rawcc = 0;
818 tif->tif_rawcp = tif->tif_rawdata;
819 return (0);
820 }
821 tif->tif_rawcc = 0;
822 tif->tif_rawcp = tif->tif_rawdata;
823 }
824 return (1);
825}
826
827/*
828 * Set the current write offset. This should only be
829 * used to set the offset to a known previous location
830 * (very carefully), or to 0 so that the next write gets
831 * appended to the end of the file.
832 */
833void
835{
836 tif->tif_curoff = off;
837}
838
839/* vim: set ts=8 sts=8 sw=8 noet: */
840/*
841 * Local Variables:
842 * mode: c
843 * c-basic-offset: 8
844 * fill-column: 78
845 * End:
846 */
#define O_RDONLY
Definition: acwin.h:108
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
unsigned char uint8
Definition: types.h:28
#define SEEK_END
Definition: cabinet.c:29
return
Definition: dirsup.c:529
#define NULL
Definition: types.h:112
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define assert(x)
Definition: debug.h:53
unsigned long long uint64
Definition: platform.h:18
long long int64
Definition: platform.h:13
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLdouble GLdouble z
Definition: glext.h:5874
const GLfloat * m
Definition: glext.h:10848
uint32_t cc
Definition: isohybrid.c:75
if(dx< 0)
Definition: linetemp.h:194
uint64 toff_long8
Definition: tif_dir.h:59
uint64 tdir_count
Definition: tif_dir.h:55
uint16 tdir_tag
Definition: tif_dir.h:53
uint16 tdir_type
Definition: tif_dir.h:54
union TIFFDirEntry::@3465 tdir_offset
uint64 * td_stripbytecount_p
Definition: tif_dir.h:102
uint16 td_samplesperpixel
Definition: tif_dir.h:82
uint32 td_imagewidth
Definition: tif_dir.h:72
uint32 td_rowsperstrip
Definition: tif_dir.h:83
uint16 td_fillorder
Definition: tif_dir.h:80
TIFFDirEntry td_stripoffset_entry
Definition: tif_dir.h:107
uint16 td_planarconfig
Definition: tif_dir.h:89
uint32 td_tilelength
Definition: tif_dir.h:73
uint32 td_nstrips
Definition: tif_dir.h:100
uint32 td_stripsperimage
Definition: tif_dir.h:99
uint16 td_compression
Definition: tif_dir.h:77
uint32 td_tilewidth
Definition: tif_dir.h:73
uint32 td_imagelength
Definition: tif_dir.h:72
uint64 * td_stripoffset_p
Definition: tif_dir.h:101
TIFFDirEntry td_stripbytecount_entry
Definition: tif_dir.h:108
Definition: ps.c:97
Definition: tiffiop.h:115
TIFFCodeMethod tif_encodestrip
Definition: tiffiop.h:183
TIFFSeekMethod tif_seek
Definition: tiffiop.h:187
TIFFCodeMethod tif_encodetile
Definition: tiffiop.h:185
tmsize_t tif_scanlinesize
Definition: tiffiop.h:193
TIFFPreMethod tif_preencode
Definition: tiffiop.h:178
tmsize_t tif_rawcc
Definition: tiffiop.h:200
TIFFPostMethod tif_postdecode
Definition: tiffiop.h:214
thandle_t tif_clientdata
Definition: tiffiop.h:207
uint32 tif_flags
Definition: tiffiop.h:119
TIFFBoolMethod tif_setupencode
Definition: tiffiop.h:176
TIFFDirectory tif_dir
Definition: tiffiop.h:151
TIFFBoolMethod tif_postencode
Definition: tiffiop.h:179
TIFFCodeMethod tif_encoderow
Definition: tiffiop.h:181
uint32 tif_curstrip
Definition: tiffiop.h:161
uint32 tif_row
Definition: tiffiop.h:159
uint32 tif_curtile
Definition: tiffiop.h:169
tmsize_t tif_rawdatasize
Definition: tiffiop.h:196
tmsize_t tif_tilesize
Definition: tiffiop.h:170
uint8 * tif_rawcp
Definition: tiffiop.h:199
uint32 tif_col
Definition: tiffiop.h:168
int tif_mode
Definition: tiffiop.h:118
uint64 tif_curoff
Definition: tiffiop.h:162
uint8 * tif_rawdata
Definition: tiffiop.h:195
void * _TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size, const char *what)
Definition: tif_aux.c:121
#define FIELD_STRIPOFFSETS
Definition: tif_dir.h:162
#define FIELD_IMAGEDIMENSIONS
Definition: tif_dir.h:141
#define TIFFFieldSet(tif, field)
Definition: tif_dir.h:196
#define FIELD_TILEDIMENSIONS
Definition: tif_dir.h:142
#define FIELD_ROWSPERSTRIP
Definition: tif_dir.h:155
#define FIELD_STRIPBYTECOUNTS
Definition: tif_dir.h:161
#define TIFFSetFieldBit(tif, field)
Definition: tif_dir.h:197
#define FIELD_PLANARCONFIG
Definition: tif_dir.h:158
int _TIFFFillStriles(TIFF *tif)
Definition: tif_dirread.c:6320
void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt,...)
Definition: tif_error.c:65
int TIFFForceStrileArrayWriting(TIFF *tif)
Definition: tif_flush.c:79
int TIFFFlushData(TIFF *tif)
Definition: tif_flush.c:156
tmsize_t TIFFStripSize(TIFF *tif)
Definition: tif_strip.c:202
tmsize_t TIFFScanlineSize(TIFF *tif)
Definition: tif_strip.c:314
uint32 TIFFNumberOfStrips(TIFF *tif)
Definition: tif_strip.c:59
void TIFFReverseBits(uint8 *cp, tmsize_t n)
Definition: tif_swab.c:284
tmsize_t TIFFTileSize(TIFF *tif)
Definition: tif_tile.c:257
int TIFFCheckTile(TIFF *tif, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_tile.c:73
uint32 TIFFComputeTile(TIFF *tif, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_tile.c:36
uint32 TIFFNumberOfTiles(TIFF *tif)
Definition: tif_tile.c:113
void _TIFFfree(void *p)
Definition: tif_unix.c:326
void _TIFFmemset(void *p, int v, tmsize_t c)
Definition: tif_unix.c:338
void * _TIFFmalloc(tmsize_t s)
Definition: tif_unix.c:309
void * _TIFFrealloc(void *p, tmsize_t s)
Definition: tif_unix.c:332
tmsize_t TIFFWriteRawTile(TIFF *tif, uint32 tile, void *data, tmsize_t cc)
Definition: tif_write.c:503
static int TIFFAppendToStrip(TIFF *tif, uint32 strip, uint8 *data, tmsize_t cc)
Definition: tif_write.c:728
#define BUFFERCHECK(tif)
Definition: tif_write.c:39
#define isUnspecified(tif, f)
Definition: tif_write.c:519
tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32 tile, void *data, tmsize_t cc)
Definition: tif_write.c:391
int TIFFWriteScanline(TIFF *tif, void *buf, uint32 row, uint16 sample)
Definition: tif_write.c:47
tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_write.c:364
void TIFFSetWriteOffset(TIFF *tif, toff_t off)
Definition: tif_write.c:834
tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32 strip, void *data, tmsize_t cc)
Definition: tif_write.c:316
static int TIFFGrowStrips(TIFF *tif, uint32 delta, const char *module)
Definition: tif_write.c:692
#define WRITECHECKTILES(tif, module)
Definition: tif_write.c:37
int TIFFFlushData1(TIFF *tif)
Definition: tif_write.c:803
int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
Definition: tif_write.c:650
tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32 strip, void *data, tmsize_t cc)
Definition: tif_write.c:212
int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
Definition: tif_write.c:565
int TIFFSetupStrips(TIFF *tif)
Definition: tif_write.c:523
#define WRITECHECKSTRIPS(tif, module)
Definition: tif_write.c:35
static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32 strip_or_tile)
Definition: tif_write.c:183
#define COMPRESSION_NONE
Definition: tiff.h:158
#define PLANARCONFIG_SEPARATE
Definition: tiff.h:240
#define PLANARCONFIG_CONTIG
Definition: tiff.h:239
uint64 toff_t
Definition: tiffio.h:66
TIFF_SSIZE_T tmsize_t
Definition: tiffio.h:65
#define TIFFroundup_64(x, y)
Definition: tiffiop.h:275
#define isTiled(tif)
Definition: tiffiop.h:229
#define WriteOK(tif, buf, size)
Definition: tiffiop.h:259
#define TIFF_MYBUFFER
Definition: tiffiop.h:128
#define TIFF_BUFFERSETUP
Definition: tiffiop.h:123
#define TIFF_CODERSETUP
Definition: tiffiop.h:124
#define TIFF_POSTENCODE
Definition: tiffiop.h:131
#define TIFF_BUF4WRITE
Definition: tiffiop.h:139
#define SeekOK(tif, off)
Definition: tiffiop.h:256
#define isFillOrder(tif, o)
Definition: tiffiop.h:231
#define TIFF_BEENWRITING
Definition: tiffiop.h:125
#define TIFF_DIRTYSTRIP
Definition: tiffiop.h:140
#define TIFFSeekFile(tif, off, whence)
Definition: tiffiop.h:237
#define TIFF_DIRTYDIRECT
Definition: tiffiop.h:122
#define TIFF_BIGTIFF
Definition: tiffiop.h:138
#define TIFFhowmany_32(x, y)
Definition: tiffiop.h:264
#define TIFF_NOBITREV
Definition: tiffiop.h:127
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList