2012.06.06 05:05 "[Tiff] Custom and EXIF directory read/write", by Frank Warmerdam

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>
 *

 */

/*
 * 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