xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_flush.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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