2012.06.06 05:05 "[Tiff] Custom and EXIF directory read/write", by Frank Warmerdam
Folks,
I have been working to harden libtiff4 somewhat and one area of problems I have encountered is when custom tags in non-image directories (like EXIF) have the same tag values as real TIFF tags (often through file fuzzing). This results in various kinds of crashes. I have made a bunch of changes to make this more bulletproof.
In order to avoid too many future regressions in this complicated area I wanted to add a test program for custom and exif directory handling and I discovered (as many have before) that libtiff does not support creating EXIF or custom directories. However, it was very close.
So I have added two new functions:
TIFFCreateCustomDirectory()
TIFFCreateEXIFDirectory()
Unfortunately to create or read custom directories with predefined fields it is necessary to include the private tif_dir.h. However, this is not needed for EXIF directories which have a predefined schema.
I have attached the test program which briefly demonstrates creating and reading EXIF and custom directories.
All code is now in CVS.
Possibly I already mentioned it, but I also added a new test program for JPEG-in-TIFF last week including the "raw" IO interface. This has been another very fragile and bug prone area.
Best regards,
--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up | Frank Warmerdam, warmerdam@pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush | Geospatial Software Developer
/* $Id: custom_dir.c,v 1.1 2012-06-06 04:58:29 fwarmerdam Exp $ */
/*
* Copyright (c) 2012, Frank Warmerdam <warmerdam@pobox.com>
*
- 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
*
* Module to handling of custom directories like EXIF.
*/
#include "tif_config.h"
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "tiffio.h"
#include "tif_dir.h"
#include "tifftest.h"
static const char filename[] = "custom_dir.tif";
#define SPP 3 /* Samples per pixel */
const uint16 width = 1;
const uint16 length = 1;
const uint16 bps = 8;
const uint16 photometric = PHOTOMETRIC_RGB;
const uint16 rows_per_strip = 1;
const uint16 planarconfig = PLANARCONFIG_CONTIG;
static TIFFField
customFields[] = {
{ TIFFTAG_IMAGEWIDTH, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Custom1", NULL },
{ TIFFTAG_DOTRANGE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Custom2", NULL },
};
static TIFFFieldArray customFieldArray = { tfiatOther, 0, 2, customFields };
int
main()
{
TIFF *tif;
unsigned char buf[SPP] = { 0, 127, 255 };
uint64 dir_offset = 0, dir_offset2 = 0;
uint64 read_dir_offset = 0, read_dir_offset2 = 0;
uint64 *dir_offset2_ptr = NULL;
char *ascii_value;
uint16 count16 = 0;
/* We write the main directory as a simple image. */
tif = TIFFOpen(filename, "w+");
if (!tif) {
fprintf (stderr, "Can't create test TIFF file %s.\n", filename);
return 1;
}
if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width)) {
fprintf (stderr, "Can't set ImageWidth tag.\n");
goto failure;
}
if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, length)) {
fprintf (stderr, "Can't set ImageLength tag.\n");
goto failure;
}
if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps)) {
fprintf (stderr, "Can't set BitsPerSample tb