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_t delta, const char* module);
44 static int TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc);
45 
46 int
TIFFWriteScanline(TIFF * tif,void * buf,uint32_t row,uint16_t sample)47 TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample)
48 {
49 	static const char module[] = "TIFFWriteScanline";
50 	register TIFFDirectory *td;
51 	int status, imagegrew = 0;
52 	uint32_t 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_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);
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_t*) buf, tif->tif_scanlinesize );
170 
171 	status = (*tif->tif_encoderow)(tif, (uint8_t*) 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) */
_TIFFReserveLargeEnoughWriteBuffer(TIFF * tif,uint32_t strip_or_tile)183 static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t 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_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 )
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  */
211 tmsize_t
TIFFWriteEncodedStrip(TIFF * tif,uint32_t strip,void * data,tmsize_t cc)212 TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
213 {
214 	static const char module[] = "TIFFWriteEncodedStrip";
215 	TIFFDirectory *td = &tif->tif_dir;
216 	uint16_t 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) {
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);
234 		}
235 		if (!TIFFGrowStrips(tif, 1, module))
236 			return ((tmsize_t) -1);
237 		td->td_stripsperimage =
238 		    TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
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 
248         tif->tif_flags |= TIFF_BUF4WRITE;
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);
267 		tif->tif_flags |= TIFF_CODERSETUP;
268 	}
269 
270 	tif->tif_flags &= ~TIFF_POSTENCODE;
271 
272     /* shortcut to avoid an extra memcpy() */
273     if( td->td_compression == COMPRESSION_NONE )
274     {
275         /* swab if needed - note that source buffer will be altered */
276         tif->tif_postdecode(tif, (uint8_t*) data, cc );
277 
278         if (!isFillOrder(tif, td->td_fillorder) &&
279             (tif->tif_flags & TIFF_NOBITREV) == 0)
280             TIFFReverseBits((uint8_t*) data, cc);
281 
282         if (cc > 0 &&
283             !TIFFAppendToStrip(tif, strip, (uint8_t*) data, cc))
284             return ((tmsize_t) -1);
285         return (cc);
286     }
287 
288 	sample = (uint16_t)(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_t*) data, cc );
294 
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);
308 }
309 
310 /*
311  * Write the supplied data to the specified strip.
312  *
313  * NB: Image length must be setup before writing.
314  */
315 tmsize_t
TIFFWriteRawStrip(TIFF * tif,uint32_t strip,void * data,tmsize_t cc)316 TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc)
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) {
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);
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)
344 			td->td_stripsperimage =
345 			    TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
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_t*) 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  */
363 tmsize_t
TIFFWriteTile(TIFF * tif,void * buf,uint32_t x,uint32_t y,uint32_t z,uint16_t s)364 TIFFWriteTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t s)
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  */
390 tmsize_t
TIFFWriteEncodedTile(TIFF * tif,uint32_t tile,void * data,tmsize_t cc)391 TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
392 {
393 	static const char module[] = "TIFFWriteEncodedTile";
394 	TIFFDirectory *td;
395 	uint16_t sample;
396         uint32_t 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 
414         tif->tif_flags |= TIFF_BUF4WRITE;
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));
444 		tif->tif_flags |= TIFF_CODERSETUP;
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() */
457     if( td->td_compression == COMPRESSION_NONE )
458     {
459         /* swab if needed - note that source buffer will be altered */
460         tif->tif_postdecode(tif, (uint8_t*) data, cc );
461 
462         if (!isFillOrder(tif, td->td_fillorder) &&
463             (tif->tif_flags & TIFF_NOBITREV) == 0)
464             TIFFReverseBits((uint8_t*) data, cc);
465 
466         if (cc > 0 &&
467             !TIFFAppendToStrip(tif, tile, (uint8_t*) data, cc))
468             return ((tmsize_t) -1);
469         return (cc);
470     }
471 
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 );
477 
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);
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  */
502 tmsize_t
TIFFWriteRawTile(TIFF * tif,uint32_t tile,void * data,tmsize_t cc)503 TIFFWriteRawTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc)
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_t*) 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 
522 int
TIFFSetupStrips(TIFF * tif)523 TIFFSetupStrips(TIFF* tif)
524 {
525 	TIFFDirectory* td = &tif->tif_dir;
526 
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) )
538         {
539             TIFFErrorExt(tif->tif_clientdata, "TIFFSetupStrips",
540                          "Too large Strip/Tile Offsets/ByteCounts arrays");
541             return 0;
542         }
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);
553 	/*
554 	 * Place data at the end-of-file
555 	 * (by setting offsets to zero).
556 	 */
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);
562 }
563 #undef isUnspecified
564 
565 /*
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.
570  */
571 int
TIFFWriteCheck(TIFF * tif,int tiles,const char * module)572 TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
573 {
574 	if (tif->tif_mode == O_RDONLY) {
575 		TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
576 		return (0);
577 	}
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);
583 	}
584 
585         _TIFFFillStriles( tif );
586 
587 	/*
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).
596 	 */
597 	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
598 		TIFFErrorExt(tif->tif_clientdata, module,
599 		    "Must set \"ImageWidth\" before writing data");
600 		return (0);
601 	}
602 	if (tif->tif_dir.td_samplesperpixel == 1) {
603 		/*
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.
608 		 */
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);
616 		}
617 	}
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);
623 	}
624 	if (isTiled(tif))
625 	{
626 		tif->tif_tilesize = TIFFTileSize(tif);
627 		if (tif->tif_tilesize == 0)
628 			return (0);
629 	}
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;
636 
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)  )
646         {
647             TIFFForceStrileArrayWriting(tif);
648         }
649 
650 	return (1);
651 }
652 
653 /*
654  * Setup the raw data buffer used for encoding.
655  */
656 int
TIFFWriteBufferSetup(TIFF * tif,void * bp,tmsize_t size)657 TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
658 {
659 	static const char module[] = "TIFFWriteBufferSetup";
660 
661 	if (tif->tif_rawdata) {
662 		if (tif->tif_flags & TIFF_MYBUFFER) {
663 			_TIFFfree(tif->tif_rawdata);
664 			tif->tif_flags &= ~TIFF_MYBUFFER;
665 		}
666 		tif->tif_rawdata = NULL;
667 	}
668 	if (size == (tmsize_t)(-1)) {
669 		size = (isTiled(tif) ?
670 		    tif->tif_tilesize : TIFFStripSize(tif));
671 
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;
675 		/*
676 		 * Make raw data buffer at least 8K
677 		 */
678 		if (size < 8*1024)
679 			size = 8*1024;
680 		bp = NULL;			/* NB: force malloc */
681 	}
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);
687 		}
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);
697 }
698 
699 /*
700  * Grow the strip data structures by delta strips.
701  */
702 static int
TIFFGrowStrips(TIFF * tif,uint32_t delta,const char * module)703 TIFFGrowStrips(TIFF* tif, uint32_t delta, const char* module)
704 {
705 	TIFFDirectory *td = &tif->tif_dir;
706 	uint64_t* new_stripoffset;
707 	uint64_t* new_stripbytecount;
708 
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);
722 	}
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;
731 
732 	return (1);
733 }
734 
735 /*
736  * Append the data to the specified strip.
737  */
738 static int
TIFFAppendToStrip(TIFF * tif,uint32_t strip,uint8_t * data,tmsize_t cc)739 TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc)
740 {
741 	static const char module[] = "TIFFAppendToStrip";
742 	TIFFDirectory *td = &tif->tif_dir;
743 	uint64_t m;
744     int64_t old_byte_count = -1;
745 
746     if( tif->tif_curoff == 0 )
747         tif->tif_lastvalidoff = 0;
748 
749     if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) {
750             assert(td->td_nstrips > 0);
751 
752             if( td->td_stripbytecount_p[strip] != 0
753                 && td->td_stripoffset_p[strip] != 0
754                 && td->td_stripbytecount_p[strip] >= (uint64_t) cc )
755             {
756                 /*
757                  * There is already tile data on disk, and the new tile
758                  * data we have will fit in the same space.  The only
759                  * aspect of this that is risky is that there could be
760                  * more data to append to this strip before we are done
761                  * depending on how we are getting called.
762                  */
763                 if (!SeekOK(tif, td->td_stripoffset_p[strip])) {
764                     TIFFErrorExt(tif->tif_clientdata, module,
765                                  "Seek error at scanline %lu",
766                                  (unsigned long)tif->tif_row);
767                     return (0);
768                 }
769 
770                 tif->tif_lastvalidoff = td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
771             }
772             else
773             {
774                 /*
775                  * Seek to end of file, and set that as our location to
776                  * write this strip.
777                  */
778                 td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
779                 tif->tif_flags |= TIFF_DIRTYSTRIP;
780             }
781 
782             tif->tif_curoff = td->td_stripoffset_p[strip];
783 
784             /*
785              * We are starting a fresh strip/tile, so set the size to zero.
786              */
787             old_byte_count = td->td_stripbytecount_p[strip];
788             td->td_stripbytecount_p[strip] = 0;
789 	}
790 
791 	m = tif->tif_curoff+cc;
792 	if (!(tif->tif_flags&TIFF_BIGTIFF))
793 		m = (uint32_t)m;
794 	if ((m<tif->tif_curoff)||(m<(uint64_t)cc))
795 	{
796 		TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
797 		return (0);
798 	}
799 
800     if( tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff )
801     {
802         /* Ouch: we have detected that we are rewriting in place a strip/tile */
803         /* with several calls to TIFFAppendToStrip(). The first call was with */
804         /* a size smaller than the previous size of the strip/tile, so we */
805         /* opted to rewrite in place, but a following call causes us to go */
806         /* outsize of the strip/tile area, so we have to finally go for a */
807         /* append-at-end-of-file strategy, and start by moving what we already */
808         /* wrote. */
809         tmsize_t tempSize;
810         void* temp;
811         uint64_t offsetRead;
812         uint64_t offsetWrite;
813         uint64_t toCopy = td->td_stripbytecount_p[strip];
814 
815         if( toCopy < 1024 * 1024 )
816             tempSize = (tmsize_t)toCopy;
817         else
818             tempSize = 1024 * 1024;
819 
820         offsetRead = td->td_stripoffset_p[strip];
821         offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
822 
823         m = offsetWrite + toCopy + cc;
824         if (!(tif->tif_flags&TIFF_BIGTIFF) && m != (uint32_t)m)
825         {
826             TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
827             return (0);
828         }
829 
830         temp = _TIFFmalloc(tempSize);
831         if (temp == NULL) {
832             TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
833             return (0);
834         }
835 
836         tif->tif_flags |= TIFF_DIRTYSTRIP;
837 
838         td->td_stripoffset_p[strip] = offsetWrite;
839         td->td_stripbytecount_p[strip] = 0;
840 
841         /* Move data written by previous calls to us at end of file */
842         while( toCopy > 0 )
843         {
844             if( !SeekOK(tif, offsetRead) ) {
845                 TIFFErrorExt(tif->tif_clientdata, module, "Seek error");
846                 _TIFFfree(temp);
847                 return (0);
848             }
849             if( !ReadOK(tif, temp, tempSize) ) {
850                 TIFFErrorExt(tif->tif_clientdata, module, "Cannot read");
851                 _TIFFfree(temp);
852                 return (0);
853             }
854             if (!SeekOK(tif, offsetWrite) ) {
855                 TIFFErrorExt(tif->tif_clientdata, module, "Seek error");
856                 _TIFFfree(temp);
857                 return (0);
858             }
859             if( !WriteOK(tif, temp, tempSize) ) {
860                 TIFFErrorExt(tif->tif_clientdata, module, "Cannot write");
861                 _TIFFfree(temp);
862                 return (0);
863             }
864             offsetRead += tempSize;
865             offsetWrite += tempSize;
866             td->td_stripbytecount_p[strip] += tempSize;
867             toCopy -= tempSize;
868         }
869         _TIFFfree(temp);
870 
871         /* Append the data of this call */
872         offsetWrite += cc;
873         m = offsetWrite;
874     }
875 
876 	if (!WriteOK(tif, data, cc)) {
877 		TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
878 		    (unsigned long) tif->tif_row);
879 		    return (0);
880 	}
881 	tif->tif_curoff = m;
882 	td->td_stripbytecount_p[strip] += cc;
883 
884         if((int64_t) td->td_stripbytecount_p[strip] != old_byte_count )
885             tif->tif_flags |= TIFF_DIRTYSTRIP;
886 
887 	return (1);
888 }
889 
890 /*
891  * Internal version of TIFFFlushData that can be
892  * called by ``encodestrip routines'' w/o concern
893  * for infinite recursion.
894  */
895 int
TIFFFlushData1(TIFF * tif)896 TIFFFlushData1(TIFF* tif)
897 {
898 	if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
899 		if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
900 		    (tif->tif_flags & TIFF_NOBITREV) == 0)
901 			TIFFReverseBits((uint8_t*)tif->tif_rawdata,
902 			    tif->tif_rawcc);
903 		if (!TIFFAppendToStrip(tif,
904 		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
905 		    tif->tif_rawdata, tif->tif_rawcc))
906         {
907             /* We update those variables even in case of error since there's */
908             /* code that doesn't really check the return code of this */
909             /* function */
910             tif->tif_rawcc = 0;
911             tif->tif_rawcp = tif->tif_rawdata;
912 			return (0);
913         }
914 		tif->tif_rawcc = 0;
915 		tif->tif_rawcp = tif->tif_rawdata;
916 	}
917 	return (1);
918 }
919 
920 /*
921  * Set the current write offset.  This should only be
922  * used to set the offset to a known previous location
923  * (very carefully), or to 0 so that the next write gets
924  * appended to the end of the file.
925  */
926 void
TIFFSetWriteOffset(TIFF * tif,toff_t off)927 TIFFSetWriteOffset(TIFF* tif, toff_t off)
928 {
929 	tif->tif_curoff = off;
930 }
931 
932 /* vim: set ts=8 sts=8 sw=8 noet: */
933 /*
934  * Local Variables:
935  * mode: c
936  * c-basic-offset: 8
937  * fill-column: 78
938  * End:
939  */
940