]> git.saurik.com Git - wxWidgets.git/blob - src/tiff/test/raw_decode.c
ce9e8f2701c21663b5c47603bc2962e1b02f8ba3
[wxWidgets.git] / src / tiff / test / raw_decode.c
1 /* $Id$ */
2
3 /*
4 * Copyright (c) 2012, Frank Warmerdam <warmerdam@pobox.com>
5 *
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.
13 *
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.
17 *
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
23 * OF THIS SOFTWARE.
24 */
25
26 /*
27 * TIFF Library
28 *
29 * The objective of this test suite is to test the JPEGRawDecode()
30 * interface via TIFReadEncodedTile(). This function with YCbCr subsampling
31 * is a frequent source of bugs.
32 */
33
34 #include "tif_config.h"
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #ifdef HAVE_UNISTD_H
40 # include <unistd.h>
41 #endif
42
43 #include "tiffio.h"
44
45 #include "jpeglib.h" /* Needed for JPEG_LIB_VERSION */
46
47 static unsigned char cluster_0[] = { 0, 0, 2, 0, 138, 139 };
48 static unsigned char cluster_64[] = { 0, 0, 9, 6, 134, 119 };
49 static unsigned char cluster_128[] = { 44, 40, 63, 59, 230, 95 };
50
51 static int check_cluster( int cluster, unsigned char *buffer, unsigned char *expected_cluster ) {
52 unsigned char *target = buffer + cluster*6;
53
54 if (memcmp(target, expected_cluster, 6) == 0) {
55 return 0;
56 }
57
58 fprintf( stderr, "Cluster %d did not match expected results.\n", cluster );
59 fprintf( stderr,
60 "Expect: %3d %3d %3d %3d\n"
61 " %3d %3d\n",
62 expected_cluster[0], expected_cluster[1],
63 expected_cluster[4], expected_cluster[5],
64 expected_cluster[2], expected_cluster[3] );
65 fprintf( stderr,
66 " Got: %3d %3d %3d %3d\n"
67 " %3d %3d\n",
68 target[0], target[1],
69 target[4], target[5],
70 target[2], target[3] );
71 return 1;
72 }
73
74 static int check_rgb_pixel( int pixel, int red, int green, int blue, unsigned char *buffer ) {
75 unsigned char *rgb = buffer + 3 * pixel;
76
77 if( rgb[0] == red && rgb[1] == green && rgb[2] == blue ) {
78 return 0;
79 }
80
81 fprintf( stderr, "Pixel %d did not match expected results.\n", pixel );
82 fprintf( stderr, "Expect: %3d %3d %3d\n", red, green, blue );
83 fprintf( stderr, " Got: %3d %3d %3d\n", rgb[0], rgb[1], rgb[2] );
84 return 1;
85 }
86
87 static int check_rgba_pixel( int pixel, int red, int green, int blue, int alpha, uint32 *buffer ) {
88 /* RGBA images are upside down - adjust for normal ordering */
89 int adjusted_pixel = pixel % 128 + (127 - (pixel/128)) * 128;
90 uint32 rgba = buffer[adjusted_pixel];
91
92 if( TIFFGetR(rgba) == (uint32) red && TIFFGetG(rgba) == (uint32) green &&
93 TIFFGetB(rgba) == (uint32) blue && TIFFGetA(rgba) == (uint32) alpha ) {
94 return 0;
95 }
96
97 fprintf( stderr, "Pixel %d did not match expected results.\n", pixel );
98 fprintf( stderr, "Expect: %3d %3d %3d %3d\n", red, green, blue, alpha );
99 fprintf( stderr, " Got: %3d %3d %3d %3d\n",
100 TIFFGetR(rgba), TIFFGetG(rgba), TIFFGetB(rgba), TIFFGetA(rgba) );
101 return 1;
102 }
103
104 int
105 main(int argc, char **argv)
106 {
107 TIFF *tif;
108 static const char *srcfilerel = "images/quad-tile.jpg.tiff";
109 char *srcdir = NULL;
110 char srcfile[1024];
111 unsigned short h, v;
112 int status;
113 unsigned char *buffer;
114 uint32 *rgba_buffer;
115 tsize_t sz, szout;
116 unsigned int pixel_status = 0;
117
118 (void) argc;
119 (void) argv;
120
121 if ((srcdir = getenv("srcdir")) == NULL) {
122 srcdir = ".";
123 }
124 if ((strlen(srcdir) + 1 + strlen(srcfilerel)) >= sizeof(srcfile)) {
125 fprintf( stderr, "srcdir too long %s\n", srcdir);
126 exit( 1 );
127 }
128 strcpy(srcfile,srcdir);
129 strcat(srcfile,"/");
130 strcat(srcfile,srcfilerel);
131
132 tif = TIFFOpen(srcfile,"r");
133 if ( tif == NULL ) {
134 fprintf( stderr, "Could not open %s\n", srcfile);
135 exit( 1 );
136 }
137
138 status = TIFFGetField(tif,TIFFTAG_YCBCRSUBSAMPLING, &h, &v);
139 if ( status == 0 || h != 2 || v != 2) {
140 fprintf( stderr, "Could not retrieve subsampling tag.\n" );
141 exit(1);
142 }
143
144 /*
145 * What is the appropriate size of a YCbCr encoded tile?
146 */
147 sz = TIFFTileSize(tif);
148 if( sz != 24576) {
149 fprintf(stderr, "tiles are %d bytes\n", (int)sz);
150 exit(1);
151 }
152
153 buffer = (unsigned char *) malloc(sz);
154
155 /*
156 * Read a tile in decompressed form, but still YCbCr subsampled.
157 */
158 szout = TIFFReadEncodedTile(tif,9,buffer,sz);
159 if (szout != sz) {
160 fprintf( stderr,
161 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n",
162 (int) szout, (int) sz );
163 return 1;
164 }
165
166 if( check_cluster( 0, buffer, cluster_0 )
167 || check_cluster( 64, buffer, cluster_64 )
168 || check_cluster( 128, buffer, cluster_128 ) ) {
169 exit(1);
170 }
171 free(buffer);
172
173 /*
174 * Read a tile using the built-in conversion to RGB format provided by the JPEG library.
175 */
176 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
177
178 sz = TIFFTileSize(tif);
179 if( sz != 128*128*3) {
180 fprintf(stderr, "tiles are %d bytes\n", (int)sz);
181 exit(1);
182 }
183
184 buffer = (unsigned char *) malloc(sz);
185
186 szout = TIFFReadEncodedTile(tif,9,buffer,sz);
187 if (szout != sz) {
188 fprintf( stderr,
189 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n",
190 (int) szout, (int) sz );
191 return 1;
192 }
193
194 #if JPEG_LIB_VERSION >= 70
195 pixel_status |= check_rgb_pixel( 0, 18, 0, 41, buffer );
196 pixel_status |= check_rgb_pixel( 64, 0, 0, 0, buffer );
197 pixel_status |= check_rgb_pixel( 512, 5, 34, 196, buffer );
198 #else
199 pixel_status |= check_rgb_pixel( 0, 15, 0, 18, buffer );
200 pixel_status |= check_rgb_pixel( 64, 0, 0, 2, buffer );
201 pixel_status |= check_rgb_pixel( 512, 6, 36, 182, buffer );
202 #endif
203
204 free( buffer );
205
206 TIFFClose(tif);
207
208 /*
209 * Reopen and test reading using the RGBA interface.
210 */
211 tif = TIFFOpen(srcfile,"r");
212
213 sz = 128 * 128 * sizeof(uint32);
214 rgba_buffer = (uint32 *) malloc(sz);
215
216 if (!TIFFReadRGBATile( tif, 1*128, 2*128, rgba_buffer )) {
217 fprintf( stderr, "TIFFReadRGBATile() returned failure code.\n" );
218 return 1;
219 }
220
221 /*
222 * Currently TIFFReadRGBATile() just uses JPEGCOLORMODE_RGB so this
223 * trivally matches the last results. Eventually we should actually
224 * accomplish it from the YCbCr subsampled buffer ourselves in which
225 * case the results may be subtly different but similar.
226 */
227 #if JPEG_LIB_VERSION >= 70
228 pixel_status |= check_rgba_pixel( 0, 18, 0, 41, 255, rgba_buffer );
229 pixel_status |= check_rgba_pixel( 64, 0, 0, 0, 255, rgba_buffer );
230 pixel_status |= check_rgba_pixel( 512, 5, 34, 196, 255, rgba_buffer );
231 #else
232 pixel_status |= check_rgba_pixel( 0, 15, 0, 18, 255, rgba_buffer );
233 pixel_status |= check_rgba_pixel( 64, 0, 0, 2, 255, rgba_buffer );
234 pixel_status |= check_rgba_pixel( 512, 6, 36, 182, 255, rgba_buffer );
235 #endif
236
237 free( rgba_buffer );
238 TIFFClose(tif);
239
240 if (pixel_status) {
241 exit(1);
242 }
243
244 exit( 0 );
245 }
246
247 /* vim: set ts=8 sts=8 sw=8 noet: */
248 /*
249 * Local Variables:
250 * mode: c
251 * c-basic-offset: 8
252 * fill-column: 78
253 * End:
254 */