[trunk] rename opj_setup_decoder_v2 to opj_setup_decoder
[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\r
46 #include <windows.h>\r
47 #define strcasecmp _stricmp\r
48 #define strncasecmp _strnicmp\r
49 #else\r
50 #include <strings.h>\r
51 #endif /* _WIN32 */
52
53 #include "openjpeg.h"
54 #include "format_defs.h"
55
56
57 /* -------------------------------------------------------------------------- */\r
58 /* Declarations                                                               */ 
59 int get_file_format(const char *filename);\r
60 static int infile_format(const char *fname);
61
62 /* -------------------------------------------------------------------------- */\r
63 int get_file_format(const char *filename) {\r
64         unsigned int i;\r
65         static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };\r
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 };\r
67         char * ext = strrchr(filename, '.');\r
68         if (ext == NULL)\r
69                 return -1;\r
70         ext++;\r
71         if(ext) {\r
72                 for(i = 0; i < sizeof(format)/sizeof(*format); i++) {\r
73                         if(strcasecmp(ext, extension[i]) == 0) {\r
74                                 return format[i];\r
75                         }\r
76                 }\r
77         }\r
78 \r
79         return -1;\r
80 }
81
82 /* -------------------------------------------------------------------------- */\r
83 #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"\r
84 #define JP2_MAGIC "\x0d\x0a\x87\x0a"\r
85 /* position 45: "\xff\x52" */\r
86 #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"\r
87 \r
88 static int infile_format(const char *fname)\r
89 {\r
90         FILE *reader;\r
91         const char *s, *magic_s;\r
92         int ext_format, magic_format;\r
93         unsigned char buf[12];\r
94         unsigned int l_nb_read;\r
95 \r
96         reader = fopen(fname, "rb");\r
97 \r
98         if (reader == NULL)\r
99                 return -1;\r
100 \r
101         memset(buf, 0, 12);\r
102         l_nb_read = fread(buf, 1, 12, reader);\r
103         fclose(reader);\r
104         if (l_nb_read != 12)\r
105                 return -1;\r
106 \r
107         ext_format = get_file_format(fname);\r
108 \r
109         if (ext_format == JPT_CFMT)\r
110                 return JPT_CFMT;\r
111 \r
112         if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {\r
113                 magic_format = JP2_CFMT;\r
114                 magic_s = ".jp2";\r
115         }\r
116         else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {\r
117                 magic_format = J2K_CFMT;\r
118                 magic_s = ".j2k or .jpc or .j2c";\r
119         }\r
120         else\r
121                 return -1;\r
122 \r
123         if (magic_format == ext_format)\r
124                 return ext_format;\r
125 \r
126         s = fname + strlen(fname) - 4;\r
127 \r
128         fputs("\n===========================================\n", stderr);\r
129         fprintf(stderr, "The extension of this file is incorrect.\n"\r
130                                         "FOUND %s. SHOULD BE %s\n", s, magic_s);\r
131         fputs("===========================================\n", stderr);\r
132 \r
133         return magic_format;\r
134 }
135
136
137 /* -------------------------------------------------------------------------- */
138
139 /**
140 sample error callback expecting a FILE* client object
141 */
142 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 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 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 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 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){\r
232             fclose(l_file);\r
233         free(l_data);\r
234             fprintf(stderr, "ERROR -> failed to create the stream from the file\n");\r
235                 return EXIT_FAILURE;\r
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) {\r
256         case J2K_CFMT:  /* JPEG-2000 codestream */\r
257         {\r
258             /* Get a decoder handle */\r
259             l_codec = opj_create_decompress(CODEC_J2K);\r
260             break;\r
261         }\r
262         case JP2_CFMT:  /* JPEG 2000 compressed image data */\r
263         {\r
264             /* Get a decoder handle */\r
265             l_codec = opj_create_decompress(CODEC_JP2);\r
266             break;\r
267         }\r
268         default:\r
269         {    \r
270             fprintf(stderr, "ERROR -> Not a valid JPEG2000 file!\n");\r
271             fclose(l_file);\r
272             free(l_data);\r
273             opj_stream_destroy(l_stream);\r
274             return EXIT_FAILURE;\r
275         }\r
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)){\r
306         fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n");\r
307         fclose(l_file);
308         free(l_data);\r
309         opj_stream_destroy(l_stream);\r
310         opj_destroy_codec(l_codec);\r
311         opj_image_destroy(l_image);\r
312         return EXIT_FAILURE;\r
313     }\r
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                                 l_data = (OPJ_BYTE *) realloc(l_data,l_data_size);
342                                 if (! l_data)
343                 {
344                     fclose(l_file);
345                                     opj_stream_destroy(l_stream);
346                                         opj_destroy_codec(l_codec);
347                                         opj_image_destroy(l_image);
348                                         return EXIT_FAILURE;
349                                 }
350                                 l_max_data_size = l_data_size;
351                         }
352
353                         if (! opj_decode_tile_data(l_codec,l_tile_index,l_data,l_data_size,l_stream))
354                         {
355                 fclose(l_file);
356                                 free(l_data);
357                                 opj_stream_destroy(l_stream);
358                                 opj_destroy_codec(l_codec);
359                                 opj_image_destroy(l_image);
360                                 return EXIT_FAILURE;
361                         }
362                         /** now should inspect image to know the reduction factor and then how to behave with data */
363                 }
364         }
365
366         if (! opj_end_decompress(l_codec,l_stream))
367     {
368         fclose(l_file);
369                 free(l_data);
370                 opj_stream_destroy(l_stream);
371                 opj_destroy_codec(l_codec);
372                 opj_image_destroy(l_image);
373                 return EXIT_FAILURE;
374         }
375
376     /* Free memory */
377     fclose(l_file);
378         free(l_data);
379         opj_stream_destroy(l_stream);
380         opj_destroy_codec(l_codec);
381         opj_image_destroy(l_image);
382
383         // Print profiling
384         //PROFPRINT();
385
386         return EXIT_SUCCESS;
387 }