test_tile_decoder.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. #include <stdio.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include <math.h>
  34. #ifdef _WIN32
  35. #include <malloc.h>
  36. #else
  37. #include <stdlib.h>
  38. #endif
  39. #include "opj_config.h"
  40. #include <stdlib.h>
  41. #ifdef _WIN32
  42. #include <windows.h>
  43. #define strcasecmp _stricmp
  44. #define strncasecmp _strnicmp
  45. #else
  46. #include <strings.h>
  47. #endif /* _WIN32 */
  48. #include "openjpeg.h"
  49. #include "format_defs.h"
  50. /* -------------------------------------------------------------------------- */
  51. /* Declarations */
  52. int get_file_format(const char *filename);
  53. static int infile_format(const char *fname);
  54. /* -------------------------------------------------------------------------- */
  55. int get_file_format(const char *filename) {
  56. unsigned int i;
  57. static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
  58. 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 };
  59. char * ext = strrchr(filename, '.');
  60. if (ext == NULL)
  61. return -1;
  62. ext++;
  63. if(ext) {
  64. for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
  65. if(strcasecmp(ext, extension[i]) == 0) {
  66. return format[i];
  67. }
  68. }
  69. }
  70. return -1;
  71. }
  72. /* -------------------------------------------------------------------------- */
  73. #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
  74. #define JP2_MAGIC "\x0d\x0a\x87\x0a"
  75. /* position 45: "\xff\x52" */
  76. #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
  77. static int infile_format(const char *fname)
  78. {
  79. FILE *reader;
  80. const char *s, *magic_s;
  81. int ext_format, magic_format;
  82. unsigned char buf[12];
  83. unsigned int l_nb_read;
  84. reader = fopen(fname, "rb");
  85. if (reader == NULL)
  86. return -1;
  87. memset(buf, 0, 12);
  88. l_nb_read = (unsigned int)fread(buf, 1, 12, reader);
  89. fclose(reader);
  90. if (l_nb_read != 12)
  91. return -1;
  92. ext_format = get_file_format(fname);
  93. if (ext_format == JPT_CFMT)
  94. return JPT_CFMT;
  95. if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
  96. magic_format = JP2_CFMT;
  97. magic_s = ".jp2";
  98. }
  99. else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
  100. magic_format = J2K_CFMT;
  101. magic_s = ".j2k or .jpc or .j2c";
  102. }
  103. else
  104. return -1;
  105. if (magic_format == ext_format)
  106. return ext_format;
  107. s = fname + strlen(fname) - 4;
  108. fputs("\n===========================================\n", stderr);
  109. fprintf(stderr, "The extension of this file is incorrect.\n"
  110. "FOUND %s. SHOULD BE %s\n", s, magic_s);
  111. fputs("===========================================\n", stderr);
  112. return magic_format;
  113. }
  114. /* -------------------------------------------------------------------------- */
  115. /**
  116. sample error debug callback expecting no client object
  117. */
  118. static void error_callback(const char *msg, void *client_data) {
  119. (void)client_data;
  120. fprintf(stdout, "[ERROR] %s", msg);
  121. }
  122. /**
  123. sample warning debug callback expecting no client object
  124. */
  125. static void warning_callback(const char *msg, void *client_data) {
  126. (void)client_data;
  127. fprintf(stdout, "[WARNING] %s", msg);
  128. }
  129. /**
  130. sample debug callback expecting no client object
  131. */
  132. static void info_callback(const char *msg, void *client_data) {
  133. (void)client_data;
  134. fprintf(stdout, "[INFO] %s", msg);
  135. }
  136. /* -------------------------------------------------------------------------- */
  137. int main (int argc, char *argv[])
  138. {
  139. opj_dparameters_t l_param;
  140. opj_codec_t * l_codec;
  141. opj_image_t * l_image;
  142. opj_stream_t * l_stream;
  143. OPJ_UINT32 l_data_size;
  144. OPJ_UINT32 l_max_data_size = 1000;
  145. OPJ_UINT32 l_tile_index;
  146. OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000);
  147. OPJ_BOOL l_go_on = OPJ_TRUE;
  148. OPJ_UINT32 l_nb_comps=0 ;
  149. OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1;
  150. int da_x0=0;
  151. int da_y0=0;
  152. int da_x1=1000;
  153. int da_y1=1000;
  154. const char *input_file;
  155. /* should be test_tile_decoder 0 0 1000 1000 tte1.j2k */
  156. if( argc == 6 )
  157. {
  158. da_x0=atoi(argv[1]);
  159. da_y0=atoi(argv[2]);
  160. da_x1=atoi(argv[3]);
  161. da_y1=atoi(argv[4]);
  162. input_file = argv[5];
  163. }
  164. else
  165. {
  166. da_x0=0;
  167. da_y0=0;
  168. da_x1=1000;
  169. da_y1=1000;
  170. input_file = "test.j2k";
  171. }
  172. if (! l_data) {
  173. return EXIT_FAILURE;
  174. }
  175. l_stream = opj_stream_create_default_file_stream(input_file,OPJ_TRUE);
  176. if (!l_stream){
  177. free(l_data);
  178. fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
  179. return EXIT_FAILURE;
  180. }
  181. /* Set the default decoding parameters */
  182. opj_set_default_decoder_parameters(&l_param);
  183. /* */
  184. l_param.decod_format = infile_format(input_file);
  185. /** you may here add custom decoding parameters */
  186. /* do not use layer decoding limitations */
  187. l_param.cp_layer = 0;
  188. /* do not use resolutions reductions */
  189. l_param.cp_reduce = 0;
  190. /* to decode only a part of the image data */
  191. /*opj_restrict_decoding(&l_param,0,0,1000,1000);*/
  192. switch(l_param.decod_format) {
  193. case J2K_CFMT: /* JPEG-2000 codestream */
  194. {
  195. /* Get a decoder handle */
  196. l_codec = opj_create_decompress(OPJ_CODEC_J2K);
  197. break;
  198. }
  199. case JP2_CFMT: /* JPEG 2000 compressed image data */
  200. {
  201. /* Get a decoder handle */
  202. l_codec = opj_create_decompress(OPJ_CODEC_JP2);
  203. break;
  204. }
  205. default:
  206. {
  207. fprintf(stderr, "ERROR -> Not a valid JPEG2000 file!\n");
  208. free(l_data);
  209. opj_stream_destroy(l_stream);
  210. return EXIT_FAILURE;
  211. }
  212. }
  213. /* catch events using our callbacks and give a local context */
  214. opj_set_info_handler(l_codec, info_callback,00);
  215. opj_set_warning_handler(l_codec, warning_callback,00);
  216. opj_set_error_handler(l_codec, error_callback,00);
  217. /* Setup the decoder decoding parameters using user parameters */
  218. if (! opj_setup_decoder(l_codec, &l_param))
  219. {
  220. fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
  221. free(l_data);
  222. opj_stream_destroy(l_stream);
  223. opj_destroy_codec(l_codec);
  224. return EXIT_FAILURE;
  225. }
  226. /* Read the main header of the codestream and if necessary the JP2 boxes*/
  227. if (! opj_read_header(l_stream, l_codec, &l_image))
  228. {
  229. fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
  230. free(l_data);
  231. opj_stream_destroy(l_stream);
  232. opj_destroy_codec(l_codec);
  233. return EXIT_FAILURE;
  234. }
  235. if (!opj_set_decode_area(l_codec, l_image, da_x0, da_y0,da_x1, da_y1)){
  236. fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n");
  237. free(l_data);
  238. opj_stream_destroy(l_stream);
  239. opj_destroy_codec(l_codec);
  240. opj_image_destroy(l_image);
  241. return EXIT_FAILURE;
  242. }
  243. while (l_go_on)
  244. {
  245. if (! opj_read_tile_header( l_codec,
  246. l_stream,
  247. &l_tile_index,
  248. &l_data_size,
  249. &l_current_tile_x0,
  250. &l_current_tile_y0,
  251. &l_current_tile_x1,
  252. &l_current_tile_y1,
  253. &l_nb_comps,
  254. &l_go_on))
  255. {
  256. free(l_data);
  257. opj_stream_destroy(l_stream);
  258. opj_destroy_codec(l_codec);
  259. opj_image_destroy(l_image);
  260. return EXIT_FAILURE;
  261. }
  262. if (l_go_on)
  263. {
  264. if (l_data_size > l_max_data_size)
  265. {
  266. OPJ_BYTE *l_new_data = (OPJ_BYTE *) realloc(l_data, l_data_size);
  267. if (! l_new_data)
  268. {
  269. free(l_new_data);
  270. opj_stream_destroy(l_stream);
  271. opj_destroy_codec(l_codec);
  272. opj_image_destroy(l_image);
  273. return EXIT_FAILURE;
  274. }
  275. l_data = l_new_data;
  276. l_max_data_size = l_data_size;
  277. }
  278. if (! opj_decode_tile_data(l_codec,l_tile_index,l_data,l_data_size,l_stream))
  279. {
  280. free(l_data);
  281. opj_stream_destroy(l_stream);
  282. opj_destroy_codec(l_codec);
  283. opj_image_destroy(l_image);
  284. return EXIT_FAILURE;
  285. }
  286. /** now should inspect image to know the reduction factor and then how to behave with data */
  287. }
  288. }
  289. if (! opj_end_decompress(l_codec,l_stream))
  290. {
  291. free(l_data);
  292. opj_stream_destroy(l_stream);
  293. opj_destroy_codec(l_codec);
  294. opj_image_destroy(l_image);
  295. return EXIT_FAILURE;
  296. }
  297. /* Free memory */
  298. free(l_data);
  299. opj_stream_destroy(l_stream);
  300. opj_destroy_codec(l_codec);
  301. opj_image_destroy(l_image);
  302. /* Print profiling*/
  303. /*PROFPRINT();*/
  304. return EXIT_SUCCESS;
  305. }