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 "tiffiop.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 
43 static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
44 static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
45 
46 int
TIFFWriteScanline(TIFF * tif,void * buf,uint32 row,uint16 sample)47 TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
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 */
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);
75 		}
76 		td->td_imagelength = row+1;
77 		imagegrew = 1;
78 	}
79 	/*
80 	 * Calculate strip and check for crossings.
81 	 */
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);
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)
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);
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);
125 			tif->tif_flags |= TIFF_CODERSETUP;
126 		}
127 
128 		tif->tif_rawcc = 0;
129 		tif->tif_rawcp = tif->tif_rawdata;
130 
131 		if( td->td_stripbytecount[strip] > 0 )
132 		{
133 			/* if we are writing over existing tiles, zero length */
134 			td->td_stripbytecount[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);
142 		tif->tif_flags |= TIFF_POSTENCODE;
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 /*
180  * Encode the supplied data and write it to the
181  * specified strip.
182  *
183  * NB: Image length must be setup before writing.
184  */
185 tmsize_t
TIFFWriteEncodedStrip(TIFF * tif,uint32 strip,void * data,tmsize_t cc)186 TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
187 {
188 	static const char module[] = "TIFFWriteEncodedStrip";
189 	TIFFDirectory *td = &tif->tif_dir;
190 	uint16 sample;
191 
192 	if (!WRITECHECKSTRIPS(tif, module))
193 		return ((tmsize_t) -1);
194 	/*
195 	 * Check strip array to make sure there's space.
196 	 * We don't support dynamically growing files that
197 	 * have data organized in separate bitplanes because
198 	 * it's too painful.  In that case we require that
199 	 * the imagelength be set properly before the first
200 	 * write (so that the strips array will be fully
201 	 * allocated above).
202 	 */
203 	if (strip >= td->td_nstrips) {
204 		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
205 			TIFFErrorExt(tif->tif_clientdata, module,
206 			    "Can not grow image by strips when using separate planes");
207 			return ((tmsize_t) -1);
208 		}
209 		if (!TIFFGrowStrips(tif, 1, module))
210 			return ((tmsize_t) -1);
211 		td->td_stripsperimage =
212 		    TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
213 	}
214 	/*
215 	 * Handle delayed allocation of data buffer.  This
216 	 * permits it to be sized according to the directory
217 	 * info.
218 	 */
219 	if (!BUFFERCHECK(tif))
220 		return ((tmsize_t) -1);
221 
222         tif->tif_flags |= TIFF_BUF4WRITE;
223 	tif->tif_curstrip = strip;
224 
225         if (td->td_stripsperimage == 0) {
226                 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
227                 return ((tmsize_t) -1);
228         }
229 
230 	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
231 	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
232 		if (!(*tif->tif_setupencode)(tif))
233 			return ((tmsize_t) -1);
234 		tif->tif_flags |= TIFF_CODERSETUP;
235 	}
236 
237 	if( td->td_stripbytecount[strip] > 0 )
238         {
239             /* Make sure that at the first attempt of rewriting the tile, we will have */
240             /* more bytes available in the output buffer than the previous byte count, */
241             /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
242             /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
243             if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
244             {
245                 if( !(TIFFWriteBufferSetup(tif, NULL,
246                     (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
247                     return ((tmsize_t)(-1));
248             }
249 
250 	    /* Force TIFFAppendToStrip() to consider placing data at end
251                of file. */
252             tif->tif_curoff = 0;
253         }
254 
255     tif->tif_rawcc = 0;
256     tif->tif_rawcp = tif->tif_rawdata;
257 
258 	tif->tif_flags &= ~TIFF_POSTENCODE;
259 
260     /* shortcut to avoid an extra memcpy() */
261     if( td->td_compression == COMPRESSION_NONE )
262     {
263         /* swab if needed - note that source buffer will be altered */
264         tif->tif_postdecode( tif, (uint8*) data, cc );
265 
266         if (!isFillOrder(tif, td->td_fillorder) &&
267             (tif->tif_flags & TIFF_NOBITREV) == 0)
268             TIFFReverseBits((uint8*) data, cc);
269 
270         if (cc > 0 &&
271             !TIFFAppendToStrip(tif, strip, (uint8*) data, cc))
272             return ((tmsize_t) -1);
273         return (cc);
274     }
275 
276 	sample = (uint16)(strip / td->td_stripsperimage);
277 	if (!(*tif->tif_preencode)(tif, sample))
278 		return ((tmsize_t) -1);
279 
280         /* swab if needed - note that source buffer will be altered */
281 	tif->tif_postdecode( tif, (uint8*) data, cc );
282 
283 	if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
284 		return ((tmsize_t) -1);
285 	if (!(*tif->tif_postencode)(tif))
286 		return ((tmsize_t) -1);
287 	if (!isFillOrder(tif, td->td_fillorder) &&
288 	    (tif->tif_flags & TIFF_NOBITREV) == 0)
289 		TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
290 	if (tif->tif_rawcc > 0 &&
291 	    !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
292 		return ((tmsize_t) -1);
293 	tif->tif_rawcc = 0;
294 	tif->tif_rawcp = tif->tif_rawdata;
295 	return (cc);
296 }
297 
298 /*
299  * Write the supplied data to the specified strip.
300  *
301  * NB: Image length must be setup before writing.
302  */
303 tmsize_t
TIFFWriteRawStrip(TIFF * tif,uint32 strip,void * data,tmsize_t cc)304 TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
305 {
306 	static const char module[] = "TIFFWriteRawStrip";
307 	TIFFDirectory *td = &tif->tif_dir;
308 
309 	if (!WRITECHECKSTRIPS(tif, module))
310 		return ((tmsize_t) -1);
311 	/*
312 	 * Check strip array to make sure there's space.
313 	 * We don't support dynamically growing files that
314 	 * have data organized in separate bitplanes because
315 	 * it's too painful.  In that case we require that
316 	 * the imagelength be set properly before the first
317 	 * write (so that the strips array will be fully
318 	 * allocated above).
319 	 */
320 	if (strip >= td->td_nstrips) {
321 		if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
322 			TIFFErrorExt(tif->tif_clientdata, module,
323 			    "Can not grow image by strips when using separate planes");
324 			return ((tmsize_t) -1);
325 		}
326 		/*
327 		 * Watch out for a growing image.  The value of
328 		 * strips/image will initially be 1 (since it
329 		 * can't be deduced until the imagelength is known).
330 		 */
331 		if (strip >= td->td_stripsperimage)
332 			td->td_stripsperimage =
333 			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
334 		if (!TIFFGrowStrips(tif, 1, module))
335 			return ((tmsize_t) -1);
336 	}
337 	tif->tif_curstrip = strip;
338         if (td->td_stripsperimage == 0) {
339                 TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image");
340                 return ((tmsize_t) -1);
341         }
342 	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
343 	return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
344 	    cc : (tmsize_t) -1);
345 }
346 
347 /*
348  * Write and compress a tile of data.  The
349  * tile is selected by the (x,y,z,s) coordinates.
350  */
351 tmsize_t
TIFFWriteTile(TIFF * tif,void * buf,uint32 x,uint32 y,uint32 z,uint16 s)352 TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
353 {
354 	if (!TIFFCheckTile(tif, x, y, z, s))
355 		return ((tmsize_t)(-1));
356 	/*
357 	 * NB: A tile size of -1 is used instead of tif_tilesize knowing
358 	 *     that TIFFWriteEncodedTile will clamp this to the tile size.
359 	 *     This is done because the tile size may not be defined until
360 	 *     after the output buffer is setup in TIFFWriteBufferSetup.
361 	 */
362 	return (TIFFWriteEncodedTile(tif,
363 	    TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
364 }
365 
366 /*
367  * Encode the supplied data and write it to the
368  * specified tile.  There must be space for the
369  * data.  The function clamps individual writes
370  * to a tile to the tile size, but does not (and
371  * can not) check that multiple writes to the same
372  * tile do not write more than tile size data.
373  *
374  * NB: Image length must be setup before writing; this
375  *     interface does not support automatically growing
376  *     the image on each write (as TIFFWriteScanline does).
377  */
378 tmsize_t
TIFFWriteEncodedTile(TIFF * tif,uint32 tile,void * data,tmsize_t cc)379 TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
380 {
381 	static const char module[] = "TIFFWriteEncodedTile";
382 	TIFFDirectory *td;
383 	uint16 sample;
384         uint32 howmany32;
385 
386 	if (!WRITECHECKTILES(tif, module))
387 		return ((tmsize_t)(-1));
388 	td = &tif->tif_dir;
389 	if (tile >= td->td_nstrips) {
390 		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
391 		    (unsigned long) tile, (unsigned long) td->td_nstrips);
392 		return ((tmsize_t)(-1));
393 	}
394 	/*
395 	 * Handle delayed allocation of data buffer.  This
396 	 * permits it to be sized more intelligently (using
397 	 * directory information).
398 	 */
399 	if (!BUFFERCHECK(tif))
400 		return ((tmsize_t)(-1));
401 
402         tif->tif_flags |= TIFF_BUF4WRITE;
403 	tif->tif_curtile = tile;
404 
405 	if( td->td_stripbytecount[tile] > 0 )
406         {
407             /* Make sure that at the first attempt of rewriting the tile, we will have */
408             /* more bytes available in the output buffer than the previous byte count, */
409             /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
410             /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
411             if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
412             {
413                 if( !(TIFFWriteBufferSetup(tif, NULL,
414                     (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
415                     return ((tmsize_t)(-1));
416             }
417 
418 	    /* Force TIFFAppendToStrip() to consider placing data at end
419                of file. */
420             tif->tif_curoff = 0;
421         }
422 
423 	tif->tif_rawcc = 0;
424 	tif->tif_rawcp = tif->tif_rawdata;
425 
426 	/*
427 	 * Compute tiles per row & per column to compute
428 	 * current row and column
429 	 */
430         howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
431         if (howmany32 == 0) {
432                  TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
433                 return ((tmsize_t)(-1));
434         }
435 	tif->tif_row = (tile % howmany32) * td->td_tilelength;
436         howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
437         if (howmany32 == 0) {
438                  TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
439                 return ((tmsize_t)(-1));
440         }
441 	tif->tif_col = (tile % howmany32) * td->td_tilewidth;
442 
443 	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
444 		if (!(*tif->tif_setupencode)(tif))
445 			return ((tmsize_t)(-1));
446 		tif->tif_flags |= TIFF_CODERSETUP;
447 	}
448 	tif->tif_flags &= ~TIFF_POSTENCODE;
449 
450 	/*
451 	 * Clamp write amount to the tile size.  This is mostly
452 	 * done so that callers can pass in some large number
453 	 * (e.g. -1) and have the tile size used instead.
454 	 */
455 	if ( cc < 1 || cc > tif->tif_tilesize)
456 		cc = tif->tif_tilesize;
457 
458     /* shortcut to avoid an extra memcpy() */
459     if( td->td_compression == COMPRESSION_NONE )
460     {
461         /* swab if needed - note that source buffer will be altered */
462         tif->tif_postdecode( tif, (uint8*) data, cc );
463 
464         if (!isFillOrder(tif, td->td_fillorder) &&
465             (tif->tif_flags & TIFF_NOBITREV) == 0)
466             TIFFReverseBits((uint8*) data, cc);
467 
468         if (cc > 0 &&
469             !TIFFAppendToStrip(tif, tile, (uint8*) data, cc))
470             return ((tmsize_t) -1);
471         return (cc);
472     }
473 
474     sample = (uint16)(tile/td->td_stripsperimage);
475     if (!(*tif->tif_preencode)(tif, sample))
476         return ((tmsize_t)(-1));
477     /* swab if needed - note that source buffer will be altered */
478     tif->tif_postdecode( tif, (uint8*) data, cc );
479 
480     if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
481             return ((tmsize_t) -1);
482     if (!(*tif->tif_postencode)(tif))
483             return ((tmsize_t)(-1));
484     if (!isFillOrder(tif, td->td_fillorder) &&
485         (tif->tif_flags & TIFF_NOBITREV) == 0)
486             TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
487     if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
488         tif->tif_rawdata, tif->tif_rawcc))
489             return ((tmsize_t)(-1));
490     tif->tif_rawcc = 0;
491     tif->tif_rawcp = tif->tif_rawdata;
492     return (cc);
493 }
494 
495 /*
496  * Write the supplied data to the specified strip.
497  * There must be space for the data; we don't check
498  * if strips overlap!
499  *
500  * NB: Image length must be setup before writing; this
501  *     interface does not support automatically growing
502  *     the image on each write (as TIFFWriteScanline does).
503  */
504 tmsize_t
TIFFWriteRawTile(TIFF * tif,uint32 tile,void * data,tmsize_t cc)505 TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
506 {
507 	static const char module[] = "TIFFWriteRawTile";
508 
509 	if (!WRITECHECKTILES(tif, module))
510 		return ((tmsize_t)(-1));
511 	if (tile >= tif->tif_dir.td_nstrips) {
512 		TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
513 		    (unsigned long) tile,
514 		    (unsigned long) tif->tif_dir.td_nstrips);
515 		return ((tmsize_t)(-1));
516 	}
517 	return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
518 	    cc : (tmsize_t)(-1));
519 }
520 
521 #define	isUnspecified(tif, f) \
522     (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
523 
524 int
TIFFSetupStrips(TIFF * tif)525 TIFFSetupStrips(TIFF* tif)
526 {
527 	TIFFDirectory* td = &tif->tif_dir;
528 
529 	if (isTiled(tif))
530 		td->td_stripsperimage =
531 		    isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
532 			td->td_samplesperpixel : TIFFNumberOfTiles(tif);
533 	else
534 		td->td_stripsperimage =
535 		    isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
536 			td->td_samplesperpixel : TIFFNumberOfStrips(tif);
537 	td->td_nstrips = td->td_stripsperimage;
538 	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
539 		td->td_stripsperimage /= td->td_samplesperpixel;
540 	td->td_stripoffset = (uint64 *)
541 	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
542 	td->td_stripbytecount = (uint64 *)
543 	    _TIFFmalloc(td->td_nstrips * sizeof (uint64));
544 	if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
545 		return (0);
546 	/*
547 	 * Place data at the end-of-file
548 	 * (by setting offsets to zero).
549 	 */
550 	_TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
551 	_TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
552 	TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
553 	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
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  */
564 int
TIFFWriteCheck(TIFF * tif,int tiles,const char * module)565 TIFFWriteCheck(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 stripped 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 	 */
590 	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
591 		TIFFErrorExt(tif->tif_clientdata, module,
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 		 */
602 		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
603                     tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
604 	} else {
605 		if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
606 			TIFFErrorExt(tif->tif_clientdata, module,
607 			    "Must set \"PlanarConfiguration\" before writing data");
608 			return (0);
609 		}
610 	}
611 	if (tif->tif_dir.td_stripoffset == 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);
625 	tif->tif_scanlinesize = TIFFScanlineSize(tif);
626 	if (tif->tif_scanlinesize == 0)
627 		return (0);
628 	tif->tif_flags |= TIFF_BEENWRITING;
629 	return (1);
630 }
631 
632 /*
633  * Setup the raw data buffer used for encoding.
634  */
635 int
TIFFWriteBufferSetup(TIFF * tif,void * bp,tmsize_t size)636 TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
637 {
638 	static const char module[] = "TIFFWriteBufferSetup";
639 
640 	if (tif->tif_rawdata) {
641 		if (tif->tif_flags & TIFF_MYBUFFER) {
642 			_TIFFfree(tif->tif_rawdata);
643 			tif->tif_flags &= ~TIFF_MYBUFFER;
644 		}
645 		tif->tif_rawdata = NULL;
646 	}
647 	if (size == (tmsize_t)(-1)) {
648 		size = (isTiled(tif) ?
649 		    tif->tif_tilesize : TIFFStripSize(tif));
650 		/*
651 		 * Make raw data buffer at least 8K
652 		 */
653 		if (size < 8*1024)
654 			size = 8*1024;
655 		bp = NULL;			/* NB: force malloc */
656 	}
657 	if (bp == NULL) {
658 		bp = _TIFFmalloc(size);
659 		if (bp == NULL) {
660 			TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
661 			return (0);
662 		}
663 		tif->tif_flags |= TIFF_MYBUFFER;
664 	} else
665 		tif->tif_flags &= ~TIFF_MYBUFFER;
666 	tif->tif_rawdata = (uint8*) bp;
667 	tif->tif_rawdatasize = size;
668 	tif->tif_rawcc = 0;
669 	tif->tif_rawcp = tif->tif_rawdata;
670 	tif->tif_flags |= TIFF_BUFFERSETUP;
671 	return (1);
672 }
673 
674 /*
675  * Grow the strip data structures by delta strips.
676  */
677 static int
TIFFGrowStrips(TIFF * tif,uint32 delta,const char * module)678 TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
679 {
680 	TIFFDirectory *td = &tif->tif_dir;
681 	uint64* new_stripoffset;
682 	uint64* new_stripbytecount;
683 
684 	assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
685 	new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
686 		(td->td_nstrips + delta) * sizeof (uint64));
687 	new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
688 		(td->td_nstrips + delta) * sizeof (uint64));
689 	if (new_stripoffset == NULL || new_stripbytecount == NULL) {
690 		if (new_stripoffset)
691 			_TIFFfree(new_stripoffset);
692 		if (new_stripbytecount)
693 			_TIFFfree(new_stripbytecount);
694 		td->td_nstrips = 0;
695 		TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
696 		return (0);
697 	}
698 	td->td_stripoffset = new_stripoffset;
699 	td->td_stripbytecount = new_stripbytecount;
700 	_TIFFmemset(td->td_stripoffset + td->td_nstrips,
701 		    0, delta*sizeof (uint64));
702 	_TIFFmemset(td->td_stripbytecount + td->td_nstrips,
703 		    0, delta*sizeof (uint64));
704 	td->td_nstrips += delta;
705         tif->tif_flags |= TIFF_DIRTYDIRECT;
706 
707 	return (1);
708 }
709 
710 /*
711  * Append the data to the specified strip.
712  */
713 static int
TIFFAppendToStrip(TIFF * tif,uint32 strip,uint8 * data,tmsize_t cc)714 TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
715 {
716 	static const char module[] = "TIFFAppendToStrip";
717 	TIFFDirectory *td = &tif->tif_dir;
718 	uint64 m;
719         int64 old_byte_count = -1;
720 
721 	if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
722             assert(td->td_nstrips > 0);
723 
724             if( td->td_stripbytecount[strip] != 0
725                 && td->td_stripoffset[strip] != 0
726                 && td->td_stripbytecount[strip] >= (uint64) cc )
727             {
728                 /*
729                  * There is already tile data on disk, and the new tile
730                  * data we have will fit in the same space.  The only
731                  * aspect of this that is risky is that there could be
732                  * more data to append to this strip before we are done
733                  * depending on how we are getting called.
734                  */
735                 if (!SeekOK(tif, td->td_stripoffset[strip])) {
736                     TIFFErrorExt(tif->tif_clientdata, module,
737                                  "Seek error at scanline %lu",
738                                  (unsigned long)tif->tif_row);
739                     return (0);
740                 }
741             }
742             else
743             {
744                 /*
745                  * Seek to end of file, and set that as our location to
746                  * write this strip.
747                  */
748                 td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
749                 tif->tif_flags |= TIFF_DIRTYSTRIP;
750             }
751 
752             tif->tif_curoff = td->td_stripoffset[strip];
753 
754             /*
755              * We are starting a fresh strip/tile, so set the size to zero.
756              */
757             old_byte_count = td->td_stripbytecount[strip];
758             td->td_stripbytecount[strip] = 0;
759 	}
760 
761 	m = tif->tif_curoff+cc;
762 	if (!(tif->tif_flags&TIFF_BIGTIFF))
763 		m = (uint32)m;
764 	if ((m<tif->tif_curoff)||(m<(uint64)cc))
765 	{
766 		TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
767 		return (0);
768 	}
769 	if (!WriteOK(tif, data, cc)) {
770 		TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
771 		    (unsigned long) tif->tif_row);
772 		    return (0);
773 	}
774 	tif->tif_curoff = m;
775 	td->td_stripbytecount[strip] += cc;
776 
777         if( (int64) td->td_stripbytecount[strip] != old_byte_count )
778             tif->tif_flags |= TIFF_DIRTYSTRIP;
779 
780 	return (1);
781 }
782 
783 /*
784  * Internal version of TIFFFlushData that can be
785  * called by ``encodestrip routines'' w/o concern
786  * for infinite recursion.
787  */
788 int
TIFFFlushData1(TIFF * tif)789 TIFFFlushData1(TIFF* tif)
790 {
791 	if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
792 		if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
793 		    (tif->tif_flags & TIFF_NOBITREV) == 0)
794 			TIFFReverseBits((uint8*)tif->tif_rawdata,
795 			    tif->tif_rawcc);
796 		if (!TIFFAppendToStrip(tif,
797 		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
798 		    tif->tif_rawdata, tif->tif_rawcc))
799         {
800             /* We update those variables even in case of error since there's */
801             /* code that doesn't really check the return code of this */
802             /* function */
803             tif->tif_rawcc = 0;
804             tif->tif_rawcp = tif->tif_rawdata;
805 			return (0);
806         }
807 		tif->tif_rawcc = 0;
808 		tif->tif_rawcp = tif->tif_rawdata;
809 	}
810 	return (1);
811 }
812 
813 /*
814  * Set the current write offset.  This should only be
815  * used to set the offset to a known previous location
816  * (very carefully), or to 0 so that the next write gets
817  * appended to the end of the file.
818  */
819 void
TIFFSetWriteOffset(TIFF * tif,toff_t off)820 TIFFSetWriteOffset(TIFF* tif, toff_t off)
821 {
822 	tif->tif_curoff = off;
823 }
824 
825 /* vim: set ts=8 sts=8 sw=8 noet: */
826 /*
827  * Local Variables:
828  * mode: c
829  * c-basic-offset: 8
830  * fill-column: 78
831  * End:
832  */
833