[trunk] use the right v2 structure
[openjpeg.git] / tests / test_tile_decoder.c
1 /*
2  * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 #define USE_OPJ_DEPRECATED
27 /* set this macro to enable profiling for the given test */
28 /* warning : in order to be effective, openjpeg must have been built with profiling enabled !! */
29 /*#define _PROFILE*/
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <math.h>
35
36 #ifdef _WIN32
37 #include <malloc.h>
38 #else
39 #include <stdlib.h>
40 #endif
41
42 #include "opj_config.h"
43 #include <stdlib.h>
44
45 #ifdef _WIN32
46 #include <windows.h>
47 #define strcasecmp _stricmp
48 #define strncasecmp _strnicmp
49 #else
50 #include <strings.h>
51 #endif /* _WIN32 */
52
53 #include "openjpeg.h"
54 #include "format_defs.h"
55
56
57 /* -------------------------------------------------------------------------- */
58 /* Declarations                                                               */ 
59 int get_file_format(const char *filename);
60 static int infile_format(const char *fname);
61
62 /* -------------------------------------------------------------------------- */
63 int get_file_format(const char *filename) {
64         unsigned int i;
65         static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
66         static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
67         char * ext = strrchr(filename, '.');
68         if (ext == NULL)
69                 return -1;
70         ext++;
71         if(ext) {
72                 for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
73                         if(strcasecmp(ext, extension[i]) == 0) {
74                                 return format[i];
75                         }
76                 }
77         }
78
79         return -1;
80 }
81
82 /* -------------------------------------------------------------------------- */
83 #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
84 #define JP2_MAGIC "\x0d\x0a\x87\x0a"
85 /* position 45: "\xff\x52" */
86 #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
87
88 static int infile_format(const char *fname)
89 {
90         FILE *reader;
91         const char *s, *magic_s;
92         int ext_format, magic_format;
93         unsigned char buf[12];
94         unsigned int l_nb_read;
95
96         reader = fopen(fname, "rb");
97
98         if (reader == NULL)
99                 return -1;
100
101         memset(buf, 0, 12);
102         l_nb_read = fread(buf, 1, 12, reader);
103         fclose(reader);
104         if (l_nb_read != 12)
105                 return -1;
106
107         ext_format = get_file_format(fname);
108
109         if (ext_format == JPT_CFMT)
110                 return JPT_CFMT;
111
112         if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
113                 magic_format = JP2_CFMT;
114                 magic_s = ".jp2";
115         }
116         else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
117                 magic_format = J2K_CFMT;
118                 magic_s = ".j2k or .jpc or .j2c";
119         }
120         else
121                 return -1;
122
123         if (magic_format == ext_format)
124                 return ext_format;
125
126         s = fname + strlen(fname) - 4;
127
128         fputs("\n===========================================\n", stderr);
129         fprintf(stderr, "The extension of this file is incorrect.\n"
130                         "FOUND %s. SHOULD BE %s\n", s, magic_s);
131         fputs("===========================================\n", stderr);
132
133         return magic_format;
134 }
135
136
137 /* -------------------------------------------------------------------------- */
138
139 /**
140   sample error callback expecting a FILE* client object
141  */
142 static void error_callback_file(const char *msg, void *client_data) {
143         FILE *stream = (FILE*)client_data;
144         fprintf(stream, "[ERROR] %s", msg);
145 }
146 /**
147   sample warning callback expecting a FILE* client object
148  */
149 static void warning_callback_file(const char *msg, void *client_data) {
150         FILE *stream = (FILE*)client_data;
151         fprintf(stream, "[WARNING] %s", msg);
152 }
153 /**
154   sample error debug callback expecting no client object
155  */
156 static void error_callback(const char *msg, void *client_data) {
157         (void)client_data;
158         fprintf(stdout, "[ERROR] %s", msg);
159 }
160 /**
161   sample warning debug callback expecting no client object
162  */
163 static void warning_callback(const char *msg, void *client_data) {
164         (void)client_data;
165         fprintf(stdout, "[WARNING] %s", msg);
166 }
167 /**
168   sample debug callback expecting no client object
169  */
170 static void info_callback(const char *msg, void *client_data) {
171         (void)client_data;
172         fprintf(stdout, "[INFO] %s", msg);
173 }
174
175 /* -------------------------------------------------------------------------- */
176
177 int main (int argc, char *argv[])
178 {
179         opj_dparameters_t l_param;
180         opj_codec_t * l_codec;
181         opj_image_t * l_image;
182         FILE * l_file;
183         opj_stream_t * l_stream;
184         OPJ_UINT32 l_data_size;
185         OPJ_UINT32 l_max_data_size = 1000;
186         OPJ_UINT32 l_tile_index;
187         OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000);
188         opj_bool l_go_on = OPJ_TRUE;
189         OPJ_INT32 l_tile_x0=0, l_tile_y0=0 ;
190         OPJ_UINT32 l_tile_width=0, l_tile_height=0, l_nb_tiles_x=0, l_nb_tiles_y=0, l_nb_comps=0 ;
191         OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1;
192
193         int da_x0=0;
194         int da_y0=0;
195         int da_x1=1000;
196         int da_y1=1000;
197         char input_file[64];
198
199         /* should be test_tile_decoder 0 0 1000 1000 tte1.j2k */
200         if( argc == 6 )
201         {
202                 da_x0=atoi(argv[1]);
203                 da_y0=atoi(argv[2]);
204                 da_x1=atoi(argv[3]);
205                 da_y1=atoi(argv[4]);
206                 strcpy(input_file,argv[5]);
207
208         }
209         else
210         {
211                 da_x0=0;
212                 da_y0=0;
213                 da_x1=1000;
214                 da_y1=1000;
215                 strcpy(input_file,"test.j2k");
216         }
217
218         if (! l_data) {
219                 return EXIT_FAILURE;
220         }
221
222         l_file = fopen(input_file,"rb");
223         if (! l_file)
224         {
225                 fprintf(stdout, "ERROR while opening input file\n");
226                 free(l_data);
227                 return EXIT_FAILURE;
228         }
229
230         l_stream = opj_stream_create_default_file_stream(l_file,OPJ_TRUE);
231         if (!l_stream){
232                 fclose(l_file);
233                 free(l_data);
234                 fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
235                 return EXIT_FAILURE;
236         }
237
238         /* Set the default decoding parameters */
239         opj_set_default_decoder_parameters(&l_param);
240
241         /* */
242         l_param.decod_format = infile_format(input_file);
243
244         /** you may here add custom decoding parameters */
245         /* do not use layer decoding limitations */
246         l_param.cp_layer = 0;
247
248         /* do not use resolutions reductions */
249         l_param.cp_reduce = 0;
250
251         /* to decode only a part of the image data */
252         /*opj_restrict_decoding(&l_param,0,0,1000,1000);*/
253
254
255         switch(l_param.decod_format) {
256                 case J2K_CFMT:  /* JPEG-2000 codestream */
257                         {
258                                 /* Get a decoder handle */
259                                 l_codec = opj_create_decompress(CODEC_J2K);
260                                 break;
261                         }
262                 case JP2_CFMT:  /* JPEG 2000 compressed image data */
263                         {
264                                 /* Get a decoder handle */
265                                 l_codec = opj_create_decompress(CODEC_JP2);
266                                 break;
267                         }
268                 default:
269                         {    
270                                 fprintf(stderr, "ERROR -> Not a valid JPEG2000 file!\n");
271                                 fclose(l_file);
272                                 free(l_data);
273                                 opj_stream_destroy(l_stream);
274                                 return EXIT_FAILURE;
275                         }
276         }
277
278         /* catch events using our callbacks and give a local context */         
279         opj_set_info_handler(l_codec, info_callback,00);
280         opj_set_warning_handler(l_codec, warning_callback,00);
281         opj_set_error_handler(l_codec, error_callback,00);
282
283         /* Setup the decoder decoding parameters using user parameters */
284         if (! opj_setup_decoder(l_codec, &l_param))
285         {
286                 fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
287                 fclose(l_file);
288                 free(l_data);
289                 opj_stream_destroy(l_stream);
290                 opj_destroy_codec(l_codec);
291                 return EXIT_FAILURE;
292         }
293
294         /* Read the main header of the codestream and if necessary the JP2 boxes*/
295         if (! opj_read_header(l_stream, l_codec, &l_image))
296         {
297                 fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
298                 fclose(l_file);
299                 free(l_data);
300                 opj_stream_destroy(l_stream);
301                 opj_destroy_codec(l_codec);
302                 return EXIT_FAILURE;
303         }
304
305         if (!opj_set_decode_area(l_codec, l_image, da_x0, da_y0,da_x1, da_y1)){
306                 fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n");
307                 fclose(l_file);
308                 free(l_data);
309                 opj_stream_destroy(l_stream);
310                 opj_destroy_codec(l_codec);
311                 opj_image_destroy(l_image);
312                 return EXIT_FAILURE;
313         }
314
315
316         while (l_go_on)
317         {
318                 if (! opj_read_tile_header( l_codec,
319                                         l_stream,
320                                         &l_tile_index,
321                                         &l_data_size,
322                                         &l_current_tile_x0,
323                                         &l_current_tile_y0,
324                                         &l_current_tile_x1,
325                                         &l_current_tile_y1,
326                                         &l_nb_comps,
327                                         &l_go_on))
328                 {
329                         fclose(l_file);
330                         free(l_data);
331                         opj_stream_destroy(l_stream);
332                         opj_destroy_codec(l_codec);
333                         opj_image_destroy(l_image);
334                         return EXIT_FAILURE;
335                 }
336
337                 if (l_go_on)
338                 {
339                         if (l_data_size > l_max_data_size)
340                         {
341                                 OPJ_BYTE *l_new_data = (OPJ_BYTE *) realloc(l_data, l_data_size);
342                                 if (! l_new_data)
343                                 {
344                                         fclose(l_file);
345                                         free(l_new_data);
346                                         opj_stream_destroy(l_stream);
347                                         opj_destroy_codec(l_codec);
348                                         opj_image_destroy(l_image);
349                                         return EXIT_FAILURE;
350                                 }
351                                 l_data = l_new_data;
352                                 l_max_data_size = l_data_size;
353                         }
354
355                         if (! opj_decode_tile_data(l_codec,l_tile_index,l_data,l_data_size,l_stream))
356                         {
357                                 fclose(l_file);
358                                 free(l_data);
359                                 opj_stream_destroy(l_stream);
360                                 opj_destroy_codec(l_codec);
361                                 opj_image_destroy(l_image);
362                                 return EXIT_FAILURE;
363                         }
364                         /** now should inspect image to know the reduction factor and then how to behave with data */
365                 }
366         }
367
368         if (! opj_end_decompress(l_codec,l_stream))
369         {
370                 fclose(l_file);
371                 free(l_data);
372                 opj_stream_destroy(l_stream);
373                 opj_destroy_codec(l_codec);
374                 opj_image_destroy(l_image);
375                 return EXIT_FAILURE;
376         }
377
378         /* Free memory */
379         fclose(l_file);
380         free(l_data);
381         opj_stream_destroy(l_stream);
382         opj_destroy_codec(l_codec);
383         opj_image_destroy(l_image);
384
385         /* Print profiling*/
386         /*PROFPRINT();*/
387
388         return EXIT_SUCCESS;
389 }
390