/src/FreeImage/Source/FreeImage/PluginJP2.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 339 lines · 194 code · 69 blank · 76 comment · 30 complexity · ca615216ed4900436a17e17539217777 MD5 · raw file

  1. // ==========================================================
  2. // JPEG2000 JP2 file format Loader and Writer
  3. //
  4. // Design and implementation by
  5. // - Hervé Drolon (drolon@infonie.fr)
  6. //
  7. // This file is part of FreeImage 3
  8. //
  9. // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
  10. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
  11. // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
  12. // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
  13. // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
  14. // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
  15. // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
  16. // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  17. // THIS DISCLAIMER.
  18. //
  19. // Use at your own risk!
  20. // ==========================================================
  21. #include "FreeImage.h"
  22. #include "Utilities.h"
  23. #include "../LibOpenJPEG/openjpeg.h"
  24. // ==========================================================
  25. // Plugin Interface
  26. // ==========================================================
  27. static int s_format_id;
  28. // ==========================================================
  29. // Helper functions (see J2KHelper.cpp)
  30. // ==========================================================
  31. FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image);
  32. opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters);
  33. // ==========================================================
  34. // Internal functions
  35. // ==========================================================
  36. /**
  37. OpenJPEG Error callback
  38. */
  39. static void jp2_error_callback(const char *msg, void *client_data) {
  40. FreeImage_OutputMessageProc(s_format_id, "Error: %s", msg);
  41. }
  42. /**
  43. OpenJPEG Warning callback
  44. */
  45. static void jp2_warning_callback(const char *msg, void *client_data) {
  46. FreeImage_OutputMessageProc(s_format_id, "Warning: %s", msg);
  47. }
  48. // ==========================================================
  49. // Plugin Implementation
  50. // ==========================================================
  51. static const char * DLL_CALLCONV
  52. Format() {
  53. return "JP2";
  54. }
  55. static const char * DLL_CALLCONV
  56. Description() {
  57. return "JPEG-2000 File Format";
  58. }
  59. static const char * DLL_CALLCONV
  60. Extension() {
  61. return "jp2";
  62. }
  63. static const char * DLL_CALLCONV
  64. RegExpr() {
  65. return NULL;
  66. }
  67. static const char * DLL_CALLCONV
  68. MimeType() {
  69. return "image/jp2";
  70. }
  71. static BOOL DLL_CALLCONV
  72. Validate(FreeImageIO *io, fi_handle handle) {
  73. BYTE jp2_signature[] = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A };
  74. BYTE signature[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  75. long tell = io->tell_proc(handle);
  76. io->read_proc(signature, 1, sizeof(jp2_signature), handle);
  77. io->seek_proc(handle, tell, SEEK_SET);
  78. return (memcmp(jp2_signature, signature, sizeof(jp2_signature)) == 0);
  79. }
  80. static BOOL DLL_CALLCONV
  81. SupportsExportDepth(int depth) {
  82. return (
  83. (depth == 8) ||
  84. (depth == 24) ||
  85. (depth == 32)
  86. );
  87. }
  88. static BOOL DLL_CALLCONV
  89. SupportsExportType(FREE_IMAGE_TYPE type) {
  90. return (
  91. (type == FIT_BITMAP) ||
  92. (type == FIT_UINT16) ||
  93. (type == FIT_RGB16) ||
  94. (type == FIT_RGBA16)
  95. );
  96. }
  97. // ----------------------------------------------------------
  98. static void * DLL_CALLCONV
  99. Open(FreeImageIO *io, fi_handle handle, BOOL read) {
  100. return NULL;
  101. }
  102. static void DLL_CALLCONV
  103. Close(FreeImageIO *io, fi_handle handle, void *data) {
  104. }
  105. // ----------------------------------------------------------
  106. static FIBITMAP * DLL_CALLCONV
  107. Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  108. if (handle) {
  109. opj_dparameters_t parameters; // decompression parameters
  110. opj_event_mgr_t event_mgr; // event manager
  111. opj_image_t *image = NULL; // decoded image
  112. BYTE *src = NULL;
  113. long file_length;
  114. opj_dinfo_t* dinfo = NULL; // handle to a decompressor
  115. opj_cio_t *cio = NULL;
  116. FIBITMAP *dib = NULL;
  117. // check the file format
  118. if(!Validate(io, handle)) {
  119. return NULL;
  120. }
  121. // configure the event callbacks
  122. memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  123. event_mgr.error_handler = jp2_error_callback;
  124. event_mgr.warning_handler = jp2_warning_callback;
  125. event_mgr.info_handler = NULL;
  126. // set decoding parameters to default values
  127. opj_set_default_decoder_parameters(&parameters);
  128. try {
  129. // read the input file and put it in memory
  130. long start_pos = io->tell_proc(handle);
  131. io->seek_proc(handle, 0, SEEK_END);
  132. file_length = io->tell_proc(handle) - start_pos;
  133. io->seek_proc(handle, start_pos, SEEK_SET);
  134. src = (BYTE*)malloc(file_length * sizeof(BYTE));
  135. if(!src) {
  136. throw FI_MSG_ERROR_MEMORY;
  137. }
  138. if(io->read_proc(src, 1, file_length, handle) < 1) {
  139. throw "Error while reading input stream";
  140. }
  141. // decode the JPEG-2000 file
  142. // get a decoder handle
  143. dinfo = opj_create_decompress(CODEC_JP2);
  144. // catch events using our callbacks
  145. opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);
  146. // setup the decoder decoding parameters using user parameters
  147. opj_setup_decoder(dinfo, &parameters);
  148. // open a byte stream
  149. cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
  150. // decode the stream and fill the image structure
  151. image = opj_decode(dinfo, cio);
  152. if(!image) {
  153. throw "Failed to decode image!\n";
  154. }
  155. // close the byte stream
  156. opj_cio_close(cio);
  157. cio = NULL;
  158. // free the memory containing the code-stream
  159. free(src);
  160. src = NULL;
  161. // free the codec context
  162. opj_destroy_decompress(dinfo);
  163. // create output image
  164. dib = J2KImageToFIBITMAP(s_format_id, image);
  165. if(!dib) throw "Failed to import JPEG2000 image";
  166. // free image data structure
  167. opj_image_destroy(image);
  168. return dib;
  169. } catch (const char *text) {
  170. if(src) free(src);
  171. if(dib) FreeImage_Unload(dib);
  172. // free remaining structures
  173. opj_destroy_decompress(dinfo);
  174. opj_image_destroy(image);
  175. // close the byte stream
  176. if(cio) opj_cio_close(cio);
  177. FreeImage_OutputMessageProc(s_format_id, text);
  178. return NULL;
  179. }
  180. }
  181. return NULL;
  182. }
  183. static BOOL DLL_CALLCONV
  184. Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
  185. if ((dib) && (handle)) {
  186. BOOL bSuccess;
  187. opj_cparameters_t parameters; // compression parameters
  188. opj_event_mgr_t event_mgr; // event manager
  189. opj_image_t *image = NULL; // image to encode
  190. opj_cinfo_t* cinfo = NULL; // codec context
  191. opj_cio_t *cio = NULL; // memory byte stream
  192. // configure the event callbacks
  193. memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  194. event_mgr.error_handler = jp2_error_callback;
  195. event_mgr.warning_handler = jp2_warning_callback;
  196. event_mgr.info_handler = NULL;
  197. // set encoding parameters to default values
  198. opj_set_default_encoder_parameters(&parameters);
  199. parameters.tcp_numlayers = 0;
  200. // if no rate entered, apply a 16:1 rate by default
  201. if(flags == JP2_DEFAULT) {
  202. parameters.tcp_rates[0] = (float)16;
  203. } else {
  204. // for now, the flags parameter is only used to specify the rate
  205. parameters.tcp_rates[0] = (float)flags;
  206. }
  207. parameters.tcp_numlayers++;
  208. parameters.cp_disto_alloc = 1;
  209. try {
  210. // convert the dib to a OpenJPEG image
  211. image = FIBITMAPToJ2KImage(s_format_id, dib, &parameters);
  212. if(!image) return FALSE;
  213. // decide if MCT should be used
  214. parameters.tcp_mct = (image->numcomps == 3) ? 1 : 0;
  215. // encode the destination image
  216. // get a J2K compressor handle
  217. cinfo = opj_create_compress(CODEC_JP2);
  218. // catch events using our callbacks
  219. opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, NULL);
  220. // setup the encoder parameters using the current image and using user parameters
  221. opj_setup_encoder(cinfo, &parameters, image);
  222. // open a byte stream for writing, allocate memory for all tiles
  223. cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
  224. // encode the image
  225. bSuccess = opj_encode(cinfo, cio, image, NULL/*parameters.index*/);
  226. if (!bSuccess) {
  227. throw "Failed to encode image";
  228. }
  229. int codestream_length = cio_tell(cio);
  230. // write the buffer to user's IO handle
  231. io->write_proc(cio->buffer, 1, codestream_length, handle);
  232. // close and free the byte stream
  233. opj_cio_close(cio);
  234. // free remaining compression structures
  235. opj_destroy_compress(cinfo);
  236. // free image data
  237. opj_image_destroy(image);
  238. return TRUE;
  239. } catch (const char *text) {
  240. if(cio) opj_cio_close(cio);
  241. if(cinfo) opj_destroy_compress(cinfo);
  242. if(image) opj_image_destroy(image);
  243. FreeImage_OutputMessageProc(s_format_id, text);
  244. return FALSE;
  245. }
  246. }
  247. return FALSE;
  248. }
  249. // ==========================================================
  250. // Init
  251. // ==========================================================
  252. void DLL_CALLCONV
  253. InitJP2(Plugin *plugin, int format_id) {
  254. s_format_id = format_id;
  255. plugin->format_proc = Format;
  256. plugin->description_proc = Description;
  257. plugin->extension_proc = Extension;
  258. plugin->regexpr_proc = RegExpr;
  259. plugin->open_proc = Open;
  260. plugin->close_proc = Close;
  261. plugin->pagecount_proc = NULL;
  262. plugin->pagecapability_proc = NULL;
  263. plugin->load_proc = Load;
  264. plugin->save_proc = Save;
  265. plugin->validate_proc = Validate;
  266. plugin->mime_proc = MimeType;
  267. plugin->supports_export_bpp_proc = SupportsExportDepth;
  268. plugin->supports_export_type_proc = SupportsExportType;
  269. plugin->supports_icc_profiles_proc = NULL;
  270. }