source: trunk/third/tiff/libtiff/tif_write.c @ 18174

Revision 18174, 19.8 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18173, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tiff/libtiff/tif_write.c,v 1.1.1.1 2002-12-26 02:38:10 ghudson 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 <assert.h>
34#include <stdio.h>
35
36#define REWRITE_HACK
37
38#define STRIPINCR       20              /* expansion factor on strip array */
39
40#define WRITECHECKSTRIPS(tif, module)                           \
41        (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
42#define WRITECHECKTILES(tif, module)                            \
43        (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
44#define BUFFERCHECK(tif)                                        \
45        ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
46            TIFFWriteBufferSetup((tif), NULL, (tsize_t) -1))
47
48static  int TIFFGrowStrips(TIFF*, int, const char*);
49static  int TIFFAppendToStrip(TIFF*, tstrip_t, tidata_t, tsize_t);
50static  int TIFFSetupStrips(TIFF*);
51
52int
53TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)
54{
55        static const char module[] = "TIFFWriteScanline";
56        register TIFFDirectory *td;
57        int status, imagegrew = 0;
58        tstrip_t strip;
59
60        if (!WRITECHECKSTRIPS(tif, module))
61                return (-1);
62        /*
63         * Handle delayed allocation of data buffer.  This
64         * permits it to be sized more intelligently (using
65         * directory information).
66         */
67        if (!BUFFERCHECK(tif))
68                return (-1);
69        td = &tif->tif_dir;
70        /*
71         * Extend image length if needed
72         * (but only for PlanarConfig=1).
73         */
74        if (row >= td->td_imagelength) {        /* extend image */
75                if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
76                        TIFFError(tif->tif_name,
77                "Can not change \"ImageLength\" when using separate planes");
78                        return (-1);
79                }
80                td->td_imagelength = row+1;
81                imagegrew = 1;
82        }
83        /*
84         * Calculate strip and check for crossings.
85         */
86        if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
87                if (sample >= td->td_samplesperpixel) {
88                        TIFFError(tif->tif_name,
89                            "%d: Sample out of range, max %d",
90                            sample, td->td_samplesperpixel);
91                        return (-1);
92                }
93                strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
94        } else
95                strip = row / td->td_rowsperstrip;
96        if (strip != tif->tif_curstrip) {
97                /*
98                 * Changing strips -- flush any data present.
99                 */
100                if (!TIFFFlushData(tif))
101                        return (-1);
102                tif->tif_curstrip = strip;
103                /*
104                 * Watch out for a growing image.  The value of
105                 * strips/image will initially be 1 (since it
106                 * can't be deduced until the imagelength is known).
107                 */
108                if (strip >= td->td_stripsperimage && imagegrew)
109                        td->td_stripsperimage =
110                            TIFFhowmany(td->td_imagelength,td->td_rowsperstrip);
111                tif->tif_row =
112                    (strip % td->td_stripsperimage) * td->td_rowsperstrip;
113                if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
114                        if (!(*tif->tif_setupencode)(tif))
115                                return (-1);
116                        tif->tif_flags |= TIFF_CODERSETUP;
117                }
118                if (!(*tif->tif_preencode)(tif, sample))
119                        return (-1);
120                tif->tif_flags |= TIFF_POSTENCODE;
121        }
122        /*
123         * Check strip array to make sure there's space.
124         * We don't support dynamically growing files that
125         * have data organized in separate bitplanes because
126         * it's too painful.  In that case we require that
127         * the imagelength be set properly before the first
128         * write (so that the strips array will be fully
129         * allocated above).
130         */
131        if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
132                return (-1);
133        /*
134         * Ensure the write is either sequential or at the
135         * beginning of a strip (or that we can randomly
136         * access the data -- i.e. no encoding).
137         */
138        if (row != tif->tif_row) {
139                if (row < tif->tif_row) {
140                        /*
141                         * Moving backwards within the same strip:
142                         * backup to the start and then decode
143                         * forward (below).
144                         */
145                        tif->tif_row = (strip % td->td_stripsperimage) *
146                            td->td_rowsperstrip;
147                        tif->tif_rawcp = tif->tif_rawdata;
148                }
149                /*
150                 * Seek forward to the desired row.
151                 */
152                if (!(*tif->tif_seek)(tif, row - tif->tif_row))
153                        return (-1);
154                tif->tif_row = row;
155        }
156        status = (*tif->tif_encoderow)(tif, (tidata_t) buf,
157            tif->tif_scanlinesize, sample);
158        tif->tif_row++;
159        return (status);
160}
161
162/*
163 * Encode the supplied data and write it to the
164 * specified strip.  There must be space for the
165 * data; we don't check if strips overlap!
166 *
167 * NB: Image length must be setup before writing.
168 */
169tsize_t
170TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
171{
172        static const char module[] = "TIFFWriteEncodedStrip";
173        TIFFDirectory *td = &tif->tif_dir;
174        tsample_t sample;
175
176        if (!WRITECHECKSTRIPS(tif, module))
177                return ((tsize_t) -1);
178        /*
179         * Check strip array to make sure there's space.
180         * We don't support dynamically growing files that
181         * have data organized in separate bitplanes because
182         * it's too painful.  In that case we require that
183         * the imagelength be set properly before the first
184         * write (so that the strips array will be fully
185         * allocated above).
186         */
187        if (strip >= td->td_nstrips) {
188                if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
189                        TIFFError(tif->tif_name,
190                "Can not grow image by strips when using separate planes");
191                        return ((tsize_t) -1);
192                }
193                if (!TIFFGrowStrips(tif, 1, module))
194                        return ((tsize_t) -1);
195                td->td_stripsperimage =
196                    TIFFhowmany(td->td_imagelength, td->td_rowsperstrip);
197        }
198        /*
199         * Handle delayed allocation of data buffer.  This
200         * permits it to be sized according to the directory
201         * info.
202         */
203        if (!BUFFERCHECK(tif))
204                return ((tsize_t) -1);
205        tif->tif_curstrip = strip;
206        tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
207        if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
208                if (!(*tif->tif_setupencode)(tif))
209                        return ((tsize_t) -1);
210                tif->tif_flags |= TIFF_CODERSETUP;
211        }
212       
213#ifdef REWRITE_HACK       
214        tif->tif_rawcc = 0;
215        tif->tif_rawcp = tif->tif_rawdata;
216
217        if( td->td_stripbytecount[strip] > 0 )
218        {
219            /* if we are writing over existing tiles, zero length. */
220            td->td_stripbytecount[strip] = 0;
221
222            /* this forces TIFFAppendToStrip() to do a seek */
223            tif->tif_curoff = 0;
224        }
225#endif
226       
227        tif->tif_flags &= ~TIFF_POSTENCODE;
228        sample = (tsample_t)(strip / td->td_stripsperimage);
229        if (!(*tif->tif_preencode)(tif, sample))
230                return ((tsize_t) -1);
231        if (!(*tif->tif_encodestrip)(tif, (tidata_t) data, cc, sample))
232                return ((tsize_t) 0);
233        if (!(*tif->tif_postencode)(tif))
234                return ((tsize_t) -1);
235        if (!isFillOrder(tif, td->td_fillorder) &&
236            (tif->tif_flags & TIFF_NOBITREV) == 0)
237                TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
238        if (tif->tif_rawcc > 0 &&
239            !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
240                return ((tsize_t) -1);
241        tif->tif_rawcc = 0;
242        tif->tif_rawcp = tif->tif_rawdata;
243        return (cc);
244}
245
246/*
247 * Write the supplied data to the specified strip.
248 * There must be space for the data; we don't check
249 * if strips overlap!
250 *
251 * NB: Image length must be setup before writing.
252 */
253tsize_t
254TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
255{
256        static const char module[] = "TIFFWriteRawStrip";
257        TIFFDirectory *td = &tif->tif_dir;
258
259        if (!WRITECHECKSTRIPS(tif, module))
260                return ((tsize_t) -1);
261        /*
262         * Check strip array to make sure there's space.
263         * We don't support dynamically growing files that
264         * have data organized in separate bitplanes because
265         * it's too painful.  In that case we require that
266         * the imagelength be set properly before the first
267         * write (so that the strips array will be fully
268         * allocated above).
269         */
270        if (strip >= td->td_nstrips) {
271                if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
272                        TIFFError(tif->tif_name,
273                "Can not grow image by strips when using separate planes");
274                        return ((tsize_t) -1);
275                }
276                /*
277                 * Watch out for a growing image.  The value of
278                 * strips/image will initially be 1 (since it
279                 * can't be deduced until the imagelength is known).
280                 */
281                if (strip >= td->td_stripsperimage)
282                        td->td_stripsperimage =
283                            TIFFhowmany(td->td_imagelength,td->td_rowsperstrip);
284                if (!TIFFGrowStrips(tif, 1, module))
285                        return ((tsize_t) -1);
286        }
287        tif->tif_curstrip = strip;
288        tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
289        return (TIFFAppendToStrip(tif, strip, (tidata_t) data, cc) ?
290            cc : (tsize_t) -1);
291}
292
293/*
294 * Write and compress a tile of data.  The
295 * tile is selected by the (x,y,z,s) coordinates.
296 */
297tsize_t
298TIFFWriteTile(TIFF* tif,
299    tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s)
300{
301        if (!TIFFCheckTile(tif, x, y, z, s))
302                return (-1);
303        /*
304         * NB: A tile size of -1 is used instead of tif_tilesize knowing
305         *     that TIFFWriteEncodedTile will clamp this to the tile size.
306         *     This is done because the tile size may not be defined until
307         *     after the output buffer is setup in TIFFWriteBufferSetup.
308         */
309        return (TIFFWriteEncodedTile(tif,
310            TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));
311}
312
313/*
314 * Encode the supplied data and write it to the
315 * specified tile.  There must be space for the
316 * data.  The function clamps individual writes
317 * to a tile to the tile size, but does not (and
318 * can not) check that multiple writes to the same
319 * tile do not write more than tile size data.
320 *
321 * NB: Image length must be setup before writing; this
322 *     interface does not support automatically growing
323 *     the image on each write (as TIFFWriteScanline does).
324 */
325tsize_t
326TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
327{
328        static const char module[] = "TIFFWriteEncodedTile";
329        TIFFDirectory *td;
330        tsample_t sample;
331
332        if (!WRITECHECKTILES(tif, module))
333                return ((tsize_t) -1);
334        td = &tif->tif_dir;
335        if (tile >= td->td_nstrips) {
336                TIFFError(module, "%s: Tile %lu out of range, max %lu",
337                    tif->tif_name, (u_long) tile, (u_long) td->td_nstrips);
338                return ((tsize_t) -1);
339        }
340        /*
341         * Handle delayed allocation of data buffer.  This
342         * permits it to be sized more intelligently (using
343         * directory information).
344         */
345        if (!BUFFERCHECK(tif))
346                return ((tsize_t) -1);
347        tif->tif_curtile = tile;
348
349#ifdef REWRITE_HACK       
350        tif->tif_rawcc = 0;
351        tif->tif_rawcp = tif->tif_rawdata;
352
353        if( td->td_stripbytecount[tile] > 0 )
354        {
355            /* if we are writing over existing tiles, zero length. */
356            td->td_stripbytecount[tile] = 0;
357
358            /* this forces TIFFAppendToStrip() to do a seek */
359            tif->tif_curoff = 0;
360        }
361#endif
362       
363        /*
364         * Compute tiles per row & per column to compute
365         * current row and column
366         */
367        tif->tif_row = (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength))
368                * td->td_tilelength;
369        tif->tif_col = (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth))
370                * td->td_tilewidth;
371
372        if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
373                if (!(*tif->tif_setupencode)(tif))
374                        return ((tsize_t) -1);
375                tif->tif_flags |= TIFF_CODERSETUP;
376        }
377        tif->tif_flags &= ~TIFF_POSTENCODE;
378        sample = (tsample_t)(tile/td->td_stripsperimage);
379        if (!(*tif->tif_preencode)(tif, sample))
380                return ((tsize_t) -1);
381        /*
382         * Clamp write amount to the tile size.  This is mostly
383         * done so that callers can pass in some large number
384         * (e.g. -1) and have the tile size used instead.
385         */
386        if ( cc < 1 || cc > tif->tif_tilesize)
387                cc = tif->tif_tilesize;
388        if (!(*tif->tif_encodetile)(tif, (tidata_t) data, cc, sample))
389                return ((tsize_t) 0);
390        if (!(*tif->tif_postencode)(tif))
391                return ((tsize_t) -1);
392        if (!isFillOrder(tif, td->td_fillorder) &&
393            (tif->tif_flags & TIFF_NOBITREV) == 0)
394                TIFFReverseBits((u_char *)tif->tif_rawdata, tif->tif_rawcc);
395        if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
396            tif->tif_rawdata, tif->tif_rawcc))
397                return ((tsize_t) -1);
398        tif->tif_rawcc = 0;
399        tif->tif_rawcp = tif->tif_rawdata;
400        return (cc);
401}
402
403/*
404 * Write the supplied data to the specified strip.
405 * There must be space for the data; we don't check
406 * if strips overlap!
407 *
408 * NB: Image length must be setup before writing; this
409 *     interface does not support automatically growing
410 *     the image on each write (as TIFFWriteScanline does).
411 */
412tsize_t
413TIFFWriteRawTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
414{
415        static const char module[] = "TIFFWriteRawTile";
416
417        if (!WRITECHECKTILES(tif, module))
418                return ((tsize_t) -1);
419        if (tile >= tif->tif_dir.td_nstrips) {
420                TIFFError(module, "%s: Tile %lu out of range, max %lu",
421                    tif->tif_name, (u_long) tile,
422                    (u_long) tif->tif_dir.td_nstrips);
423                return ((tsize_t) -1);
424        }
425        return (TIFFAppendToStrip(tif, tile, (tidata_t) data, cc) ?
426            cc : (tsize_t) -1);
427}
428
429#define isUnspecified(tif, f) \
430    (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
431
432static int
433TIFFSetupStrips(TIFF* tif)
434{
435        TIFFDirectory* td = &tif->tif_dir;
436
437        if (isTiled(tif))
438                td->td_stripsperimage =
439                    isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
440                        td->td_samplesperpixel : TIFFNumberOfTiles(tif);
441        else
442                td->td_stripsperimage =
443                    isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
444                        td->td_samplesperpixel : TIFFNumberOfStrips(tif);
445        td->td_nstrips = td->td_stripsperimage;
446        if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
447                td->td_stripsperimage /= td->td_samplesperpixel;
448        td->td_stripoffset = (uint32 *)
449            _TIFFmalloc(td->td_nstrips * sizeof (uint32));
450        td->td_stripbytecount = (uint32 *)
451            _TIFFmalloc(td->td_nstrips * sizeof (uint32));
452        if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
453                return (0);
454        /*
455         * Place data at the end-of-file
456         * (by setting offsets to zero).
457         */
458        _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint32));
459        _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint32));
460        TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
461        TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
462        return (1);
463}
464#undef isUnspecified
465
466/*
467 * Verify file is writable and that the directory
468 * information is setup properly.  In doing the latter
469 * we also "freeze" the state of the directory so
470 * that important information is not changed.
471 */
472int
473TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
474{
475        if (tif->tif_mode == O_RDONLY) {
476                TIFFError(module, "%s: File not open for writing",
477                    tif->tif_name);
478                return (0);
479        }
480        if (tiles ^ isTiled(tif)) {
481                TIFFError(tif->tif_name, tiles ?
482                    "Can not write tiles to a stripped image" :
483                    "Can not write scanlines to a tiled image");
484                return (0);
485        }
486        /*
487         * On the first write verify all the required information
488         * has been setup and initialize any data structures that
489         * had to wait until directory information was set.
490         * Note that a lot of our work is assumed to remain valid
491         * because we disallow any of the important parameters
492         * from changing after we start writing (i.e. once
493         * TIFF_BEENWRITING is set, TIFFSetField will only allow
494         * the image's length to be changed).
495         */
496        if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
497                TIFFError(module,
498                    "%s: Must set \"ImageWidth\" before writing data",
499                    tif->tif_name);
500                return (0);
501        }
502        if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
503                TIFFError(module,
504            "%s: Must set \"PlanarConfiguration\" before writing data",
505                    tif->tif_name);
506                return (0);
507        }
508        if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
509                tif->tif_dir.td_nstrips = 0;
510                TIFFError(module, "%s: No space for %s arrays",
511                    tif->tif_name, isTiled(tif) ? "tile" : "strip");
512                return (0);
513        }
514        tif->tif_tilesize = TIFFTileSize(tif);
515        tif->tif_scanlinesize = TIFFScanlineSize(tif);
516        tif->tif_flags |= TIFF_BEENWRITING;
517        return (1);
518}
519
520/*
521 * Setup the raw data buffer used for encoding.
522 */
523int
524TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size)
525{
526        static const char module[] = "TIFFWriteBufferSetup";
527
528        if (tif->tif_rawdata) {
529                if (tif->tif_flags & TIFF_MYBUFFER) {
530                        _TIFFfree(tif->tif_rawdata);
531                        tif->tif_flags &= ~TIFF_MYBUFFER;
532                }
533                tif->tif_rawdata = NULL;
534        }
535        if (size == (tsize_t) -1) {
536                size = (isTiled(tif) ?
537                    tif->tif_tilesize : tif->tif_scanlinesize);
538                /*
539                 * Make raw data buffer at least 8K
540                 */
541                if (size < 8*1024)
542                        size = 8*1024;
543                bp = NULL;                      /* NB: force malloc */
544        }
545        if (bp == NULL) {
546                bp = _TIFFmalloc(size);
547                if (bp == NULL) {
548                        TIFFError(module, "%s: No space for output buffer",
549                            tif->tif_name);
550                        return (0);
551                }
552                tif->tif_flags |= TIFF_MYBUFFER;
553        } else
554                tif->tif_flags &= ~TIFF_MYBUFFER;
555        tif->tif_rawdata = (tidata_t) bp;
556        tif->tif_rawdatasize = size;
557        tif->tif_rawcc = 0;
558        tif->tif_rawcp = tif->tif_rawdata;
559        tif->tif_flags |= TIFF_BUFFERSETUP;
560        return (1);
561}
562
563/*
564 * Grow the strip data structures by delta strips.
565 */
566static int
567TIFFGrowStrips(TIFF* tif, int delta, const char* module)
568{
569        TIFFDirectory *td = &tif->tif_dir;
570
571        assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
572        td->td_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset,
573            (td->td_nstrips + delta) * sizeof (uint32));
574        td->td_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount,
575            (td->td_nstrips + delta) * sizeof (uint32));
576        if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) {
577                td->td_nstrips = 0;
578                TIFFError(module, "%s: No space to expand strip arrays",
579                    tif->tif_name);
580                return (0);
581        }
582        _TIFFmemset(td->td_stripoffset+td->td_nstrips, 0, delta*sizeof (uint32));
583        _TIFFmemset(td->td_stripbytecount+td->td_nstrips, 0, delta*sizeof (uint32));
584        td->td_nstrips += delta;
585        return (1);
586}
587
588/*
589 * Append the data to the specified strip.
590 *
591 * NB: We don't check that there's space in the
592 *     file (i.e. that strips do not overlap).
593 */
594static int
595TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc)
596{
597        TIFFDirectory *td = &tif->tif_dir;
598        static const char module[] = "TIFFAppendToStrip";
599
600        if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
601                /*
602                 * No current offset, set the current strip.
603                 */
604                if (td->td_stripoffset[strip] != 0) {
605                        if (!SeekOK(tif, td->td_stripoffset[strip])) {
606                                TIFFError(module,
607                                    "%s: Seek error at scanline %lu",
608                                    tif->tif_name, (u_long) tif->tif_row);
609                                return (0);
610                        }
611                } else
612                        td->td_stripoffset[strip] =
613                            TIFFSeekFile(tif, (toff_t) 0, SEEK_END);
614                tif->tif_curoff = td->td_stripoffset[strip];
615        }
616        if (!WriteOK(tif, data, cc)) {
617                TIFFError(module, "%s: Write error at scanline %lu",
618                    tif->tif_name, (u_long) tif->tif_row);
619                return (0);
620        }
621        tif->tif_curoff += cc;
622        td->td_stripbytecount[strip] += cc;
623        return (1);
624}
625
626/*
627 * Internal version of TIFFFlushData that can be
628 * called by ``encodestrip routines'' w/o concern
629 * for infinite recursion.
630 */
631int
632TIFFFlushData1(TIFF* tif)
633{
634        if (tif->tif_rawcc > 0) {
635                if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
636                    (tif->tif_flags & TIFF_NOBITREV) == 0)
637                        TIFFReverseBits((u_char *)tif->tif_rawdata,
638                            tif->tif_rawcc);
639                if (!TIFFAppendToStrip(tif,
640                    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
641                    tif->tif_rawdata, tif->tif_rawcc))
642                        return (0);
643                tif->tif_rawcc = 0;
644                tif->tif_rawcp = tif->tif_rawdata;
645        }
646        return (1);
647}
648
649/*
650 * Set the current write offset.  This should only be
651 * used to set the offset to a known previous location
652 * (very carefully), or to 0 so that the next write gets
653 * appended to the end of the file.
654 */
655void
656TIFFSetWriteOffset(TIFF* tif, toff_t off)
657{
658        tif->tif_curoff = off;
659}
Note: See TracBrowser for help on using the repository browser.