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