xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_close.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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 #include "tiffiop.h"
29 #include <string.h>
30 
31 /************************************************************************/
32 /*                            TIFFCleanup()                             */
33 /************************************************************************/
34 
35 /**
36  * Auxiliary function to free the TIFF structure. Given structure will be
37  * completely freed, so you should save opened file handle and pointer
38  * to the close procedure in external variables before calling
39  * _TIFFCleanup(), if you will need these ones to close the file.
40  *
41  * @param tif A TIFF pointer.
42  */
43 
TIFFCleanup(TIFF * tif)44 void TIFFCleanup(TIFF *tif)
45 {
46     /*
47      * Flush buffered data and directory (if dirty).
48      */
49     if (tif->tif_mode != O_RDONLY)
50         TIFFFlush(tif);
51     (*tif->tif_cleanup)(tif);
52     TIFFFreeDirectory(tif);
53 
54     _TIFFCleanupIFDOffsetAndNumberMaps(tif);
55 
56     /*
57      * Clean up client info links.
58      */
59     while (tif->tif_clientinfo)
60     {
61         TIFFClientInfoLink *psLink = tif->tif_clientinfo;
62 
63         tif->tif_clientinfo = psLink->next;
64         _TIFFfreeExt(tif, psLink->name);
65         _TIFFfreeExt(tif, psLink);
66     }
67 
68     if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))
69         _TIFFfreeExt(tif, tif->tif_rawdata);
70     if (isMapped(tif))
71         TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
72 
73     /*
74      * Clean up custom fields.
75      */
76     if (tif->tif_fields && tif->tif_nfields > 0)
77     {
78         uint32_t i;
79 
80         for (i = 0; i < tif->tif_nfields; i++)
81         {
82             TIFFField *fld = tif->tif_fields[i];
83             if (fld->field_name != NULL)
84             {
85                 if (fld->field_bit == FIELD_CUSTOM &&
86                     /* caution: tif_fields[i] must not be the beginning of a
87                      * fields-array. Otherwise the following tags are also freed
88                      * with the first free().
89                      */
90                     TIFFFieldIsAnonymous(fld))
91                 {
92                     _TIFFfreeExt(tif, fld->field_name);
93                     _TIFFfreeExt(tif, fld);
94                 }
95             }
96         }
97 
98         _TIFFfreeExt(tif, tif->tif_fields);
99     }
100 
101     if (tif->tif_nfieldscompat > 0)
102     {
103         uint32_t i;
104 
105         for (i = 0; i < tif->tif_nfieldscompat; i++)
106         {
107             if (tif->tif_fieldscompat[i].allocated_size)
108                 _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
109         }
110         _TIFFfreeExt(tif, tif->tif_fieldscompat);
111     }
112 
113     _TIFFfreeExt(NULL, tif);
114 }
115 
116 /************************************************************************/
117 /*                    _TIFFCleanupIFDOffsetAndNumberMaps()              */
118 /************************************************************************/
119 
_TIFFCleanupIFDOffsetAndNumberMaps(TIFF * tif)120 void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)
121 {
122     if (tif->tif_map_dir_offset_to_number)
123     {
124         TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number);
125         tif->tif_map_dir_offset_to_number = NULL;
126     }
127     if (tif->tif_map_dir_number_to_offset)
128     {
129         TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset);
130         tif->tif_map_dir_number_to_offset = NULL;
131     }
132 }
133 
134 /************************************************************************/
135 /*                            TIFFClose()                               */
136 /************************************************************************/
137 
138 /**
139  * Close a previously opened TIFF file.
140  *
141  * TIFFClose closes a file that was previously opened with TIFFOpen().
142  * Any buffered data are flushed to the file, including the contents of
143  * the current directory (if modified); and all resources are reclaimed.
144  *
145  * @param tif A TIFF pointer.
146  */
147 
TIFFClose(TIFF * tif)148 void TIFFClose(TIFF *tif)
149 {
150     if (tif != NULL)
151     {
152         TIFFCloseProc closeproc = tif->tif_closeproc;
153         thandle_t fd = tif->tif_clientdata;
154 
155         TIFFCleanup(tif);
156         (void)(*closeproc)(fd);
157     }
158 }
159