j2k_random_tile_access.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*
  2. * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France
  3. * Copyright (c) 2012, CS Systemes d'Information, France
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "opj_config.h"
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <stdlib.h>
  31. #include <math.h>
  32. #ifdef _WIN32
  33. #include <windows.h>
  34. #else
  35. #include <strings.h>
  36. #define _stricmp strcasecmp
  37. #define _strnicmp strncasecmp
  38. #endif /* _WIN32 */
  39. #include "openjpeg.h"
  40. #include "format_defs.h"
  41. /* -------------------------------------------------------------------------- */
  42. static int get_file_format(const char *filename) {
  43. unsigned int i;
  44. static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
  45. static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
  46. char * ext = strrchr(filename, '.');
  47. if (ext == NULL)
  48. return -1;
  49. ext++;
  50. if(ext) {
  51. for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
  52. if(_strnicmp(ext, extension[i], 3) == 0) {
  53. return format[i];
  54. }
  55. }
  56. }
  57. return -1;
  58. }
  59. /* -------------------------------------------------------------------------- */
  60. /**
  61. sample error callback expecting a FILE* client object
  62. */
  63. static void error_callback(const char *msg, void *client_data) {
  64. (void)client_data;
  65. fprintf(stdout, "[ERROR] %s", msg);
  66. }
  67. /**
  68. sample warning callback expecting a FILE* client object
  69. */
  70. static void warning_callback(const char *msg, void *client_data) {
  71. (void)client_data;
  72. fprintf(stdout, "[WARNING] %s", msg);
  73. }
  74. /**
  75. sample debug callback expecting no client object
  76. */
  77. static void info_callback(const char *msg, void *client_data) {
  78. (void)client_data;
  79. fprintf(stdout, "[INFO] %s", msg);
  80. }
  81. /* -------------------------------------------------------------------------- */
  82. #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
  83. #define JP2_MAGIC "\x0d\x0a\x87\x0a"
  84. /* position 45: "\xff\x52" */
  85. #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
  86. static int infile_format(const char *fname)
  87. {
  88. FILE *reader;
  89. const char *s, *magic_s;
  90. int ext_format, magic_format;
  91. unsigned char buf[12];
  92. OPJ_SIZE_T l_nb_read;
  93. reader = fopen(fname, "rb");
  94. if (reader == NULL)
  95. return -1;
  96. memset(buf, 0, 12);
  97. l_nb_read = fread(buf, 1, 12, reader);
  98. fclose(reader);
  99. if (l_nb_read != 12)
  100. return -1;
  101. ext_format = get_file_format(fname);
  102. if (ext_format == JPT_CFMT)
  103. return JPT_CFMT;
  104. if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
  105. magic_format = JP2_CFMT;
  106. magic_s = ".jp2";
  107. }
  108. else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
  109. magic_format = J2K_CFMT;
  110. magic_s = ".j2k or .jpc or .j2c";
  111. }
  112. else
  113. return -1;
  114. if (magic_format == ext_format)
  115. return ext_format;
  116. s = fname + strlen(fname) - 4;
  117. fputs("\n===========================================\n", stderr);
  118. fprintf(stderr, "The extension of this file is incorrect.\n"
  119. "FOUND %s. SHOULD BE %s\n", s, magic_s);
  120. fputs("===========================================\n", stderr);
  121. return magic_format;
  122. }
  123. /* -------------------------------------------------------------------------- */
  124. /**
  125. * J2K_RANDOM_TILE_ACCESS MAIN
  126. */
  127. /* -------------------------------------------------------------------------- */
  128. int main(int argc, char **argv)
  129. {
  130. OPJ_UINT32 index;
  131. opj_dparameters_t parameters; /* decompression parameters */
  132. opj_image_t* image = NULL;
  133. opj_stream_t *l_stream = NULL; /* Stream */
  134. opj_codec_t* l_codec = NULL; /* Handle to a decompressor */
  135. opj_codestream_info_v2_t* cstr_info = NULL;
  136. /* Index of corner tiles */
  137. OPJ_UINT32 tile_ul = 0;
  138. OPJ_UINT32 tile_ur = 0;
  139. OPJ_UINT32 tile_lr = 0;
  140. OPJ_UINT32 tile_ll = 0;
  141. if (argc != 2) {
  142. fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
  143. return EXIT_FAILURE;
  144. }
  145. /* Set decoding parameters to default values */
  146. opj_set_default_decoder_parameters(&parameters);
  147. strncpy(parameters.infile, argv[1], OPJ_PATH_LEN - 1);
  148. /* decode the JPEG2000 stream */
  149. /* -------------------------- */
  150. parameters.decod_format = infile_format(parameters.infile);
  151. switch(parameters.decod_format) {
  152. case J2K_CFMT: /* JPEG-2000 codestream */
  153. {
  154. /* Get a decoder handle */
  155. l_codec = opj_create_decompress(OPJ_CODEC_J2K);
  156. break;
  157. }
  158. case JP2_CFMT: /* JPEG 2000 compressed image data */
  159. {
  160. /* Get a decoder handle */
  161. l_codec = opj_create_decompress(OPJ_CODEC_JP2);
  162. break;
  163. }
  164. case JPT_CFMT: /* JPEG 2000, JPIP */
  165. {
  166. /* Get a decoder handle */
  167. l_codec = opj_create_decompress(OPJ_CODEC_JPT);
  168. break;
  169. }
  170. default:
  171. fprintf(stderr,
  172. "Unrecognized format for input %s [accept only *.j2k, *.jp2, *.jpc or *.jpt]\n\n",
  173. parameters.infile);
  174. return EXIT_FAILURE;
  175. }
  176. /* catch events using our callbacks and give a local context */
  177. opj_set_info_handler(l_codec, info_callback,00);
  178. opj_set_warning_handler(l_codec, warning_callback,00);
  179. opj_set_error_handler(l_codec, error_callback,00);
  180. l_stream = opj_stream_create_default_file_stream(parameters.infile,1);
  181. if (!l_stream){
  182. fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", parameters.infile);
  183. return EXIT_FAILURE;
  184. }
  185. /* Setup the decoder decoding parameters using user parameters */
  186. if ( !opj_setup_decoder(l_codec, &parameters) ){
  187. fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
  188. opj_stream_destroy(l_stream);
  189. opj_destroy_codec(l_codec);
  190. return EXIT_FAILURE;
  191. }
  192. /* Read the main header of the codestream and if necessary the JP2 boxes*/
  193. if(! opj_read_header(l_stream, l_codec, &image)){
  194. fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
  195. opj_stream_destroy(l_stream);
  196. opj_destroy_codec(l_codec);
  197. opj_image_destroy(image);
  198. return EXIT_FAILURE;
  199. }
  200. /* Extract some info from the code stream */
  201. cstr_info = opj_get_cstr_info(l_codec);
  202. fprintf(stdout, "The file contains %dx%d tiles\n", cstr_info->tw, cstr_info->th);
  203. tile_ul = 0;
  204. tile_ur = cstr_info->tw - 1;
  205. tile_lr = cstr_info->tw * cstr_info->th - 1;
  206. tile_ll = tile_lr - cstr_info->tw;
  207. #define TEST_TILE( tile_index ) \
  208. fprintf(stdout, "Decoding tile %d ...\n", tile_index); \
  209. if(!opj_get_decoded_tile(l_codec, l_stream, image, tile_index )){ \
  210. fprintf(stderr, "ERROR -> j2k_to_image: failed to decode tile %d\n", tile_index); \
  211. opj_stream_destroy(l_stream); \
  212. opj_destroy_cstr_info(&cstr_info); \
  213. opj_destroy_codec(l_codec); \
  214. opj_image_destroy(image); \
  215. return EXIT_FAILURE; \
  216. } \
  217. for(index = 0; index < image->numcomps; ++index) { \
  218. if( image->comps[index].data == NULL ){ \
  219. fprintf(stderr, "ERROR -> j2k_to_image: failed to decode tile %d\n", tile_index); \
  220. opj_stream_destroy(l_stream); \
  221. opj_destroy_cstr_info(&cstr_info); \
  222. opj_destroy_codec(l_codec); \
  223. opj_image_destroy(image); \
  224. return EXIT_FAILURE; \
  225. } \
  226. } \
  227. fprintf(stdout, "Tile %d is decoded successfully\n", tile_index);
  228. TEST_TILE(tile_ul)
  229. TEST_TILE(tile_lr)
  230. TEST_TILE(tile_ul)
  231. TEST_TILE(tile_ll)
  232. TEST_TILE(tile_ur)
  233. TEST_TILE(tile_lr)
  234. /* Close the byte stream */
  235. opj_stream_destroy(l_stream);
  236. /* Destroy code stream info */
  237. opj_destroy_cstr_info(&cstr_info);
  238. /* Free remaining structures */
  239. opj_destroy_codec(l_codec);
  240. /* Free image data structure */
  241. opj_image_destroy(image);
  242. return EXIT_SUCCESS;
  243. }
  244. /*end main*/