[trunk] move to the new API for function opj_stream_create_default_file_stream. Use...
[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         opj_stream_t * l_stream;
183         OPJ_UINT32 l_data_size;
184         OPJ_UINT32 l_max_data_size = 1000;
185         OPJ_UINT32 l_tile_index;
186         OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000);
187         OPJ_BOOL l_go_on = OPJ_TRUE;
188         OPJ_INT32 l_tile_x0=0, l_tile_y0=0 ;
189         OPJ_UINT32 l_tile_width=0, l_tile_height=0, l_nb_tiles_x=0, l_nb_tiles_y=0, l_nb_comps=0 ;
190         OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1;
191
192         int da_x0=0;
193         int da_y0=0;
194         int da_x1=1000;
195         int da_y1=1000;
196         char input_file[64];
197
198         /* should be test_tile_decoder 0 0 1000 1000 tte1.j2k */
199         if( argc == 6 )
200         {
201                 da_x0=atoi(argv[1]);
202                 da_y0=atoi(argv[2]);
203                 da_x1=atoi(argv[3]);
204                 da_y1=atoi(argv[4]);
205                 strcpy(input_file,argv[5]);
206
207         }
208         else
209         {
210                 da_x0=0;
211                 da_y0=0;
212                 da_x1=1000;
213                 da_y1=1000;
214                 strcpy(input_file,"test.j2k");
215         }
216
217         if (! l_data) {
218                 return EXIT_FAILURE;
219         }
220
221         l_stream = opj_stream_create_default_file_stream_v3(input_file,OPJ_TRUE);
222         if (!l_stream){
223                 free(l_data);
224                 fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
225                 return EXIT_FAILURE;
226         }
227
228         /* Set the default decoding parameters */
229         opj_set_default_decoder_parameters(&l_param);
230
231         /* */
232         l_param.decod_format = infile_format(input_file);
233
234         /** you may here add custom decoding parameters */
235         /* do not use layer decoding limitations */
236         l_param.cp_layer = 0;
237
238         /* do not use resolutions reductions */
239         l_param.cp_reduce = 0;
240
241         /* to decode only a part of the image data */
242         /*opj_restrict_decoding(&l_param,0,0,1000,1000);*/
243
244
245         switch(l_param.decod_format) {
246                 case J2K_CFMT:  /* JPEG-2000 codestream */
247                         {
248                                 /* Get a decoder handle */
249                                 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
250                                 break;
251                         }
252                 case JP2_CFMT:  /* JPEG 2000 compressed image data */
253                         {
254                                 /* Get a decoder handle */
255                                 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
256                                 break;
257                         }
258                 default:
259                         {    
260                                 fprintf(stderr, "ERROR -> Not a valid JPEG2000 file!\n");
261                                 free(l_data);
262                                 opj_stream_destroy_v3(l_stream);
263                                 return EXIT_FAILURE;
264                         }
265         }
266
267         /* catch events using our callbacks and give a local context */         
268         opj_set_info_handler(l_codec, info_callback,00);
269         opj_set_warning_handler(l_codec, warning_callback,00);
270         opj_set_error_handler(l_codec, error_callback,00);
271
272         /* Setup the decoder decoding parameters using user parameters */
273         if (! opj_setup_decoder(l_codec, &l_param))
274         {
275                 fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
276                 free(l_data);
277                 opj_stream_destroy_v3(l_stream);
278                 opj_destroy_codec(l_codec);
279                 return EXIT_FAILURE;
280         }
281
282         /* Read the main header of the codestream and if necessary the JP2 boxes*/
283         if (! opj_read_header(l_stream, l_codec, &l_image))
284         {
285                 fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
286                 free(l_data);
287                 opj_stream_destroy_v3(l_stream);
288                 opj_destroy_codec(l_codec);
289                 return EXIT_FAILURE;
290         }
291
292         if (!opj_set_decode_area(l_codec, l_image, da_x0, da_y0,da_x1, da_y1)){
293                 fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n");
294                 free(l_data);
295                 opj_stream_destroy_v3(l_stream);
296                 opj_destroy_codec(l_codec);
297                 opj_image_destroy(l_image);
298                 return EXIT_FAILURE;
299         }
300
301
302         while (l_go_on)
303         {
304                 if (! opj_read_tile_header( l_codec,
305                                         l_stream,
306                                         &l_tile_index,
307                                         &l_data_size,
308                                         &l_current_tile_x0,
309                                         &l_current_tile_y0,
310                                         &l_current_tile_x1,
311                                         &l_current_tile_y1,
312                                         &l_nb_comps,
313                                         &l_go_on))
314                 {
315                         free(l_data);
316                         opj_stream_destroy_v3(l_stream);
317                         opj_destroy_codec(l_codec);
318                         opj_image_destroy(l_image);
319                         return EXIT_FAILURE;
320                 }
321
322                 if (l_go_on)
323                 {
324                         if (l_data_size > l_max_data_size)
325                         {
326                                 OPJ_BYTE *l_new_data = (OPJ_BYTE *) realloc(l_data, l_data_size);
327                                 if (! l_new_data)
328                                 {
329                                         free(l_new_data);
330                                         opj_stream_destroy_v3(l_stream);
331                                         opj_destroy_codec(l_codec);
332                                         opj_image_destroy(l_image);
333                                         return EXIT_FAILURE;
334                                 }
335                                 l_data = l_new_data;
336                                 l_max_data_size = l_data_size;
337                         }
338
339                         if (! opj_decode_tile_data(l_codec,l_tile_index,l_data,l_data_size,l_stream))
340                         {
341                                 free(l_data);
342                                 opj_stream_destroy_v3(l_stream);
343                                 opj_destroy_codec(l_codec);
344                                 opj_image_destroy(l_image);
345                                 return EXIT_FAILURE;
346                         }
347                         /** now should inspect image to know the reduction factor and then how to behave with data */
348                 }
349         }
350
351         if (! opj_end_decompress(l_codec,l_stream))
352         {
353                 free(l_data);
354                 opj_stream_destroy_v3(l_stream);
355                 opj_destroy_codec(l_codec);
356                 opj_image_destroy(l_image);
357                 return EXIT_FAILURE;
358         }
359
360         /* Free memory */
361         free(l_data);
362         opj_stream_destroy_v3(l_stream);
363         opj_destroy_codec(l_codec);
364         opj_image_destroy(l_image);
365
366         /* Print profiling*/
367         /*PROFPRINT();*/
368
369         return EXIT_SUCCESS;
370 }
371