/indra/llimagej2coj/llimagej2coj.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 491 lines · 283 code · 93 blank · 115 comment · 29 complexity · 5eecdc091c0942d8208945ed392407ea MD5 · raw file

  1. /**
  2. * @file llimagej2coj.cpp
  3. * @brief This is an implementation of JPEG2000 encode/decode using OpenJPEG.
  4. *
  5. * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llimagej2coj.h"
  28. // this is defined so that we get static linking.
  29. #include "openjpeg.h"
  30. #include "lltimer.h"
  31. //#include "llmemory.h"
  32. const char* fallbackEngineInfoLLImageJ2CImpl()
  33. {
  34. static std::string version_string =
  35. std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
  36. + opj_version();
  37. return version_string.c_str();
  38. }
  39. LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
  40. {
  41. return new LLImageJ2COJ();
  42. }
  43. void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
  44. {
  45. delete impl;
  46. impl = NULL;
  47. }
  48. // Return string from message, eliminating final \n if present
  49. static std::string chomp(const char* msg)
  50. {
  51. // stomp trailing \n
  52. std::string message = msg;
  53. if (!message.empty())
  54. {
  55. size_t last = message.size() - 1;
  56. if (message[last] == '\n')
  57. {
  58. message.resize( last );
  59. }
  60. }
  61. return message;
  62. }
  63. /**
  64. sample error callback expecting a LLFILE* client object
  65. */
  66. void error_callback(const char* msg, void*)
  67. {
  68. lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
  69. }
  70. /**
  71. sample warning callback expecting a LLFILE* client object
  72. */
  73. void warning_callback(const char* msg, void*)
  74. {
  75. lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
  76. }
  77. /**
  78. sample debug callback expecting no client object
  79. */
  80. void info_callback(const char* msg, void*)
  81. {
  82. lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
  83. }
  84. // Divide a by 2 to the power of b and round upwards
  85. int ceildivpow2(int a, int b)
  86. {
  87. return (a + (1 << b) - 1) >> b;
  88. }
  89. LLImageJ2COJ::LLImageJ2COJ()
  90. : LLImageJ2CImpl()
  91. {
  92. }
  93. LLImageJ2COJ::~LLImageJ2COJ()
  94. {
  95. }
  96. BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
  97. {
  98. // No specific implementation for this method in the OpenJpeg case
  99. return FALSE;
  100. }
  101. BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
  102. {
  103. // No specific implementation for this method in the OpenJpeg case
  104. return FALSE;
  105. }
  106. BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
  107. {
  108. //
  109. // FIXME: Get the comment field out of the texture
  110. //
  111. LLTimer decode_timer;
  112. opj_dparameters_t parameters; /* decompression parameters */
  113. opj_event_mgr_t event_mgr; /* event manager */
  114. opj_image_t *image = NULL;
  115. opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
  116. opj_cio_t *cio = NULL;
  117. /* configure the event callbacks (not required) */
  118. memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  119. event_mgr.error_handler = error_callback;
  120. event_mgr.warning_handler = warning_callback;
  121. event_mgr.info_handler = info_callback;
  122. /* set decoding parameters to default values */
  123. opj_set_default_decoder_parameters(&parameters);
  124. parameters.cp_reduce = base.getRawDiscardLevel();
  125. /* decode the code-stream */
  126. /* ---------------------- */
  127. /* JPEG-2000 codestream */
  128. /* get a decoder handle */
  129. dinfo = opj_create_decompress(CODEC_J2K);
  130. /* catch events using our callbacks and give a local context */
  131. opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
  132. /* setup the decoder decoding parameters using user parameters */
  133. opj_setup_decoder(dinfo, &parameters);
  134. /* open a byte stream */
  135. cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
  136. /* decode the stream and fill the image structure */
  137. image = opj_decode(dinfo, cio);
  138. /* close the byte stream */
  139. opj_cio_close(cio);
  140. /* free remaining structures */
  141. if(dinfo)
  142. {
  143. opj_destroy_decompress(dinfo);
  144. }
  145. // The image decode failed if the return was NULL or the component
  146. // count was zero. The latter is just a sanity check before we
  147. // dereference the array.
  148. if(!image || !image->numcomps)
  149. {
  150. LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
  151. if (image)
  152. {
  153. opj_image_destroy(image);
  154. }
  155. return TRUE; // done
  156. }
  157. // sometimes we get bad data out of the cache - check to see if the decode succeeded
  158. for (S32 i = 0; i < image->numcomps; i++)
  159. {
  160. if (image->comps[i].factor != base.getRawDiscardLevel())
  161. {
  162. // if we didn't get the discard level we're expecting, fail
  163. opj_image_destroy(image);
  164. base.mDecoding = FALSE;
  165. return TRUE;
  166. }
  167. }
  168. if(image->numcomps <= first_channel)
  169. {
  170. llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
  171. if (image)
  172. {
  173. opj_image_destroy(image);
  174. }
  175. return TRUE;
  176. }
  177. // Copy image data into our raw image format (instead of the separate channel format
  178. S32 img_components = image->numcomps;
  179. S32 channels = img_components - first_channel;
  180. if( channels > max_channel_count )
  181. channels = max_channel_count;
  182. // Component buffers are allocated in an image width by height buffer.
  183. // The image placed in that buffer is ceil(width/2^factor) by
  184. // ceil(height/2^factor) and if the factor isn't zero it will be at the
  185. // top left of the buffer with black filled in the rest of the pixels.
  186. // It is integer math so the formula is written in ceildivpo2.
  187. // (Assuming all the components have the same width, height and
  188. // factor.)
  189. S32 comp_width = image->comps[0].w;
  190. S32 f=image->comps[0].factor;
  191. S32 width = ceildivpow2(image->x1 - image->x0, f);
  192. S32 height = ceildivpow2(image->y1 - image->y0, f);
  193. raw_image.resize(width, height, channels);
  194. U8 *rawp = raw_image.getData();
  195. // first_channel is what channel to start copying from
  196. // dest is what channel to copy to. first_channel comes from the
  197. // argument, dest always starts writing at channel zero.
  198. for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
  199. comp++, dest++)
  200. {
  201. if (image->comps[comp].data)
  202. {
  203. S32 offset = dest;
  204. for (S32 y = (height - 1); y >= 0; y--)
  205. {
  206. for (S32 x = 0; x < width; x++)
  207. {
  208. rawp[offset] = image->comps[comp].data[y*comp_width + x];
  209. offset += channels;
  210. }
  211. }
  212. }
  213. else // Some rare OpenJPEG versions have this bug.
  214. {
  215. LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
  216. opj_image_destroy(image);
  217. return TRUE; // done
  218. }
  219. }
  220. /* free image data structure */
  221. opj_image_destroy(image);
  222. return TRUE; // done
  223. }
  224. BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
  225. {
  226. const S32 MAX_COMPS = 5;
  227. opj_cparameters_t parameters; /* compression parameters */
  228. opj_event_mgr_t event_mgr; /* event manager */
  229. /*
  230. configure the event callbacks (not required)
  231. setting of each callback is optional
  232. */
  233. memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  234. event_mgr.error_handler = error_callback;
  235. event_mgr.warning_handler = warning_callback;
  236. event_mgr.info_handler = info_callback;
  237. /* set encoding parameters to default values */
  238. opj_set_default_encoder_parameters(&parameters);
  239. parameters.cod_format = 0;
  240. parameters.cp_disto_alloc = 1;
  241. if (reversible)
  242. {
  243. parameters.tcp_numlayers = 1;
  244. parameters.tcp_rates[0] = 0.0f;
  245. }
  246. else
  247. {
  248. parameters.tcp_numlayers = 5;
  249. parameters.tcp_rates[0] = 1920.0f;
  250. parameters.tcp_rates[1] = 480.0f;
  251. parameters.tcp_rates[2] = 120.0f;
  252. parameters.tcp_rates[3] = 30.0f;
  253. parameters.tcp_rates[4] = 10.0f;
  254. parameters.irreversible = 1;
  255. if (raw_image.getComponents() >= 3)
  256. {
  257. parameters.tcp_mct = 1;
  258. }
  259. }
  260. if (!comment_text)
  261. {
  262. parameters.cp_comment = (char *) "";
  263. }
  264. else
  265. {
  266. // Awful hacky cast, too lazy to copy right now.
  267. parameters.cp_comment = (char *) comment_text;
  268. }
  269. //
  270. // Fill in the source image from our raw image
  271. //
  272. OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
  273. opj_image_cmptparm_t cmptparm[MAX_COMPS];
  274. opj_image_t * image = NULL;
  275. S32 numcomps = raw_image.getComponents();
  276. S32 width = raw_image.getWidth();
  277. S32 height = raw_image.getHeight();
  278. memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t));
  279. for(S32 c = 0; c < numcomps; c++) {
  280. cmptparm[c].prec = 8;
  281. cmptparm[c].bpp = 8;
  282. cmptparm[c].sgnd = 0;
  283. cmptparm[c].dx = parameters.subsampling_dx;
  284. cmptparm[c].dy = parameters.subsampling_dy;
  285. cmptparm[c].w = width;
  286. cmptparm[c].h = height;
  287. }
  288. /* create the image */
  289. image = opj_image_create(numcomps, &cmptparm[0], color_space);
  290. image->x1 = width;
  291. image->y1 = height;
  292. S32 i = 0;
  293. const U8 *src_datap = raw_image.getData();
  294. for (S32 y = height - 1; y >= 0; y--)
  295. {
  296. for (S32 x = 0; x < width; x++)
  297. {
  298. const U8 *pixel = src_datap + (y*width + x) * numcomps;
  299. for (S32 c = 0; c < numcomps; c++)
  300. {
  301. image->comps[c].data[i] = *pixel;
  302. pixel++;
  303. }
  304. i++;
  305. }
  306. }
  307. /* encode the destination image */
  308. /* ---------------------------- */
  309. int codestream_length;
  310. opj_cio_t *cio = NULL;
  311. /* get a J2K compressor handle */
  312. opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
  313. /* catch events using our callbacks and give a local context */
  314. opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
  315. /* setup the encoder parameters using the current image and using user parameters */
  316. opj_setup_encoder(cinfo, &parameters, image);
  317. /* open a byte stream for writing */
  318. /* allocate memory for all tiles */
  319. cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
  320. /* encode the image */
  321. bool bSuccess = opj_encode(cinfo, cio, image, NULL);
  322. if (!bSuccess)
  323. {
  324. opj_cio_close(cio);
  325. LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL;
  326. return FALSE;
  327. }
  328. codestream_length = cio_tell(cio);
  329. base.copyData(cio->buffer, codestream_length);
  330. base.updateData(); // set width, height
  331. /* close and free the byte stream */
  332. opj_cio_close(cio);
  333. /* free remaining compression structures */
  334. opj_destroy_compress(cinfo);
  335. /* free user parameters structure */
  336. if(parameters.cp_matrice) free(parameters.cp_matrice);
  337. /* free image data */
  338. opj_image_destroy(image);
  339. return TRUE;
  340. }
  341. BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
  342. {
  343. //
  344. // FIXME: We get metadata by decoding the ENTIRE image.
  345. //
  346. // Update the raw discard level
  347. base.updateRawDiscardLevel();
  348. opj_dparameters_t parameters; /* decompression parameters */
  349. opj_event_mgr_t event_mgr; /* event manager */
  350. opj_image_t *image = NULL;
  351. opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
  352. opj_cio_t *cio = NULL;
  353. /* configure the event callbacks (not required) */
  354. memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  355. event_mgr.error_handler = error_callback;
  356. event_mgr.warning_handler = warning_callback;
  357. event_mgr.info_handler = info_callback;
  358. /* set decoding parameters to default values */
  359. opj_set_default_decoder_parameters(&parameters);
  360. // Only decode what's required to get the size data.
  361. parameters.cp_limit_decoding=LIMIT_TO_MAIN_HEADER;
  362. //parameters.cp_reduce = mRawDiscardLevel;
  363. /* decode the code-stream */
  364. /* ---------------------- */
  365. /* JPEG-2000 codestream */
  366. /* get a decoder handle */
  367. dinfo = opj_create_decompress(CODEC_J2K);
  368. /* catch events using our callbacks and give a local context */
  369. opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
  370. /* setup the decoder decoding parameters using user parameters */
  371. opj_setup_decoder(dinfo, &parameters);
  372. /* open a byte stream */
  373. cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
  374. /* decode the stream and fill the image structure */
  375. image = opj_decode(dinfo, cio);
  376. /* close the byte stream */
  377. opj_cio_close(cio);
  378. /* free remaining structures */
  379. if(dinfo)
  380. {
  381. opj_destroy_decompress(dinfo);
  382. }
  383. if(!image)
  384. {
  385. llwarns << "ERROR -> getMetadata: failed to decode image!" << llendl;
  386. return FALSE;
  387. }
  388. // Copy image data into our raw image format (instead of the separate channel format
  389. S32 width = 0;
  390. S32 height = 0;
  391. S32 img_components = image->numcomps;
  392. width = image->x1 - image->x0;
  393. height = image->y1 - image->y0;
  394. base.setSize(width, height, img_components);
  395. /* free image data structure */
  396. opj_image_destroy(image);
  397. return TRUE;
  398. }