summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Leigh <rleigh@codelibre.net>2021-01-02 22:41:23 +0000
committerRoger Leigh <rleigh@codelibre.net>2021-01-02 22:41:23 +0000
commit290ef04b7383a4b6e1f972d06b863a4d9a1719b1 (patch)
tree0b10baf6bf6cc8ee74643da579ef582c8ff44f90
parentf2bc2e9d6b34d1f70ad2d48237a21dfdcfaed9c8 (diff)
parentfa9266f3c7dbcc81879d849f0f24826510b19b17 (diff)
downloadlibtiff-git-290ef04b7383a4b6e1f972d06b863a4d9a1719b1.tar.gz
Merge branch 'codespell-custom_dir_EXIF_231' into 'master'
custom_dir_EXIF_231.c: dos2unix and codespell See merge request libtiff/libtiff!184
-rw-r--r--test/custom_dir_EXIF_231.c2795
1 files changed, 1397 insertions, 1398 deletions
diff --git a/test/custom_dir_EXIF_231.c b/test/custom_dir_EXIF_231.c
index 854b19a9..627edf84 100644
--- a/test/custom_dir_EXIF_231.c
+++ b/test/custom_dir_EXIF_231.c
@@ -1,1398 +1,1397 @@
-
-/*
- * 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 copied from custom_dir.c --
- *=========== Purpose ===================================================================================
- * Extended and amended version for testing of EXIF 2.32, GPS and handling of custom fields.
- * EXIF 2.32 and GPS are defined in amended files tif_dirinfo.c, tif_dirread.c, tiff.h, tiffio.h, tif_dir.h, tif_dir.c
- *
- *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values are defined as double precision
- * and need to be written and also read in double precision!
- * In order to maintain this code for both cases, it is checked above if the TiffLibrary is
- * compiled with the new interface with Rational2Double or still uses the old definitions,
- * by setting blnIsRational2Double above.
- *
- */
-
-
-/*------------
- * This version writes the GPS and EXIF tags correctly, without additonal main-IFD and parameters!
- * In contrary, custom_dir.c does write additional main-IFD and parameters to file.
- -------------*/
-
-
-#define FOR_AUTO_TESTING
-#ifdef FOR_AUTO_TESTING
-/* Only for automake and CMake infrastructure the test should:
- a.) delete any written testfiles when test passed (otherwise autotest will fail)
- b.) goto failure, if any failure is detected, which is not necessary when test is initiated manually for debugging
-*/
-#define GOTOFAILURE goto failure;
-#define GOTOFAILURE_GPS goto failure;
-#define GOTOFAILURE_ALL_EXIF goto failure;
-#else
-#define GOTOFAILURE
-#define GOTOFAILURE_GPS
-#define GOTOFAILURE_ALL_EXIF
-#endif
-
-
-#ifdef _MSC_VER
-#pragma warning( disable : 4101)
-#endif
-
-#include "tif_config.h"
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <errno.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#include "tiffio.h"
-#include "tiffiop.h"
-#include "tif_dir.h"
-#include "tifftest.h"
-
-
-
-int write_test_tiff(TIFF *tif, const char *filenameRead);
-
-static const char filename[] = "custom_dir_EXIF_231.tif";
-static const char filenameBigTiff[] = "custom_dir_EXIF_231_Big.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;
-
-
-int
-main()
-{
- TIFF *tif;
- int ret, ret1, ret2;
-
- fprintf(stderr, "==== Test automatically if all EXIF and GPS tags are written/read correctly. ====\n");
- /* --- Test with Classic-TIFF ---*/
- /* delete file, if exists */
- ret = unlink(filename);
- if (ret != 0 && errno != ENOENT) {
- fprintf(stderr, "Can't delete test TIFF file %s.\n", filename);
- }
-
- /* 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;
- }
- fprintf(stderr, "-------- Test with ClassicTIFF started ----------\n");
- ret1 = write_test_tiff(tif, filename);
-
- if (ret1 > 0) return(ret1);
-
- /*--- Test with BIG-TIFF ---*/
- /* delete file, if exists */
- ret = unlink(filenameBigTiff);
- if (ret != 0 && errno != ENOENT) {
- fprintf(stderr, "Can't delete test TIFF file %s.\n", filenameBigTiff);
- }
-
- tif = TIFFOpen(filenameBigTiff, "w8");
- if (!tif) {
- fprintf(stderr, "Can't create test TIFF file %s.\n", filenameBigTiff);
- return 1;
- }
- fprintf(stderr, "\n\n-------- Test with BigTIFF started ----------\n");
- ret2 = write_test_tiff(tif, filenameBigTiff);
-
- if (ret2 > 0) return(ret2 + 10); else return(ret2);
-
-} /* main() */
-
-
-
-
-
-
-
-int
-write_test_tiff(TIFF *tif, const char *filenameRead)
-{
- unsigned char buf[SPP] = { 0, 127, 255 };
- uint64 dir_offset = 0;
- uint64 dir_offset_GPS = 0, dir_offset_EXIF = 0;
- uint64 read_dir_offset = 0;
- /*-- Additional variables --*/
- int retCode, retCode2;
- unsigned char exifVersion[4] = {'0','2','3','1'}; /* EXIF 2.31 version is 4 characters of a string! */
- unsigned char gpsVersion[4] = {2,2,0,1}; /* GPS Version is 4 numbers! */
- unsigned char *pGpsVersion;
- float auxFloat = 0.0f;
- double auxDouble = 0.0;
- char auxChar = 0;
- uint32 auxUint32 = 0;
- short auxShort=0;
- long auxLong = 0;
- void *pVoid;
- int blnIsRational2Double;
-
- int i, j;
- long nTags;
-
- const TIFFFieldArray* tFieldArray;
- unsigned long tTag;
- TIFFDataType tType;
- short tWriteCount;
- TIFFSetGetFieldType tSetFieldType;
- char *tFieldName;
- const TIFFField *fip;
-
- char blnFillGPSManually = 1;
-
-#define STRSIZE 1000
-#define N_SIZE 120
-#define VARIABLE_ARRAY_SIZE 6
-
- /* -- Test data for writing -- */
- char auxCharArrayW[N_SIZE];
- short auxShortArrayW[N_SIZE];
- long auxLongArrayW[N_SIZE];
- float auxFloatArrayW[N_SIZE];
- double auxDoubleArrayW[N_SIZE];
- char auxTextArrayW[N_SIZE][STRSIZE];
- double auxDoubleArrayGPS1[3] = {1.0/7.0, 61.23456789012345, 62.0};
- double auxDoubleArrayGPS2[3] = {1.0/19.0, 88.34434, 15.12345678901234567890};
- double auxDoubleArrayGPSTime[3] = {22.0, 17.0, 15.3456789};
- double auxDoubleGPSAltitude = 3456.0;
- double auxDoubleGPSDirection = 63.7;
- float auxFloatArrayN1[3] = { 1.0f / 7.0f, 61.23456789012345f, 62.3f };
- float auxFloatArrayN2[3] = { -1.0f / 7.0f, -61.23456789012345f, -62.3f };
-
- /* -- Variables for reading -- */
- uint16 count16 = 0;
- union {
- long Long;
- short Short1;
- short Short2[2];
- char Char[4];
- } unionLong;
- union {
- double dbl;
- float flt1;
- float flt2;
- } auxDblUnion;
- void *pVoidArray;
- char *pAscii;
- char auxCharArray[2*STRSIZE];
- short auxShortArray[2*N_SIZE];
- long auxLongArray[2*N_SIZE];
- float auxFloatArray[2*N_SIZE];
- double auxDoubleArray[2*N_SIZE];
- double dblDiff, dblDiffLimit;
-#define RATIONAL_EPS (1.0/30000.0) /* reduced difference of rational values, approx 3.3e-5 */
-
- /*-- Fill test data arrays for writing ----------- */
- for (i=0; i<N_SIZE; i++) {
- sprintf(auxTextArrayW[i],"N%d-String-%d_tttttttttttttttttttttttttttttx", i, i);
- }
- for (i=0; i<N_SIZE; i++) {
- auxCharArrayW[i] = (char)(i+1);
- }
- for (i=0; i<N_SIZE; i++) {
- auxShortArrayW[i] = (short)(i+1)*7;
- }
- for (i=0; i<N_SIZE; i++) {
- auxLongArrayW[i] = (i+1)*133;
- }
- for (i=0; i<N_SIZE; i++) {
- auxFloatArrayW[i] = (float)((i+1)*133)/3.3f;
- }
- for (i=0; i<N_SIZE; i++) {
- auxDoubleArrayW[i] = (double)((i+1)*3689)/4.5697;
- }
-
- /*-- Setup standard tags of a simple tiff file --*/
- 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 tag.\n");
- goto failure;
- }
- if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, SPP)) {
- fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
- goto failure;
- }
- if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rows_per_strip)) {
- fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
- goto failure;
- }
- if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, planarconfig)) {
- fprintf (stderr, "Can't set PlanarConfiguration tag.\n");
- goto failure;
- }
- if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
- fprintf (stderr, "Can't set PhotometricInterpretation tag.\n");
- goto failure;
- }
-
-#define ADDITIONAL_TAGS
-#ifdef ADDITIONAL_TAGS
- /*-- Additional tags to check Rational standard tags, which are also defined as FIELD_CUSTOM */
-
- /*- TIFFTAG_INKSET is a SHORT parameter (TIFF_SHORT, TIFF_SETGET_UINT16) with field_bit=FIELD_CUSTOM !! -*/
- if (!TIFFSetField(tif, TIFFTAG_INKSET, 34)) {
- fprintf(stderr, "Can't set TIFFTAG_INKSET tag.\n");
- goto failure;
- }
-
- /*- TIFFTAG_PIXAR_FOVCOT is a FLOAT parameter ( TIFF_FLOAT, TIFF_SETGET_FLOAT) with field_bit=FIELD_CUSTOM !! -*/
- /* - can be written with Double but has to be read with float parameter */
-#define PIXAR_FOVCOT_VAL 5.123456789123456789
- auxFloat = (float)PIXAR_FOVCOT_VAL;
- auxDouble = (double)PIXAR_FOVCOT_VAL;
- if (!TIFFSetField(tif, TIFFTAG_PIXAR_FOVCOT, auxDouble)) {
- fprintf(stderr, "Can't set TIFFTAG_PIXAR_FOVCOT tag.\n");
- goto failure;
- }
- /*- TIFFTAG_STONITS is a DOUBLE parameter (TIFF_DOUBLE, TIFF_SETGET_DOUBLE) with field_bit=FIELD_CUSTOM!
- * Only TIFFTAG_STONITS is a TIFF_DOUBLE, which has to be read as DOUBLE!!
- */
-#define STONITS_VAL 6.123456789123456789
- auxDouble = STONITS_VAL;
- auxFloat = (float)auxDouble;
- if (!TIFFSetField(tif, TIFFTAG_STONITS, auxDouble)) {
- fprintf(stderr, "Can't set TIFFTAG_STONITS tag.\n");
- goto failure;
- }
-
- /*- TIFFTAG_YCBCRPOSITIONING is a SHORT parameter */
- auxLong = auxShort = 5;
- if (!TIFFSetField(tif, TIFFTAG_YCBCRPOSITIONING, auxLong )) {
- fprintf (stderr, "Can't set TIFFTAG_YCBCRPOSITIONING tag.\n");
- goto failure;
- }
-
- /* - TIFFTAG_BESTQUALITYSCALE is a Rational parameter, FIELD_CUSTOM and TIFF_SETGET_DOUBLE */
- /* With Rational2Double upgrade tag is redefined to TIFF_SETGET_FLOAT, but can be still written with double. */
-#define BESTQUALITYSCALE_VAL 15.3
- auxDouble = BESTQUALITYSCALE_VAL;
- if (!TIFFSetField(tif, TIFFTAG_BESTQUALITYSCALE, auxDouble )) {
- fprintf (stderr, "Can't set TIFFTAG_BESTQUALITYSCALE tag.\n");
- goto failure;
- }
-
- /* - TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT */
- if (!TIFFSetField(tif, TIFFTAG_BASELINENOISE, auxDouble)) {
- fprintf(stderr, "Can't set TIFFTAG_BASELINENOISE tag.\n");
- goto failure;
- }
-
-
- /*--- For static or variable ARRAYs the case is different ---*/
-/*- Variable Array: TIFFTAG_DECODE is a SRATIONAL parameter TIFF_SETGET_C16_FLOAT type FIELD_CUSTOM with passcount=1 and variable length of array. */
- if (!TIFFSetField(tif, TIFFTAG_DECODE, 3, auxFloatArrayN2)) {
- fprintf(stderr, "Can't set TIFFTAG_DECODE tag.\n");
- goto failure;
- }
-
- /*- Varable Array: TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT */
- if (!TIFFSetField(tif, TIFFTAG_BLACKLEVEL, 3, auxFloatArrayN1)) {
- fprintf(stderr, "Can't set TIFFTAG_BLACKLEVEL tag.\n");
- goto failure;
- }
-
- /*- Fixed Array: TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT */
- if (!TIFFSetField(tif, TIFFTAG_DEFAULTCROPSIZE, &auxFloatArrayW[0])) {
- fprintf(stderr, "Can't set TIFFTAG_DEFAULTCROPSIZE tag.\n");
- goto failure;
- }
-#endif /* -- ADDITIONAL_TAGS -- */
-
-/*================== Rational2Double Interface Check =====================*/
- /*-- Check, if the TiffLibrary is compiled with the new interface with Rational2Double or still uses the old definitions.
- For that, TIFF_RATIONAL tags with FIELD_CUSTOM are changed from TIFF_SETGET_DOUBLE to TIFF_SETGET_FLOAT for the
- new interface in order to prevent the old reading behaviour.
- Tags to check: TIFFTAG_BESTQUALITYSCALE, TIFFTAG_BASELINENOISE, TIFFTAG_BASELINESHARPNESS
- */
- fip = TIFFFindField(tif, TIFFTAG_BESTQUALITYSCALE, TIFF_ANY);
- tSetFieldType = fip->set_field_type;
- if (tSetFieldType == TIFF_SETGET_DOUBLE) {
- blnIsRational2Double = FALSE;
- } else {
- blnIsRational2Double = TRUE;
- fprintf(stderr, "-- Rational2Double from TIFF tag detected --\n");
- }
-
-/*================== Write GPS and EXIF tags =====================*/
-
- /*-- Set dummy EXIF/GPS tag in original tiff-structure in order to reserve space for final dir_offset value, */
- /* which is properly written at the end. */
- dir_offset = 0; /* Zero, in case no Custom-IFD is written */
-
-#define WRITE_GPS_TAGS
-#ifdef WRITE_GPS_TAGS
- if (!TIFFSetField(tif, TIFFTAG_GPSIFD, dir_offset )) {
- fprintf (stderr, "Can't write TIFFTAG_GPSIFD\n" );
- }
-#endif
-
- /*------- And also do the same for the EXIF IFD tag here, because we have to save the main directory next ------*/
- /*-- Set dummy EXIF/GPS tag in original tiff-structure in order to reserve space for final dir_offset value,
- * which is properly written at the end.
- */
-#define WRITE_EXIF_TAGS
-#ifdef WRITE_EXIF_TAGS
- if (!TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset )) {
- fprintf (stderr, "Can't write TIFFTAG_EXIFIFD\n" );
- }
-#endif
-
-#ifndef WRITEPIXELLAST
- /*-- Write dummy pixel data. --*/
- if (TIFFWriteScanline(tif, buf, 0, 0) < 0) {
- fprintf (stderr, "Can't write image data.\n");
- goto failure;
- }
-#endif
-
-
-#ifdef WRITE_GPS_TAGS
-#define READ_GPS_TAGS
- /*================== Write GPS tags =====================*/
-
- /*-- Save current tiff-directory to file before directory is changed. Otherwise it will be lost! */
- /* The tif-structure is overwritten/ freshly initialized by any "CreateDirectory" */
- /*retCode = TIFFCheckpointDirectory(tif);*/ /* does not cleanup Tiff-Structure */
- retCode = TIFFWriteDirectory(tif); /* cleanup Tiff-structure */
-
- /*-- Now create a GPS directory. */
- if (TIFFCreateGPSDirectory(tif) != 0) {
- fprintf (stderr, "TIFFCreateGPSDirectory() failed.\n" );
- goto failure;
- }
-
- if (!TIFFSetField( tif, GPSTAG_VERSIONID, gpsVersion)) {
- fprintf (stderr, "Can't write GPSTAG_VERSIONID\n" );
- goto failure;
- }
-
- if (blnFillGPSManually) {
- /*================= Write manually valid data to the GPS fields ==============*/
- if (!TIFFSetField( tif, GPSTAG_LATITUDEREF, "N\0")) {
- fprintf (stderr, "Can't write GPSTAG_LATITUDEREF\n" );
- goto failure;
- }
- /*-- Unfortunately, Rational values are defined as SETGET_DOUBLE but are internally always stored as float.
- * Single Rational values do not matter for writing, because TIFFSetField() uses va_arg() which performs "variables promotion" from type float to type double!
- * However, for reading of Rational values ONLY float-variables are allowed - in contrary to the SETGET_DOUBLE specification at tiffFields[] in tif_dirinfo.c.
- */
- /*-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values are defined as double precision
- * and need to be written and also read in double precision!
- * In order to maintain this code for both cases, it is checked above if the TiffLibrary is
- * compiled with the new interface with Rational2Double or still uses the old definitions,
- * by setting blnIsRational2Double above.
- */
- if (blnIsRational2Double) {
- fprintf(stderr, "-- GPS tags are written using Rational2Double --\n");
- } else {
- fprintf(stderr, "-- GPS tags are written using standard --\n");
- }
- if (!blnIsRational2Double) {
- for (j = 0; j < 3; j++) auxFloatArray[j] = (float)auxDoubleArrayGPS1[j];
- if (!TIFFSetField(tif, GPSTAG_LATITUDE, auxFloatArray)) {
- fprintf(stderr, "Can't write GPSTAG_LATITUDE\n");
- goto failure;
- }
- } else {
- /* Rational2Double interface for GPSTAG */
- if (!TIFFSetField(tif, GPSTAG_LATITUDE, auxDoubleArrayGPS1)) {
- fprintf(stderr, "Can't write GPSTAG_LATITUDE\n");
- goto failure;
- }
- }
- if (!TIFFSetField( tif, GPSTAG_LONGITUDEREF, "W\0")) {
- fprintf (stderr, "Can't write GPSTAG_LONGITUDEREF\n" );
- goto failure;
- }
- if (!blnIsRational2Double) {
- for (j=0; j<3; j++) auxFloatArray[j] = (float)auxDoubleArrayGPS2[j];
- if (!TIFFSetField( tif, GPSTAG_LONGITUDE, auxFloatArray)) {
- fprintf (stderr, "Can't write GPSTAG_LONGITUDE\n" );
- goto failure;
- }
- } else {
- /* Rational2Double interface for GPSTAG */
- if (!TIFFSetField(tif, GPSTAG_LONGITUDE, auxDoubleArrayGPS2)) {
- fprintf(stderr, "Can't write GPSTAG_LATITUDE\n");
- goto failure;
- }
- }
- /*-- AltitudeRef: default is above sea level!! */
- if (!TIFFSetField( tif, GPSTAG_ALTITUDEREF, 0)) {
- fprintf (stderr, "Can't write GPSTAG_ALTITUDEREF\n" );
- goto failure;
- }
- if (!TIFFSetField( tif, GPSTAG_ALTITUDE, auxDoubleGPSAltitude)) {
- fprintf (stderr, "Can't write GPSTAG_ALTITUDE\n" );
- goto failure;
- }
- /*-- TimeStamp is only hh:mm:ss. See also DateTime string */
- if (!TIFFSetField( tif, GPSTAG_TIMESTAMP, auxDoubleArrayGPSTime)) {
- fprintf (stderr, "Can't write GPSTAG_TIMESTAMP\n" );
- goto failure;
- }
- if (!TIFFSetField( tif, GPSTAG_DATESTAMP, "2012:11:04")) {
- fprintf (stderr, "Can't write GPSTAG_DATESTAMP\n" );
- goto failure;
- }
-
- if (!TIFFSetField( tif, GPSTAG_IMGDIRECTIONREF, "T\0")) {
- fprintf (stderr, "Can't write GPSTAG_IMGDIRECTIONREF\n" );
- goto failure;
- }
- if (!TIFFSetField( tif, GPSTAG_IMGDIRECTION, auxDoubleGPSDirection)) {
- fprintf (stderr, "Can't write GPSTAG_IMGDIRECTION\n" );
- goto failure;
- }
-
- /*-- Type TIFF_UNDEFINED */
- if (!TIFFSetField( tif, GPSTAG_PROCESSINGMETHOD, 3, &auxCharArrayW[10])) {
- fprintf (stderr, "Can't write GPSTAG_PROCESSINGMETHOD\n" );
- goto failure;
- }
- if (!TIFFSetField( tif, GPSTAG_AREAINFORMATION, 4, &auxCharArrayW[20])) {
- fprintf (stderr, "Can't write GPSTAG_AREAINFORMATION\n" );
- goto failure;
- }
-
- /*-- PSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 */
- if (!TIFFSetField( tif, GPSTAG_DIFFERENTIAL, auxShortArrayW[5])) {
- fprintf (stderr, "Can't write GPSTAG_DIFFERENTIAL\n" );
- goto failure;
- }
-
- /* GPSTAG_GPSHPOSITIONINGERROR , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE but here written in float-precision */
-#define GPSHPOSITIONINGERROR_VAL 0.369
- auxFloat = (float)GPSHPOSITIONINGERROR_VAL;
- if (!TIFFSetField( tif, GPSTAG_GPSHPOSITIONINGERROR, auxFloat)) {
- fprintf (stderr, "Can't write GPSTAG_GPSHPOSITIONINGERROR\n" );
- goto failure;
- }
-
- } else {
- /*================= Write arbitrary data to the GPS fields ==============*/
-
- /*-- Get array, where GPS tag fields are defined --*/
- tFieldArray = _TIFFGetGpsFields();
- nTags = tFieldArray->count;
-
- /*-- TODO: fill in the for / switch part of EXIF writing, when finished and tested!! */
-
- } /*-- if (blnFillGPSManually) --*/
-
-
-
-
- /*-- GPS - write custom directory GPS into file...---*/
- /* (Get back the offset of GPS directory) */
- if (!TIFFWriteCustomDirectory( tif, &dir_offset_GPS )) {
- fprintf (stderr, "TIFFWriteCustomDirectory() with GPS failed.\n");
- goto failure;
- }
-
- /*--- CheckpointDirectory at this place generates a second Main-IFD!!! */
- /* retCode = TIFFCheckpointDirectory(tif); */
-
- /*-- Set / reload previously saved main directory from file ---*/
- if (!TIFFSetDirectory(tif, 0)) {
- fprintf (stderr, "TIFFSetDirectory() within GPS failed.\n");
- goto failure;
- }
-
- /*-- Write GPS tag reference / offset into GPSIFD tag in main directory --*/
- if (!TIFFSetField(tif, TIFFTAG_GPSIFD, dir_offset_GPS )) {
- fprintf (stderr, "Can't write TIFFTAG_GPSIFD\n");
- goto failure;
- }
-
- /*=============== END writing GPS tags ==========================*/
-#endif /*-- WRITE_GPS_TAGS --*/
-
-
-/*================== Write EXIF 2.31 tags =====================*/
-
- /*-- Set dummy EXIF/GPS tag in original tiff-structure in order to reserve space for final dir_offset value, */
- /* which is properly written at the end.*/
- /*- We did this already above together with the GPS IFD-tag. Otherwise we would do this here !! --------*/
- /* if (!TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset )) {
- fprintf (stderr, "Can't write TIFFTAG_EXIFIFD\n" );
- }
- */
-
-#ifdef WRITE_EXIF_TAGS
-#define READ_EXIF_TAGS
- /*-- Save current tiff-directory to file before directory is changed. Otherwise it will be lost!
- * The tif-structure is overwritten/ freshly initialized by any "CreateDirectory"
- */
-
- /*----- What is needed here ??? ----
- * In custom_dir.c only TIFFFreeDirectory( tif ); is used to set fields of another Sub-Directory
- * TIFFFreeDirectory(tif); *-- Release storage associated with a directory, especially custom-fields.
- *-- Using only TIFFFreeDirectory() here leads to an error!!
- *-- Using here TIFFCheckpointDirectory() leads to an additional Main-IFD ??
- */
- /*retCode = TIFFCheckpointDirectory(tif);*/ /* does not cleanup Tiff-Structure */
- retCode = TIFFWriteDirectory(tif); /* cleanup Tiff-structure */
-
- /*-- Now create an EXIF directory. */
- if (TIFFCreateEXIFDirectory(tif) != 0) {
- fprintf (stderr, "TIFFCreateEXIFDirectory() failed.\n" );
- goto failure;
- }
-
-#define WRITE_ALL_EXIF_TAGS
-#ifdef WRITE_ALL_EXIF_TAGS
-#define READ_ALL_EXIF_TAGS
- /*================= EXIF: Write arbitrary data to the EXIF fields ==============*/
- /*-- Get array, where EXIF tag fields are defined
- * EXIF tags are written automatically with the defined precision according to its tSetFieldType using the code below --*/
- tFieldArray = _TIFFGetExifFields();
- nTags = tFieldArray->count;
-
- for (i=0; i<nTags; i++) {
- tTag = tFieldArray->fields[i].field_tag;
- tType = tFieldArray->fields[i].field_type; /* e.g. TIFF_RATIONAL */
- tWriteCount = tFieldArray->fields[i].field_writecount;
- tSetFieldType = tFieldArray->fields[i].set_field_type; /* e.g. TIFF_SETGET_C0_FLOAT */
- tFieldName = tFieldArray->fields[i].field_name;
- pVoid = NULL;
-
- /*-- dependent on set_field_type write value --*/
- switch (tSetFieldType)
- {
- case TIFF_SETGET_ASCII:
- /* Either the stringlength is defined as a fixed length in .field_writecount or a NULL-terminated string is used. */
- /* Shorter strings than in auxTextArraxW need a NULL-termination. Therefore copy the string. */
- if (tWriteCount > 0) auxLong = tWriteCount-1; else auxLong = (long)strlen(auxTextArrayW[i])-1;
- strncpy(auxCharArray, auxTextArrayW[i], auxLong);
- auxCharArray[auxLong] = 0;
- if (!TIFFSetField( tif, tTag, auxCharArray)) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- break;
- case TIFF_SETGET_UINT8:
- case TIFF_SETGET_UINT16:
- case TIFF_SETGET_UINT32:
- case TIFF_SETGET_IFD8:
- case TIFF_SETGET_INT:
- /*-- All those can be written with char, short or long parameter. Only value range should be in line. */
- if (!TIFFSetField( tif, tTag, auxLongArrayW[i])) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- break;
- case TIFF_SETGET_SINT8:
- case TIFF_SETGET_SINT16:
- case TIFF_SETGET_SINT32:
- /*-- All those can be written with char, short or long parameter. Only value range should be in line. */
- if (!TIFFSetField( tif, tTag, -1.0*auxLongArrayW[i])) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- break;
- case TIFF_SETGET_FLOAT:
- case TIFF_SETGET_DOUBLE:
- if (tWriteCount == 1) {
- /*-- All single values can be written with float or double parameter. Only value range should be in line. */
- if (!TIFFSetField( tif, tTag, auxDoubleArrayW[i])) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- } else {
- fprintf (stderr, "WriteCount for .set_field_type %d should be 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
- }
- break;
- case TIFF_SETGET_C0_FLOAT:
- case TIFF_SETGET_C0_DOUBLE:
- case TIFF_SETGET_C16_FLOAT:
- case TIFF_SETGET_C16_DOUBLE:
- case TIFF_SETGET_C32_FLOAT:
- case TIFF_SETGET_C32_DOUBLE:
- /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
- /*-- Check, if it is a single parameter, a fixed array or a variable array */
- if (tWriteCount == 1) {
- fprintf (stderr, "WriteCount for .set_field_type %d should be -1 or greather than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
- } else {
- /*-- Either fix or variable array --*/
- /* For arrays, distinguishing between float or double is essential, even for writing */
- if (tSetFieldType == TIFF_SETGET_C0_FLOAT || tSetFieldType == TIFF_SETGET_C16_FLOAT || tSetFieldType == TIFF_SETGET_C32_FLOAT)
- pVoid = &auxFloatArrayW[i]; else pVoid = &auxDoubleArrayW[i];
- /* Now decide between fixed or variable array */
- if (tWriteCount > 1) {
- /* fixed array with needed arraysize defined in .field_writecount */
- if (!TIFFSetField( tif, tTag, pVoid)) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- } else {
- /* special treatment of variable array */
- /* for test, use always arraysize of VARIABLE_ARRAY_SIZE */
- if (!TIFFSetField( tif, tTag, VARIABLE_ARRAY_SIZE, pVoid)) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- }
- }
- break;
- case TIFF_SETGET_C0_UINT8:
- case TIFF_SETGET_C0_SINT8:
- case TIFF_SETGET_C16_UINT8:
- case TIFF_SETGET_C16_SINT8:
- case TIFF_SETGET_C32_UINT8:
- case TIFF_SETGET_C32_SINT8:
- /* For arrays, distinguishing between float or double is essential, even for writing */
- pVoid = &auxCharArrayW[i];
- case TIFF_SETGET_C0_UINT16:
- case TIFF_SETGET_C0_SINT16:
- case TIFF_SETGET_C16_UINT16:
- case TIFF_SETGET_C16_SINT16:
- case TIFF_SETGET_C32_UINT16:
- case TIFF_SETGET_C32_SINT16:
- if (pVoid == NULL) pVoid = &auxShortArrayW[i];
- case TIFF_SETGET_C0_UINT32:
- case TIFF_SETGET_C0_SINT32:
- case TIFF_SETGET_C16_UINT32:
- case TIFF_SETGET_C16_SINT32:
- case TIFF_SETGET_C32_UINT32:
- case TIFF_SETGET_C32_SINT32:
- if (pVoid == NULL) pVoid = &auxLongArrayW[i];
- /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
- /*-- Check, if it is a single parameter, a fixed array or a variable array */
- if (tWriteCount == 1) {
- fprintf (stderr, "WriteCount for .set_field_type %d should be -1 or greather than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
- } else {
- /*-- Either fix or variable array --*/
- /* Now decide between fixed or variable array */
- if (tWriteCount > 1) {
- /* fixed array with needed arraysize defined in .field_writecount */
- if (!TIFFSetField( tif, tTag, pVoid)) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- } else {
- /* special treatment of variable array */
- /* for test, use always arraysize of VARIABLE_ARRAY_SIZE */
- if (!TIFFSetField( tif, tTag, VARIABLE_ARRAY_SIZE, pVoid)) {
- fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
- goto failure;
- }
- }
- }
- break;
- default:
- fprintf (stderr, "SetFieldType %d not defined within writing switch for %s.\n", tSetFieldType, tFieldName);
- }; /*-- switch() --*/
- } /*-- for() --*/
- /*================= EXIF: END Writing arbitrary data to the EXIF fields END END END ==============*/
-#endif /*-- WRITE_ALL_EXIF_TAGS --*/
-
- /*--- Set valid EXIF version, which is a 4 byte string --*/
- if (!TIFFSetField( tif, EXIFTAG_EXIFVERSION, exifVersion)) {
- fprintf (stderr, "Can't write EXIFTAG_EXIFVERSION\n" );
- goto failure;
- }
-
-
- /*-- EXIF - write custom directory EXIF into file...---*/
- /* (Get back the offset of EXIF directory) */
- if (!TIFFWriteCustomDirectory( tif, &dir_offset_EXIF )) {
- fprintf (stderr, "TIFFWriteCustomDirectory() with EXIF failed.\n");
- goto failure;
- }
-
- /*-- Go back to the first (main) directory, and set correct value of the EXIFIFD pointer. */
- /* (directory is reloaded from file!) */
- TIFFSetDirectory(tif, 0);
- TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset_EXIF );
-#endif /*-- WRITE_EXIF_TAGS --*/
-
-#ifdef WRITEPIXELLAST
- /*-- Write dummy pixel data. --*/
- if (TIFFWriteScanline(tif, buf, 0, 0) < 0) {
- fprintf (stderr, "Can't write image data.\n");
- goto failure;
- }
-#endif
- /*-- Write directory to file --*/
- /* Always WriteDirectory before using/creating another directory. */
- /* Not necessary before TIFFClose(), however, TIFFClose() uses TIFFReWriteDirectory(), which forces directory to be written at another location. */
- retCode = TIFFWriteDirectory(tif);
-
- /*-- Write File to disk and close file --*/
- /* TIFFClose() uses TIFFReWriteDirectory(), which forces directory to be written at another location. */
- /* Therefore, better use TIFFWriteDirectory() before. */
- TIFFClose(tif);
-
- fprintf (stderr, "-------- Continue Test ---------- reading ...\n");
-
-/*========================= READING ============= READING ========================================*/
- /* Ok, now test whether we can read written values correctly. */
- tif = TIFFOpen(filenameRead, "r");
-
-
- /*-- Read some parameters out of the main directory --*/
-
- /*-- IMAGEWIDTH and -LENGTH are defined as TIFF_SETGET_UINT32 */
- retCode = TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &auxUint32 );
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_IMAGEWIDTH"); }
- if (auxUint32 != width) {
- fprintf (stderr, "Read value of IMAGEWIDTH %d differs from set value %d\n", auxUint32, width);
- }
- retCode = TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &auxUint32 );
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_IMAGELENGTH"); }
- if (auxUint32 != width) {
- fprintf (stderr, "Read value of TIFFTAG_IMAGELENGTH %d differs from set value %d\n", auxUint32, length);
- }
-
-#ifdef ADDITIONAL_TAGS
- /*- TIFFTAG_PIXAR_FOVCOT is a FLOAT parameter of type FIELD_CUSTOM !! */
- retCode = TIFFGetField(tif, TIFFTAG_PIXAR_FOVCOT, &auxFloat );
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_PIXAR_FOVCOT"); }
- if (auxFloat != (float)PIXAR_FOVCOT_VAL) {
- fprintf (stderr, "Read value of TIFFTAG_PIXAR_FOVCOT %f differs from set value %f\n", auxFloat, PIXAR_FOVCOT_VAL);
- }
-
- /* - TIFFTAG_BESTQUALITYSCALE is a Rational parameter, FIELD_CUSTOM and TIFF_SETGET_FLOAT */
- retCode = TIFFGetField(tif, TIFFTAG_BESTQUALITYSCALE, &auxFloat );
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_BESTQUALITYSCALE"); }
- if (auxFloat != (float)BESTQUALITYSCALE_VAL) {
- fprintf (stderr, "Read value of TIFFTAG_BESTQUALITYSCALE %f differs from set value %f\n", auxFloat, BESTQUALITYSCALE_VAL);
- }
-
- /* - TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT */
- retCode = TIFFGetField(tif, TIFFTAG_BASELINENOISE, &auxDblUnion.dbl);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_BASELINENOISE"); }
- if (auxDblUnion.flt1 != (float)BESTQUALITYSCALE_VAL) {
- fprintf(stderr, "Read float value of TIFFTAG_BASELINENOISE %f differs from set value %f\n", auxDblUnion.flt1, BESTQUALITYSCALE_VAL);
- }
-
-
- /*- Variable Array: TIFFTAG_DECODE is a SRATIONAL parameter TIFF_SETGET_C16_FLOAT type FIELD_CUSTOM with passcount=1 and variable length of array. */
- retCode = TIFFGetField(tif, TIFFTAG_DECODE, &count16, &pVoidArray );
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_DECODE"); }
- /*- pVoidArray points to a Tiff-internal temporary memorypart. Thus, contents needs to be saved. */
- memcpy(&auxFloatArray, pVoidArray,(count16 * sizeof(auxFloatArray[0])));
- for (i=0; i<count16; i++) {
- dblDiffLimit = RATIONAL_EPS*auxFloatArrayN2[i];
- dblDiff = auxFloatArray[i] - auxFloatArrayN2[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf (stderr, "Read value %d of TIFFTAG_DECODE Array %f differs from set value %f\n", i, auxFloatArray[i], auxFloatArrayN2[i]);
- }
- }
-
- retCode = TIFFGetField(tif, TIFFTAG_BLACKLEVEL, &count16, &pVoidArray);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_BLACKLEVEL"); }
- /*- pVoidArray points to a Tiff-internal temporary memorypart. Thus, contents needs to be saved. */
- memcpy(&auxFloatArray, pVoidArray, (count16 * sizeof(auxFloatArray[0])));
- for (i = 0; i<count16; i++) {
- dblDiffLimit = RATIONAL_EPS*auxFloatArrayN1[i];
- dblDiff = auxFloatArray[i] - auxFloatArrayN1[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value %d of TIFFTAG_BLACKLEVEL Array %f differs from set value %f\n", i, auxFloatArray[i], auxFloatArrayN1[i]);
- }
- }
-
- /*- Fixed Array: TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT */
- retCode = TIFFGetField(tif, TIFFTAG_DEFAULTCROPSIZE, &pVoidArray);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_DEFAULTCROPSIZE"); }
- /*- pVoidArray points to a Tiff-internal temporary memorypart. Thus, contents needs to be saved. */
- memcpy(&auxFloatArray, pVoidArray, (2 * sizeof(auxFloatArray[0])));
- for (i = 0; i < 2; i++) {
- dblDiffLimit = RATIONAL_EPS * auxFloatArrayW[i];
- dblDiff = auxFloatArray[i] - auxFloatArrayW[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value %d of TIFFTAG_DEFAULTCROPSIZE Array %f differs from set value %f\n", i, auxFloatArray[i], auxFloatArrayW[i]);
- }
- }
-
-#endif /*-- ADDITIONAL_TAGS --*/
-
-
-#ifdef READ_GPS_TAGS
-/*================== Reading GPS tags =====================*/
- /*-- First get offset to GPS-directory and set it active (this will destroy previously main directory fields in memory!) */
- retCode = TIFFGetField(tif, TIFFTAG_GPSIFD, &read_dir_offset );
- if (!retCode) {fprintf(stderr, "Can't read %s\n", "TIFFTAG_GPSIFD"); }
- retCode = TIFFReadGPSDirectory(tif, read_dir_offset);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFReadGPSDirectory()"); }
-
- /*-- Now read some parameters from GPS-directory --*/
-
- /*-- Fixed Array: GPS-Version is a fixed array (of 4 characters) */
- retCode = TIFFGetField(tif, GPSTAG_VERSIONID, &pGpsVersion);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_VERSIONID"); }
- else {
- memcpy(auxCharArray, pGpsVersion, sizeof(gpsVersion));
- for (i = 0; i < 4; i++) {
- if (auxCharArray[i] != pGpsVersion[i]) {
- fprintf(stderr, "Read value %d of GPSTAG_VERSIONID %d differs from set value %d\n", i, auxCharArray[i], pGpsVersion[i]);
- }
- }
- }
- /*-- LATITUDEREF is a fixed String of one character plus ending zero. */
- retCode = TIFFGetField(tif, GPSTAG_LATITUDEREF, &pAscii);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LATITUDEREF"); }
- retCode2 = strncmp("N", pAscii, 1);
- if (retCode2 != 0) {
- fprintf (stderr, "Read value %d of GPSTAG_LATITUDEREF %s differs from set value %s\n", i, "N", pAscii);
- }
-
- /*-- Fixed Array: Latitude is an array of 3 Rational-values. TIFFGetField() returns a pointer to a temporary float-/double-array. */
- /*-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values are defined as double precision
- * and need to be written and also read in double precision!
- * In order to maintain this code for both cases, it is checked above if the TiffLibrary is
- * compiled with the new interface with Rational2Double or still uses the old definitions,
- * by setting blnIsRational2Double above.
- */
- if (blnIsRational2Double) {
- fprintf(stderr, "-- GPS tags are read using Rational2Double --\n");
- } else {
- fprintf(stderr, "-- GPS tags are read using standard --\n");
- }
- retCode = TIFFGetField(tif, GPSTAG_LATITUDE, &pVoidArray);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LATITUDE"); }
- if (!blnIsRational2Double) {
- /* Reset arrays for debugging purpose first */
- memset(auxFloatArray, 0, sizeof(auxFloatArray));
- memcpy(auxFloatArray, pVoidArray, 3*sizeof(float));
- /* for comparison copy to doubleArray */
- for (i=0; i<3; i++) auxDoubleArray[i] = (double)auxFloatArray[i];
- } else {
- /* Rational2Double interface for GPSTAG reads double array */
- memset(auxDoubleArray, 0, sizeof(auxDoubleArray));
- memcpy(auxDoubleArray, pVoidArray, 3 * sizeof(double));
- }
- for (i=0; i<3; i++) {
- dblDiffLimit = RATIONAL_EPS*auxDoubleArrayGPS1[i];
- dblDiff = auxDoubleArray[i] - auxDoubleArrayGPS1[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf (stderr, "Read value %d of GPSTAG_LATITUDE %f differs from set value %f\n", i, auxDoubleArray[i], auxDoubleArrayGPS1[i]);
- }
- }
-
- /*-- LONGITUDEREF is a fixed String of one character plus ending zero. */
- retCode = TIFFGetField(tif, GPSTAG_LONGITUDEREF, &pAscii);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LONGITUDEREF"); }
- retCode2 = strncmp("W", pAscii, 1);
- if (retCode2 != 0) {
- fprintf(stderr, "Read value %d of GPSTAG_LONGITUDEREF %s differs from set value %s\n", i, "W", pAscii);
- }
-
- retCode = TIFFGetField(tif, GPSTAG_LONGITUDE, &pVoidArray);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LONGITUDE"); }
- if (!blnIsRational2Double) {
- /* Reset arrays for debugging purpose first */
- memset(auxFloatArray, 0, sizeof(auxFloatArray));
- memcpy(auxFloatArray, pVoidArray, 3 * sizeof(float));
- /* for comparison copy to doubleArray */
- for (i = 0; i < 3; i++) auxDoubleArray[i] = (double)auxFloatArray[i];
- } else {
- /* Rational2Double interface for GPSTAG reads double array */
- memset(auxDoubleArray, 0, sizeof(auxDoubleArray));
- memcpy(auxDoubleArray, pVoidArray, 3 * sizeof(double));
- }
- for (i = 0; i < 3; i++) {
- dblDiffLimit = RATIONAL_EPS * auxDoubleArrayGPS2[i];
- dblDiff = auxDoubleArray[i] - auxDoubleArrayGPS2[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value %d of GPSTAG_LONGITUDE %f differs from set value %f\n", i, auxDoubleArray[i], auxDoubleArrayGPS2[i]);
- }
- }
-
- /* TIFF_RATIONAL, TIFF_SETGET_DOUBLE */
- if (!TIFFGetField(tif, GPSTAG_ALTITUDE, &auxDblUnion.dbl)) {
- fprintf(stderr, "Can't read GPSTAG_ALTITUDE\n");
- GOTOFAILURE_GPS
- }
- if (blnIsRational2Double) {
- /* New interface allows also double precision for TIFF_RATIONAL */
- auxDouble = auxDblUnion.dbl;
- } else {
- /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE alwasy as FLOAT */
- auxDouble = (double)auxDblUnion.flt1;
- }
- /* compare read values with written ones */
- dblDiffLimit = RATIONAL_EPS * auxDoubleGPSAltitude;
- dblDiff = auxDouble - auxDoubleGPSAltitude;
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value of GPSTAG_ALTITUDE %f differs from set value %f\n", auxDouble, auxDoubleGPSAltitude);
- GOTOFAILURE_GPS
- }
-
- /*-- TimeStamp is only hh:mm:ss. See also DateTime string 3, TIFF_RATIONAL, TIFF_SETGET_C0_DOUBLE */
- retCode = TIFFGetField(tif, GPSTAG_TIMESTAMP, &pVoidArray);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_TIMESTAMP"); }
- if (!blnIsRational2Double) {
- /* Reset arrays for debugging purpose first */
- memset(auxFloatArray, 0, sizeof(auxFloatArray));
- memcpy(auxFloatArray, pVoidArray, 3 * sizeof(float));
- /* for comparison copy to doubleArray */
- for (i = 0; i < 3; i++) auxDoubleArray[i] = (double)auxFloatArray[i];
- } else {
- /* Rational2Double interface for GPSTAG reads double array */
- memset(auxDoubleArray, 0, sizeof(auxDoubleArray));
- memcpy(auxDoubleArray, pVoidArray, 3 * sizeof(double));
- }
- for (i = 0; i < 3; i++) {
- dblDiffLimit = RATIONAL_EPS * auxDoubleArrayGPSTime[i];
- dblDiff = auxDoubleArray[i] - auxDoubleArrayGPSTime[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value %d of GPSTAG_TIMESTAMP %f differs from set value %f\n", i, auxDoubleArray[i], auxDoubleArrayGPS2[i]);
- GOTOFAILURE_GPS
- }
- }
-
- /* GPSTAG_IMGDIRECTION --- TIFF_RATIONAL, TIFF_SETGET_DOUBLE */
- if (!TIFFGetField(tif, GPSTAG_IMGDIRECTION, &auxDblUnion.dbl)) {
- fprintf(stderr, "Can't read GPSTAG_IMGDIRECTION\n");
- GOTOFAILURE_GPS
- }
- if (blnIsRational2Double) {
- /* New interface allows also double precision for TIFF_RATIONAL */
- auxDouble = auxDblUnion.dbl;
- } else {
- /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE alwasy as FLOAT */
- auxDouble = (double)auxDblUnion.flt1;
- }
- /* compare read values with written ones */
- dblDiffLimit = RATIONAL_EPS * auxDoubleGPSDirection;
- dblDiff = auxDouble - auxDoubleGPSDirection;
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value of GPSTAG_IMGDIRECTION %f differs from set value %f\n", auxDouble, auxDoubleGPSDirection);
- GOTOFAILURE_GPS
- }
-
- /*-- GPSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 */
- retCode = TIFFGetField(tif, GPSTAG_DIFFERENTIAL, &auxShort);
- if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_DIFFERENTIAL"); }
- if (auxShort != auxShortArrayW[5]) {
- fprintf(stderr, "Read value of GPSTAG_DIFFERENTIAL %d differs from set value %d\n", auxShort, auxShortArrayW[5]);
- GOTOFAILURE_GPS
- }
-
- /*-- GPSHPOSITIONINGERROR - new tag for EXIF 2.31 --*/
- if (!TIFFGetField(tif, GPSTAG_GPSHPOSITIONINGERROR, &auxDblUnion.dbl)) {
- fprintf(stderr, "Can't read GPSTAG_GPSHPOSITIONINGERROR\n");
- GOTOFAILURE_GPS
- }
- if (blnIsRational2Double) {
- /* New interface allows also double precision for TIFF_RATIONAL */
- auxDouble = auxDblUnion.dbl;
- } else {
- /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE alwasy as FLOAT */
- auxDouble = (double)auxDblUnion.flt1;
- }
- /* compare read values with written ones */
- auxFloat = (float)GPSHPOSITIONINGERROR_VAL;
- dblDiffLimit = RATIONAL_EPS * auxFloat;
- dblDiff = auxDouble - auxFloat;
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- fprintf(stderr, "Read value of GPSTAG_GPSHPOSITIONINGERROR %f differs from set value %f\n", auxDouble, auxFloat);
- GOTOFAILURE_GPS
- }
-
- /*=============== END reading GPS tags ==========================*/
-#endif /*-- READ_GPS_TAGS --*/
-
-
-
-/*================== Reading EXIF 2.31 tags =====================*/
-
- /*--- Firstly, get EXIF directory offset from main directory. */
-
- /*-- Go back to the first (main) directory, and get value of the EXIFIFD directory- offset. */
- /* (directory is reloaded from file!) */
- TIFFSetDirectory(tif, 0);
- retCode = TIFFGetField(tif, TIFFTAG_EXIFIFD, &read_dir_offset );
-
-#ifdef READ_EXIF_TAGS
- /*-- Now read EXIF directory from file into memory --*/
- retCode = TIFFReadEXIFDirectory(tif, read_dir_offset);
-
- /*-- Now get some parameters from EXIF-directory (already read into memory) --*/
- retCode = TIFFGetField(tif, EXIFTAG_EXIFVERSION, &pAscii);
-
-
-#ifdef READ_ALL_EXIF_TAGS
- /*-- Get array, where EXIF tag fields are defined --*/
- tFieldArray = _TIFFGetExifFields();
- nTags = tFieldArray->count;
- /*-- Check, if the TiffLibrary is compiled with the new interface with Rational2Double or still uses the old definitions. */
- /* tif points to EXIF tags, so TIFFFindField() can only access the EXIF tag fields */
- fip = TIFFFindField(tif, EXIFTAG_EXPOSURETIME, TIFF_ANY);
- tSetFieldType = fip->set_field_type;
- if (tSetFieldType == TIFF_SETGET_DOUBLE) {
- blnIsRational2Double = FALSE;
- fprintf(stderr, "-- EXIF tags read with standard --\n");
- } else {
- blnIsRational2Double = TRUE;
- fprintf(stderr, "-- Rational2Double for reading EXIF tags detected --\n");
- }
-
- for (i=0; i<nTags; i++) {
- tTag = tFieldArray->fields[i].field_tag;
- tType = tFieldArray->fields[i].field_type; /* e.g. TIFF_RATIONAL */
- tWriteCount = tFieldArray->fields[i].field_writecount;
- tSetFieldType = tFieldArray->fields[i].set_field_type; /* e.g. TIFF_SETGET_C0_FLOAT */
- tFieldName = tFieldArray->fields[i].field_name;
- pVoid = NULL;
-
- /*-- dependent on set_field_type read value --*/
- switch (tSetFieldType)
- {
- case TIFF_SETGET_ASCII:
- /* Either the stringlength is defined as a fixed length in .field_writecount or a NULL-terminated string is used. */
- if (!TIFFGetField( tif, tTag, &pAscii)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* Save string from temporary buffer and compare with written string. */
- strncpy(auxCharArray, pAscii, sizeof(auxCharArray));
- if (tWriteCount > 0) auxLong = tWriteCount-1; else auxLong = (long)strlen(auxCharArray);
- retCode2 = strncmp(auxCharArray, auxTextArrayW[i], auxLong);
- if (retCode2 != 0) {
- fprintf (stderr, "%d:Read value of %s %s differs from set value %s\n", i, tFieldName, auxCharArray, auxTextArrayW[i]);
- GOTOFAILURE_ALL_EXIF
- }
- break;
- /*-- For reading, the parameter size is to be observed !! */
- case TIFF_SETGET_UINT8:
- case TIFF_SETGET_SINT8:
- if (!TIFFGetField( tif, tTag, &auxChar)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* compare read values with written ones */
- auxLong = auxChar;
- if (auxLong != (char)auxLongArrayW[i]) {
- fprintf (stderr, "%d:Read value of %s %ld differs from set value %ld\n", i, tFieldName, auxLong, auxLongArrayW[i]);
- }
- break;
- case TIFF_SETGET_UINT16:
- case TIFF_SETGET_SINT16:
- if (!TIFFGetField( tif, tTag, &auxShort)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* compare read values with written ones */
- auxLong = auxShort;
- if (auxLong != (short)auxLongArrayW[i]) {
- fprintf (stderr, "%d:Read value of %s %ld differs from set value %ld\n", i, tFieldName, auxLong, auxLongArrayW[i]);
- }
- break;
- case TIFF_SETGET_UINT32:
- case TIFF_SETGET_SINT32:
- case TIFF_SETGET_IFD8:
- case TIFF_SETGET_INT:
- if (!TIFFGetField( tif, tTag, &auxUint32)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* compare read values with written ones */
- auxLong = auxUint32;
- if (auxLong != auxLongArrayW[i]) {
- fprintf (stderr, "%d:Read value of %s %ld differs from set value %ld\n", i, tFieldName, auxLong, auxLongArrayW[i]);
- }
- break;
- case TIFF_SETGET_FLOAT:
- if (!TIFFGetField( tif, tTag, &auxFloat)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* compare read values with written ones */
- if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
- dblDiff = auxFloat - auxDoubleArrayW[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1.0" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
- * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
- * which are not treated within LibTiff!!
- */
- if (!(tTag == EXIFTAG_SUBJECTDISTANCE && auxFloat == -1.0)) {
- fprintf (stderr, "%d:Read value of %s %f differs from set value %f\n", i, tFieldName, auxFloat, auxDoubleArrayW[i]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- break;
- case TIFF_SETGET_DOUBLE:
- /*-- Unfortunately, TIFF_SETGET_DOUBLE is used for TIFF_RATIONAL but those have to be read with FLOAT !!! */
- /* Only TIFFTAG_STONITS is a TIFF_DOUBLE, which has to be read as DOUBLE!! */
- /*-- ATTENTION: ----
- * Only after update with Rational2Double feature, also TIFF_RATIONAL can be read in double precision!!!
- * Therefore, use a union to avoid overflow in TIFFGetField() return value
- * and depending on version check for the right interface here:
- * - old interface: correct value should be here a float
- * - new interface: correct value should be here a double
- * Interface version (old/new) is determined above.
- -------------------*/
- if (!TIFFGetField(tif, tTag, &auxDblUnion.dbl)) {
- fprintf(stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) {
- if (blnIsRational2Double) {
- /* New interface allows also double precision for TIFF_RATIONAL */
- auxDouble = auxDblUnion.dbl;
- }
- else {
- /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE alwasy as FLOAT */
- auxDouble = (double)auxDblUnion.flt1;
- }
- }
- else {
- auxDouble = auxDblUnion.dbl;
- }
- /* compare read values with written ones */
- if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
- dblDiff = auxDouble - auxDoubleArrayW[i];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1.0" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! */
- if (!(tTag == EXIFTAG_SUBJECTDISTANCE && auxDouble == -1.0)) {
- fprintf (stderr, "%d:Read value of %s %f differs from set value %f\n", i, tFieldName, auxDouble, auxDoubleArrayW[i]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- break;
-
- case TIFF_SETGET_C0_FLOAT:
- case TIFF_SETGET_C0_DOUBLE:
- case TIFF_SETGET_C16_FLOAT:
- case TIFF_SETGET_C16_DOUBLE:
- case TIFF_SETGET_C32_FLOAT:
- case TIFF_SETGET_C32_DOUBLE:
- /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
- /*-- Check, if it is a single parameter, a fixed array or a variable array */
- if (tWriteCount == 1) {
- fprintf (stderr, "Reading: WriteCount for .set_field_type %d should be -1 or greather than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
- } else {
- /*-- Either fix or variable array --*/
- /* For arrays, distinguishing between float or double is essential. */
- /* Now decide between fixed or variable array */
- if (tWriteCount > 1) {
- /* fixed array with needed arraysize defined in .field_writecount */
- if (!TIFFGetField( tif, tTag, &pVoidArray)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* set tWriteCount to number of read samples for next steps */
- auxLong = tWriteCount;
- } else {
- /* Special treatment of variable array. */
- /* Dependent on Cxx, the count parameter is char, short or long. Therefore use unionLong! */
- if (!TIFFGetField( tif, tTag, &unionLong, &pVoidArray)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* set tWriteCount to number of read samples for next steps */
- auxLong = unionLong.Short1;
- }
- /* Save values from temporary array */
- if (tSetFieldType == TIFF_SETGET_C0_FLOAT || tSetFieldType == TIFF_SETGET_C16_FLOAT || tSetFieldType == TIFF_SETGET_C32_FLOAT) {
- memcpy(&auxFloatArray, pVoidArray,(auxLong * sizeof(auxFloatArray[0])));
- /* compare read values with written ones */
- if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
- for (j=0; j<auxLong; j++) {
- dblDiff = auxFloatArray[j] - auxFloatArrayW[i+j];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- /*if (auxFloatArray[j] != (float)auxFloatArrayW[i+j]) { */
- fprintf (stderr, "Read value %d of %s #%d %f differs from set value %f\n", i, tFieldName, j, auxFloatArray[j], auxFloatArrayW[i+j]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- } else {
- memcpy(&auxDoubleArray, pVoidArray,(auxLong * sizeof(auxDoubleArray[0])));
- /* compare read values with written ones */
- if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
- for (j=0; j<auxLong; j++) {
- dblDiff = auxDoubleArray[j] - auxDoubleArrayW[i+j];
- if (fabs(dblDiff) > fabs(dblDiffLimit)) {
- /*if (auxDoubleArray[j] != auxDoubleArrayW[i+j]) { */
- fprintf (stderr, "Read value %d of %s #%d %f differs from set value %f\n", i, tFieldName, j, auxDoubleArray[j], auxDoubleArrayW[i+j]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- }
- }
- break;
- case TIFF_SETGET_C0_UINT8:
- case TIFF_SETGET_C0_SINT8:
- case TIFF_SETGET_C16_UINT8:
- case TIFF_SETGET_C16_SINT8:
- case TIFF_SETGET_C32_UINT8:
- case TIFF_SETGET_C32_SINT8:
- /* For arrays, distinguishing between float or double is essential, even for writing */
- pVoid = &auxCharArrayW[i];
- case TIFF_SETGET_C0_UINT16:
- case TIFF_SETGET_C0_SINT16:
- case TIFF_SETGET_C16_UINT16:
- case TIFF_SETGET_C16_SINT16:
- case TIFF_SETGET_C32_UINT16:
- case TIFF_SETGET_C32_SINT16:
- if (pVoid == NULL) pVoid = &auxShortArrayW[i];
- case TIFF_SETGET_C0_UINT32:
- case TIFF_SETGET_C0_SINT32:
- case TIFF_SETGET_C16_UINT32:
- case TIFF_SETGET_C16_SINT32:
- case TIFF_SETGET_C32_UINT32:
- case TIFF_SETGET_C32_SINT32:
- if (pVoid == NULL) pVoid = &auxLongArrayW[i];
- /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
- /*-- Check, if it is a single parameter, a fixed array or a variable array */
- if (tWriteCount == 1) {
- fprintf (stderr, "WriteCount for .set_field_type %d should be -1 or greather than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
- } else {
- /*-- Either fix or variable array --*/
- /* Now decide between fixed or variable array */
- if (tWriteCount > 1) {
- /* fixed array with needed arraysize defined in .field_writecount */
- if (!TIFFGetField( tif, tTag, &pVoidArray)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* set tWriteCount to number of read samples for next steps */
- auxLong = tWriteCount;
- } else {
- /* special treatment of variable array */
- /* for test, use always arraysize of VARIABLE_ARRAY_SIZE */
- if (!TIFFGetField( tif, tTag, &unionLong, &pVoidArray)) {
- fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
- GOTOFAILURE_ALL_EXIF
- break;
- }
- /* set tWriteCount to number of read samples for next steps */
- auxLong = unionLong.Short1;
- }
- /* Save values from temporary array */
- if (tSetFieldType == TIFF_SETGET_C0_UINT8 || tSetFieldType == TIFF_SETGET_C0_SINT8 ||
- tSetFieldType == TIFF_SETGET_C16_UINT8 || tSetFieldType == TIFF_SETGET_C16_SINT8 ||
- tSetFieldType == TIFF_SETGET_C32_UINT8 || tSetFieldType == TIFF_SETGET_C32_SINT8 ) {
- memcpy(&auxCharArray, pVoidArray,(auxLong * sizeof(auxCharArray[0])));
- /* Compare and check values */
- for (j=0; j<auxLong; j++) {
- if (tTag == EXIFTAG_EXIFVERSION) {
- /*-- Use exifVersion[] instead of auxCharArrayW[] for differently set EXIFVERSION tag */
- if (auxCharArray[j] != exifVersion[j]) {
- fprintf(stderr, "Read value %d of %s #%d %d differs from set value %d\n", i, tFieldName, j, auxCharArray[j], auxCharArrayW[i + j]);
- GOTOFAILURE_ALL_EXIF
- }
- } else {
- if (auxCharArray[j] != auxCharArrayW[i + j]) {
- fprintf(stderr, "Read value %d of %s #%d %d differs from set value %d\n", i, tFieldName, j, auxCharArray[j], auxCharArrayW[i + j]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- }
- } else if (tSetFieldType == TIFF_SETGET_C0_UINT16 || tSetFieldType == TIFF_SETGET_C0_SINT16 ||
- tSetFieldType == TIFF_SETGET_C16_UINT16 || tSetFieldType == TIFF_SETGET_C16_SINT16 ||
- tSetFieldType == TIFF_SETGET_C32_UINT16 || tSetFieldType == TIFF_SETGET_C32_SINT16 ) {
- memcpy(&auxShortArray, pVoidArray,(auxLong * sizeof(auxShortArray[0])));
- /* Compare and check values */
- for (j=0; j<auxLong; j++) {
- if (auxShortArray[j] != auxShortArrayW[i+j]) {
- fprintf (stderr, "Read value %d of %s #%d %d differs from set value %d\n", i, tFieldName, j, auxShortArray[j], auxShortArrayW[i+j]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- } else if (tSetFieldType == TIFF_SETGET_C0_UINT32 || tSetFieldType == TIFF_SETGET_C0_SINT32 ||
- tSetFieldType == TIFF_SETGET_C16_UINT32 || tSetFieldType == TIFF_SETGET_C16_SINT32 ||
- tSetFieldType == TIFF_SETGET_C32_UINT32 || tSetFieldType == TIFF_SETGET_C32_SINT32 ) {
- memcpy(&auxLongArray, pVoidArray,(auxLong * sizeof(auxLongArray[0])));
- /* Compare and check values */
- for (j=0; j<auxLong; j++) {
- if (auxLongArray[j] != auxLongArrayW[i+j]) {
- fprintf (stderr, "Read value %d of %s #%d %ld differs from set value %ld\n", i, tFieldName, j, auxLongArray[j], auxLongArrayW[i+j]);
- GOTOFAILURE_ALL_EXIF
- }
- }
- } else {
- fprintf (stderr, "SetFieldType %d not defined within switch case reading for UINT for %s.\n", tSetFieldType, tFieldName);
- GOTOFAILURE
- }
- }
- break;
- default:
- fprintf (stderr, "SetFieldType %d not defined within writing switch for %s.\n", tSetFieldType, tFieldName);
- GOTOFAILURE
- }; /*-- switch() --*/
- } /*-- for() --*/
- /*================= EXIF: END Reading arbitrary data to the EXIF fields END END END ==============*/
-#endif /*-- READ_ALL_EXIF_TAGS --*/
-#endif /*-- READ_EXIF_TAGS --*/
-
-
-
-
- TIFFClose(tif);
-
- /* All tests passed; delete file and exit with success status. */
-#ifdef FOR_AUTO_TESTING
- unlink(filenameRead);
-#endif
- fprintf(stderr, "-------- Test finished OK ----------\n");
- return 0;
-
-failure:
- /*
- * Something goes wrong; close file and return unsuccessful status.
- * Do not remove the file for further manual investigation.
- */
- TIFFClose(tif);
- fprintf(stderr, "-------- Test finished with FAILURE --------\n");
- return 1;
-}
+/*
+ * 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 copied from custom_dir.c --
+ *=========== Purpose ===================================================================================
+ * Extended and amended version for testing of EXIF 2.32, GPS and handling of custom fields.
+ * EXIF 2.32 and GPS are defined in amended files tif_dirinfo.c, tif_dirread.c, tiff.h, tiffio.h, tif_dir.h, tif_dir.c
+ *
+ *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values are defined as double precision
+ * and need to be written and also read in double precision!
+ * In order to maintain this code for both cases, it is checked above if the TiffLibrary is
+ * compiled with the new interface with Rational2Double or still uses the old definitions,
+ * by setting blnIsRational2Double above.
+ *
+ */
+
+
+/*------------
+ * This version writes the GPS and EXIF tags correctly, without additional main-IFD and parameters!
+ * In contrary, custom_dir.c does write additional main-IFD and parameters to file.
+ -------------*/
+
+
+#define FOR_AUTO_TESTING
+#ifdef FOR_AUTO_TESTING
+/* Only for automake and CMake infrastructure the test should:
+ a.) delete any written testfiles when test passed (otherwise autotest will fail)
+ b.) goto failure, if any failure is detected, which is not necessary when test is initiated manually for debugging
+*/
+#define GOTOFAILURE goto failure;
+#define GOTOFAILURE_GPS goto failure;
+#define GOTOFAILURE_ALL_EXIF goto failure;
+#else
+#define GOTOFAILURE
+#define GOTOFAILURE_GPS
+#define GOTOFAILURE_ALL_EXIF
+#endif
+
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4101)
+#endif
+
+#include "tif_config.h"
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "tiffio.h"
+#include "tiffiop.h"
+#include "tif_dir.h"
+#include "tifftest.h"
+
+
+
+int write_test_tiff(TIFF *tif, const char *filenameRead);
+
+static const char filename[] = "custom_dir_EXIF_231.tif";
+static const char filenameBigTiff[] = "custom_dir_EXIF_231_Big.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;
+
+
+int
+main()
+{
+ TIFF *tif;
+ int ret, ret1, ret2;
+
+ fprintf(stderr, "==== Test automatically if all EXIF and GPS tags are written/read correctly. ====\n");
+ /* --- Test with Classic-TIFF ---*/
+ /* delete file, if exists */
+ ret = unlink(filename);
+ if (ret != 0 && errno != ENOENT) {
+ fprintf(stderr, "Can't delete test TIFF file %s.\n", filename);
+ }
+
+ /* 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;
+ }
+ fprintf(stderr, "-------- Test with ClassicTIFF started ----------\n");
+ ret1 = write_test_tiff(tif, filename);
+
+ if (ret1 > 0) return(ret1);
+
+ /*--- Test with BIG-TIFF ---*/
+ /* delete file, if exists */
+ ret = unlink(filenameBigTiff);
+ if (ret != 0 && errno != ENOENT) {
+ fprintf(stderr, "Can't delete test TIFF file %s.\n", filenameBigTiff);
+ }
+
+ tif = TIFFOpen(filenameBigTiff, "w8");
+ if (!tif) {
+ fprintf(stderr, "Can't create test TIFF file %s.\n", filenameBigTiff);
+ return 1;
+ }
+ fprintf(stderr, "\n\n-------- Test with BigTIFF started ----------\n");
+ ret2 = write_test_tiff(tif, filenameBigTiff);
+
+ if (ret2 > 0) return(ret2 + 10); else return(ret2);
+
+} /* main() */
+
+
+
+
+
+
+
+int
+write_test_tiff(TIFF *tif, const char *filenameRead)
+{
+ unsigned char buf[SPP] = { 0, 127, 255 };
+ uint64 dir_offset = 0;
+ uint64 dir_offset_GPS = 0, dir_offset_EXIF = 0;
+ uint64 read_dir_offset = 0;
+ /*-- Additional variables --*/
+ int retCode, retCode2;
+ unsigned char exifVersion[4] = {'0','2','3','1'}; /* EXIF 2.31 version is 4 characters of a string! */
+ unsigned char gpsVersion[4] = {2,2,0,1}; /* GPS Version is 4 numbers! */
+ unsigned char *pGpsVersion;
+ float auxFloat = 0.0f;
+ double auxDouble = 0.0;
+ char auxChar = 0;
+ uint32 auxUint32 = 0;
+ short auxShort=0;
+ long auxLong = 0;
+ void *pVoid;
+ int blnIsRational2Double;
+
+ int i, j;
+ long nTags;
+
+ const TIFFFieldArray* tFieldArray;
+ unsigned long tTag;
+ TIFFDataType tType;
+ short tWriteCount;
+ TIFFSetGetFieldType tSetFieldType;
+ char *tFieldName;
+ const TIFFField *fip;
+
+ char blnFillGPSManually = 1;
+
+#define STRSIZE 1000
+#define N_SIZE 120
+#define VARIABLE_ARRAY_SIZE 6
+
+ /* -- Test data for writing -- */
+ char auxCharArrayW[N_SIZE];
+ short auxShortArrayW[N_SIZE];
+ long auxLongArrayW[N_SIZE];
+ float auxFloatArrayW[N_SIZE];
+ double auxDoubleArrayW[N_SIZE];
+ char auxTextArrayW[N_SIZE][STRSIZE];
+ double auxDoubleArrayGPS1[3] = {1.0/7.0, 61.23456789012345, 62.0};
+ double auxDoubleArrayGPS2[3] = {1.0/19.0, 88.34434, 15.12345678901234567890};
+ double auxDoubleArrayGPSTime[3] = {22.0, 17.0, 15.3456789};
+ double auxDoubleGPSAltitude = 3456.0;
+ double auxDoubleGPSDirection = 63.7;
+ float auxFloatArrayN1[3] = { 1.0f / 7.0f, 61.23456789012345f, 62.3f };
+ float auxFloatArrayN2[3] = { -1.0f / 7.0f, -61.23456789012345f, -62.3f };
+
+ /* -- Variables for reading -- */
+ uint16 count16 = 0;
+ union {
+ long Long;
+ short Short1;
+ short Short2[2];
+ char Char[4];
+ } unionLong;
+ union {
+ double dbl;
+ float flt1;
+ float flt2;
+ } auxDblUnion;
+ void *pVoidArray;
+ char *pAscii;
+ char auxCharArray[2*STRSIZE];
+ short auxShortArray[2*N_SIZE];
+ long auxLongArray[2*N_SIZE];
+ float auxFloatArray[2*N_SIZE];
+ double auxDoubleArray[2*N_SIZE];
+ double dblDiff, dblDiffLimit;
+#define RATIONAL_EPS (1.0/30000.0) /* reduced difference of rational values, approx 3.3e-5 */
+
+ /*-- Fill test data arrays for writing ----------- */
+ for (i=0; i<N_SIZE; i++) {
+ sprintf(auxTextArrayW[i],"N%d-String-%d_tttttttttttttttttttttttttttttx", i, i);
+ }
+ for (i=0; i<N_SIZE; i++) {
+ auxCharArrayW[i] = (char)(i+1);
+ }
+ for (i=0; i<N_SIZE; i++) {
+ auxShortArrayW[i] = (short)(i+1)*7;
+ }
+ for (i=0; i<N_SIZE; i++) {
+ auxLongArrayW[i] = (i+1)*133;
+ }
+ for (i=0; i<N_SIZE; i++) {
+ auxFloatArrayW[i] = (float)((i+1)*133)/3.3f;
+ }
+ for (i=0; i<N_SIZE; i++) {
+ auxDoubleArrayW[i] = (double)((i+1)*3689)/4.5697;
+ }
+
+ /*-- Setup standard tags of a simple tiff file --*/
+ 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 tag.\n");
+ goto failure;
+ }
+ if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, SPP)) {
+ fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
+ goto failure;
+ }
+ if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rows_per_strip)) {
+ fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
+ goto failure;
+ }
+ if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, planarconfig)) {
+ fprintf (stderr, "Can't set PlanarConfiguration tag.\n");
+ goto failure;
+ }
+ if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
+ fprintf (stderr, "Can't set PhotometricInterpretation tag.\n");
+ goto failure;
+ }
+
+#define ADDITIONAL_TAGS
+#ifdef ADDITIONAL_TAGS
+ /*-- Additional tags to check Rational standard tags, which are also defined as FIELD_CUSTOM */
+
+ /*- TIFFTAG_INKSET is a SHORT parameter (TIFF_SHORT, TIFF_SETGET_UINT16) with field_bit=FIELD_CUSTOM !! -*/
+ if (!TIFFSetField(tif, TIFFTAG_INKSET, 34)) {
+ fprintf(stderr, "Can't set TIFFTAG_INKSET tag.\n");
+ goto failure;
+ }
+
+ /*- TIFFTAG_PIXAR_FOVCOT is a FLOAT parameter ( TIFF_FLOAT, TIFF_SETGET_FLOAT) with field_bit=FIELD_CUSTOM !! -*/
+ /* - can be written with Double but has to be read with float parameter */
+#define PIXAR_FOVCOT_VAL 5.123456789123456789
+ auxFloat = (float)PIXAR_FOVCOT_VAL;
+ auxDouble = (double)PIXAR_FOVCOT_VAL;
+ if (!TIFFSetField(tif, TIFFTAG_PIXAR_FOVCOT, auxDouble)) {
+ fprintf(stderr, "Can't set TIFFTAG_PIXAR_FOVCOT tag.\n");
+ goto failure;
+ }
+ /*- TIFFTAG_STONITS is a DOUBLE parameter (TIFF_DOUBLE, TIFF_SETGET_DOUBLE) with field_bit=FIELD_CUSTOM!
+ * Only TIFFTAG_STONITS is a TIFF_DOUBLE, which has to be read as DOUBLE!!
+ */
+#define STONITS_VAL 6.123456789123456789
+ auxDouble = STONITS_VAL;
+ auxFloat = (float)auxDouble;
+ if (!TIFFSetField(tif, TIFFTAG_STONITS, auxDouble)) {
+ fprintf(stderr, "Can't set TIFFTAG_STONITS tag.\n");
+ goto failure;
+ }
+
+ /*- TIFFTAG_YCBCRPOSITIONING is a SHORT parameter */
+ auxLong = auxShort = 5;
+ if (!TIFFSetField(tif, TIFFTAG_YCBCRPOSITIONING, auxLong )) {
+ fprintf (stderr, "Can't set TIFFTAG_YCBCRPOSITIONING tag.\n");
+ goto failure;
+ }
+
+ /* - TIFFTAG_BESTQUALITYSCALE is a Rational parameter, FIELD_CUSTOM and TIFF_SETGET_DOUBLE */
+ /* With Rational2Double upgrade tag is redefined to TIFF_SETGET_FLOAT, but can be still written with double. */
+#define BESTQUALITYSCALE_VAL 15.3
+ auxDouble = BESTQUALITYSCALE_VAL;
+ if (!TIFFSetField(tif, TIFFTAG_BESTQUALITYSCALE, auxDouble )) {
+ fprintf (stderr, "Can't set TIFFTAG_BESTQUALITYSCALE tag.\n");
+ goto failure;
+ }
+
+ /* - TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT */
+ if (!TIFFSetField(tif, TIFFTAG_BASELINENOISE, auxDouble)) {
+ fprintf(stderr, "Can't set TIFFTAG_BASELINENOISE tag.\n");
+ goto failure;
+ }
+
+
+ /*--- For static or variable ARRAYs the case is different ---*/
+/*- Variable Array: TIFFTAG_DECODE is a SRATIONAL parameter TIFF_SETGET_C16_FLOAT type FIELD_CUSTOM with passcount=1 and variable length of array. */
+ if (!TIFFSetField(tif, TIFFTAG_DECODE, 3, auxFloatArrayN2)) {
+ fprintf(stderr, "Can't set TIFFTAG_DECODE tag.\n");
+ goto failure;
+ }
+
+ /*- Variable Array: TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT */
+ if (!TIFFSetField(tif, TIFFTAG_BLACKLEVEL, 3, auxFloatArrayN1)) {
+ fprintf(stderr, "Can't set TIFFTAG_BLACKLEVEL tag.\n");
+ goto failure;
+ }
+
+ /*- Fixed Array: TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT */
+ if (!TIFFSetField(tif, TIFFTAG_DEFAULTCROPSIZE, &auxFloatArrayW[0])) {
+ fprintf(stderr, "Can't set TIFFTAG_DEFAULTCROPSIZE tag.\n");
+ goto failure;
+ }
+#endif /* -- ADDITIONAL_TAGS -- */
+
+/*================== Rational2Double Interface Check =====================*/
+ /*-- Check, if the TiffLibrary is compiled with the new interface with Rational2Double or still uses the old definitions.
+ For that, TIFF_RATIONAL tags with FIELD_CUSTOM are changed from TIFF_SETGET_DOUBLE to TIFF_SETGET_FLOAT for the
+ new interface in order to prevent the old reading behaviour.
+ Tags to check: TIFFTAG_BESTQUALITYSCALE, TIFFTAG_BASELINENOISE, TIFFTAG_BASELINESHARPNESS
+ */
+ fip = TIFFFindField(tif, TIFFTAG_BESTQUALITYSCALE, TIFF_ANY);
+ tSetFieldType = fip->set_field_type;
+ if (tSetFieldType == TIFF_SETGET_DOUBLE) {
+ blnIsRational2Double = FALSE;
+ } else {
+ blnIsRational2Double = TRUE;
+ fprintf(stderr, "-- Rational2Double from TIFF tag detected --\n");
+ }
+
+/*================== Write GPS and EXIF tags =====================*/
+
+ /*-- Set dummy EXIF/GPS tag in original tiff-structure in order to reserve space for final dir_offset value, */
+ /* which is properly written at the end. */
+ dir_offset = 0; /* Zero, in case no Custom-IFD is written */
+
+#define WRITE_GPS_TAGS
+#ifdef WRITE_GPS_TAGS
+ if (!TIFFSetField(tif, TIFFTAG_GPSIFD, dir_offset )) {
+ fprintf (stderr, "Can't write TIFFTAG_GPSIFD\n" );
+ }
+#endif
+
+ /*------- And also do the same for the EXIF IFD tag here, because we have to save the main directory next ------*/
+ /*-- Set dummy EXIF/GPS tag in original tiff-structure in order to reserve space for final dir_offset value,
+ * which is properly written at the end.
+ */
+#define WRITE_EXIF_TAGS
+#ifdef WRITE_EXIF_TAGS
+ if (!TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset )) {
+ fprintf (stderr, "Can't write TIFFTAG_EXIFIFD\n" );
+ }
+#endif
+
+#ifndef WRITEPIXELLAST
+ /*-- Write dummy pixel data. --*/
+ if (TIFFWriteScanline(tif, buf, 0, 0) < 0) {
+ fprintf (stderr, "Can't write image data.\n");
+ goto failure;
+ }
+#endif
+
+
+#ifdef WRITE_GPS_TAGS
+#define READ_GPS_TAGS
+ /*================== Write GPS tags =====================*/
+
+ /*-- Save current tiff-directory to file before directory is changed. Otherwise it will be lost! */
+ /* The tif-structure is overwritten/ freshly initialized by any "CreateDirectory" */
+ /*retCode = TIFFCheckpointDirectory(tif);*/ /* does not cleanup Tiff-Structure */
+ retCode = TIFFWriteDirectory(tif); /* cleanup Tiff-structure */
+
+ /*-- Now create a GPS directory. */
+ if (TIFFCreateGPSDirectory(tif) != 0) {
+ fprintf (stderr, "TIFFCreateGPSDirectory() failed.\n" );
+ goto failure;
+ }
+
+ if (!TIFFSetField( tif, GPSTAG_VERSIONID, gpsVersion)) {
+ fprintf (stderr, "Can't write GPSTAG_VERSIONID\n" );
+ goto failure;
+ }
+
+ if (blnFillGPSManually) {
+ /*================= Write manually valid data to the GPS fields ==============*/
+ if (!TIFFSetField( tif, GPSTAG_LATITUDEREF, "N\0")) {
+ fprintf (stderr, "Can't write GPSTAG_LATITUDEREF\n" );
+ goto failure;
+ }
+ /*-- Unfortunately, Rational values are defined as SETGET_DOUBLE but are internally always stored as float.
+ * Single Rational values do not matter for writing, because TIFFSetField() uses va_arg() which performs "variables promotion" from type float to type double!
+ * However, for reading of Rational values ONLY float-variables are allowed - in contrary to the SETGET_DOUBLE specification at tiffFields[] in tif_dirinfo.c.
+ */
+ /*-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values are defined as double precision
+ * and need to be written and also read in double precision!
+ * In order to maintain this code for both cases, it is checked above if the TiffLibrary is
+ * compiled with the new interface with Rational2Double or still uses the old definitions,
+ * by setting blnIsRational2Double above.
+ */
+ if (blnIsRational2Double) {
+ fprintf(stderr, "-- GPS tags are written using Rational2Double --\n");
+ } else {
+ fprintf(stderr, "-- GPS tags are written using standard --\n");
+ }
+ if (!blnIsRational2Double) {
+ for (j = 0; j < 3; j++) auxFloatArray[j] = (float)auxDoubleArrayGPS1[j];
+ if (!TIFFSetField(tif, GPSTAG_LATITUDE, auxFloatArray)) {
+ fprintf(stderr, "Can't write GPSTAG_LATITUDE\n");
+ goto failure;
+ }
+ } else {
+ /* Rational2Double interface for GPSTAG */
+ if (!TIFFSetField(tif, GPSTAG_LATITUDE, auxDoubleArrayGPS1)) {
+ fprintf(stderr, "Can't write GPSTAG_LATITUDE\n");
+ goto failure;
+ }
+ }
+ if (!TIFFSetField( tif, GPSTAG_LONGITUDEREF, "W\0")) {
+ fprintf (stderr, "Can't write GPSTAG_LONGITUDEREF\n" );
+ goto failure;
+ }
+ if (!blnIsRational2Double) {
+ for (j=0; j<3; j++) auxFloatArray[j] = (float)auxDoubleArrayGPS2[j];
+ if (!TIFFSetField( tif, GPSTAG_LONGITUDE, auxFloatArray)) {
+ fprintf (stderr, "Can't write GPSTAG_LONGITUDE\n" );
+ goto failure;
+ }
+ } else {
+ /* Rational2Double interface for GPSTAG */
+ if (!TIFFSetField(tif, GPSTAG_LONGITUDE, auxDoubleArrayGPS2)) {
+ fprintf(stderr, "Can't write GPSTAG_LATITUDE\n");
+ goto failure;
+ }
+ }
+ /*-- AltitudeRef: default is above sea level!! */
+ if (!TIFFSetField( tif, GPSTAG_ALTITUDEREF, 0)) {
+ fprintf (stderr, "Can't write GPSTAG_ALTITUDEREF\n" );
+ goto failure;
+ }
+ if (!TIFFSetField( tif, GPSTAG_ALTITUDE, auxDoubleGPSAltitude)) {
+ fprintf (stderr, "Can't write GPSTAG_ALTITUDE\n" );
+ goto failure;
+ }
+ /*-- TimeStamp is only hh:mm:ss. See also DateTime string */
+ if (!TIFFSetField( tif, GPSTAG_TIMESTAMP, auxDoubleArrayGPSTime)) {
+ fprintf (stderr, "Can't write GPSTAG_TIMESTAMP\n" );
+ goto failure;
+ }
+ if (!TIFFSetField( tif, GPSTAG_DATESTAMP, "2012:11:04")) {
+ fprintf (stderr, "Can't write GPSTAG_DATESTAMP\n" );
+ goto failure;
+ }
+
+ if (!TIFFSetField( tif, GPSTAG_IMGDIRECTIONREF, "T\0")) {
+ fprintf (stderr, "Can't write GPSTAG_IMGDIRECTIONREF\n" );
+ goto failure;
+ }
+ if (!TIFFSetField( tif, GPSTAG_IMGDIRECTION, auxDoubleGPSDirection)) {
+ fprintf (stderr, "Can't write GPSTAG_IMGDIRECTION\n" );
+ goto failure;
+ }
+
+ /*-- Type TIFF_UNDEFINED */
+ if (!TIFFSetField( tif, GPSTAG_PROCESSINGMETHOD, 3, &auxCharArrayW[10])) {
+ fprintf (stderr, "Can't write GPSTAG_PROCESSINGMETHOD\n" );
+ goto failure;
+ }
+ if (!TIFFSetField( tif, GPSTAG_AREAINFORMATION, 4, &auxCharArrayW[20])) {
+ fprintf (stderr, "Can't write GPSTAG_AREAINFORMATION\n" );
+ goto failure;
+ }
+
+ /*-- PSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 */
+ if (!TIFFSetField( tif, GPSTAG_DIFFERENTIAL, auxShortArrayW[5])) {
+ fprintf (stderr, "Can't write GPSTAG_DIFFERENTIAL\n" );
+ goto failure;
+ }
+
+ /* GPSTAG_GPSHPOSITIONINGERROR , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE but here written in float-precision */
+#define GPSHPOSITIONINGERROR_VAL 0.369
+ auxFloat = (float)GPSHPOSITIONINGERROR_VAL;
+ if (!TIFFSetField( tif, GPSTAG_GPSHPOSITIONINGERROR, auxFloat)) {
+ fprintf (stderr, "Can't write GPSTAG_GPSHPOSITIONINGERROR\n" );
+ goto failure;
+ }
+
+ } else {
+ /*================= Write arbitrary data to the GPS fields ==============*/
+
+ /*-- Get array, where GPS tag fields are defined --*/
+ tFieldArray = _TIFFGetGpsFields();
+ nTags = tFieldArray->count;
+
+ /*-- TODO: fill in the for / switch part of EXIF writing, when finished and tested!! */
+
+ } /*-- if (blnFillGPSManually) --*/
+
+
+
+
+ /*-- GPS - write custom directory GPS into file...---*/
+ /* (Get back the offset of GPS directory) */
+ if (!TIFFWriteCustomDirectory( tif, &dir_offset_GPS )) {
+ fprintf (stderr, "TIFFWriteCustomDirectory() with GPS failed.\n");
+ goto failure;
+ }
+
+ /*--- CheckpointDirectory at this place generates a second Main-IFD!!! */
+ /* retCode = TIFFCheckpointDirectory(tif); */
+
+ /*-- Set / reload previously saved main directory from file ---*/
+ if (!TIFFSetDirectory(tif, 0)) {
+ fprintf (stderr, "TIFFSetDirectory() within GPS failed.\n");
+ goto failure;
+ }
+
+ /*-- Write GPS tag reference / offset into GPSIFD tag in main directory --*/
+ if (!TIFFSetField(tif, TIFFTAG_GPSIFD, dir_offset_GPS )) {
+ fprintf (stderr, "Can't write TIFFTAG_GPSIFD\n");
+ goto failure;
+ }
+
+ /*=============== END writing GPS tags ==========================*/
+#endif /*-- WRITE_GPS_TAGS --*/
+
+
+/*================== Write EXIF 2.31 tags =====================*/
+
+ /*-- Set dummy EXIF/GPS tag in original tiff-structure in order to reserve space for final dir_offset value, */
+ /* which is properly written at the end.*/
+ /*- We did this already above together with the GPS IFD-tag. Otherwise we would do this here !! --------*/
+ /* if (!TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset )) {
+ fprintf (stderr, "Can't write TIFFTAG_EXIFIFD\n" );
+ }
+ */
+
+#ifdef WRITE_EXIF_TAGS
+#define READ_EXIF_TAGS
+ /*-- Save current tiff-directory to file before directory is changed. Otherwise it will be lost!
+ * The tif-structure is overwritten/ freshly initialized by any "CreateDirectory"
+ */
+
+ /*----- What is needed here ??? ----
+ * In custom_dir.c only TIFFFreeDirectory( tif ); is used to set fields of another Sub-Directory
+ * TIFFFreeDirectory(tif); *-- Release storage associated with a directory, especially custom-fields.
+ *-- Using only TIFFFreeDirectory() here leads to an error!!
+ *-- Using here TIFFCheckpointDirectory() leads to an additional Main-IFD ??
+ */
+ /*retCode = TIFFCheckpointDirectory(tif);*/ /* does not cleanup Tiff-Structure */
+ retCode = TIFFWriteDirectory(tif); /* cleanup Tiff-structure */
+
+ /*-- Now create an EXIF directory. */
+ if (TIFFCreateEXIFDirectory(tif) != 0) {
+ fprintf (stderr, "TIFFCreateEXIFDirectory() failed.\n" );
+ goto failure;
+ }
+
+#define WRITE_ALL_EXIF_TAGS
+#ifdef WRITE_ALL_EXIF_TAGS
+#define READ_ALL_EXIF_TAGS
+ /*================= EXIF: Write arbitrary data to the EXIF fields ==============*/
+ /*-- Get array, where EXIF tag fields are defined
+ * EXIF tags are written automatically with the defined precision according to its tSetFieldType using the code below --*/
+ tFieldArray = _TIFFGetExifFields();
+ nTags = tFieldArray->count;
+
+ for (i=0; i<nTags; i++) {
+ tTag = tFieldArray->fields[i].field_tag;
+ tType = tFieldArray->fields[i].field_type; /* e.g. TIFF_RATIONAL */
+ tWriteCount = tFieldArray->fields[i].field_writecount;
+ tSetFieldType = tFieldArray->fields[i].set_field_type; /* e.g. TIFF_SETGET_C0_FLOAT */
+ tFieldName = tFieldArray->fields[i].field_name;
+ pVoid = NULL;
+
+ /*-- dependent on set_field_type write value --*/
+ switch (tSetFieldType)
+ {
+ case TIFF_SETGET_ASCII:
+ /* Either the stringlength is defined as a fixed length in .field_writecount or a NULL-terminated string is used. */
+ /* Shorter strings than in auxTextArraxW need a NULL-termination. Therefore copy the string. */
+ if (tWriteCount > 0) auxLong = tWriteCount-1; else auxLong = (long)strlen(auxTextArrayW[i])-1;
+ strncpy(auxCharArray, auxTextArrayW[i], auxLong);
+ auxCharArray[auxLong] = 0;
+ if (!TIFFSetField( tif, tTag, auxCharArray)) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ break;
+ case TIFF_SETGET_UINT8:
+ case TIFF_SETGET_UINT16:
+ case TIFF_SETGET_UINT32:
+ case TIFF_SETGET_IFD8:
+ case TIFF_SETGET_INT:
+ /*-- All those can be written with char, short or long parameter. Only value range should be in line. */
+ if (!TIFFSetField( tif, tTag, auxLongArrayW[i])) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ break;
+ case TIFF_SETGET_SINT8:
+ case TIFF_SETGET_SINT16:
+ case TIFF_SETGET_SINT32:
+ /*-- All those can be written with char, short or long parameter. Only value range should be in line. */
+ if (!TIFFSetField( tif, tTag, -1.0*auxLongArrayW[i])) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ break;
+ case TIFF_SETGET_FLOAT:
+ case TIFF_SETGET_DOUBLE:
+ if (tWriteCount == 1) {
+ /*-- All single values can be written with float or double parameter. Only value range should be in line. */
+ if (!TIFFSetField( tif, tTag, auxDoubleArrayW[i])) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ } else {
+ fprintf (stderr, "WriteCount for .set_field_type %d should be 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
+ }
+ break;
+ case TIFF_SETGET_C0_FLOAT:
+ case TIFF_SETGET_C0_DOUBLE:
+ case TIFF_SETGET_C16_FLOAT:
+ case TIFF_SETGET_C16_DOUBLE:
+ case TIFF_SETGET_C32_FLOAT:
+ case TIFF_SETGET_C32_DOUBLE:
+ /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
+ /*-- Check, if it is a single parameter, a fixed array or a variable array */
+ if (tWriteCount == 1) {
+ fprintf (stderr, "WriteCount for .set_field_type %d should be -1 or greater than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
+ } else {
+ /*-- Either fix or variable array --*/
+ /* For arrays, distinguishing between float or double is essential, even for writing */
+ if (tSetFieldType == TIFF_SETGET_C0_FLOAT || tSetFieldType == TIFF_SETGET_C16_FLOAT || tSetFieldType == TIFF_SETGET_C32_FLOAT)
+ pVoid = &auxFloatArrayW[i]; else pVoid = &auxDoubleArrayW[i];
+ /* Now decide between fixed or variable array */
+ if (tWriteCount > 1) {
+ /* fixed array with needed arraysize defined in .field_writecount */
+ if (!TIFFSetField( tif, tTag, pVoid)) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ } else {
+ /* special treatment of variable array */
+ /* for test, use always arraysize of VARIABLE_ARRAY_SIZE */
+ if (!TIFFSetField( tif, tTag, VARIABLE_ARRAY_SIZE, pVoid)) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_UINT8:
+ case TIFF_SETGET_C0_SINT8:
+ case TIFF_SETGET_C16_UINT8:
+ case TIFF_SETGET_C16_SINT8:
+ case TIFF_SETGET_C32_UINT8:
+ case TIFF_SETGET_C32_SINT8:
+ /* For arrays, distinguishing between float or double is essential, even for writing */
+ pVoid = &auxCharArrayW[i];
+ case TIFF_SETGET_C0_UINT16:
+ case TIFF_SETGET_C0_SINT16:
+ case TIFF_SETGET_C16_UINT16:
+ case TIFF_SETGET_C16_SINT16:
+ case TIFF_SETGET_C32_UINT16:
+ case TIFF_SETGET_C32_SINT16:
+ if (pVoid == NULL) pVoid = &auxShortArrayW[i];
+ case TIFF_SETGET_C0_UINT32:
+ case TIFF_SETGET_C0_SINT32:
+ case TIFF_SETGET_C16_UINT32:
+ case TIFF_SETGET_C16_SINT32:
+ case TIFF_SETGET_C32_UINT32:
+ case TIFF_SETGET_C32_SINT32:
+ if (pVoid == NULL) pVoid = &auxLongArrayW[i];
+ /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
+ /*-- Check, if it is a single parameter, a fixed array or a variable array */
+ if (tWriteCount == 1) {
+ fprintf (stderr, "WriteCount for .set_field_type %d should be -1 or greater than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
+ } else {
+ /*-- Either fix or variable array --*/
+ /* Now decide between fixed or variable array */
+ if (tWriteCount > 1) {
+ /* fixed array with needed arraysize defined in .field_writecount */
+ if (!TIFFSetField( tif, tTag, pVoid)) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ } else {
+ /* special treatment of variable array */
+ /* for test, use always arraysize of VARIABLE_ARRAY_SIZE */
+ if (!TIFFSetField( tif, tTag, VARIABLE_ARRAY_SIZE, pVoid)) {
+ fprintf (stderr, "Can't write %s\n", tFieldArray->fields[i].field_name);
+ goto failure;
+ }
+ }
+ }
+ break;
+ default:
+ fprintf (stderr, "SetFieldType %d not defined within writing switch for %s.\n", tSetFieldType, tFieldName);
+ }; /*-- switch() --*/
+ } /*-- for() --*/
+ /*================= EXIF: END Writing arbitrary data to the EXIF fields END END END ==============*/
+#endif /*-- WRITE_ALL_EXIF_TAGS --*/
+
+ /*--- Set valid EXIF version, which is a 4 byte string --*/
+ if (!TIFFSetField( tif, EXIFTAG_EXIFVERSION, exifVersion)) {
+ fprintf (stderr, "Can't write EXIFTAG_EXIFVERSION\n" );
+ goto failure;
+ }
+
+
+ /*-- EXIF - write custom directory EXIF into file...---*/
+ /* (Get back the offset of EXIF directory) */
+ if (!TIFFWriteCustomDirectory( tif, &dir_offset_EXIF )) {
+ fprintf (stderr, "TIFFWriteCustomDirectory() with EXIF failed.\n");
+ goto failure;
+ }
+
+ /*-- Go back to the first (main) directory, and set correct value of the EXIFIFD pointer. */
+ /* (directory is reloaded from file!) */
+ TIFFSetDirectory(tif, 0);
+ TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset_EXIF );
+#endif /*-- WRITE_EXIF_TAGS --*/
+
+#ifdef WRITEPIXELLAST
+ /*-- Write dummy pixel data. --*/
+ if (TIFFWriteScanline(tif, buf, 0, 0) < 0) {
+ fprintf (stderr, "Can't write image data.\n");
+ goto failure;
+ }
+#endif
+ /*-- Write directory to file --*/
+ /* Always WriteDirectory before using/creating another directory. */
+ /* Not necessary before TIFFClose(), however, TIFFClose() uses TIFFReWriteDirectory(), which forces directory to be written at another location. */
+ retCode = TIFFWriteDirectory(tif);
+
+ /*-- Write File to disk and close file --*/
+ /* TIFFClose() uses TIFFReWriteDirectory(), which forces directory to be written at another location. */
+ /* Therefore, better use TIFFWriteDirectory() before. */
+ TIFFClose(tif);
+
+ fprintf (stderr, "-------- Continue Test ---------- reading ...\n");
+
+/*========================= READING ============= READING ========================================*/
+ /* Ok, now test whether we can read written values correctly. */
+ tif = TIFFOpen(filenameRead, "r");
+
+
+ /*-- Read some parameters out of the main directory --*/
+
+ /*-- IMAGEWIDTH and -LENGTH are defined as TIFF_SETGET_UINT32 */
+ retCode = TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &auxUint32 );
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_IMAGEWIDTH"); }
+ if (auxUint32 != width) {
+ fprintf (stderr, "Read value of IMAGEWIDTH %d differs from set value %d\n", auxUint32, width);
+ }
+ retCode = TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &auxUint32 );
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_IMAGELENGTH"); }
+ if (auxUint32 != width) {
+ fprintf (stderr, "Read value of TIFFTAG_IMAGELENGTH %d differs from set value %d\n", auxUint32, length);
+ }
+
+#ifdef ADDITIONAL_TAGS
+ /*- TIFFTAG_PIXAR_FOVCOT is a FLOAT parameter of type FIELD_CUSTOM !! */
+ retCode = TIFFGetField(tif, TIFFTAG_PIXAR_FOVCOT, &auxFloat );
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_PIXAR_FOVCOT"); }
+ if (auxFloat != (float)PIXAR_FOVCOT_VAL) {
+ fprintf (stderr, "Read value of TIFFTAG_PIXAR_FOVCOT %f differs from set value %f\n", auxFloat, PIXAR_FOVCOT_VAL);
+ }
+
+ /* - TIFFTAG_BESTQUALITYSCALE is a Rational parameter, FIELD_CUSTOM and TIFF_SETGET_FLOAT */
+ retCode = TIFFGetField(tif, TIFFTAG_BESTQUALITYSCALE, &auxFloat );
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_BESTQUALITYSCALE"); }
+ if (auxFloat != (float)BESTQUALITYSCALE_VAL) {
+ fprintf (stderr, "Read value of TIFFTAG_BESTQUALITYSCALE %f differs from set value %f\n", auxFloat, BESTQUALITYSCALE_VAL);
+ }
+
+ /* - TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT */
+ retCode = TIFFGetField(tif, TIFFTAG_BASELINENOISE, &auxDblUnion.dbl);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_BASELINENOISE"); }
+ if (auxDblUnion.flt1 != (float)BESTQUALITYSCALE_VAL) {
+ fprintf(stderr, "Read float value of TIFFTAG_BASELINENOISE %f differs from set value %f\n", auxDblUnion.flt1, BESTQUALITYSCALE_VAL);
+ }
+
+
+ /*- Variable Array: TIFFTAG_DECODE is a SRATIONAL parameter TIFF_SETGET_C16_FLOAT type FIELD_CUSTOM with passcount=1 and variable length of array. */
+ retCode = TIFFGetField(tif, TIFFTAG_DECODE, &count16, &pVoidArray );
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_DECODE"); }
+ /*- pVoidArray points to a Tiff-internal temporary memorypart. Thus, contents needs to be saved. */
+ memcpy(&auxFloatArray, pVoidArray,(count16 * sizeof(auxFloatArray[0])));
+ for (i=0; i<count16; i++) {
+ dblDiffLimit = RATIONAL_EPS*auxFloatArrayN2[i];
+ dblDiff = auxFloatArray[i] - auxFloatArrayN2[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf (stderr, "Read value %d of TIFFTAG_DECODE Array %f differs from set value %f\n", i, auxFloatArray[i], auxFloatArrayN2[i]);
+ }
+ }
+
+ retCode = TIFFGetField(tif, TIFFTAG_BLACKLEVEL, &count16, &pVoidArray);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_BLACKLEVEL"); }
+ /*- pVoidArray points to a Tiff-internal temporary memorypart. Thus, contents needs to be saved. */
+ memcpy(&auxFloatArray, pVoidArray, (count16 * sizeof(auxFloatArray[0])));
+ for (i = 0; i<count16; i++) {
+ dblDiffLimit = RATIONAL_EPS*auxFloatArrayN1[i];
+ dblDiff = auxFloatArray[i] - auxFloatArrayN1[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value %d of TIFFTAG_BLACKLEVEL Array %f differs from set value %f\n", i, auxFloatArray[i], auxFloatArrayN1[i]);
+ }
+ }
+
+ /*- Fixed Array: TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT */
+ retCode = TIFFGetField(tif, TIFFTAG_DEFAULTCROPSIZE, &pVoidArray);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_DEFAULTCROPSIZE"); }
+ /*- pVoidArray points to a Tiff-internal temporary memorypart. Thus, contents needs to be saved. */
+ memcpy(&auxFloatArray, pVoidArray, (2 * sizeof(auxFloatArray[0])));
+ for (i = 0; i < 2; i++) {
+ dblDiffLimit = RATIONAL_EPS * auxFloatArrayW[i];
+ dblDiff = auxFloatArray[i] - auxFloatArrayW[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value %d of TIFFTAG_DEFAULTCROPSIZE Array %f differs from set value %f\n", i, auxFloatArray[i], auxFloatArrayW[i]);
+ }
+ }
+
+#endif /*-- ADDITIONAL_TAGS --*/
+
+
+#ifdef READ_GPS_TAGS
+/*================== Reading GPS tags =====================*/
+ /*-- First get offset to GPS-directory and set it active (this will destroy previously main directory fields in memory!) */
+ retCode = TIFFGetField(tif, TIFFTAG_GPSIFD, &read_dir_offset );
+ if (!retCode) {fprintf(stderr, "Can't read %s\n", "TIFFTAG_GPSIFD"); }
+ retCode = TIFFReadGPSDirectory(tif, read_dir_offset);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFReadGPSDirectory()"); }
+
+ /*-- Now read some parameters from GPS-directory --*/
+
+ /*-- Fixed Array: GPS-Version is a fixed array (of 4 characters) */
+ retCode = TIFFGetField(tif, GPSTAG_VERSIONID, &pGpsVersion);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_VERSIONID"); }
+ else {
+ memcpy(auxCharArray, pGpsVersion, sizeof(gpsVersion));
+ for (i = 0; i < 4; i++) {
+ if (auxCharArray[i] != pGpsVersion[i]) {
+ fprintf(stderr, "Read value %d of GPSTAG_VERSIONID %d differs from set value %d\n", i, auxCharArray[i], pGpsVersion[i]);
+ }
+ }
+ }
+ /*-- LATITUDEREF is a fixed String of one character plus ending zero. */
+ retCode = TIFFGetField(tif, GPSTAG_LATITUDEREF, &pAscii);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LATITUDEREF"); }
+ retCode2 = strncmp("N", pAscii, 1);
+ if (retCode2 != 0) {
+ fprintf (stderr, "Read value %d of GPSTAG_LATITUDEREF %s differs from set value %s\n", i, "N", pAscii);
+ }
+
+ /*-- Fixed Array: Latitude is an array of 3 Rational-values. TIFFGetField() returns a pointer to a temporary float-/double-array. */
+ /*-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values are defined as double precision
+ * and need to be written and also read in double precision!
+ * In order to maintain this code for both cases, it is checked above if the TiffLibrary is
+ * compiled with the new interface with Rational2Double or still uses the old definitions,
+ * by setting blnIsRational2Double above.
+ */
+ if (blnIsRational2Double) {
+ fprintf(stderr, "-- GPS tags are read using Rational2Double --\n");
+ } else {
+ fprintf(stderr, "-- GPS tags are read using standard --\n");
+ }
+ retCode = TIFFGetField(tif, GPSTAG_LATITUDE, &pVoidArray);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LATITUDE"); }
+ if (!blnIsRational2Double) {
+ /* Reset arrays for debugging purpose first */
+ memset(auxFloatArray, 0, sizeof(auxFloatArray));
+ memcpy(auxFloatArray, pVoidArray, 3*sizeof(float));
+ /* for comparison copy to doubleArray */
+ for (i=0; i<3; i++) auxDoubleArray[i] = (double)auxFloatArray[i];
+ } else {
+ /* Rational2Double interface for GPSTAG reads double array */
+ memset(auxDoubleArray, 0, sizeof(auxDoubleArray));
+ memcpy(auxDoubleArray, pVoidArray, 3 * sizeof(double));
+ }
+ for (i=0; i<3; i++) {
+ dblDiffLimit = RATIONAL_EPS*auxDoubleArrayGPS1[i];
+ dblDiff = auxDoubleArray[i] - auxDoubleArrayGPS1[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf (stderr, "Read value %d of GPSTAG_LATITUDE %f differs from set value %f\n", i, auxDoubleArray[i], auxDoubleArrayGPS1[i]);
+ }
+ }
+
+ /*-- LONGITUDEREF is a fixed String of one character plus ending zero. */
+ retCode = TIFFGetField(tif, GPSTAG_LONGITUDEREF, &pAscii);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LONGITUDEREF"); }
+ retCode2 = strncmp("W", pAscii, 1);
+ if (retCode2 != 0) {
+ fprintf(stderr, "Read value %d of GPSTAG_LONGITUDEREF %s differs from set value %s\n", i, "W", pAscii);
+ }
+
+ retCode = TIFFGetField(tif, GPSTAG_LONGITUDE, &pVoidArray);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_LONGITUDE"); }
+ if (!blnIsRational2Double) {
+ /* Reset arrays for debugging purpose first */
+ memset(auxFloatArray, 0, sizeof(auxFloatArray));
+ memcpy(auxFloatArray, pVoidArray, 3 * sizeof(float));
+ /* for comparison copy to doubleArray */
+ for (i = 0; i < 3; i++) auxDoubleArray[i] = (double)auxFloatArray[i];
+ } else {
+ /* Rational2Double interface for GPSTAG reads double array */
+ memset(auxDoubleArray, 0, sizeof(auxDoubleArray));
+ memcpy(auxDoubleArray, pVoidArray, 3 * sizeof(double));
+ }
+ for (i = 0; i < 3; i++) {
+ dblDiffLimit = RATIONAL_EPS * auxDoubleArrayGPS2[i];
+ dblDiff = auxDoubleArray[i] - auxDoubleArrayGPS2[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value %d of GPSTAG_LONGITUDE %f differs from set value %f\n", i, auxDoubleArray[i], auxDoubleArrayGPS2[i]);
+ }
+ }
+
+ /* TIFF_RATIONAL, TIFF_SETGET_DOUBLE */
+ if (!TIFFGetField(tif, GPSTAG_ALTITUDE, &auxDblUnion.dbl)) {
+ fprintf(stderr, "Can't read GPSTAG_ALTITUDE\n");
+ GOTOFAILURE_GPS
+ }
+ if (blnIsRational2Double) {
+ /* New interface allows also double precision for TIFF_RATIONAL */
+ auxDouble = auxDblUnion.dbl;
+ } else {
+ /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE always as FLOAT */
+ auxDouble = (double)auxDblUnion.flt1;
+ }
+ /* compare read values with written ones */
+ dblDiffLimit = RATIONAL_EPS * auxDoubleGPSAltitude;
+ dblDiff = auxDouble - auxDoubleGPSAltitude;
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value of GPSTAG_ALTITUDE %f differs from set value %f\n", auxDouble, auxDoubleGPSAltitude);
+ GOTOFAILURE_GPS
+ }
+
+ /*-- TimeStamp is only hh:mm:ss. See also DateTime string 3, TIFF_RATIONAL, TIFF_SETGET_C0_DOUBLE */
+ retCode = TIFFGetField(tif, GPSTAG_TIMESTAMP, &pVoidArray);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_TIMESTAMP"); }
+ if (!blnIsRational2Double) {
+ /* Reset arrays for debugging purpose first */
+ memset(auxFloatArray, 0, sizeof(auxFloatArray));
+ memcpy(auxFloatArray, pVoidArray, 3 * sizeof(float));
+ /* for comparison copy to doubleArray */
+ for (i = 0; i < 3; i++) auxDoubleArray[i] = (double)auxFloatArray[i];
+ } else {
+ /* Rational2Double interface for GPSTAG reads double array */
+ memset(auxDoubleArray, 0, sizeof(auxDoubleArray));
+ memcpy(auxDoubleArray, pVoidArray, 3 * sizeof(double));
+ }
+ for (i = 0; i < 3; i++) {
+ dblDiffLimit = RATIONAL_EPS * auxDoubleArrayGPSTime[i];
+ dblDiff = auxDoubleArray[i] - auxDoubleArrayGPSTime[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value %d of GPSTAG_TIMESTAMP %f differs from set value %f\n", i, auxDoubleArray[i], auxDoubleArrayGPS2[i]);
+ GOTOFAILURE_GPS
+ }
+ }
+
+ /* GPSTAG_IMGDIRECTION --- TIFF_RATIONAL, TIFF_SETGET_DOUBLE */
+ if (!TIFFGetField(tif, GPSTAG_IMGDIRECTION, &auxDblUnion.dbl)) {
+ fprintf(stderr, "Can't read GPSTAG_IMGDIRECTION\n");
+ GOTOFAILURE_GPS
+ }
+ if (blnIsRational2Double) {
+ /* New interface allows also double precision for TIFF_RATIONAL */
+ auxDouble = auxDblUnion.dbl;
+ } else {
+ /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE always as FLOAT */
+ auxDouble = (double)auxDblUnion.flt1;
+ }
+ /* compare read values with written ones */
+ dblDiffLimit = RATIONAL_EPS * auxDoubleGPSDirection;
+ dblDiff = auxDouble - auxDoubleGPSDirection;
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value of GPSTAG_IMGDIRECTION %f differs from set value %f\n", auxDouble, auxDoubleGPSDirection);
+ GOTOFAILURE_GPS
+ }
+
+ /*-- GPSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 */
+ retCode = TIFFGetField(tif, GPSTAG_DIFFERENTIAL, &auxShort);
+ if (!retCode) { fprintf(stderr, "Can't read %s\n", "GPSTAG_DIFFERENTIAL"); }
+ if (auxShort != auxShortArrayW[5]) {
+ fprintf(stderr, "Read value of GPSTAG_DIFFERENTIAL %d differs from set value %d\n", auxShort, auxShortArrayW[5]);
+ GOTOFAILURE_GPS
+ }
+
+ /*-- GPSHPOSITIONINGERROR - new tag for EXIF 2.31 --*/
+ if (!TIFFGetField(tif, GPSTAG_GPSHPOSITIONINGERROR, &auxDblUnion.dbl)) {
+ fprintf(stderr, "Can't read GPSTAG_GPSHPOSITIONINGERROR\n");
+ GOTOFAILURE_GPS
+ }
+ if (blnIsRational2Double) {
+ /* New interface allows also double precision for TIFF_RATIONAL */
+ auxDouble = auxDblUnion.dbl;
+ } else {
+ /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE always as FLOAT */
+ auxDouble = (double)auxDblUnion.flt1;
+ }
+ /* compare read values with written ones */
+ auxFloat = (float)GPSHPOSITIONINGERROR_VAL;
+ dblDiffLimit = RATIONAL_EPS * auxFloat;
+ dblDiff = auxDouble - auxFloat;
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ fprintf(stderr, "Read value of GPSTAG_GPSHPOSITIONINGERROR %f differs from set value %f\n", auxDouble, auxFloat);
+ GOTOFAILURE_GPS
+ }
+
+ /*=============== END reading GPS tags ==========================*/
+#endif /*-- READ_GPS_TAGS --*/
+
+
+
+/*================== Reading EXIF 2.31 tags =====================*/
+
+ /*--- Firstly, get EXIF directory offset from main directory. */
+
+ /*-- Go back to the first (main) directory, and get value of the EXIFIFD directory- offset. */
+ /* (directory is reloaded from file!) */
+ TIFFSetDirectory(tif, 0);
+ retCode = TIFFGetField(tif, TIFFTAG_EXIFIFD, &read_dir_offset );
+
+#ifdef READ_EXIF_TAGS
+ /*-- Now read EXIF directory from file into memory --*/
+ retCode = TIFFReadEXIFDirectory(tif, read_dir_offset);
+
+ /*-- Now get some parameters from EXIF-directory (already read into memory) --*/
+ retCode = TIFFGetField(tif, EXIFTAG_EXIFVERSION, &pAscii);
+
+
+#ifdef READ_ALL_EXIF_TAGS
+ /*-- Get array, where EXIF tag fields are defined --*/
+ tFieldArray = _TIFFGetExifFields();
+ nTags = tFieldArray->count;
+ /*-- Check, if the TiffLibrary is compiled with the new interface with Rational2Double or still uses the old definitions. */
+ /* tif points to EXIF tags, so TIFFFindField() can only access the EXIF tag fields */
+ fip = TIFFFindField(tif, EXIFTAG_EXPOSURETIME, TIFF_ANY);
+ tSetFieldType = fip->set_field_type;
+ if (tSetFieldType == TIFF_SETGET_DOUBLE) {
+ blnIsRational2Double = FALSE;
+ fprintf(stderr, "-- EXIF tags read with standard --\n");
+ } else {
+ blnIsRational2Double = TRUE;
+ fprintf(stderr, "-- Rational2Double for reading EXIF tags detected --\n");
+ }
+
+ for (i=0; i<nTags; i++) {
+ tTag = tFieldArray->fields[i].field_tag;
+ tType = tFieldArray->fields[i].field_type; /* e.g. TIFF_RATIONAL */
+ tWriteCount = tFieldArray->fields[i].field_writecount;
+ tSetFieldType = tFieldArray->fields[i].set_field_type; /* e.g. TIFF_SETGET_C0_FLOAT */
+ tFieldName = tFieldArray->fields[i].field_name;
+ pVoid = NULL;
+
+ /*-- dependent on set_field_type read value --*/
+ switch (tSetFieldType)
+ {
+ case TIFF_SETGET_ASCII:
+ /* Either the stringlength is defined as a fixed length in .field_writecount or a NULL-terminated string is used. */
+ if (!TIFFGetField( tif, tTag, &pAscii)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* Save string from temporary buffer and compare with written string. */
+ strncpy(auxCharArray, pAscii, sizeof(auxCharArray));
+ if (tWriteCount > 0) auxLong = tWriteCount-1; else auxLong = (long)strlen(auxCharArray);
+ retCode2 = strncmp(auxCharArray, auxTextArrayW[i], auxLong);
+ if (retCode2 != 0) {
+ fprintf (stderr, "%d:Read value of %s %s differs from set value %s\n", i, tFieldName, auxCharArray, auxTextArrayW[i]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ break;
+ /*-- For reading, the parameter size is to be observed !! */
+ case TIFF_SETGET_UINT8:
+ case TIFF_SETGET_SINT8:
+ if (!TIFFGetField( tif, tTag, &auxChar)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* compare read values with written ones */
+ auxLong = auxChar;
+ if (auxLong != (char)auxLongArrayW[i]) {
+ fprintf (stderr, "%d:Read value of %s %ld differs from set value %ld\n", i, tFieldName, auxLong, auxLongArrayW[i]);
+ }
+ break;
+ case TIFF_SETGET_UINT16:
+ case TIFF_SETGET_SINT16:
+ if (!TIFFGetField( tif, tTag, &auxShort)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* compare read values with written ones */
+ auxLong = auxShort;
+ if (auxLong != (short)auxLongArrayW[i]) {
+ fprintf (stderr, "%d:Read value of %s %ld differs from set value %ld\n", i, tFieldName, auxLong, auxLongArrayW[i]);
+ }
+ break;
+ case TIFF_SETGET_UINT32:
+ case TIFF_SETGET_SINT32:
+ case TIFF_SETGET_IFD8:
+ case TIFF_SETGET_INT:
+ if (!TIFFGetField( tif, tTag, &auxUint32)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* compare read values with written ones */
+ auxLong = auxUint32;
+ if (auxLong != auxLongArrayW[i]) {
+ fprintf (stderr, "%d:Read value of %s %ld differs from set value %ld\n", i, tFieldName, auxLong, auxLongArrayW[i]);
+ }
+ break;
+ case TIFF_SETGET_FLOAT:
+ if (!TIFFGetField( tif, tTag, &auxFloat)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* compare read values with written ones */
+ if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
+ dblDiff = auxFloat - auxDoubleArrayW[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1.0" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
+ * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
+ * which are not treated within LibTiff!!
+ */
+ if (!(tTag == EXIFTAG_SUBJECTDISTANCE && auxFloat == -1.0)) {
+ fprintf (stderr, "%d:Read value of %s %f differs from set value %f\n", i, tFieldName, auxFloat, auxDoubleArrayW[i]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ break;
+ case TIFF_SETGET_DOUBLE:
+ /*-- Unfortunately, TIFF_SETGET_DOUBLE is used for TIFF_RATIONAL but those have to be read with FLOAT !!! */
+ /* Only TIFFTAG_STONITS is a TIFF_DOUBLE, which has to be read as DOUBLE!! */
+ /*-- ATTENTION: ----
+ * Only after update with Rational2Double feature, also TIFF_RATIONAL can be read in double precision!!!
+ * Therefore, use a union to avoid overflow in TIFFGetField() return value
+ * and depending on version check for the right interface here:
+ * - old interface: correct value should be here a float
+ * - new interface: correct value should be here a double
+ * Interface version (old/new) is determined above.
+ -------------------*/
+ if (!TIFFGetField(tif, tTag, &auxDblUnion.dbl)) {
+ fprintf(stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) {
+ if (blnIsRational2Double) {
+ /* New interface allows also double precision for TIFF_RATIONAL */
+ auxDouble = auxDblUnion.dbl;
+ }
+ else {
+ /* Old interface reads TIFF_RATIONAL defined as TIFF_SETGET_DOUBLE always as FLOAT */
+ auxDouble = (double)auxDblUnion.flt1;
+ }
+ }
+ else {
+ auxDouble = auxDblUnion.dbl;
+ }
+ /* compare read values with written ones */
+ if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
+ dblDiff = auxDouble - auxDoubleArrayW[i];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1.0" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! */
+ if (!(tTag == EXIFTAG_SUBJECTDISTANCE && auxDouble == -1.0)) {
+ fprintf (stderr, "%d:Read value of %s %f differs from set value %f\n", i, tFieldName, auxDouble, auxDoubleArrayW[i]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ break;
+
+ case TIFF_SETGET_C0_FLOAT:
+ case TIFF_SETGET_C0_DOUBLE:
+ case TIFF_SETGET_C16_FLOAT:
+ case TIFF_SETGET_C16_DOUBLE:
+ case TIFF_SETGET_C32_FLOAT:
+ case TIFF_SETGET_C32_DOUBLE:
+ /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
+ /*-- Check, if it is a single parameter, a fixed array or a variable array */
+ if (tWriteCount == 1) {
+ fprintf (stderr, "Reading: WriteCount for .set_field_type %d should be -1 or greater than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
+ } else {
+ /*-- Either fix or variable array --*/
+ /* For arrays, distinguishing between float or double is essential. */
+ /* Now decide between fixed or variable array */
+ if (tWriteCount > 1) {
+ /* fixed array with needed arraysize defined in .field_writecount */
+ if (!TIFFGetField( tif, tTag, &pVoidArray)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* set tWriteCount to number of read samples for next steps */
+ auxLong = tWriteCount;
+ } else {
+ /* Special treatment of variable array. */
+ /* Dependent on Cxx, the count parameter is char, short or long. Therefore use unionLong! */
+ if (!TIFFGetField( tif, tTag, &unionLong, &pVoidArray)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* set tWriteCount to number of read samples for next steps */
+ auxLong = unionLong.Short1;
+ }
+ /* Save values from temporary array */
+ if (tSetFieldType == TIFF_SETGET_C0_FLOAT || tSetFieldType == TIFF_SETGET_C16_FLOAT || tSetFieldType == TIFF_SETGET_C32_FLOAT) {
+ memcpy(&auxFloatArray, pVoidArray,(auxLong * sizeof(auxFloatArray[0])));
+ /* compare read values with written ones */
+ if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
+ for (j=0; j<auxLong; j++) {
+ dblDiff = auxFloatArray[j] - auxFloatArrayW[i+j];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ /*if (auxFloatArray[j] != (float)auxFloatArrayW[i+j]) { */
+ fprintf (stderr, "Read value %d of %s #%d %f differs from set value %f\n", i, tFieldName, j, auxFloatArray[j], auxFloatArrayW[i+j]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ } else {
+ memcpy(&auxDoubleArray, pVoidArray,(auxLong * sizeof(auxDoubleArray[0])));
+ /* compare read values with written ones */
+ if (tType == TIFF_RATIONAL || tType == TIFF_SRATIONAL) dblDiffLimit = RATIONAL_EPS*auxDoubleArrayW[i]; else dblDiffLimit = 1e-6;
+ for (j=0; j<auxLong; j++) {
+ dblDiff = auxDoubleArray[j] - auxDoubleArrayW[i+j];
+ if (fabs(dblDiff) > fabs(dblDiffLimit)) {
+ /*if (auxDoubleArray[j] != auxDoubleArrayW[i+j]) { */
+ fprintf (stderr, "Read value %d of %s #%d %f differs from set value %f\n", i, tFieldName, j, auxDoubleArray[j], auxDoubleArrayW[i+j]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_UINT8:
+ case TIFF_SETGET_C0_SINT8:
+ case TIFF_SETGET_C16_UINT8:
+ case TIFF_SETGET_C16_SINT8:
+ case TIFF_SETGET_C32_UINT8:
+ case TIFF_SETGET_C32_SINT8:
+ /* For arrays, distinguishing between float or double is essential, even for writing */
+ pVoid = &auxCharArrayW[i];
+ case TIFF_SETGET_C0_UINT16:
+ case TIFF_SETGET_C0_SINT16:
+ case TIFF_SETGET_C16_UINT16:
+ case TIFF_SETGET_C16_SINT16:
+ case TIFF_SETGET_C32_UINT16:
+ case TIFF_SETGET_C32_SINT16:
+ if (pVoid == NULL) pVoid = &auxShortArrayW[i];
+ case TIFF_SETGET_C0_UINT32:
+ case TIFF_SETGET_C0_SINT32:
+ case TIFF_SETGET_C16_UINT32:
+ case TIFF_SETGET_C16_SINT32:
+ case TIFF_SETGET_C32_UINT32:
+ case TIFF_SETGET_C32_SINT32:
+ if (pVoid == NULL) pVoid = &auxLongArrayW[i];
+ /* _Cxx_ just defines the size of the count parameter for the array as C0=char, C16=short or C32=long */
+ /*-- Check, if it is a single parameter, a fixed array or a variable array */
+ if (tWriteCount == 1) {
+ fprintf (stderr, "WriteCount for .set_field_type %d should be -1 or greater than 1! %s\n", tSetFieldType, tFieldArray->fields[i].field_name);
+ } else {
+ /*-- Either fix or variable array --*/
+ /* Now decide between fixed or variable array */
+ if (tWriteCount > 1) {
+ /* fixed array with needed arraysize defined in .field_writecount */
+ if (!TIFFGetField( tif, tTag, &pVoidArray)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* set tWriteCount to number of read samples for next steps */
+ auxLong = tWriteCount;
+ } else {
+ /* special treatment of variable array */
+ /* for test, use always arraysize of VARIABLE_ARRAY_SIZE */
+ if (!TIFFGetField( tif, tTag, &unionLong, &pVoidArray)) {
+ fprintf (stderr, "Can't read %s\n", tFieldArray->fields[i].field_name);
+ GOTOFAILURE_ALL_EXIF
+ break;
+ }
+ /* set tWriteCount to number of read samples for next steps */
+ auxLong = unionLong.Short1;
+ }
+ /* Save values from temporary array */
+ if (tSetFieldType == TIFF_SETGET_C0_UINT8 || tSetFieldType == TIFF_SETGET_C0_SINT8 ||
+ tSetFieldType == TIFF_SETGET_C16_UINT8 || tSetFieldType == TIFF_SETGET_C16_SINT8 ||
+ tSetFieldType == TIFF_SETGET_C32_UINT8 || tSetFieldType == TIFF_SETGET_C32_SINT8 ) {
+ memcpy(&auxCharArray, pVoidArray,(auxLong * sizeof(auxCharArray[0])));
+ /* Compare and check values */
+ for (j=0; j<auxLong; j++) {
+ if (tTag == EXIFTAG_EXIFVERSION) {
+ /*-- Use exifVersion[] instead of auxCharArrayW[] for differently set EXIFVERSION tag */
+ if (auxCharArray[j] != exifVersion[j]) {
+ fprintf(stderr, "Read value %d of %s #%d %d differs from set value %d\n", i, tFieldName, j, auxCharArray[j], auxCharArrayW[i + j]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ } else {
+ if (auxCharArray[j] != auxCharArrayW[i + j]) {
+ fprintf(stderr, "Read value %d of %s #%d %d differs from set value %d\n", i, tFieldName, j, auxCharArray[j], auxCharArrayW[i + j]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ }
+ } else if (tSetFieldType == TIFF_SETGET_C0_UINT16 || tSetFieldType == TIFF_SETGET_C0_SINT16 ||
+ tSetFieldType == TIFF_SETGET_C16_UINT16 || tSetFieldType == TIFF_SETGET_C16_SINT16 ||
+ tSetFieldType == TIFF_SETGET_C32_UINT16 || tSetFieldType == TIFF_SETGET_C32_SINT16 ) {
+ memcpy(&auxShortArray, pVoidArray,(auxLong * sizeof(auxShortArray[0])));
+ /* Compare and check values */
+ for (j=0; j<auxLong; j++) {
+ if (auxShortArray[j] != auxShortArrayW[i+j]) {
+ fprintf (stderr, "Read value %d of %s #%d %d differs from set value %d\n", i, tFieldName, j, auxShortArray[j], auxShortArrayW[i+j]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ } else if (tSetFieldType == TIFF_SETGET_C0_UINT32 || tSetFieldType == TIFF_SETGET_C0_SINT32 ||
+ tSetFieldType == TIFF_SETGET_C16_UINT32 || tSetFieldType == TIFF_SETGET_C16_SINT32 ||
+ tSetFieldType == TIFF_SETGET_C32_UINT32 || tSetFieldType == TIFF_SETGET_C32_SINT32 ) {
+ memcpy(&auxLongArray, pVoidArray,(auxLong * sizeof(auxLongArray[0])));
+ /* Compare and check values */
+ for (j=0; j<auxLong; j++) {
+ if (auxLongArray[j] != auxLongArrayW[i+j]) {
+ fprintf (stderr, "Read value %d of %s #%d %ld differs from set value %ld\n", i, tFieldName, j, auxLongArray[j], auxLongArrayW[i+j]);
+ GOTOFAILURE_ALL_EXIF
+ }
+ }
+ } else {
+ fprintf (stderr, "SetFieldType %d not defined within switch case reading for UINT for %s.\n", tSetFieldType, tFieldName);
+ GOTOFAILURE
+ }
+ }
+ break;
+ default:
+ fprintf (stderr, "SetFieldType %d not defined within writing switch for %s.\n", tSetFieldType, tFieldName);
+ GOTOFAILURE
+ }; /*-- switch() --*/
+ } /*-- for() --*/
+ /*================= EXIF: END Reading arbitrary data to the EXIF fields END END END ==============*/
+#endif /*-- READ_ALL_EXIF_TAGS --*/
+#endif /*-- READ_EXIF_TAGS --*/
+
+
+
+
+ TIFFClose(tif);
+
+ /* All tests passed; delete file and exit with success status. */
+#ifdef FOR_AUTO_TESTING
+ unlink(filenameRead);
+#endif
+ fprintf(stderr, "-------- Test finished OK ----------\n");
+ return 0;
+
+failure:
+ /*
+ * Something goes wrong; close file and return unsuccessful status.
+ * Do not remove the file for further manual investigation.
+ */
+ TIFFClose(tif);
+ fprintf(stderr, "-------- Test finished with FAILURE --------\n");
+ return 1;
+}