1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 1988-1997 Sam Leffler
3*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4*3ac0a46fSAndroid Build Coastguard Worker *
5*3ac0a46fSAndroid Build Coastguard Worker * Permission to use, copy, modify, distribute, and sell this software and
6*3ac0a46fSAndroid Build Coastguard Worker * its documentation for any purpose is hereby granted without fee, provided
7*3ac0a46fSAndroid Build Coastguard Worker * that (i) the above copyright notices and this permission notice appear in
8*3ac0a46fSAndroid Build Coastguard Worker * all copies of the software and related documentation, and (ii) the names of
9*3ac0a46fSAndroid Build Coastguard Worker * Sam Leffler and Silicon Graphics may not be used in any advertising or
10*3ac0a46fSAndroid Build Coastguard Worker * publicity relating to the software without the specific, prior written
11*3ac0a46fSAndroid Build Coastguard Worker * permission of Sam Leffler and Silicon Graphics.
12*3ac0a46fSAndroid Build Coastguard Worker *
13*3ac0a46fSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14*3ac0a46fSAndroid Build Coastguard Worker * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15*3ac0a46fSAndroid Build Coastguard Worker * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16*3ac0a46fSAndroid Build Coastguard Worker *
17*3ac0a46fSAndroid Build Coastguard Worker * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18*3ac0a46fSAndroid Build Coastguard Worker * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19*3ac0a46fSAndroid Build Coastguard Worker * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20*3ac0a46fSAndroid Build Coastguard Worker * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21*3ac0a46fSAndroid Build Coastguard Worker * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22*3ac0a46fSAndroid Build Coastguard Worker * OF THIS SOFTWARE.
23*3ac0a46fSAndroid Build Coastguard Worker */
24*3ac0a46fSAndroid Build Coastguard Worker
25*3ac0a46fSAndroid Build Coastguard Worker /*
26*3ac0a46fSAndroid Build Coastguard Worker * TIFF Library.
27*3ac0a46fSAndroid Build Coastguard Worker */
28*3ac0a46fSAndroid Build Coastguard Worker #include "tiffiop.h"
29*3ac0a46fSAndroid Build Coastguard Worker
TIFFFlush(TIFF * tif)30*3ac0a46fSAndroid Build Coastguard Worker int TIFFFlush(TIFF *tif)
31*3ac0a46fSAndroid Build Coastguard Worker {
32*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY)
33*3ac0a46fSAndroid Build Coastguard Worker return 1;
34*3ac0a46fSAndroid Build Coastguard Worker
35*3ac0a46fSAndroid Build Coastguard Worker if (!TIFFFlushData(tif))
36*3ac0a46fSAndroid Build Coastguard Worker return (0);
37*3ac0a46fSAndroid Build Coastguard Worker
38*3ac0a46fSAndroid Build Coastguard Worker /* In update (r+) mode we try to detect the case where
39*3ac0a46fSAndroid Build Coastguard Worker only the strip/tile map has been altered, and we try to
40*3ac0a46fSAndroid Build Coastguard Worker rewrite only that portion of the directory without
41*3ac0a46fSAndroid Build Coastguard Worker making any other changes */
42*3ac0a46fSAndroid Build Coastguard Worker
43*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_flags & TIFF_DIRTYSTRIP) &&
44*3ac0a46fSAndroid Build Coastguard Worker !(tif->tif_flags & TIFF_DIRTYDIRECT) && tif->tif_mode == O_RDWR)
45*3ac0a46fSAndroid Build Coastguard Worker {
46*3ac0a46fSAndroid Build Coastguard Worker if (TIFFForceStrileArrayWriting(tif))
47*3ac0a46fSAndroid Build Coastguard Worker return 1;
48*3ac0a46fSAndroid Build Coastguard Worker }
49*3ac0a46fSAndroid Build Coastguard Worker
50*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_flags & (TIFF_DIRTYDIRECT | TIFF_DIRTYSTRIP)) &&
51*3ac0a46fSAndroid Build Coastguard Worker !TIFFRewriteDirectory(tif))
52*3ac0a46fSAndroid Build Coastguard Worker return (0);
53*3ac0a46fSAndroid Build Coastguard Worker
54*3ac0a46fSAndroid Build Coastguard Worker return (1);
55*3ac0a46fSAndroid Build Coastguard Worker }
56*3ac0a46fSAndroid Build Coastguard Worker
57*3ac0a46fSAndroid Build Coastguard Worker /*
58*3ac0a46fSAndroid Build Coastguard Worker * This is an advanced writing function that must be used in a particular
59*3ac0a46fSAndroid Build Coastguard Worker * sequence, and together with TIFFDeferStrileArrayWriting(),
60*3ac0a46fSAndroid Build Coastguard Worker * to make its intended effect. Its aim is to force the writing of
61*3ac0a46fSAndroid Build Coastguard Worker * the [Strip/Tile][Offsets/ByteCounts] arrays at the end of the file, when
62*3ac0a46fSAndroid Build Coastguard Worker * they have not yet been rewritten.
63*3ac0a46fSAndroid Build Coastguard Worker *
64*3ac0a46fSAndroid Build Coastguard Worker * The typical sequence of calls is:
65*3ac0a46fSAndroid Build Coastguard Worker * TIFFOpen()
66*3ac0a46fSAndroid Build Coastguard Worker * [ TIFFCreateDirectory(tif) ]
67*3ac0a46fSAndroid Build Coastguard Worker * Set fields with calls to TIFFSetField(tif, ...)
68*3ac0a46fSAndroid Build Coastguard Worker * TIFFDeferStrileArrayWriting(tif)
69*3ac0a46fSAndroid Build Coastguard Worker * TIFFWriteCheck(tif, ...)
70*3ac0a46fSAndroid Build Coastguard Worker * TIFFWriteDirectory(tif)
71*3ac0a46fSAndroid Build Coastguard Worker * ... potentially create other directories and come back to the above directory
72*3ac0a46fSAndroid Build Coastguard Worker * TIFFForceStrileArrayWriting(tif)
73*3ac0a46fSAndroid Build Coastguard Worker *
74*3ac0a46fSAndroid Build Coastguard Worker * Returns 1 in case of success, 0 otherwise.
75*3ac0a46fSAndroid Build Coastguard Worker */
TIFFForceStrileArrayWriting(TIFF * tif)76*3ac0a46fSAndroid Build Coastguard Worker int TIFFForceStrileArrayWriting(TIFF *tif)
77*3ac0a46fSAndroid Build Coastguard Worker {
78*3ac0a46fSAndroid Build Coastguard Worker static const char module[] = "TIFFForceStrileArrayWriting";
79*3ac0a46fSAndroid Build Coastguard Worker const int isTiled = TIFFIsTiled(tif);
80*3ac0a46fSAndroid Build Coastguard Worker
81*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_mode == O_RDONLY)
82*3ac0a46fSAndroid Build Coastguard Worker {
83*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
84*3ac0a46fSAndroid Build Coastguard Worker return 0;
85*3ac0a46fSAndroid Build Coastguard Worker }
86*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_diroff == 0)
87*3ac0a46fSAndroid Build Coastguard Worker {
88*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Directory has not yet been written");
89*3ac0a46fSAndroid Build Coastguard Worker return 0;
90*3ac0a46fSAndroid Build Coastguard Worker }
91*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_flags & TIFF_DIRTYDIRECT) != 0)
92*3ac0a46fSAndroid Build Coastguard Worker {
93*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
94*3ac0a46fSAndroid Build Coastguard Worker "Directory has changes other than the strile arrays. "
95*3ac0a46fSAndroid Build Coastguard Worker "TIFFRewriteDirectory() should be called instead");
96*3ac0a46fSAndroid Build Coastguard Worker return 0;
97*3ac0a46fSAndroid Build Coastguard Worker }
98*3ac0a46fSAndroid Build Coastguard Worker
99*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_flags & TIFF_DIRTYSTRIP))
100*3ac0a46fSAndroid Build Coastguard Worker {
101*3ac0a46fSAndroid Build Coastguard Worker if (!(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
102*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
103*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
104*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
105*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
106*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
107*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
108*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0))
109*3ac0a46fSAndroid Build Coastguard Worker {
110*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module,
111*3ac0a46fSAndroid Build Coastguard Worker "Function not called together with "
112*3ac0a46fSAndroid Build Coastguard Worker "TIFFDeferStrileArrayWriting()");
113*3ac0a46fSAndroid Build Coastguard Worker return 0;
114*3ac0a46fSAndroid Build Coastguard Worker }
115*3ac0a46fSAndroid Build Coastguard Worker
116*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
117*3ac0a46fSAndroid Build Coastguard Worker return 0;
118*3ac0a46fSAndroid Build Coastguard Worker }
119*3ac0a46fSAndroid Build Coastguard Worker
120*3ac0a46fSAndroid Build Coastguard Worker if (_TIFFRewriteField(tif,
121*3ac0a46fSAndroid Build Coastguard Worker isTiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS,
122*3ac0a46fSAndroid Build Coastguard Worker TIFF_LONG8, tif->tif_dir.td_nstrips,
123*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripoffset_p) &&
124*3ac0a46fSAndroid Build Coastguard Worker _TIFFRewriteField(
125*3ac0a46fSAndroid Build Coastguard Worker tif, isTiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS,
126*3ac0a46fSAndroid Build Coastguard Worker TIFF_LONG8, tif->tif_dir.td_nstrips,
127*3ac0a46fSAndroid Build Coastguard Worker tif->tif_dir.td_stripbytecount_p))
128*3ac0a46fSAndroid Build Coastguard Worker {
129*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_DIRTYSTRIP;
130*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_BEENWRITING;
131*3ac0a46fSAndroid Build Coastguard Worker return 1;
132*3ac0a46fSAndroid Build Coastguard Worker }
133*3ac0a46fSAndroid Build Coastguard Worker
134*3ac0a46fSAndroid Build Coastguard Worker return 0;
135*3ac0a46fSAndroid Build Coastguard Worker }
136*3ac0a46fSAndroid Build Coastguard Worker
137*3ac0a46fSAndroid Build Coastguard Worker /*
138*3ac0a46fSAndroid Build Coastguard Worker * Flush buffered data to the file.
139*3ac0a46fSAndroid Build Coastguard Worker *
140*3ac0a46fSAndroid Build Coastguard Worker * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
141*3ac0a46fSAndroid Build Coastguard Worker * is not set, so that TIFFFlush() will proceed to write out the directory.
142*3ac0a46fSAndroid Build Coastguard Worker * The documentation says returning 1 is an error indicator, but not having
143*3ac0a46fSAndroid Build Coastguard Worker * been writing isn't exactly a an error. Hopefully this doesn't cause
144*3ac0a46fSAndroid Build Coastguard Worker * problems for other people.
145*3ac0a46fSAndroid Build Coastguard Worker */
TIFFFlushData(TIFF * tif)146*3ac0a46fSAndroid Build Coastguard Worker int TIFFFlushData(TIFF *tif)
147*3ac0a46fSAndroid Build Coastguard Worker {
148*3ac0a46fSAndroid Build Coastguard Worker if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
149*3ac0a46fSAndroid Build Coastguard Worker return (1);
150*3ac0a46fSAndroid Build Coastguard Worker if (tif->tif_flags & TIFF_POSTENCODE)
151*3ac0a46fSAndroid Build Coastguard Worker {
152*3ac0a46fSAndroid Build Coastguard Worker tif->tif_flags &= ~TIFF_POSTENCODE;
153*3ac0a46fSAndroid Build Coastguard Worker if (!(*tif->tif_postencode)(tif))
154*3ac0a46fSAndroid Build Coastguard Worker return (0);
155*3ac0a46fSAndroid Build Coastguard Worker }
156*3ac0a46fSAndroid Build Coastguard Worker return (TIFFFlushData1(tif));
157*3ac0a46fSAndroid Build Coastguard Worker }
158