4 * Copyright (c) 2012, Frank Warmerdam <warmerdam@pobox.com>
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29 * Module to handling of custom directories like EXIF.
32 #include "tif_config.h"
44 static const char filename
[] = "custom_dir.tif";
46 #define SPP 3 /* Samples per pixel */
47 const uint16 width
= 1;
48 const uint16 length
= 1;
50 const uint16 photometric
= PHOTOMETRIC_RGB
;
51 const uint16 rows_per_strip
= 1;
52 const uint16 planarconfig
= PLANARCONFIG_CONTIG
;
56 { TIFFTAG_IMAGEWIDTH
, -1, -1, TIFF_ASCII
, 0, TIFF_SETGET_ASCII
, TIFF_SETGET_UNDEFINED
, FIELD_CUSTOM
, 1, 0, "Custom1", NULL
},
57 { TIFFTAG_DOTRANGE
, -1, -1, TIFF_ASCII
, 0, TIFF_SETGET_ASCII
, TIFF_SETGET_UNDEFINED
, FIELD_CUSTOM
, 1, 0, "Custom2", NULL
},
60 static TIFFFieldArray customFieldArray
= { tfiatOther
, 0, 2, customFields
};
66 unsigned char buf
[SPP
] = { 0, 127, 255 };
67 uint64 dir_offset
= 0, dir_offset2
= 0;
68 uint64 read_dir_offset
= 0, read_dir_offset2
= 0;
69 uint64
*dir_offset2_ptr
= NULL
;
74 /* We write the main directory as a simple image. */
75 tif
= TIFFOpen(filename
, "w+");
77 fprintf (stderr
, "Can't create test TIFF file %s.\n", filename
);
81 if (!TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
, width
)) {
82 fprintf (stderr
, "Can't set ImageWidth tag.\n");
85 if (!TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, length
)) {
86 fprintf (stderr
, "Can't set ImageLength tag.\n");
89 if (!TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, bps
)) {
90 fprintf (stderr
, "Can't set BitsPerSample tag.\n");
93 if (!TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, SPP
)) {
94 fprintf (stderr
, "Can't set SamplesPerPixel tag.\n");
97 if (!TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
, rows_per_strip
)) {
98 fprintf (stderr
, "Can't set SamplesPerPixel tag.\n");
101 if (!TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, planarconfig
)) {
102 fprintf (stderr
, "Can't set PlanarConfiguration tag.\n");
105 if (!TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, photometric
)) {
106 fprintf (stderr
, "Can't set PhotometricInterpretation tag.\n");
110 /* Write dummy pixel data. */
111 if (!TIFFWriteScanline(tif
, buf
, 0, 0) < 0) {
112 fprintf (stderr
, "Can't write image data.\n");
116 if (!TIFFWriteDirectory( tif
)) {
117 fprintf (stderr
, "TIFFWriteDirectory() failed.\n");
122 * Now create an EXIF directory.
124 if (TIFFCreateEXIFDirectory(tif
) != 0) {
125 fprintf (stderr
, "TIFFCreateEXIFDirectory() failed.\n" );
129 if (!TIFFSetField( tif
, EXIFTAG_SPECTRALSENSITIVITY
, "EXIF Spectral Sensitivity")) {
130 fprintf (stderr
, "Can't write SPECTRALSENSITIVITY\n" );
134 if (!TIFFWriteCustomDirectory( tif
, &dir_offset
)) {
135 fprintf (stderr
, "TIFFWriteCustomDirectory() with EXIF failed.\n");
140 * Now create a custom directory with tags that conflict with mainline
144 TIFFFreeDirectory( tif
);
145 if (TIFFCreateCustomDirectory(tif
, &customFieldArray
) != 0) {
146 fprintf (stderr
, "TIFFCreateEXIFDirectory() failed.\n" );
150 if (!TIFFSetField( tif
, TIFFTAG_IMAGEWIDTH
, "*Custom1")) { /* not really IMAGEWIDTH */
151 fprintf (stderr
, "Can't write pseudo-IMAGEWIDTH.\n" );
155 if (!TIFFSetField( tif
, TIFFTAG_DOTRANGE
, "*Custom2")) { /* not really DOTWIDTH */
156 fprintf (stderr
, "Can't write pseudo-DOTWIDTH.\n" );
160 if (!TIFFWriteCustomDirectory( tif
, &dir_offset2
)) {
161 fprintf (stderr
, "TIFFWriteCustomDirectory() with EXIF failed.\n");
166 * Go back to the first directory, and add the EXIFIFD pointer.
168 TIFFSetDirectory(tif
, 0);
169 TIFFSetField(tif
, TIFFTAG_EXIFIFD
, dir_offset
);
170 TIFFSetField(tif
, TIFFTAG_SUBIFD
, 1, &dir_offset2
);
174 /* Ok, now test whether we can read written values in the EXIF directory. */
175 tif
= TIFFOpen(filename
, "r");
177 TIFFGetField(tif
, TIFFTAG_EXIFIFD
, &read_dir_offset
);
178 if( read_dir_offset
!= dir_offset
) {
179 fprintf (stderr
, "Did not get expected EXIFIFD.\n" );
183 TIFFGetField(tif
, TIFFTAG_SUBIFD
, &count16
, &dir_offset2_ptr
);
184 read_dir_offset2
= dir_offset2_ptr
[0];
185 if( read_dir_offset2
!= dir_offset2
|| count16
!= 1) {
186 fprintf (stderr
, "Did not get expected SUBIFD.\n" );
190 if( !TIFFReadEXIFDirectory(tif
, read_dir_offset
) ) {
191 fprintf (stderr
, "TIFFReadEXIFDirectory() failed.\n" );
195 if (!TIFFGetField( tif
, EXIFTAG_SPECTRALSENSITIVITY
, &ascii_value
) ) {
196 fprintf (stderr
, "reading SPECTRALSENSITIVITY failed.\n" );
200 if( strcmp(ascii_value
,"EXIF Spectral Sensitivity") != 0) {
201 fprintf (stderr
, "got wrong SPECTRALSENSITIVITY value.\n" );
205 /* Try reading the Custom directory */
207 if( !TIFFReadCustomDirectory(tif
, read_dir_offset2
, &customFieldArray
) ) {
208 fprintf (stderr
, "TIFFReadCustomDirectory() failed.\n" );
212 if (!TIFFGetField( tif
, TIFFTAG_IMAGEWIDTH
, &ascii_value
) ) {
213 fprintf (stderr
, "reading pseudo-IMAGEWIDTH failed.\n" );
217 if( strcmp(ascii_value
,"*Custom1") != 0) {
218 fprintf (stderr
, "got wrong pseudo-IMAGEWIDTH value.\n" );
222 if (!TIFFGetField( tif
, TIFFTAG_DOTRANGE
, &ascii_value
) ) {
223 fprintf (stderr
, "reading pseudo-DOTRANGE failed.\n" );
227 if( strcmp(ascii_value
,"*Custom2") != 0) {
228 fprintf (stderr
, "got wrong pseudo-DOTRANGE value.\n" );
234 /* All tests passed; delete file and exit with success status. */
240 * Something goes wrong; close file and return unsuccessful status.
241 * Do not remove the file for further manual investigation.
247 /* vim: set ts=8 sts=8 sw=8 noet: */