Jpeg2KEncode.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. /*
  2. * The Python Imaging Library.
  3. * $Id$
  4. *
  5. * decoder for JPEG2000 image data.
  6. *
  7. * history:
  8. * 2014-03-12 ajh Created
  9. *
  10. * Copyright (c) 2014 Coriolis Systems Limited
  11. * Copyright (c) 2014 Alastair Houghton
  12. *
  13. * See the README file for details on usage and redistribution.
  14. */
  15. #include "Imaging.h"
  16. #ifdef HAVE_OPENJPEG
  17. #include "Jpeg2K.h"
  18. #define CINEMA_24_CS_LENGTH 1302083
  19. #define CINEMA_48_CS_LENGTH 651041
  20. #define COMP_24_CS_MAX_LENGTH 1041666
  21. #define COMP_48_CS_MAX_LENGTH 520833
  22. /* -------------------------------------------------------------------- */
  23. /* Error handler */
  24. /* -------------------------------------------------------------------- */
  25. static void
  26. j2k_error(const char *msg, void *client_data) {
  27. JPEG2KENCODESTATE *state = (JPEG2KENCODESTATE *)client_data;
  28. free((void *)state->error_msg);
  29. state->error_msg = strdup(msg);
  30. }
  31. static void
  32. j2k_warn(const char *msg, void *client_data) {
  33. // Null handler
  34. }
  35. /* -------------------------------------------------------------------- */
  36. /* Buffer output stream */
  37. /* -------------------------------------------------------------------- */
  38. static OPJ_SIZE_T
  39. j2k_write(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
  40. ImagingCodecState state = (ImagingCodecState)p_user_data;
  41. unsigned int result;
  42. result = _imaging_write_pyFd(state->fd, p_buffer, p_nb_bytes);
  43. return result ? result : (OPJ_SIZE_T)-1;
  44. }
  45. static OPJ_OFF_T
  46. j2k_skip(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
  47. ImagingCodecState state = (ImagingCodecState)p_user_data;
  48. char *buffer;
  49. int result;
  50. /* Explicitly write zeros */
  51. buffer = calloc(p_nb_bytes, 1);
  52. if (!buffer) {
  53. return (OPJ_OFF_T)-1;
  54. }
  55. result = _imaging_write_pyFd(state->fd, buffer, p_nb_bytes);
  56. free(buffer);
  57. return result ? result : p_nb_bytes;
  58. }
  59. static OPJ_BOOL
  60. j2k_seek(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
  61. ImagingCodecState state = (ImagingCodecState)p_user_data;
  62. off_t pos = 0;
  63. _imaging_seek_pyFd(state->fd, p_nb_bytes, SEEK_SET);
  64. pos = _imaging_tell_pyFd(state->fd);
  65. return pos == p_nb_bytes;
  66. }
  67. /* -------------------------------------------------------------------- */
  68. /* Encoder */
  69. /* -------------------------------------------------------------------- */
  70. typedef void (*j2k_pack_tile_t)(
  71. Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h);
  72. static void
  73. j2k_pack_l(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
  74. UINT8 *ptr = buf;
  75. unsigned x, y;
  76. for (y = 0; y < h; ++y) {
  77. UINT8 *data = (UINT8 *)(im->image[y + y0] + x0);
  78. for (x = 0; x < w; ++x) {
  79. *ptr++ = *data++;
  80. }
  81. }
  82. }
  83. static void
  84. j2k_pack_i16(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
  85. UINT8 *ptr = buf;
  86. unsigned x, y;
  87. for (y = 0; y < h; ++y) {
  88. UINT8 *data = (UINT8 *)(im->image[y + y0] + x0);
  89. for (x = 0; x < w; ++x) {
  90. #ifdef WORDS_BIGENDIAN
  91. ptr[0] = data[1];
  92. ptr[1] = data[0];
  93. #else
  94. ptr[0] = data[0];
  95. ptr[1] = data[1];
  96. #endif
  97. ptr += 2;
  98. data += 2;
  99. }
  100. }
  101. }
  102. static void
  103. j2k_pack_la(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
  104. UINT8 *ptr = buf;
  105. UINT8 *ptra = buf + w * h;
  106. unsigned x, y;
  107. for (y = 0; y < h; ++y) {
  108. UINT8 *data = (UINT8 *)(im->image[y + y0] + 4 * x0);
  109. for (x = 0; x < w; ++x) {
  110. *ptr++ = data[0];
  111. *ptra++ = data[3];
  112. data += 4;
  113. }
  114. }
  115. }
  116. static void
  117. j2k_pack_rgb(Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
  118. UINT8 *pr = buf;
  119. UINT8 *pg = pr + w * h;
  120. UINT8 *pb = pg + w * h;
  121. unsigned x, y;
  122. for (y = 0; y < h; ++y) {
  123. UINT8 *data = (UINT8 *)(im->image[y + y0] + 4 * x0);
  124. for (x = 0; x < w; ++x) {
  125. *pr++ = data[0];
  126. *pg++ = data[1];
  127. *pb++ = data[2];
  128. data += 4;
  129. }
  130. }
  131. }
  132. static void
  133. j2k_pack_rgba(
  134. Imaging im, UINT8 *buf, unsigned x0, unsigned y0, unsigned w, unsigned h) {
  135. UINT8 *pr = buf;
  136. UINT8 *pg = pr + w * h;
  137. UINT8 *pb = pg + w * h;
  138. UINT8 *pa = pb + w * h;
  139. unsigned x, y;
  140. for (y = 0; y < h; ++y) {
  141. UINT8 *data = (UINT8 *)(im->image[y + y0] + 4 * x0);
  142. for (x = 0; x < w; ++x) {
  143. *pr++ = *data++;
  144. *pg++ = *data++;
  145. *pb++ = *data++;
  146. *pa++ = *data++;
  147. }
  148. }
  149. }
  150. enum {
  151. J2K_STATE_START = 0,
  152. J2K_STATE_ENCODING = 1,
  153. J2K_STATE_DONE = 2,
  154. J2K_STATE_FAILED = 3,
  155. };
  156. static void
  157. j2k_set_cinema_params(Imaging im, int components, opj_cparameters_t *params) {
  158. float rate;
  159. int n;
  160. /* These settings have been copied from opj_compress in the OpenJPEG
  161. sources. */
  162. params->tile_size_on = OPJ_FALSE;
  163. params->cp_tdx = params->cp_tdy = 1;
  164. params->tp_flag = 'C';
  165. params->tp_on = 1;
  166. params->cp_tx0 = params->cp_ty0 = 0;
  167. params->image_offset_x0 = params->image_offset_y0 = 0;
  168. params->cblockw_init = 32;
  169. params->cblockh_init = 32;
  170. params->csty |= 0x01;
  171. params->prog_order = OPJ_CPRL;
  172. params->roi_compno = -1;
  173. params->subsampling_dx = params->subsampling_dy = 1;
  174. params->irreversible = 1;
  175. if (params->cp_cinema == OPJ_CINEMA4K_24) {
  176. float max_rate =
  177. ((float)(components * im->xsize * im->ysize * 8) /
  178. (CINEMA_24_CS_LENGTH * 8));
  179. params->POC[0].tile = 1;
  180. params->POC[0].resno0 = 0;
  181. params->POC[0].compno0 = 0;
  182. params->POC[0].layno1 = 1;
  183. params->POC[0].resno1 = params->numresolution - 1;
  184. params->POC[0].compno1 = 3;
  185. params->POC[0].prg1 = OPJ_CPRL;
  186. params->POC[1].tile = 1;
  187. params->POC[1].resno0 = 0;
  188. params->POC[1].compno0 = 0;
  189. params->POC[1].layno1 = 1;
  190. params->POC[1].resno1 = params->numresolution - 1;
  191. params->POC[1].compno1 = 3;
  192. params->POC[1].prg1 = OPJ_CPRL;
  193. params->numpocs = 2;
  194. for (n = 0; n < params->tcp_numlayers; ++n) {
  195. rate = 0;
  196. if (params->tcp_rates[0] == 0) {
  197. params->tcp_rates[n] = max_rate;
  198. } else {
  199. rate =
  200. ((float)(components * im->xsize * im->ysize * 8) /
  201. (params->tcp_rates[n] * 8));
  202. if (rate > CINEMA_24_CS_LENGTH) {
  203. params->tcp_rates[n] = max_rate;
  204. }
  205. }
  206. }
  207. params->max_comp_size = COMP_24_CS_MAX_LENGTH;
  208. } else {
  209. float max_rate =
  210. ((float)(components * im->xsize * im->ysize * 8) /
  211. (CINEMA_48_CS_LENGTH * 8));
  212. for (n = 0; n < params->tcp_numlayers; ++n) {
  213. rate = 0;
  214. if (params->tcp_rates[0] == 0) {
  215. params->tcp_rates[n] = max_rate;
  216. } else {
  217. rate =
  218. ((float)(components * im->xsize * im->ysize * 8) /
  219. (params->tcp_rates[n] * 8));
  220. if (rate > CINEMA_48_CS_LENGTH) {
  221. params->tcp_rates[n] = max_rate;
  222. }
  223. }
  224. }
  225. params->max_comp_size = COMP_48_CS_MAX_LENGTH;
  226. }
  227. }
  228. static int
  229. j2k_encode_entry(Imaging im, ImagingCodecState state) {
  230. JPEG2KENCODESTATE *context = (JPEG2KENCODESTATE *)state->context;
  231. opj_stream_t *stream = NULL;
  232. opj_image_t *image = NULL;
  233. opj_codec_t *codec = NULL;
  234. opj_cparameters_t params;
  235. unsigned components;
  236. OPJ_COLOR_SPACE color_space;
  237. opj_image_cmptparm_t image_params[4];
  238. unsigned xsiz, ysiz;
  239. unsigned tile_width, tile_height;
  240. unsigned tiles_x, tiles_y;
  241. unsigned x, y, tile_ndx;
  242. unsigned n;
  243. j2k_pack_tile_t pack;
  244. int ret = -1;
  245. unsigned prec = 8;
  246. unsigned _overflow_scale_factor;
  247. stream = opj_stream_create(BUFFER_SIZE, OPJ_FALSE);
  248. if (!stream) {
  249. state->errcode = IMAGING_CODEC_BROKEN;
  250. state->state = J2K_STATE_FAILED;
  251. goto quick_exit;
  252. }
  253. opj_stream_set_write_function(stream, j2k_write);
  254. opj_stream_set_skip_function(stream, j2k_skip);
  255. opj_stream_set_seek_function(stream, j2k_seek);
  256. /* OpenJPEG 2.0 doesn't have OPJ_VERSION_MAJOR */
  257. #ifndef OPJ_VERSION_MAJOR
  258. opj_stream_set_user_data(stream, state);
  259. #else
  260. opj_stream_set_user_data(stream, state, NULL);
  261. #endif
  262. /* Setup an opj_image */
  263. if (strcmp(im->mode, "L") == 0) {
  264. components = 1;
  265. color_space = OPJ_CLRSPC_GRAY;
  266. pack = j2k_pack_l;
  267. } else if (strcmp(im->mode, "I;16") == 0 || strcmp(im->mode, "I;16B") == 0) {
  268. components = 1;
  269. color_space = OPJ_CLRSPC_GRAY;
  270. pack = j2k_pack_i16;
  271. prec = 16;
  272. } else if (strcmp(im->mode, "LA") == 0) {
  273. components = 2;
  274. color_space = OPJ_CLRSPC_GRAY;
  275. pack = j2k_pack_la;
  276. } else if (strcmp(im->mode, "RGB") == 0) {
  277. components = 3;
  278. color_space = OPJ_CLRSPC_SRGB;
  279. pack = j2k_pack_rgb;
  280. } else if (strcmp(im->mode, "YCbCr") == 0) {
  281. components = 3;
  282. color_space = OPJ_CLRSPC_SYCC;
  283. pack = j2k_pack_rgb;
  284. } else if (strcmp(im->mode, "RGBA") == 0) {
  285. components = 4;
  286. color_space = OPJ_CLRSPC_SRGB;
  287. pack = j2k_pack_rgba;
  288. } else {
  289. state->errcode = IMAGING_CODEC_BROKEN;
  290. state->state = J2K_STATE_FAILED;
  291. goto quick_exit;
  292. }
  293. for (n = 0; n < components; ++n) {
  294. image_params[n].dx = image_params[n].dy = 1;
  295. image_params[n].w = im->xsize;
  296. image_params[n].h = im->ysize;
  297. image_params[n].x0 = image_params[n].y0 = 0;
  298. image_params[n].prec = prec;
  299. image_params[n].sgnd = context->sgnd == 0 ? 0 : 1;
  300. }
  301. image = opj_image_create(components, image_params, color_space);
  302. if (!image) {
  303. state->errcode = IMAGING_CODEC_BROKEN;
  304. state->state = J2K_STATE_FAILED;
  305. goto quick_exit;
  306. }
  307. /* Setup compression context */
  308. context->error_msg = NULL;
  309. opj_set_default_encoder_parameters(&params);
  310. params.image_offset_x0 = context->offset_x;
  311. params.image_offset_y0 = context->offset_y;
  312. if (context->tile_size_x && context->tile_size_y) {
  313. params.tile_size_on = OPJ_TRUE;
  314. params.cp_tx0 = context->tile_offset_x;
  315. params.cp_ty0 = context->tile_offset_y;
  316. params.cp_tdx = context->tile_size_x;
  317. params.cp_tdy = context->tile_size_y;
  318. tile_width = params.cp_tdx;
  319. tile_height = params.cp_tdy;
  320. } else {
  321. params.cp_tx0 = 0;
  322. params.cp_ty0 = 0;
  323. params.cp_tdx = 1;
  324. params.cp_tdy = 1;
  325. tile_width = im->xsize;
  326. tile_height = im->ysize;
  327. }
  328. if (context->quality_layers && PySequence_Check(context->quality_layers)) {
  329. Py_ssize_t len = PySequence_Length(context->quality_layers);
  330. Py_ssize_t n;
  331. float *pq;
  332. if (len > 0) {
  333. if ((size_t)len >
  334. sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0])) {
  335. len = sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0]);
  336. }
  337. params.tcp_numlayers = (int)len;
  338. if (context->quality_is_in_db) {
  339. params.cp_disto_alloc = params.cp_fixed_alloc = 0;
  340. params.cp_fixed_quality = 1;
  341. pq = params.tcp_distoratio;
  342. } else {
  343. params.cp_disto_alloc = 1;
  344. params.cp_fixed_alloc = params.cp_fixed_quality = 0;
  345. pq = params.tcp_rates;
  346. }
  347. for (n = 0; n < len; ++n) {
  348. PyObject *obj = PySequence_ITEM(context->quality_layers, n);
  349. pq[n] = PyFloat_AsDouble(obj);
  350. }
  351. }
  352. } else {
  353. params.tcp_numlayers = 1;
  354. params.tcp_rates[0] = 0;
  355. params.cp_disto_alloc = 1;
  356. }
  357. if (context->num_resolutions) {
  358. params.numresolution = context->num_resolutions;
  359. }
  360. if (context->cblk_width >= 4 && context->cblk_width <= 1024 &&
  361. context->cblk_height >= 4 && context->cblk_height <= 1024 &&
  362. context->cblk_width * context->cblk_height <= 4096) {
  363. params.cblockw_init = context->cblk_width;
  364. params.cblockh_init = context->cblk_height;
  365. }
  366. if (context->precinct_width >= 4 && context->precinct_height >= 4 &&
  367. context->precinct_width >= context->cblk_width &&
  368. context->precinct_height > context->cblk_height) {
  369. params.prcw_init[0] = context->precinct_width;
  370. params.prch_init[0] = context->precinct_height;
  371. params.res_spec = 1;
  372. params.csty |= 0x01;
  373. }
  374. params.irreversible = context->irreversible;
  375. if (components == 3) {
  376. params.tcp_mct = context->mct;
  377. }
  378. if (context->comment) {
  379. params.cp_comment = context->comment;
  380. }
  381. params.prog_order = context->progression;
  382. params.cp_cinema = context->cinema_mode;
  383. switch (params.cp_cinema) {
  384. case OPJ_OFF:
  385. params.cp_rsiz = OPJ_STD_RSIZ;
  386. break;
  387. case OPJ_CINEMA2K_24:
  388. case OPJ_CINEMA2K_48:
  389. params.cp_rsiz = OPJ_CINEMA2K;
  390. if (params.numresolution > 6) {
  391. params.numresolution = 6;
  392. }
  393. break;
  394. case OPJ_CINEMA4K_24:
  395. params.cp_rsiz = OPJ_CINEMA4K;
  396. if (params.numresolution > 7) {
  397. params.numresolution = 7;
  398. }
  399. break;
  400. }
  401. if (!context->num_resolutions) {
  402. while (tile_width < (1U << (params.numresolution - 1U)) || tile_height < (1U << (params.numresolution - 1U))) {
  403. params.numresolution -= 1;
  404. }
  405. }
  406. if (context->cinema_mode != OPJ_OFF) {
  407. j2k_set_cinema_params(im, components, &params);
  408. }
  409. /* Set up the reference grid in the image */
  410. image->x0 = params.image_offset_x0;
  411. image->y0 = params.image_offset_y0;
  412. image->x1 = xsiz = im->xsize + params.image_offset_x0;
  413. image->y1 = ysiz = im->ysize + params.image_offset_y0;
  414. /* Create the compressor */
  415. codec = opj_create_compress(context->format);
  416. if (!codec) {
  417. state->errcode = IMAGING_CODEC_BROKEN;
  418. state->state = J2K_STATE_FAILED;
  419. goto quick_exit;
  420. }
  421. if (strcmp(im->mode, "RGBA") == 0) {
  422. image->comps[3].alpha = 1;
  423. } else if (strcmp(im->mode, "LA") == 0) {
  424. image->comps[1].alpha = 1;
  425. }
  426. opj_set_error_handler(codec, j2k_error, context);
  427. opj_set_info_handler(codec, j2k_warn, context);
  428. opj_set_warning_handler(codec, j2k_warn, context);
  429. opj_setup_encoder(codec, &params, image);
  430. /* Enabling PLT markers only supported in OpenJPEG 2.4.0 and up */
  431. #if ((OPJ_VERSION_MAJOR == 2 && OPJ_VERSION_MINOR >= 4) || OPJ_VERSION_MAJOR > 2)
  432. if (context->plt) {
  433. const char *plt_option[2] = {"PLT=YES", NULL};
  434. opj_encoder_set_extra_options(codec, plt_option);
  435. }
  436. #endif
  437. /* Start encoding */
  438. if (!opj_start_compress(codec, image, stream)) {
  439. state->errcode = IMAGING_CODEC_BROKEN;
  440. state->state = J2K_STATE_FAILED;
  441. goto quick_exit;
  442. }
  443. /* Write each tile */
  444. tiles_x = (im->xsize + (params.image_offset_x0 - params.cp_tx0) + tile_width - 1) /
  445. tile_width;
  446. tiles_y = (im->ysize + (params.image_offset_y0 - params.cp_ty0) + tile_height - 1) /
  447. tile_height;
  448. /* check for integer overflow for the malloc line, checking any expression
  449. that may multiply either tile_width or tile_height */
  450. _overflow_scale_factor = components * prec;
  451. if ((tile_width > UINT_MAX / _overflow_scale_factor) ||
  452. (tile_height > UINT_MAX / _overflow_scale_factor) ||
  453. (tile_width > UINT_MAX / (tile_height * _overflow_scale_factor)) ||
  454. (tile_height > UINT_MAX / (tile_width * _overflow_scale_factor))) {
  455. state->errcode = IMAGING_CODEC_BROKEN;
  456. state->state = J2K_STATE_FAILED;
  457. goto quick_exit;
  458. }
  459. /* malloc check ok, checked for overflow above */
  460. state->buffer = malloc(tile_width * tile_height * components * prec / 8);
  461. if (!state->buffer) {
  462. state->errcode = IMAGING_CODEC_BROKEN;
  463. state->state = J2K_STATE_FAILED;
  464. goto quick_exit;
  465. }
  466. tile_ndx = 0;
  467. for (y = 0; y < tiles_y; ++y) {
  468. int ty0 = params.cp_ty0 + y * tile_height;
  469. unsigned ty1 = ty0 + tile_height;
  470. unsigned pixy, pixh;
  471. if (ty0 < params.image_offset_y0) {
  472. ty0 = params.image_offset_y0;
  473. }
  474. if (ty1 > ysiz) {
  475. ty1 = ysiz;
  476. }
  477. pixy = ty0 - params.image_offset_y0;
  478. pixh = ty1 - ty0;
  479. for (x = 0; x < tiles_x; ++x) {
  480. int tx0 = params.cp_tx0 + x * tile_width;
  481. unsigned tx1 = tx0 + tile_width;
  482. unsigned pixx, pixw;
  483. unsigned data_size;
  484. if (tx0 < params.image_offset_x0) {
  485. tx0 = params.image_offset_x0;
  486. }
  487. if (tx1 > xsiz) {
  488. tx1 = xsiz;
  489. }
  490. pixx = tx0 - params.image_offset_x0;
  491. pixw = tx1 - tx0;
  492. pack(im, state->buffer, pixx, pixy, pixw, pixh);
  493. data_size = pixw * pixh * components * prec / 8;
  494. if (!opj_write_tile(codec, tile_ndx++, state->buffer, data_size, stream)) {
  495. state->errcode = IMAGING_CODEC_BROKEN;
  496. state->state = J2K_STATE_FAILED;
  497. goto quick_exit;
  498. }
  499. }
  500. }
  501. if (!opj_end_compress(codec, stream)) {
  502. state->errcode = IMAGING_CODEC_BROKEN;
  503. state->state = J2K_STATE_FAILED;
  504. goto quick_exit;
  505. }
  506. state->errcode = IMAGING_CODEC_END;
  507. state->state = J2K_STATE_DONE;
  508. ret = -1;
  509. quick_exit:
  510. if (codec) {
  511. opj_destroy_codec(codec);
  512. }
  513. if (image) {
  514. opj_image_destroy(image);
  515. }
  516. if (stream) {
  517. opj_stream_destroy(stream);
  518. }
  519. return ret;
  520. }
  521. int
  522. ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
  523. if (state->state == J2K_STATE_FAILED) {
  524. return -1;
  525. }
  526. if (state->state == J2K_STATE_START) {
  527. state->state = J2K_STATE_ENCODING;
  528. return j2k_encode_entry(im, state);
  529. }
  530. return -1;
  531. }
  532. /* -------------------------------------------------------------------- */
  533. /* Cleanup */
  534. /* -------------------------------------------------------------------- */
  535. int
  536. ImagingJpeg2KEncodeCleanup(ImagingCodecState state) {
  537. JPEG2KENCODESTATE *context = (JPEG2KENCODESTATE *)state->context;
  538. if (context->quality_layers) {
  539. Py_XDECREF(context->quality_layers);
  540. context->quality_layers = NULL;
  541. }
  542. if (context->error_msg) {
  543. free((void *)context->error_msg);
  544. }
  545. if (context->comment) {
  546. free((void *)context->comment);
  547. }
  548. context->error_msg = NULL;
  549. context->comment = NULL;
  550. return -1;
  551. }
  552. #endif /* HAVE_OPENJPEG */
  553. /*
  554. * Local Variables:
  555. * c-basic-offset: 4
  556. * End:
  557. *
  558. */