1/* $Id: tif_write.c,v 1.42 2015-06-07 23:00:23 bfriesen Exp $ */
2
3/*
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 *
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.
14 *
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.
18 *
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
24 * OF THIS SOFTWARE.
25 */
26
27/*
28 * TIFF Library.
29 *
30 * Scanline-oriented Write Support
31 */
32#include "tiffiop.h"
33#include <stdio.h>
34
35#define STRIPINCR	20		/* expansion factor on strip array */
36
37#define WRITECHECKSTRIPS(tif, module)				\
38	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
39#define WRITECHECKTILES(tif, module)				\
40	(((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
41#define BUFFERCHECK(tif)					\
42	((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) ||	\
43	    TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
44
45static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
46static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
47
48int
49TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
50{
51	static const char module[] = "TIFFWriteScanline";
52	register TIFFDirectory *td;
53	int status, imagegrew = 0;
54	uint32 strip;
55
56	if (!WRITECHECKSTRIPS(tif, module))
57		return (-1);
58	/*
59	 * Handle delayed allocation of data buffer.  This
60	 * permits it to be sized more intelligently (using
61	 * directory information).
62	 */
63	if (!BUFFERCHECK(tif))
64		return (-1);
65        tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
66
67	td = &tif->tif_dir;
68	/*
69	 * Extend image length if needed
70	 * (but only for PlanarConfig=1).
71	 */
72	if (row >= td->td_imagelength) {	/* extend image */
73		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
74			TIFFErrorExt(tif->tif_clientdata, module,
75			    "Can not change \"ImageLength\" when using separate planes");
76			return (-1);
77		}
78		td->td_imagelength = row+1;
79		imagegrew = 1;
80	}
81	/*
82	 * Calculate strip and check for crossings.
83	 */
84	if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
85		if (sample >= td->td_samplesperpixel) {
86			TIFFErrorExt(tif->tif_clientdata, module,
87			    "%lu: Sample out of range, max %lu",
88			    (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
89			return (-1);
90		}
91		strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
92	} else
93		strip = row / td->td_rowsperstrip;
94	/*
95	 * Check strip array to make sure there's space. We don't support
96	 * dynamically growing files that have data organized in separate
97	 * bitplanes because it's too painful.  In that case we require that
98	 * the imagelength be set properly before the first write (so that the
99	 * strips array will be fully allocated above).
100	 */
101	if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
102		return (-1);
103	if (strip != tif->tif_curstrip) {
104		/*
105		 * Changing strips -- flush any data present.
106		 */
107		if (!TIFFFlushData(tif))
108			return (-1);
109		tif->tif_curstrip = strip;
110		/*
111		 * Watch out for a growing image.  The value of strips/image
112		 * will initially be 1 (since it can't be deduced until the
113		 * imagelength is known).
114		 */
115		if (strip >= td->td_stripsperimage && imagegrew)
116			td->td_stripsperimage =
117			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
118                if (td->td_stripsperimage == 0) {
119                        TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
120                        return (-1);
121                }
122		tif->tif_row =
123		    (strip % td->td_stripsperimage) * td->td_rowsperstrip;
124		if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
125			if (!(*tif->tif_setupencode)(tif))
126				return (-1);
127			tif->tif_flags |= TIFF_CODERSETUP;
128		}
129
130		tif->tif_rawcc = 0;
131		tif->tif_rawcp = tif->tif_rawdata;
132
133		if( td->td_stripbytecount[strip] > 0 )
134		{
135			/* if we are writing over existing tiles, zero length */
136			td->td_stripbytecount[strip] = 0;
137
138			/* this forces TIFFAppendToStrip() to do a seek */
139			tif->tif_curoff = 0;
140		}
141
142		if (!(*tif->tif_preencode)(tif, sample))
143			return (-1);
144		tif->tif_flags |= TIFF_POSTENCODE;
145	}
146	/*
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).
150	 */
151	if (row != tif->tif_row) {
152		if (row < tif->tif_row) {
153			/*
154			 * Moving backwards within the same strip:
155			 * backup to the start and then decode
156			 * forward (below).
157			 */
158			tif->tif_row = (strip % td->td_stripsperimage) *
159			    td->td_rowsperstrip;
160			tif->tif_rawcp = tif->tif_rawdata;
161		}
162		/*
163		 * Seek forward to the desired row.
164		 */
165		if (!(*tif->tif_seek)(tif, row - tif->tif_row))
166			return (-1);
167		tif->tif_row = row;
168	}
169
170	/* swab if needed - note that source buffer will be altered */
171	tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
172
173	status = (*tif->tif_encoderow)(tif, (uint8*) buf,
174	    tif->tif_scanlinesize, sample);
175
176        /* we are now poised at the beginning of the next row */
177	tif->tif_row = row + 1;
178	return (status);
179}
180
181/*
182 * Encode the supplied data and write it to the
183 * specified strip.
184 *
185 * NB: Image length must be setup before writing.
186 */
187tmsize_t
188TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
189{
190	static const char module[] = "TIFFWriteEncodedStrip";
191	TIFFDirectory *td = &tif->tif_dir;
192	uint16 sample;
193
194	if (!WRITECHECKSTRIPS(tif, module))
195		return ((tmsize_t) -1);
196	/*
197	 * Check strip array to make sure there's space.
198	 * We don't support dynamically growing files that
199	 * have data organized in separate bitplanes because
200	 * it's too painful.  In that case we require that
201	 * the imagelength be set properly before the first
202	 * write (so that the strips array will be fully
203	 * allocated above).
204	 */
205	if (strip >= td->td_nstrips) {
206		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
207			TIFFErrorExt(tif->tif_clientdata, module,
208			    "Can not grow image by strips when using separate planes");
209			return ((tmsize_t) -1);
210		}
211		if (!TIFFGrowStrips(tif, 1, module))
212			return ((tmsize_t) -1);
213		td->td_stripsperimage =
214		    TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
215	}
216	/*
217	 * Handle delayed allocation of data buffer.  This
218	 * permits it to be sized according to the directory
219	 * info.
220	 */
221	if (!BUFFERCHECK(tif))
222		return ((tmsize_t) -1);
223
224        tif->tif_flags |= TIFF_BUF4WRITE;
225	tif->tif_curstrip = strip;
226
227        if (td->td_stripsperimage == 0) {
228                TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
229                return ((tmsize_t) -1);
230        }
231
232	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
233	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
234		if (!(*tif->tif_setupencode)(tif))
235			return ((tmsize_t) -1);
236		tif->tif_flags |= TIFF_CODERSETUP;
237	}
238
239	if( td->td_stripbytecount[strip] > 0 )
240        {
241            /* Make sure that at the first attempt of rewriting the tile, we will have */
242            /* more bytes available in the output buffer than the previous byte count, */
243            /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
244            /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
245            if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
246            {
247                if( !(TIFFWriteBufferSetup(tif, NULL,
248                    (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
249                    return ((tmsize_t)(-1));
250            }
251
252	    /* Force TIFFAppendToStrip() to consider placing data at end
253               of file. */
254            tif->tif_curoff = 0;
255        }
256
257    tif->tif_rawcc = 0;
258    tif->tif_rawcp = tif->tif_rawdata;
259
260	tif->tif_flags &= ~TIFF_POSTENCODE;
261	sample = (uint16)(strip / td->td_stripsperimage);
262	if (!(*tif->tif_preencode)(tif, sample))
263		return ((tmsize_t) -1);
264
265        /* swab if needed - note that source buffer will be altered */
266	tif->tif_postdecode( tif, (uint8*) data, cc );
267
268	if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
269		return (0);
270	if (!(*tif->tif_postencode)(tif))
271		return ((tmsize_t) -1);
272	if (!isFillOrder(tif, td->td_fillorder) &&
273	    (tif->tif_flags & TIFF_NOBITREV) == 0)
274		TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
275	if (tif->tif_rawcc > 0 &&
276	    !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
277		return ((tmsize_t) -1);
278	tif->tif_rawcc = 0;
279	tif->tif_rawcp = tif->tif_rawdata;
280	return (cc);
281}
282
283/*
284 * Write the supplied data to the specified strip.
285 *
286 * NB: Image length must be setup before writing.
287 */
288tmsize_t
289TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
290{
291	static const char module[] = "TIFFWriteRawStrip";
292	TIFFDirectory *td = &tif->tif_dir;
293
294	if (!WRITECHECKSTRIPS(tif, module))
295		return ((tmsize_t) -1);
296	/*
297	 * Check strip array to make sure there's space.
298	 * We don't support dynamically growing files that
299	 * have data organized in separate bitplanes because
300	 * it's too painful.  In that case we require that
301	 * the imagelength be set properly before the first
302	 * write (so that the strips array will be fully
303	 * allocated above).
304	 */
305	if (strip >= td->td_nstrips) {
306		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
307			TIFFErrorExt(tif->tif_clientdata, module,
308			    "Can not grow image by strips when using separate planes");
309			return ((tmsize_t) -1);
310		}
311		/*
312		 * Watch out for a growing image.  The value of
313		 * strips/image will initially be 1 (since it
314		 * can't be deduced until the imagelength is known).
315		 */
316		if (strip >= td->td_stripsperimage)
317			td->td_stripsperimage =
318			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
319		if (!TIFFGrowStrips(tif, 1, module))
320			return ((tmsize_t) -1);
321	}
322	tif->tif_curstrip = strip;
323        if (td->td_stripsperimage == 0) {
324                TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
325                return ((tmsize_t) -1);
326        }
327	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
328	return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
329	    cc : (tmsize_t) -1);
330}
331
332/*
333 * Write and compress a tile of data.  The
334 * tile is selected by the (x,y,z,s) coordinates.
335 */
336tmsize_t
337TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
338{
339	if (!TIFFCheckTile(tif, x, y, z, s))
340		return ((tmsize_t)(-1));
341	/*
342	 * NB: A tile size of -1 is used instead of tif_tilesize knowing
343	 *     that TIFFWriteEncodedTile will clamp this to the tile size.
344	 *     This is done because the tile size may not be defined until
345	 *     after the output buffer is setup in TIFFWriteBufferSetup.
346	 */
347	return (TIFFWriteEncodedTile(tif,
348	    TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
349}
350
351/*
352 * Encode the supplied data and write it to the
353 * specified tile.  There must be space for the
354 * data.  The function clamps individual writes
355 * to a tile to the tile size, but does not (and
356 * can not) check that multiple writes to the same
357 * tile do not write more than tile size data.
358 *
359 * NB: Image length must be setup before writing; this
360 *     interface does not support automatically growing
361 *     the image on each write (as TIFFWriteScanline does).
362 */
363tmsize_t
364TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
365{
366	static const char module[] = "TIFFWriteEncodedTile";
367	TIFFDirectory *td;
368	uint16 sample;
369        uint32 howmany32;
370
371	if (!WRITECHECKTILES(tif, module))
372		return ((tmsize_t)(-1));
373	td = &tif->tif_dir;
374	if (tile >= td->td_nstrips) {
375		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
376		    (unsigned long) tile, (unsigned long) td->td_nstrips);
377		return ((tmsize_t)(-1));
378	}
379	/*
380	 * Handle delayed allocation of data buffer.  This
381	 * permits it to be sized more intelligently (using
382	 * directory information).
383	 */
384	if (!BUFFERCHECK(tif))
385		return ((tmsize_t)(-1));
386
387        tif->tif_flags |= TIFF_BUF4WRITE;
388	tif->tif_curtile = tile;
389
390	if( td->td_stripbytecount[tile] > 0 )
391        {
392            /* Make sure that at the first attempt of rewriting the tile, we will have */
393            /* more bytes available in the output buffer than the previous byte count, */
394            /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
395            /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
396            if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
397            {
398                if( !(TIFFWriteBufferSetup(tif, NULL,
399                    (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
400                    return ((tmsize_t)(-1));
401            }
402
403	    /* Force TIFFAppendToStrip() to consider placing data at end
404               of file. */
405            tif->tif_curoff = 0;
406        }
407
408	tif->tif_rawcc = 0;
409	tif->tif_rawcp = tif->tif_rawdata;
410
411	/*
412	 * Compute tiles per row & per column to compute
413	 * current row and column
414	 */
415        howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
416        if (howmany32 == 0) {
417                 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
418                return ((tmsize_t)(-1));
419        }
420	tif->tif_row = (tile % howmany32) * td->td_tilelength;
421        howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
422        if (howmany32 == 0) {
423                 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
424                return ((tmsize_t)(-1));
425        }
426	tif->tif_col = (tile % howmany32) * td->td_tilewidth;
427
428	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
429		if (!(*tif->tif_setupencode)(tif))
430			return ((tmsize_t)(-1));
431		tif->tif_flags |= TIFF_CODERSETUP;
432	}
433	tif->tif_flags &= ~TIFF_POSTENCODE;
434	sample = (uint16)(tile/td->td_stripsperimage);
435	if (!(*tif->tif_preencode)(tif, sample))
436		return ((tmsize_t)(-1));
437	/*
438	 * Clamp write amount to the tile size.  This is mostly
439	 * done so that callers can pass in some large number
440	 * (e.g. -1) and have the tile size used instead.
441	 */
442	if ( cc < 1 || cc > tif->tif_tilesize)
443		cc = tif->tif_tilesize;
444
445        /* swab if needed - note that source buffer will be altered */
446	tif->tif_postdecode( tif, (uint8*) data, cc );
447
448	if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
449		return (0);
450	if (!(*tif->tif_postencode)(tif))
451		return ((tmsize_t)(-1));
452	if (!isFillOrder(tif, td->td_fillorder) &&
453	    (tif->tif_flags & TIFF_NOBITREV) == 0)
454		TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
455	if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
456	    tif->tif_rawdata, tif->tif_rawcc))
457		return ((tmsize_t)(-1));
458	tif->tif_rawcc = 0;
459	tif->tif_rawcp = tif->tif_rawdata;
460	return (cc);
461}
462
463/*
464 * Write the supplied data to the specified strip.
465 * There must be space for the data; we don't check
466 * if strips overlap!
467 *
468 * NB: Image length must be setup before writing; this
469 *     interface does not support automatically growing
470 *     the image on each write (as TIFFWriteScanline does).
471 */
472tmsize_t
473TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
474{
475	static const char module[] = "TIFFWriteRawTile";
476
477	if (!WRITECHECKTILES(tif, module))
478		return ((tmsize_t)(-1));
479	if (tile >= tif->tif_dir.td_nstrips) {
480		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
481		    (unsigned long) tile,
482		    (unsigned long) tif->tif_dir.td_nstrips);
483		return ((tmsize_t)(-1));
484	}
485	return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
486	    cc : (tmsize_t)(-1));
487}
488
489#define	isUnspecified(tif, f) \
490    (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
491
492int
493TIFFSetupStrips(TIFF* tif)
494{
495	TIFFDirectory* td = &tif->tif_dir;
496
497	if (isTiled(tif))
498		td->td_stripsperimage =
499		    isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
500			td->td_samplesperpixel : TIFFNumberOfTiles(tif);
501	else
502		td->td_stripsperimage =
503		    isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
504			td->td_samplesperpixel : TIFFNumberOfStrips(tif);
505	td->td_nstrips = td->td_stripsperimage;
506	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
507		td->td_stripsperimage /= td->td_samplesperpixel;
508	td->td_stripoffset = (uint64 *)
509	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
510	td->td_stripbytecount = (uint64 *)
511	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
512	if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
513		return (0);
514	/*
515	 * Place data at the end-of-file
516	 * (by setting offsets to zero).
517	 */
518	_TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
519	_TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
520	TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
521	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
522	return (1);
523}
524#undef isUnspecified
525
526/*
527 * Verify file is writable and that the directory
528 * information is setup properly.  In doing the latter
529 * we also "freeze" the state of the directory so
530 * that important information is not changed.
531 */
532int
533TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
534{
535	if (tif->tif_mode == O_RDONLY) {
536		TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
537		return (0);
538	}
539	if (tiles ^ isTiled(tif)) {
540		TIFFErrorExt(tif->tif_clientdata, module, tiles ?
541		    "Can not write tiles to a stripped image" :
542		    "Can not write scanlines to a tiled image");
543		return (0);
544	}
545
546        _TIFFFillStriles( tif );
547
548	/*
549	 * On the first write verify all the required information
550	 * has been setup and initialize any data structures that
551	 * had to wait until directory information was set.
552	 * Note that a lot of our work is assumed to remain valid
553	 * because we disallow any of the important parameters
554	 * from changing after we start writing (i.e. once
555	 * TIFF_BEENWRITING is set, TIFFSetField will only allow
556	 * the image's length to be changed).
557	 */
558	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
559		TIFFErrorExt(tif->tif_clientdata, module,
560		    "Must set \"ImageWidth\" before writing data");
561		return (0);
562	}
563	if (tif->tif_dir.td_samplesperpixel == 1) {
564		/*
565		 * Planarconfiguration is irrelevant in case of single band
566		 * images and need not be included. We will set it anyway,
567		 * because this field is used in other parts of library even
568		 * in the single band case.
569		 */
570		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
571                    tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
572	} else {
573		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
574			TIFFErrorExt(tif->tif_clientdata, module,
575			    "Must set \"PlanarConfiguration\" before writing data");
576			return (0);
577		}
578	}
579	if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
580		tif->tif_dir.td_nstrips = 0;
581		TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
582		    isTiled(tif) ? "tile" : "strip");
583		return (0);
584	}
585	if (isTiled(tif))
586	{
587		tif->tif_tilesize = TIFFTileSize(tif);
588		if (tif->tif_tilesize == 0)
589			return (0);
590	}
591	else
592		tif->tif_tilesize = (tmsize_t)(-1);
593	tif->tif_scanlinesize = TIFFScanlineSize(tif);
594	if (tif->tif_scanlinesize == 0)
595		return (0);
596	tif->tif_flags |= TIFF_BEENWRITING;
597	return (1);
598}
599
600/*
601 * Setup the raw data buffer used for encoding.
602 */
603int
604TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
605{
606	static const char module[] = "TIFFWriteBufferSetup";
607
608	if (tif->tif_rawdata) {
609		if (tif->tif_flags & TIFF_MYBUFFER) {
610			_TIFFfree(tif->tif_rawdata);
611			tif->tif_flags &= ~TIFF_MYBUFFER;
612		}
613		tif->tif_rawdata = NULL;
614	}
615	if (size == (tmsize_t)(-1)) {
616		size = (isTiled(tif) ?
617		    tif->tif_tilesize : TIFFStripSize(tif));
618		/*
619		 * Make raw data buffer at least 8K
620		 */
621		if (size < 8*1024)
622			size = 8*1024;
623		bp = NULL;			/* NB: force malloc */
624	}
625	if (bp == NULL) {
626		bp = _TIFFmalloc(size);
627		if (bp == NULL) {
628			TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
629			return (0);
630		}
631		tif->tif_flags |= TIFF_MYBUFFER;
632	} else
633		tif->tif_flags &= ~TIFF_MYBUFFER;
634	tif->tif_rawdata = (uint8*) bp;
635	tif->tif_rawdatasize = size;
636	tif->tif_rawcc = 0;
637	tif->tif_rawcp = tif->tif_rawdata;
638	tif->tif_flags |= TIFF_BUFFERSETUP;
639	return (1);
640}
641
642/*
643 * Grow the strip data structures by delta strips.
644 */
645static int
646TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
647{
648	TIFFDirectory *td = &tif->tif_dir;
649	uint64* new_stripoffset;
650	uint64* new_stripbytecount;
651
652	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
653	new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
654		(td->td_nstrips + delta) * sizeof (uint64));
655	new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
656		(td->td_nstrips + delta) * sizeof (uint64));
657	if (new_stripoffset == NULL || new_stripbytecount == NULL) {
658		if (new_stripoffset)
659			_TIFFfree(new_stripoffset);
660		if (new_stripbytecount)
661			_TIFFfree(new_stripbytecount);
662		td->td_nstrips = 0;
663		TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
664		return (0);
665	}
666	td->td_stripoffset = new_stripoffset;
667	td->td_stripbytecount = new_stripbytecount;
668	_TIFFmemset(td->td_stripoffset + td->td_nstrips,
669		    0, delta*sizeof (uint64));
670	_TIFFmemset(td->td_stripbytecount + td->td_nstrips,
671		    0, delta*sizeof (uint64));
672	td->td_nstrips += delta;
673        tif->tif_flags |= TIFF_DIRTYDIRECT;
674
675	return (1);
676}
677
678/*
679 * Append the data to the specified strip.
680 */
681static int
682TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
683{
684	static const char module[] = "TIFFAppendToStrip";
685	TIFFDirectory *td = &tif->tif_dir;
686	uint64 m;
687        int64 old_byte_count = -1;
688
689	if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
690            assert(td->td_nstrips > 0);
691
692            if( td->td_stripbytecount[strip] != 0
693                && td->td_stripoffset[strip] != 0
694                && td->td_stripbytecount[strip] >= (uint64) cc )
695            {
696                /*
697                 * There is already tile data on disk, and the new tile
698                 * data we have will fit in the same space.  The only
699                 * aspect of this that is risky is that there could be
700                 * more data to append to this strip before we are done
701                 * depending on how we are getting called.
702                 */
703                if (!SeekOK(tif, td->td_stripoffset[strip])) {
704                    TIFFErrorExt(tif->tif_clientdata, module,
705                                 "Seek error at scanline %lu",
706                                 (unsigned long)tif->tif_row);
707                    return (0);
708                }
709            }
710            else
711            {
712                /*
713                 * Seek to end of file, and set that as our location to
714                 * write this strip.
715                 */
716                td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
717                tif->tif_flags |= TIFF_DIRTYSTRIP;
718            }
719
720            tif->tif_curoff = td->td_stripoffset[strip];
721
722            /*
723             * We are starting a fresh strip/tile, so set the size to zero.
724             */
725            old_byte_count = td->td_stripbytecount[strip];
726            td->td_stripbytecount[strip] = 0;
727	}
728
729	m = tif->tif_curoff+cc;
730	if (!(tif->tif_flags&TIFF_BIGTIFF))
731		m = (uint32)m;
732	if ((m<tif->tif_curoff)||(m<(uint64)cc))
733	{
734		TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
735		return (0);
736	}
737	if (!WriteOK(tif, data, cc)) {
738		TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
739		    (unsigned long) tif->tif_row);
740		    return (0);
741	}
742	tif->tif_curoff = m;
743	td->td_stripbytecount[strip] += cc;
744
745        if( (int64) td->td_stripbytecount[strip] != old_byte_count )
746            tif->tif_flags |= TIFF_DIRTYSTRIP;
747
748	return (1);
749}
750
751/*
752 * Internal version of TIFFFlushData that can be
753 * called by ``encodestrip routines'' w/o concern
754 * for infinite recursion.
755 */
756int
757TIFFFlushData1(TIFF* tif)
758{
759	if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
760		if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
761		    (tif->tif_flags & TIFF_NOBITREV) == 0)
762			TIFFReverseBits((uint8*)tif->tif_rawdata,
763			    tif->tif_rawcc);
764		if (!TIFFAppendToStrip(tif,
765		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
766		    tif->tif_rawdata, tif->tif_rawcc))
767			return (0);
768		tif->tif_rawcc = 0;
769		tif->tif_rawcp = tif->tif_rawdata;
770	}
771	return (1);
772}
773
774/*
775 * Set the current write offset.  This should only be
776 * used to set the offset to a known previous location
777 * (very carefully), or to 0 so that the next write gets
778 * appended to the end of the file.
779 */
780void
781TIFFSetWriteOffset(TIFF* tif, toff_t off)
782{
783	tif->tif_curoff = off;
784}
785
786/* vim: set ts=8 sts=8 sw=8 noet: */
787/*
788 * Local Variables:
789 * mode: c
790 * c-basic-offset: 8
791 * fill-column: 78
792 * End:
793 */
794