/*1* Copyright (c) 1988-1997 Sam Leffler2* Copyright (c) 1991-1997 Silicon Graphics, Inc.3*4* Permission to use, copy, modify, distribute, and sell this software and5* its documentation for any purpose is hereby granted without fee, provided6* that (i) the above copyright notices and this permission notice appear in7* all copies of the software and related documentation, and (ii) the names of8* Sam Leffler and Silicon Graphics may not be used in any advertising or9* publicity relating to the software without the specific, prior written10* permission of Sam Leffler and Silicon Graphics.11*12* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,13* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY14* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.15*16* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR17* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,18* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,19* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF20* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE21* OF THIS SOFTWARE.22*/2324/*25* TIFF Library.26*/27#include "tiffiop.h"28#include <string.h>2930/************************************************************************/31/* TIFFCleanup() */32/************************************************************************/3334/**35* Auxiliary function to free the TIFF structure. Given structure will be36* completely freed, so you should save opened file handle and pointer37* to the close procedure in external variables before calling38* _TIFFCleanup(), if you will need these ones to close the file.39*40* @param tif A TIFF pointer.41*/4243void TIFFCleanup(TIFF *tif)44{45/*46* Flush buffered data and directory (if dirty).47*/48if (tif->tif_mode != O_RDONLY)49TIFFFlush(tif);50(*tif->tif_cleanup)(tif);51TIFFFreeDirectory(tif);5253_TIFFCleanupIFDOffsetAndNumberMaps(tif);5455/*56* Clean up client info links.57*/58while (tif->tif_clientinfo)59{60TIFFClientInfoLink *psLink = tif->tif_clientinfo;6162tif->tif_clientinfo = psLink->next;63_TIFFfreeExt(tif, psLink->name);64_TIFFfreeExt(tif, psLink);65}6667if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))68_TIFFfreeExt(tif, tif->tif_rawdata);69if (isMapped(tif))70TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);7172/*73* Clean up custom fields.74*/75if (tif->tif_fields && tif->tif_nfields > 0)76{77uint32_t i;7879for (i = 0; i < tif->tif_nfields; i++)80{81TIFFField *fld = tif->tif_fields[i];82if (fld->field_name != NULL)83{84if (fld->field_bit == FIELD_CUSTOM &&85/* caution: tif_fields[i] must not be the beginning of a86* fields-array. Otherwise the following tags are also freed87* with the first free().88*/89TIFFFieldIsAnonymous(fld))90{91_TIFFfreeExt(tif, fld->field_name);92_TIFFfreeExt(tif, fld);93}94}95}9697_TIFFfreeExt(tif, tif->tif_fields);98}99100if (tif->tif_nfieldscompat > 0)101{102uint32_t i;103104for (i = 0; i < tif->tif_nfieldscompat; i++)105{106if (tif->tif_fieldscompat[i].allocated_size)107_TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);108}109_TIFFfreeExt(tif, tif->tif_fieldscompat);110}111112if (tif->tif_cur_cumulated_mem_alloc != 0)113{114TIFFErrorExtR(tif, "TIFFCleanup",115"tif_cur_cumulated_mem_alloc = %" PRIu64 " whereas it "116"should be 0",117(uint64_t)tif->tif_cur_cumulated_mem_alloc);118}119120_TIFFfreeExt(NULL, tif);121}122123/************************************************************************/124/* _TIFFCleanupIFDOffsetAndNumberMaps() */125/************************************************************************/126127void _TIFFCleanupIFDOffsetAndNumberMaps(TIFF *tif)128{129if (tif->tif_map_dir_offset_to_number)130{131TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number);132tif->tif_map_dir_offset_to_number = NULL;133}134if (tif->tif_map_dir_number_to_offset)135{136TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset);137tif->tif_map_dir_number_to_offset = NULL;138}139}140141/************************************************************************/142/* TIFFClose() */143/************************************************************************/144145/**146* Close a previously opened TIFF file.147*148* TIFFClose closes a file that was previously opened with TIFFOpen().149* Any buffered data are flushed to the file, including the contents of150* the current directory (if modified); and all resources are reclaimed.151*152* @param tif A TIFF pointer.153*/154155void TIFFClose(TIFF *tif)156{157if (tif != NULL)158{159TIFFCloseProc closeproc = tif->tif_closeproc;160thandle_t fd = tif->tif_clientdata;161162TIFFCleanup(tif);163(void)(*closeproc)(fd);164}165}166167168