/*
 * Copyright (c) 1988-1997 Sam Leffler
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Sam Leffler and Silicon Graphics.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

/*
 * TIFF Library.
 */
#include "tiffiop.h"
#include <string.h>

/************************************************************************/
/*                            TIFFCleanup()                             */
/************************************************************************/

/**
 * Auxiliary function to free the TIFF structure. Given structure will be
 * completely freed, so you should save opened file handle and pointer
 * to the close procedure in external variables before calling
 * _TIFFCleanup(), if you will need these ones to close the file.
 *
 * @param tif A TIFF pointer.
 */

void TIFFCleanup(TIFF *tif)
{
    /*
     * Flush buffered data and directory (if dirty).
     */
    if (tif->tif_mode != O_RDONLY)
        TIFFFlush(tif);
    (*tif->tif_cleanup)(tif);
    TIFFFreeDirectory(tif);

    TIFFHashSetDestroy(tif->tif_map_dir_offset_to_number);
    TIFFHashSetDestroy(tif->tif_map_dir_number_to_offset);

    /*
     * Clean up client info links.
     */
    while (tif->tif_clientinfo)
    {
        TIFFClientInfoLink *psLink = tif->tif_clientinfo;

        tif->tif_clientinfo = psLink->next;
        _TIFFfreeExt(tif, psLink->name);
        _TIFFfreeExt(tif, psLink);
    }

    if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))
        _TIFFfreeExt(tif, tif->tif_rawdata);
    if (isMapped(tif))
        TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);

    /*
     * Clean up custom fields.
     */
    if (tif->tif_fields && tif->tif_nfields > 0)
    {
        uint32_t i;

        for (i = 0; i < tif->tif_nfields; i++)
        {
            TIFFField *fld = tif->tif_fields[i];
            if (fld->field_name != NULL)
            {
                if (fld->field_bit == FIELD_CUSTOM &&
                    /* caution: tif_fields[i] must not be the beginning of a
                     * fields-array. Otherwise the following tags are also freed
                     * with the first free().
                     */
                    TIFFFieldIsAnonymous(fld))
                {
                    _TIFFfreeExt(tif, fld->field_name);
                    _TIFFfreeExt(tif, fld);
                }
            }
        }

        _TIFFfreeExt(tif, tif->tif_fields);
    }

    if (tif->tif_nfieldscompat > 0)
    {
        uint32_t i;

        for (i = 0; i < tif->tif_nfieldscompat; i++)
        {
            if (tif->tif_fieldscompat[i].allocated_size)
                _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
        }
        _TIFFfreeExt(tif, tif->tif_fieldscompat);
    }

    _TIFFfreeExt(NULL, tif);
}

/************************************************************************/
/*                            TIFFClose()                               */
/************************************************************************/

/**
 * Close a previously opened TIFF file.
 *
 * TIFFClose closes a file that was previously opened with TIFFOpen().
 * Any buffered data are flushed to the file, including the contents of
 * the current directory (if modified); and all resources are reclaimed.
 *
 * @param tif A TIFF pointer.
 */

void TIFFClose(TIFF *tif)
{
    TIFFCloseProc closeproc = tif->tif_closeproc;
    thandle_t fd = tif->tif_clientdata;

    TIFFCleanup(tif);
    (void)(*closeproc)(fd);
}
