4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
30 * Scanline-oriented Write Support
36 #define STRIPINCR 20 /* expansion factor on strip array */
38 #define WRITECHECKSTRIPS(tif, module) \
39 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
40 #define WRITECHECKTILES(tif, module) \
41 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
42 #define BUFFERCHECK(tif) \
43 (((tif)->tif_flags & TIFF_BUFFERSETUP) || \
44 TIFFWriteBufferSetup((tif), NULL, (tsize_t) -1))
46 static int TIFFWriteCheck(TIFF
*, int, const char*);
47 static int TIFFGrowStrips(TIFF
*, int, const char*);
48 static int TIFFAppendToStrip(TIFF
*, tstrip_t
, tidata_t
, tsize_t
);
49 static int TIFFSetupStrips(TIFF
*);
52 TIFFWriteScanline(TIFF
* tif
, tdata_t buf
, uint32 row
, tsample_t sample
)
54 static const char module[] = "TIFFWriteScanline";
55 register TIFFDirectory
*td
;
56 int status
, imagegrew
= 0;
59 if (!WRITECHECKSTRIPS(tif
, module))
62 * Handle delayed allocation of data buffer. This
63 * permits it to be sized more intelligently (using
64 * directory information).
66 if (!BUFFERCHECK(tif
))
70 * Extend image length if needed
71 * (but only for PlanarConfig=1).
73 if (row
>= td
->td_imagelength
) { /* extend image */
74 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
75 TIFFError(tif
->tif_name
,
76 "Can not change \"ImageLength\" when using separate planes");
79 td
->td_imagelength
= row
+1;
83 * Calculate strip and check for crossings.
85 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
86 if (sample
>= td
->td_samplesperpixel
) {
87 TIFFError(tif
->tif_name
,
88 "%d: Sample out of range, max %d",
89 sample
, td
->td_samplesperpixel
);
92 strip
= sample
*td
->td_stripsperimage
+ row
/td
->td_rowsperstrip
;
94 strip
= row
/ td
->td_rowsperstrip
;
95 if (strip
!= tif
->tif_curstrip
) {
97 * Changing strips -- flush any data present.
99 if (!TIFFFlushData(tif
))
101 tif
->tif_curstrip
= strip
;
103 * Watch out for a growing image. The value of
104 * strips/image will initially be 1 (since it
105 * can't be deduced until the imagelength is known).
107 if (strip
>= td
->td_stripsperimage
&& imagegrew
)
108 td
->td_stripsperimage
=
109 TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
);
111 (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
112 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
113 if (!(*tif
->tif_setupencode
)(tif
))
115 tif
->tif_flags
|= TIFF_CODERSETUP
;
117 if (!(*tif
->tif_preencode
)(tif
, sample
))
119 tif
->tif_flags
|= TIFF_POSTENCODE
;
122 * Check strip array to make sure there's space.
123 * We don't support dynamically growing files that
124 * have data organized in separate bitplanes because
125 * it's too painful. In that case we require that
126 * the imagelength be set properly before the first
127 * write (so that the strips array will be fully
130 if (strip
>= td
->td_nstrips
&& !TIFFGrowStrips(tif
, 1, module))
133 * Ensure the write is either sequential or at the
134 * beginning of a strip (or that we can randomly
135 * access the data -- i.e. no encoding).
137 if (row
!= tif
->tif_row
) {
138 if (row
< tif
->tif_row
) {
140 * Moving backwards within the same strip:
141 * backup to the start and then decode
144 tif
->tif_row
= (strip
% td
->td_stripsperimage
) *
146 tif
->tif_rawcp
= tif
->tif_rawdata
;
149 * Seek forward to the desired row.
151 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
155 status
= (*tif
->tif_encoderow
)(tif
, (tidata_t
) buf
,
156 tif
->tif_scanlinesize
, sample
);
162 * Encode the supplied data and write it to the
163 * specified strip. There must be space for the
164 * data; we don't check if strips overlap!
166 * NB: Image length must be setup before writing.
169 TIFFWriteEncodedStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
171 static const char module[] = "TIFFWriteEncodedStrip";
172 TIFFDirectory
*td
= &tif
->tif_dir
;
175 if (!WRITECHECKSTRIPS(tif
, module))
176 return ((tsize_t
) -1);
178 * Check strip array to make sure there's space.
179 * We don't support dynamically growing files that
180 * have data organized in separate bitplanes because
181 * it's too painful. In that case we require that
182 * the imagelength be set properly before the first
183 * write (so that the strips array will be fully
186 if (strip
>= td
->td_nstrips
) {
187 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
188 TIFFError(tif
->tif_name
,
189 "Can not grow image by strips when using separate planes");
190 return ((tsize_t
) -1);
192 if (!TIFFGrowStrips(tif
, 1, module))
193 return ((tsize_t
) -1);
194 td
->td_stripsperimage
=
195 TIFFhowmany(td
->td_imagelength
, td
->td_rowsperstrip
);
198 * Handle delayed allocation of data buffer. This
199 * permits it to be sized according to the directory
202 if (!BUFFERCHECK(tif
))
203 return ((tsize_t
) -1);
204 tif
->tif_curstrip
= strip
;
205 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
206 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
207 if (!(*tif
->tif_setupencode
)(tif
))
208 return ((tsize_t
) -1);
209 tif
->tif_flags
|= TIFF_CODERSETUP
;
211 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
212 sample
= (tsample_t
)(strip
/ td
->td_stripsperimage
);
213 if (!(*tif
->tif_preencode
)(tif
, sample
))
214 return ((tsize_t
) -1);
215 if (!(*tif
->tif_encodestrip
)(tif
, (tidata_t
) data
, cc
, sample
))
216 return ((tsize_t
) 0);
217 if (!(*tif
->tif_postencode
)(tif
))
218 return ((tsize_t
) -1);
219 if (!isFillOrder(tif
, td
->td_fillorder
) &&
220 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
221 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
);
222 if (tif
->tif_rawcc
> 0 &&
223 !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
))
224 return ((tsize_t
) -1);
226 tif
->tif_rawcp
= tif
->tif_rawdata
;
231 * Write the supplied data to the specified strip.
232 * There must be space for the data; we don't check
235 * NB: Image length must be setup before writing.
238 TIFFWriteRawStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
)
240 static const char module[] = "TIFFWriteRawStrip";
241 TIFFDirectory
*td
= &tif
->tif_dir
;
243 if (!WRITECHECKSTRIPS(tif
, module))
244 return ((tsize_t
) -1);
246 * Check strip array to make sure there's space.
247 * We don't support dynamically growing files that
248 * have data organized in separate bitplanes because
249 * it's too painful. In that case we require that
250 * the imagelength be set properly before the first
251 * write (so that the strips array will be fully
254 if (strip
>= td
->td_nstrips
) {
255 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
256 TIFFError(tif
->tif_name
,
257 "Can not grow image by strips when using separate planes");
258 return ((tsize_t
) -1);
261 * Watch out for a growing image. The value of
262 * strips/image will initially be 1 (since it
263 * can't be deduced until the imagelength is known).
265 if (strip
>= td
->td_stripsperimage
)
266 td
->td_stripsperimage
=
267 TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
);
268 if (!TIFFGrowStrips(tif
, 1, module))
269 return ((tsize_t
) -1);
271 tif
->tif_curstrip
= strip
;
272 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
273 return (TIFFAppendToStrip(tif
, strip
, (tidata_t
) data
, cc
) ?
278 * Write and compress a tile of data. The
279 * tile is selected by the (x,y,z,s) coordinates.
282 TIFFWriteTile(TIFF
* tif
,
283 tdata_t buf
, uint32 x
, uint32 y
, uint32 z
, tsample_t s
)
285 if (!TIFFCheckTile(tif
, x
, y
, z
, s
))
288 * NB: A tile size of -1 is used instead of tif_tilesize knowing
289 * that TIFFWriteEncodedTile will clamp this to the tile size.
290 * This is done because the tile size may not be defined until
291 * after the output buffer is setup in TIFFWriteBufferSetup.
293 return (TIFFWriteEncodedTile(tif
,
294 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tsize_t
) -1));
298 * Encode the supplied data and write it to the
299 * specified tile. There must be space for the
300 * data. The function clamps individual writes
301 * to a tile to the tile size, but does not (and
302 * can not) check that multiple writes to the same
303 * tile do not write more than tile size data.
305 * NB: Image length must be setup before writing; this
306 * interface does not support automatically growing
307 * the image on each write (as TIFFWriteScanline does).
310 TIFFWriteEncodedTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
312 static const char module[] = "TIFFWriteEncodedTile";
316 if (!WRITECHECKTILES(tif
, module))
317 return ((tsize_t
) -1);
319 if (tile
>= td
->td_nstrips
) {
320 TIFFError(module, "%s: Tile %lu out of range, max %lu",
321 tif
->tif_name
, (u_long
) tile
, (u_long
) td
->td_nstrips
);
322 return ((tsize_t
) -1);
325 * Handle delayed allocation of data buffer. This
326 * permits it to be sized more intelligently (using
327 * directory information).
329 if (!BUFFERCHECK(tif
))
330 return ((tsize_t
) -1);
331 tif
->tif_curtile
= tile
;
333 * Compute tiles per row & per column to compute
334 * current row and column
336 tif
->tif_row
= (tile
% TIFFhowmany(td
->td_imagelength
, td
->td_tilelength
))
338 tif
->tif_col
= (tile
% TIFFhowmany(td
->td_imagewidth
, td
->td_tilewidth
))
341 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
342 if (!(*tif
->tif_setupencode
)(tif
))
343 return ((tsize_t
) -1);
344 tif
->tif_flags
|= TIFF_CODERSETUP
;
346 tif
->tif_flags
&= ~TIFF_POSTENCODE
;
347 sample
= (tsample_t
)(tile
/td
->td_stripsperimage
);
348 if (!(*tif
->tif_preencode
)(tif
, sample
))
349 return ((tsize_t
) -1);
351 * Clamp write amount to the tile size. This is mostly
352 * done so that callers can pass in some large number
353 * (e.g. -1) and have the tile size used instead.
355 if ((uint32
) cc
> tif
->tif_tilesize
)
356 cc
= tif
->tif_tilesize
;
357 if (!(*tif
->tif_encodetile
)(tif
, (tidata_t
) data
, cc
, sample
))
358 return ((tsize_t
) 0);
359 if (!(*tif
->tif_postencode
)(tif
))
360 return ((tsize_t
) -1);
361 if (!isFillOrder(tif
, td
->td_fillorder
) &&
362 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
363 TIFFReverseBits((u_char
*)tif
->tif_rawdata
, tif
->tif_rawcc
);
364 if (tif
->tif_rawcc
> 0 && !TIFFAppendToStrip(tif
, tile
,
365 tif
->tif_rawdata
, tif
->tif_rawcc
))
366 return ((tsize_t
) -1);
368 tif
->tif_rawcp
= tif
->tif_rawdata
;
373 * Write the supplied data to the specified strip.
374 * There must be space for the data; we don't check
377 * NB: Image length must be setup before writing; this
378 * interface does not support automatically growing
379 * the image on each write (as TIFFWriteScanline does).
382 TIFFWriteRawTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
)
384 static const char module[] = "TIFFWriteRawTile";
386 if (!WRITECHECKTILES(tif
, module))
387 return ((tsize_t
) -1);
388 if (tile
>= tif
->tif_dir
.td_nstrips
) {
389 TIFFError(module, "%s: Tile %lu out of range, max %lu",
390 tif
->tif_name
, (u_long
) tile
,
391 (u_long
) tif
->tif_dir
.td_nstrips
);
392 return ((tsize_t
) -1);
394 return (TIFFAppendToStrip(tif
, tile
, (tidata_t
) data
, cc
) ?
398 #define isUnspecified(tif, f) \
399 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
402 TIFFSetupStrips(TIFF
* tif
)
404 TIFFDirectory
* td
= &tif
->tif_dir
;
407 td
->td_stripsperimage
=
408 isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ?
409 td
->td_samplesperpixel
: TIFFNumberOfTiles(tif
);
411 td
->td_stripsperimage
=
412 isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ?
413 td
->td_samplesperpixel
: TIFFNumberOfStrips(tif
);
414 td
->td_nstrips
= td
->td_stripsperimage
;
415 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
)
416 td
->td_stripsperimage
/= td
->td_samplesperpixel
;
417 td
->td_stripoffset
= (uint32
*)
418 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
419 td
->td_stripbytecount
= (uint32
*)
420 _TIFFmalloc(td
->td_nstrips
* sizeof (uint32
));
421 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
)
424 * Place data at the end-of-file
425 * (by setting offsets to zero).
427 _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint32
));
428 _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint32
));
429 TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
);
430 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
436 * Verify file is writable and that the directory
437 * information is setup properly. In doing the latter
438 * we also "freeze" the state of the directory so
439 * that important information is not changed.
442 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module)
444 if (tif
->tif_mode
== O_RDONLY
) {
445 TIFFError(module, "%s: File not open for writing",
449 if (tiles
^ isTiled(tif
)) {
450 TIFFError(tif
->tif_name
, tiles
?
451 "Can not write tiles to a stripped image" :
452 "Can not write scanlines to a tiled image");
456 * On the first write verify all the required information
457 * has been setup and initialize any data structures that
458 * had to wait until directory information was set.
459 * Note that a lot of our work is assumed to remain valid
460 * because we disallow any of the important parameters
461 * from changing after we start writing (i.e. once
462 * TIFF_BEENWRITING is set, TIFFSetField will only allow
463 * the image's length to be changed).
465 if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) {
467 "%s: Must set \"ImageWidth\" before writing data",
471 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) {
473 "%s: Must set \"PlanarConfiguration\" before writing data",
477 if (tif
->tif_dir
.td_stripoffset
== NULL
&& !TIFFSetupStrips(tif
)) {
478 tif
->tif_dir
.td_nstrips
= 0;
479 TIFFError(module, "%s: No space for %s arrays",
480 tif
->tif_name
, isTiled(tif
) ? "tile" : "strip");
483 tif
->tif_tilesize
= TIFFTileSize(tif
);
484 tif
->tif_scanlinesize
= TIFFScanlineSize(tif
);
485 tif
->tif_flags
|= TIFF_BEENWRITING
;
490 * Setup the raw data buffer used for encoding.
493 TIFFWriteBufferSetup(TIFF
* tif
, tdata_t bp
, tsize_t size
)
495 static const char module[] = "TIFFWriteBufferSetup";
497 if (tif
->tif_rawdata
) {
498 if (tif
->tif_flags
& TIFF_MYBUFFER
) {
499 _TIFFfree(tif
->tif_rawdata
);
500 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
502 tif
->tif_rawdata
= NULL
;
504 if (size
== (tsize_t
) -1) {
505 size
= (isTiled(tif
) ?
506 tif
->tif_tilesize
: tif
->tif_scanlinesize
);
508 * Make raw data buffer at least 8K
512 bp
= NULL
; /* NB: force malloc */
515 bp
= _TIFFmalloc(size
);
517 TIFFError(module, "%s: No space for output buffer",
521 tif
->tif_flags
|= TIFF_MYBUFFER
;
523 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
524 tif
->tif_rawdata
= (tidata_t
) bp
;
525 tif
->tif_rawdatasize
= size
;
527 tif
->tif_rawcp
= tif
->tif_rawdata
;
528 tif
->tif_flags
|= TIFF_BUFFERSETUP
;
533 * Grow the strip data structures by delta strips.
536 TIFFGrowStrips(TIFF
* tif
, int delta
, const char* module)
538 TIFFDirectory
*td
= &tif
->tif_dir
;
540 assert(td
->td_planarconfig
== PLANARCONFIG_CONTIG
);
541 td
->td_stripoffset
= (uint32
*)_TIFFrealloc(td
->td_stripoffset
,
542 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
543 td
->td_stripbytecount
= (uint32
*)_TIFFrealloc(td
->td_stripbytecount
,
544 (td
->td_nstrips
+ delta
) * sizeof (uint32
));
545 if (td
->td_stripoffset
== NULL
|| td
->td_stripbytecount
== NULL
) {
547 TIFFError(module, "%s: No space to expand strip arrays",
551 _TIFFmemset(td
->td_stripoffset
+td
->td_nstrips
, 0, delta
*sizeof (uint32
));
552 _TIFFmemset(td
->td_stripbytecount
+td
->td_nstrips
, 0, delta
*sizeof (uint32
));
553 td
->td_nstrips
+= delta
;
558 * Append the data to the specified strip.
560 * NB: We don't check that there's space in the
561 * file (i.e. that strips do not overlap).
564 TIFFAppendToStrip(TIFF
* tif
, tstrip_t strip
, tidata_t data
, tsize_t cc
)
566 TIFFDirectory
*td
= &tif
->tif_dir
;
567 static const char module[] = "TIFFAppendToStrip";
569 if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff
== 0) {
571 * No current offset, set the current strip.
573 if (td
->td_stripoffset
[strip
] != 0) {
574 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
576 "%s: Seek error at scanline %lu",
577 tif
->tif_name
, (u_long
) tif
->tif_row
);
581 td
->td_stripoffset
[strip
] =
582 TIFFSeekFile(tif
, (toff_t
) 0, SEEK_END
);
583 tif
->tif_curoff
= td
->td_stripoffset
[strip
];
585 if (!WriteOK(tif
, data
, cc
)) {
586 TIFFError(module, "%s: Write error at scanline %lu",
587 tif
->tif_name
, (u_long
) tif
->tif_row
);
590 tif
->tif_curoff
+= cc
;
591 td
->td_stripbytecount
[strip
] += cc
;
596 * Internal version of TIFFFlushData that can be
597 * called by ``encodestrip routines'' w/o concern
598 * for infinite recursion.
601 TIFFFlushData1(TIFF
* tif
)
603 if (tif
->tif_rawcc
> 0) {
604 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) &&
605 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
606 TIFFReverseBits((u_char
*)tif
->tif_rawdata
,
608 if (!TIFFAppendToStrip(tif
,
609 isTiled(tif
) ? tif
->tif_curtile
: tif
->tif_curstrip
,
610 tif
->tif_rawdata
, tif
->tif_rawcc
))
613 tif
->tif_rawcp
= tif
->tif_rawdata
;
619 * Set the current write offset. This should only be
620 * used to set the offset to a known previous location
621 * (very carefully), or to 0 so that the next write gets
622 * appended to the end of the file.
625 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
)
627 tif
->tif_curoff
= off
;