3 * Copyright (c) 2012, Frank Warmerdam <warmerdam@pobox.com>
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that (i) the above copyright notices and this permission notice appear in
8 * all copies of the software and related documentation, and (ii) the names of
9 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 * publicity relating to the software without the specific, prior written
11 * permission of Sam Leffler and Silicon Graphics.
13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * Module to handling of custom directories like EXIF.
31 #include "tif_config.h"
43 static const char filename
[] = "custom_dir.tif";
45 #define SPP 3 /* Samples per pixel */
46 const uint16 width
= 1;
47 const uint16 length
= 1;
49 const uint16 photometric
= PHOTOMETRIC_RGB
;
50 const uint16 rows_per_strip
= 1;
51 const uint16 planarconfig
= PLANARCONFIG_CONTIG
;
55 { TIFFTAG_IMAGEWIDTH
, -1, -1, TIFF_ASCII
, 0, TIFF_SETGET_ASCII
, TIFF_SETGET_UNDEFINED
, FIELD_CUSTOM
, 1, 0, "Custom1", NULL
},
56 { TIFFTAG_DOTRANGE
, -1, -1, TIFF_ASCII
, 0, TIFF_SETGET_ASCII
, TIFF_SETGET_UNDEFINED
, FIELD_CUSTOM
, 1, 0, "Custom2", NULL
},
59 static TIFFFieldArray customFieldArray
= { tfiatOther
, 0, 2, customFields
};
65 unsigned char buf
[SPP
] = { 0, 127, 255 };
66 uint64 dir_offset
= 0, dir_offset2
= 0;
67 uint64 read_dir_offset
= 0, read_dir_offset2
= 0;
68 uint64
*dir_offset2_ptr
= NULL
;
73 /* We write the main directory as a simple image. */
74 tif
= TIFFOpen(filename
, "w+");
76 fprintf (stderr
, "Can't create test TIFF file %s.\n", filename
);
80 if (!TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
, width
)) {
81 fprintf (stderr
, "Can't set ImageWidth tag.\n");
84 if (!TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, length
)) {
85 fprintf (stderr
, "Can't set ImageLength tag.\n");
88 if (!TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, bps
)) {
89 fprintf (stderr
, "Can't set BitsPerSample tag.\n");
92 if (!TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, SPP
)) {
93 fprintf (stderr
, "Can't set SamplesPerPixel tag.\n");
96 if (!TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
, rows_per_strip
)) {
97 fprintf (stderr
, "Can't set SamplesPerPixel tag.\n");
100 if (!TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, planarconfig
)) {
101 fprintf (stderr
, "Can't set PlanarConfiguration tag.\n");
104 if (!TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, photometric
)) {
105 fprintf (stderr
, "Can't set PhotometricInterpretation tag.\n");
109 /* Write dummy pixel data. */
110 if (!TIFFWriteScanline(tif
, buf
, 0, 0) < 0) {
111 fprintf (stderr
, "Can't write image data.\n");
115 if (!TIFFWriteDirectory( tif
)) {
116 fprintf (stderr
, "TIFFWriteDirectory() failed.\n");
121 * Now create an EXIF directory.
123 if (TIFFCreateEXIFDirectory(tif
) != 0) {
124 fprintf (stderr
, "TIFFCreateEXIFDirectory() failed.\n" );
128 if (!TIFFSetField( tif
, EXIFTAG_SPECTRALSENSITIVITY
, "EXIF Spectral Sensitivity")) {
129 fprintf (stderr
, "Can't write SPECTRALSENSITIVITY\n" );
133 if (!TIFFWriteCustomDirectory( tif
, &dir_offset
)) {
134 fprintf (stderr
, "TIFFWriteCustomDirectory() with EXIF failed.\n");
139 * Now create a custom directory with tags that conflict with mainline
143 TIFFFreeDirectory( tif
);
144 if (TIFFCreateCustomDirectory(tif
, &customFieldArray
) != 0) {
145 fprintf (stderr
, "TIFFCreateEXIFDirectory() failed.\n" );
149 if (!TIFFSetField( tif
, TIFFTAG_IMAGEWIDTH
, "*Custom1")) { /* not really IMAGEWIDTH */
150 fprintf (stderr
, "Can't write pseudo-IMAGEWIDTH.\n" );
154 if (!TIFFSetField( tif
, TIFFTAG_DOTRANGE
, "*Custom2")) { /* not really DOTWIDTH */
155 fprintf (stderr
, "Can't write pseudo-DOTWIDTH.\n" );
159 if (!TIFFWriteCustomDirectory( tif
, &dir_offset2
)) {
160 fprintf (stderr
, "TIFFWriteCustomDirectory() with EXIF failed.\n");
165 * Go back to the first directory, and add the EXIFIFD pointer.
167 TIFFSetDirectory(tif
, 0);
168 TIFFSetField(tif
, TIFFTAG_EXIFIFD
, dir_offset
);
169 TIFFSetField(tif
, TIFFTAG_SUBIFD
, 1, &dir_offset2
);
173 /* Ok, now test whether we can read written values in the EXIF directory. */
174 tif
= TIFFOpen(filename
, "r");
176 TIFFGetField(tif
, TIFFTAG_EXIFIFD
, &read_dir_offset
);
177 if( read_dir_offset
!= dir_offset
) {
178 fprintf (stderr
, "Did not get expected EXIFIFD.\n" );
182 TIFFGetField(tif
, TIFFTAG_SUBIFD
, &count16
, &dir_offset2_ptr
);
183 read_dir_offset2
= dir_offset2_ptr
[0];
184 if( read_dir_offset2
!= dir_offset2
|| count16
!= 1) {
185 fprintf (stderr
, "Did not get expected SUBIFD.\n" );
189 if( !TIFFReadEXIFDirectory(tif
, read_dir_offset
) ) {
190 fprintf (stderr
, "TIFFReadEXIFDirectory() failed.\n" );
194 if (!TIFFGetField( tif
, EXIFTAG_SPECTRALSENSITIVITY
, &ascii_value
) ) {
195 fprintf (stderr
, "reading SPECTRALSENSITIVITY failed.\n" );
199 if( strcmp(ascii_value
,"EXIF Spectral Sensitivity") != 0) {
200 fprintf (stderr
, "got wrong SPECTRALSENSITIVITY value.\n" );
204 /* Try reading the Custom directory */
206 if( !TIFFReadCustomDirectory(tif
, read_dir_offset2
, &customFieldArray
) ) {
207 fprintf (stderr
, "TIFFReadCustomDirectory() failed.\n" );
211 if (!TIFFGetField( tif
, TIFFTAG_IMAGEWIDTH
, &ascii_value
) ) {
212 fprintf (stderr
, "reading pseudo-IMAGEWIDTH failed.\n" );
216 if( strcmp(ascii_value
,"*Custom1") != 0) {
217 fprintf (stderr
, "got wrong pseudo-IMAGEWIDTH value.\n" );
221 if (!TIFFGetField( tif
, TIFFTAG_DOTRANGE
, &ascii_value
) ) {
222 fprintf (stderr
, "reading pseudo-DOTRANGE failed.\n" );
226 if( strcmp(ascii_value
,"*Custom2") != 0) {
227 fprintf (stderr
, "got wrong pseudo-DOTRANGE value.\n" );
233 /* All tests passed; delete file and exit with success status. */
239 * Something goes wrong; close file and return unsuccessful status.
240 * Do not remove the file for further manual investigation.
246 /* vim: set ts=8 sts=8 sw=8 noet: */