PageRenderTime 8117ms CodeModel.GetById 34ms RepoModel.GetById 14ms app.codeStats 0ms

/linden/indra/llimagej2coj/llimagej2coj.cpp

https://github.com/TechyeFox/imprudence
C++ | 492 lines | 281 code | 94 blank | 117 comment | 31 complexity | f9eb540cb618984bae0a8fe63fa48265 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=viewergpl$
  6. *
  7. * Copyright (c) 2006-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include "llimagej2coj.h"
  34. // this is defined so that we get static linking.
  35. #include "openjpeg.h"
  36. #include "lltimer.h"
  37. #include "llmemory.h"
  38. const char* fallbackEngineInfoLLImageJ2CImpl()
  39. {
  40. static std::string version_string =
  41. std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
  42. + opj_version();
  43. return version_string.c_str();
  44. }
  45. LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
  46. {
  47. return new LLImageJ2COJ();
  48. }
  49. void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
  50. {
  51. delete impl;
  52. impl = NULL;
  53. }
  54. // Return string from message, eliminating final \n if present
  55. static std::string chomp(const char* msg)
  56. {
  57. // stomp trailing \n
  58. std::string message = msg;
  59. if (!message.empty())
  60. {
  61. size_t last = message.size() - 1;
  62. if (message[last] == '\n')
  63. {
  64. message.resize( last );
  65. }
  66. }
  67. return message;
  68. }
  69. /**
  70. sample error callback expecting a LLFILE* client object
  71. */
  72. void error_callback(const char* msg, void*)
  73. {
  74. lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
  75. }
  76. /**
  77. sample warning callback expecting a LLFILE* client object
  78. */
  79. void warning_callback(const char* msg, void*)
  80. {
  81. lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
  82. }
  83. /**
  84. sample debug callback expecting no client object
  85. */
  86. void info_callback(const char* msg, void*)
  87. {
  88. lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;
  89. }
  90. LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl()
  91. {
  92. mRawImagep=NULL;
  93. }
  94. LLImageJ2COJ::~LLImageJ2COJ()
  95. {
  96. }
  97. BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
  98. {
  99. //
  100. // FIXME: Get the comment field out of the texture
  101. //
  102. LLTimer decode_timer;
  103. opj_dparameters_t parameters; /* decompression parameters */
  104. opj_event_mgr_t event_mgr; /* event manager */
  105. opj_image_t *image = NULL;
  106. opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
  107. opj_cio_t *cio = NULL;
  108. /* configure the event callbacks (not required) */
  109. memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
  110. event_mgr.error_handler = error_callback;
  111. event_mgr.warning_handler = warning_callback;
  112. event_mgr.info_handler = info_callback;
  113. /* set decoding parameters to default values */
  114. opj_set_default_decoder_parameters(&parameters);
  115. parameters.cp_reduce = base.getRawDiscardLevel();
  116. /* decode the code-stream */
  117. /* ---------------------- */
  118. /* JPEG-2000 codestream */
  119. /* get a decoder handle */
  120. dinfo = opj_create_decompress(CODEC_J2K);
  121. /* catch events using our callbacks and give a local context */
  122. opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
  123. /* setup the decoder decoding parameters using user parameters */
  124. opj_setup_decoder(dinfo, &parameters);
  125. /* open a byte stream */
  126. cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
  127. /* decode the stream and fill the image structure */
  128. image = opj_decode(dinfo, cio);
  129. /* close the byte stream */
  130. opj_cio_close(cio);
  131. /* free remaining structures */
  132. if(dinfo)
  133. {
  134. opj_destroy_decompress(dinfo);
  135. }
  136. // The image decode failed if the return was NULL or the component
  137. // count was zero. The latter is just a sanity check before we
  138. // dereference the array.
  139. if(!image)
  140. {
  141. LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL;
  142. return TRUE; // done
  143. }
  144. S32 img_components = image->numcomps;
  145. if( !img_components ) // < 1 ||img_components > 4 )
  146. {
  147. LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL;
  148. if (image)
  149. {
  150. opj_image_destroy(image);
  151. }
  152. return TRUE; // done
  153. }
  154. // sometimes we get bad data out of the cache - check to see if the decode succeeded
  155. for (S32 i = 0; i < img_components; i++)
  156. {
  157. if (image->comps[i].factor != base.getRawDiscardLevel())
  158. {
  159. // if we didn't get the discard level we're expecting, fail
  160. if (image) //anyway somthing odd with the image, better check than crash
  161. opj_image_destroy(image);
  162. base.mDecoding = FALSE;
  163. return TRUE;
  164. }
  165. }
  166. if(img_components <= first_channel)
  167. {
  168. LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL;
  169. if (image)
  170. {
  171. opj_image_destroy(image);
  172. }
  173. return TRUE;
  174. }
  175. // Copy image data into our raw image format (instead of the separate channel format
  176. S32 channels = img_components - first_channel;
  177. if( channels > max_channel_count )
  178. channels = max_channel_count;
  179. // Component buffers are allocated in an image width by height buffer.
  180. // The image placed in that buffer is ceil(width/2^factor) by
  181. // ceil(height/2^factor) and if the factor isn't zero it will be at the
  182. // top left of the buffer with black filled in the rest of the pixels.
  183. // It is integer math so the formula is written in ceildivpo2.
  184. // (Assuming all the components have the same width, height and
  185. // factor.)
  186. S32 comp_width = image->comps[0].w;
  187. S32 f=image->comps[0].factor;
  188. S32 width = ceildivpow2(image->x1 - image->x0, f);
  189. S32 height = ceildivpow2(image->y1 - image->y0, f);
  190. raw_image.resize(width, height, channels);
  191. U8 *rawp = raw_image.getData();
  192. // first_channel is what channel to start copying from
  193. // dest is what channel to copy to. first_channel comes from the
  194. // argument, dest always starts writing at channel zero.
  195. for (S32 comp = first_channel, dest=0; comp < first_channel + channels;
  196. comp++, dest++)
  197. {
  198. if (image->comps[comp].data)
  199. {
  200. S32 offset = dest;
  201. for (S32 y = (height - 1); y >= 0; y--)
  202. {
  203. for (S32 x = 0; x < width; x++)
  204. {
  205. rawp[offset] = image->comps[comp].data[y*comp_width + x];
  206. offset += channels;
  207. }
  208. }
  209. }
  210. else // Some rare OpenJPEG versions have this bug.
  211. {
  212. llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl;
  213. opj_image_destroy(image);
  214. return TRUE; // done
  215. }
  216. }
  217. /* free image data structure */
  218. if (image)
  219. {
  220. opj_image_destroy(image);
  221. }
  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. llinfos << "Failed to encode image." << llendl;
  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. }