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 TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number);
55 TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset);
56
57 /*
58 * Clean up client info links.
59 */
60 while (tif->tif_clientinfo)
61 {
62 TIFFClientInfoLink *psLink = tif->tif_clientinfo;
63
64 tif->tif_clientinfo = psLink->next;
65 _TIFFfreeExt(tif, psLink->name);
66 _TIFFfreeExt(tif, psLink);
67 }
68
69 if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))
70 _TIFFfreeExt(tif, tif->tif_rawdata);
71 if (isMapped(tif))
72 TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
73
74 /*
75 * Clean up custom fields.
76 */
77 if (tif->tif_fields && tif->tif_nfields > 0)
78 {
79 uint32_t i;
80
81 for (i = 0; i < tif->tif_nfields; i++)
82 {
83 TIFFField *fld = tif->tif_fields[i];
84 if (fld->field_name != NULL)
85 {
86 if (fld->field_bit == FIELD_CUSTOM &&
87 /* caution: tif_fields[i] must not be the beginning of a
88 * fields-array. Otherwise the following tags are also freed
89 * with the first free().
90 */
91 TIFFFieldIsAnonymous(fld))
92 {
93 _TIFFfreeExt(tif, fld->field_name);
94 _TIFFfreeExt(tif, fld);
95 }
96 }
97 }
98
99 _TIFFfreeExt(tif, tif->tif_fields);
100 }
101
102 if (tif->tif_nfieldscompat > 0)
103 {
104 uint32_t i;
105
106 for (i = 0; i < tif->tif_nfieldscompat; i++)
107 {
108 if (tif->tif_fieldscompat[i].allocated_size)
109 _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
110 }
111 _TIFFfreeExt(tif, tif->tif_fieldscompat);
112 }
113
114 _TIFFfreeExt(NULL, tif);
115 }
116
117 /************************************************************************/
118 /* TIFFClose() */
119 /************************************************************************/
120
121 /**
122 * Close a previously opened TIFF file.
123 *
124 * TIFFClose closes a file that was previously opened with TIFFOpen().
125 * Any buffered data are flushed to the file, including the contents of
126 * the current directory (if modified); and all resources are reclaimed.
127 *
128 * @param tif A TIFF pointer.
129 */
130
TIFFClose(TIFF * tif)131 void TIFFClose(TIFF *tif)
132 {
133 TIFFCloseProc closeproc = tif->tif_closeproc;
134 thandle_t fd = tif->tif_clientdata;
135
136 TIFFCleanup(tif);
137 (void)(*closeproc)(fd);
138 }
139