104#include <config_auto.h>
108#include "allheaders.h"
116#include LIBJP2K_HEADER
122typedef struct OpjBuffer
132static opj_image_t *pixConvertToOpjImage(
PIX *pix);
135static opj_stream_t *opjCreateMemoryStream(OpjBuffer *buf, l_int32 is_read);
143static opj_stream_t *opjCreateStream(FILE *fp, l_int32 is_read);
149static void error_callback(
const char *msg,
void *client_data) {
151 fprintf(stdout,
"[ERROR] %s", msg);
154static void warning_callback(
const char *msg,
void *client_data) {
156 fprintf(stdout,
"[WARNING] %s", msg);
159static void info_callback(
const char *msg,
void *client_data) {
161 fprintf(stdout,
"[INFO] %s", msg);
209pixReadJp2k(
const char *filename,
219 return (
PIX *)ERROR_PTR(
"filename not defined", __func__, NULL);
221 if ((fp = fopenReadStream(filename)) == NULL)
222 return (
PIX *)ERROR_PTR_1(
"image file not found",
223 filename, __func__, NULL);
224 pix = pixReadStreamJp2k(fp, reduction, box, hint, debug);
228 return (
PIX *)ERROR_PTR_1(
"image not returned",
229 filename, __func__, NULL);
250pixReadStreamJp2k(FILE *fp,
261 return (
PIX *)ERROR_PTR(
"fp not defined", __func__, NULL);
266 if ((data = l_binaryReadStream(fp, &size)) == NULL)
267 return (
PIX *)ERROR_PTR(
"data not read", __func__, NULL);
269 pix = pixReadMemJp2k(data, size, reduction, box, hint, debug);
277pixReadMemJp2kCore(
const l_uint8 *bytes,
284const char *opjVersion;
285l_int32 i, j, index, bx, by, bw, bh, val, rval, gval, bval, aval;
286l_int32 w, h, wpl, bps, spp, xres, yres, reduce, prec, colorspace;
289l_uint32 *data, *line;
290opj_dparameters_t parameters;
291opj_image_t *image = NULL;
292opj_codec_t *l_codec = NULL;
293opj_stream_t *l_stream = NULL;
297 opjVersion = opj_version();
298 if (!opjVersion || opjVersion[0] ==
'\0')
299 return (
PIX *)ERROR_PTR(
"opj version not defined", __func__, NULL);
300 if (opjVersion[0] - 0x30 < 2 ||
301 (opjVersion[0] ==
'2' && opjVersion[2] - 0x30 == 0)) {
302 L_ERROR(
"version is %s; must be 2.1 or higher\n", __func__, opjVersion);
307 readResolutionMemJp2k(bytes, nbytes, &xres, &yres);
308 readHeaderMemJp2k(bytes, nbytes, NULL, NULL, &bps, NULL, &codec);
310 L_ERROR(
"valid codec not identified\n", __func__);
315 L_ERROR(
"found %d bps; can only handle 8 bps\n", __func__, bps);
320 opj_set_default_decoder_parameters(¶meters);
327 for (reduce = 0; (1L << reduce) < reduction; reduce++) { }
328 if ((1L << reduce) != reduction) {
329 L_ERROR(
"invalid reduction %d; not power of 2\n", __func__, reduction);
332 parameters.cp_reduce = reduce;
336 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
338 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
340 L_ERROR(
"failed to make the codec\n", __func__);
346 opj_set_info_handler(l_codec, info_callback, NULL);
347 opj_set_warning_handler(l_codec, warning_callback, NULL);
348 opj_set_error_handler(l_codec, error_callback, NULL);
352 if (!opj_setup_decoder(l_codec, ¶meters)){
353 L_ERROR(
"failed to set up decoder\n", __func__);
354 opj_destroy_codec(l_codec);
359 buffer.data = (l_uint8 *)bytes;
360 buffer.size = nbytes;
363 if ((l_stream = opjCreateMemoryStream(&buffer, 1)) == NULL) {
364 L_ERROR(
"failed to open the stream\n", __func__);
365 opj_destroy_codec(l_codec);
371 if(!opj_read_header(l_stream, l_codec, &image)){
372 L_ERROR(
"failed to read the header\n", __func__);
373 opj_stream_destroy(l_stream);
374 opj_destroy_codec(l_codec);
375 opj_image_destroy(image);
381 boxGetGeometry(box, &bx, &by, &bw, &bh);
382 if (!opj_set_decode_area(l_codec, image, bx, by,
384 L_ERROR(
"failed to set the region for decoding\n", __func__);
385 opj_stream_destroy(l_stream);
386 opj_destroy_codec(l_codec);
387 opj_image_destroy(image);
393 if (!(opj_decode(l_codec, l_stream, image) &&
394 opj_end_decompress(l_codec, l_stream))) {
395 L_ERROR(
"failed to decode the image\n", __func__);
396 opj_destroy_codec(l_codec);
397 opj_stream_destroy(l_stream);
398 opj_image_destroy(image);
403 opj_stream_destroy(l_stream);
404 opj_destroy_codec(l_codec);
407 spp = image->numcomps;
408 w = image->comps[0].w;
409 h = image->comps[0].h;
410 prec = image->comps[0].prec;
412 L_WARNING(
"precision %d != bps %d!\n", __func__, prec, bps);
414 L_INFO(
"w = %d, h = %d, bps = %d, spp = %d\n",
415 __func__, w, h, bps, spp);
416 colorspace = image->color_space;
417 if (colorspace == OPJ_CLRSPC_SRGB)
418 L_INFO(
"colorspace is sRGB\n", __func__);
419 else if (colorspace == OPJ_CLRSPC_GRAY)
420 L_INFO(
"colorspace is grayscale\n", __func__);
421 else if (colorspace == OPJ_CLRSPC_SYCC)
422 L_INFO(
"colorspace is YUV\n", __func__);
427 pix = pixCreate(w, h, 8);
429 pix = pixCreate(w, h, 32);
430 pixSetInputFormat(pix, IFF_JP2);
431 pixSetResolution(pix, xres, yres);
432 data = pixGetData(pix);
433 wpl = pixGetWpl(pix);
436 for (i = 0; i < h; i++) {
437 line = data + i * wpl;
438 for (j = 0; j < w; j++) {
439 val = image->comps[0].data[index];
444 }
else if (spp == 2) {
445 for (i = 0; i < h; i++) {
446 line = data + i * wpl;
447 for (j = 0; j < w; j++) {
448 val = image->comps[0].data[index];
449 aval = image->comps[1].data[index];
450 composeRGBAPixel(val, val, val, aval, &pixel);
455 }
else if (spp >= 3) {
456 for (i = 0; i < h; i++) {
457 line = data + i * wpl;
458 for (j = 0; j < w; j++) {
459 rval = image->comps[0].data[index];
460 gval = image->comps[1].data[index];
461 bval = image->comps[2].data[index];
463 composeRGBPixel(rval, gval, bval, &pixel);
465 aval = image->comps[3].data[index];
466 composeRGBAPixel(rval, gval, bval, aval, &pixel);
475 opj_image_destroy(image);
521pixWriteJp2k(
const char *filename,
531 return ERROR_INT(
"pix not defined", __func__, 1);
533 return ERROR_INT(
"filename not defined", __func__, 1);
535 if ((fp = fopenWriteStream(filename,
"wb+")) == NULL)
536 return ERROR_INT_1(
"stream not opened", filename, __func__, 1);
538 if (pixWriteStreamJp2k(fp, pix, quality, nlevels,
L_JP2_CODEC,
541 return ERROR_INT_1(
"pix not written to stream", filename, __func__, 1);
566pixWriteOpjStreamJp2k(opj_stream_t *l_stream,
574l_int32 i, w, h, d, depth, channels, success;
576const char *opjVersion;
578opj_cparameters_t parameters;
579opj_codec_t* l_codec = NULL;;
580opj_image_t *image = NULL;
583 return ERROR_INT(
"stream not open", __func__, 1);
585 return ERROR_INT(
"pix not defined", __func__, 1);
587 snr = (l_float64)quality;
588 if (snr <= 0.0) snr = 34.0;
590 L_WARNING(
"SNR = %d < 27; very low\n", __func__, (l_int32)snr);
591 if (snr == 100.0) snr = 0.0;
593 L_WARNING(
"SNR > 45; using lossless encoding\n", __func__);
597 if (nlevels == 0) nlevels = 6;
599 L_WARNING(
"nlevels = %d < 6; setting to 6\n", __func__, nlevels);
603 L_WARNING(
"nlevels = %d > 7; setting to 7\n", __func__, nlevels);
608 return ERROR_INT(
"valid codec not identified\n", __func__, 1);
610 opjVersion = opj_version();
611 if (!opjVersion || opjVersion[0] ==
'\0')
612 return ERROR_INT(
"opj version not defined", __func__, 1);
613 if (opjVersion[0] - 0x30 < 2 ||
614 (opjVersion[0] ==
'2' && opjVersion[2] - 0x30 == 0)) {
615 L_ERROR(
"version is %s; must be 2.1 or higher\n", __func__, opjVersion);
620 pixGetDimensions(pix, &w, &h, &d);
622 pixs = pixConvert24To32(pix);
623 }
else if (d == 32) {
624 pixs = pixClone(pix);
625 }
else if (pixGetColormap(pix) == NULL) {
626 pixs = pixConvertTo8(pix, 0);
628 L_INFO(
"removing colormap; may be better to compress losslessly\n",
632 depth = pixGetDepth(pixs);
635 for (i = 1; i < 7; i++) {
636 if ((w < (1 << i)) || (h < (1 << i))) {
638 L_INFO(
"small image: w = %d, h = %d; setting nlevels to %d\n",
647 pixSetPadBits(pixs, 0);
648 image = pixConvertToOpjImage(pixs);
653 opj_set_default_encoder_parameters(¶meters);
654 parameters.cp_fixed_quality = 1;
655 parameters.cp_disto_alloc = 0;
656 parameters.tcp_distoratio[0] = snr;
657 parameters.tcp_numlayers = 1;
658 parameters.numresolution = nlevels;
659 channels = (depth == 32) ? 3 : 1;
660 parameters.tcp_mct = (channels == 3) ? 1 : 0;
663 if (parameters.cp_comment == NULL) {
664 const char comment1[] =
"Created by Leptonica, version ";
665 const char comment2[] =
"; using OpenJPEG, version ";
666 size_t len1 = strlen(comment1);
667 size_t len2 = strlen(comment2);
668 char *version1 = getLeptonicaVersion();
669 const char *version2 = opj_version();
670 len1 += len2 + strlen(version1) + strlen(version2) + 1;
671 parameters.cp_comment = (
char *)LEPT_MALLOC(len1);
672 snprintf(parameters.cp_comment, len1,
"%s%s%s%s", comment1, version1,
679 l_codec = opj_create_compress(OPJ_CODEC_JP2);
681 l_codec = opj_create_compress(OPJ_CODEC_J2K);
683 opj_image_destroy(image);
684 LEPT_FREE(parameters.cp_comment);
685 return ERROR_INT(
"failed to get the encoder handle\n", __func__, 1);
690 opj_set_info_handler(l_codec, info_callback, NULL);
691 opj_set_warning_handler(l_codec, warning_callback, NULL);
692 opj_set_error_handler(l_codec, error_callback, NULL);
696 if (!opj_setup_encoder(l_codec, ¶meters, image)) {
697 opj_destroy_codec(l_codec);
698 opj_image_destroy(image);
699 LEPT_FREE(parameters.cp_comment);
700 return ERROR_INT(
"failed to set up the encoder\n", __func__, 1);
706 if (!opj_start_compress(l_codec, image, l_stream)) {
707 opj_destroy_codec(l_codec);
708 opj_image_destroy(image);
709 LEPT_FREE(parameters.cp_comment);
710 return ERROR_INT(
"opj_start_compress failed\n", __func__, 1);
712 if (!opj_encode(l_codec, l_stream)) {
713 opj_destroy_codec(l_codec);
714 opj_image_destroy(image);
715 LEPT_FREE(parameters.cp_comment);
716 return ERROR_INT(
"opj_encode failed\n", __func__, 1);
718 success = opj_end_compress(l_codec, l_stream);
721 opj_destroy_codec(l_codec);
722 opj_image_destroy(image);
723 LEPT_FREE(parameters.cp_comment);
727 return ERROR_INT(
"opj_end_compress failed\n", __func__, 1);
750pixWriteStreamJp2k(FILE *fp,
759opj_stream_t *l_stream;
762 return ERROR_INT(
"stream not open", __func__, 1);
768 if ((l_stream = opjCreateStream(fp, 0)) == NULL)
769 return ERROR_INT(
"failed to open l_stream\n", __func__, 1);
771 ok = pixWriteOpjStreamJp2k(l_stream, pix, quality, nlevels,
775 opj_stream_destroy(l_stream);
793pixConvertToOpjImage(
PIX *pix)
795l_int32 i, j, k, w, h, d, spp, wpl;
796OPJ_COLOR_SPACE colorspace;
801l_uint32 *line, *data;
803opj_image_cmptparm_t cmptparm[4];
806 return (opj_image_t *)ERROR_PTR(
"pix not defined", __func__, NULL);
807 pixGetDimensions(pix, &w, &h, &d);
808 if (d != 8 && d != 32) {
809 L_ERROR(
"invalid depth: %d\n", __func__, d);
814 spp = pixGetSpp(pix);
815 memset(&cmptparm[0], 0, 4 *
sizeof(opj_image_cmptparm_t));
816 for (i = 0; i < spp; i++) {
817 cmptparm[i].prec = 8;
818 cmptparm[i].sgnd = 0;
824 colorspace = (spp == 1) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
825 if ((image = opj_image_create(spp, &cmptparm[0], colorspace)) == NULL)
826 return (opj_image_t *)ERROR_PTR(
"image not made", __func__, NULL);
833 ir = image->comps[0].data;
835 ig = image->comps[1].data;
836 ib = image->comps[2].data;
839 ia = image->comps[3].data;
842 data = pixGetData(pix);
843 wpl = pixGetWpl(pix);
844 for (i = 0, k = 0; i < h; i++) {
845 line = data + i * wpl;
846 for (j = 0; j < w; j++, k++) {
849 }
else if (spp > 1) {
883pixReadMemJp2k(
const l_uint8 *data,
893 return (
PIX *)ERROR_PTR(
"data not defined", __func__, NULL);
895 pix = pixReadMemJp2kCore(data, size, reduction, box, hint, debug);
896 if (!pix) L_ERROR(
"pix not read\n", __func__);
920pixWriteMemJp2k(l_uint8 **pdata,
929opj_stream_t *l_stream;
932 if (pdata) *pdata = NULL;
933 if (psize) *psize = 0;
935 return ERROR_INT(
"&data not defined", __func__, 1 );
937 return ERROR_INT(
"&size not defined", __func__, 1 );
939 return ERROR_INT(
"&pix not defined", __func__, 1 );
943 buffer.size = OPJ_J2K_STREAM_CHUNK_SIZE;
944 buffer.data = (l_uint8 *)LEPT_MALLOC(buffer.size);
946 return ERROR_INT(
"failed to allocate buffer", __func__, 1 );
948 if ((l_stream = opjCreateMemoryStream(&buffer, 0)) == NULL) {
949 return ERROR_INT(
"failed to open l_stream\n", __func__, 1);
952 ok = pixWriteOpjStreamJp2k(l_stream, pix, quality, nlevels,
L_JP2_CODEC,
956 opj_stream_destroy(l_stream);
959 *pdata = buffer.data;
962 LEPT_FREE(buffer.data);
973opj_read_from_buffer(
void *p_buffer, OPJ_SIZE_T p_nb_bytes, OpjBuffer *pbuf) {
974 if (pbuf->pos > pbuf->len)
975 return (OPJ_SIZE_T) - 1;
977 OPJ_SIZE_T l_nb_read = pbuf->len - pbuf->pos;
978 if (l_nb_read > p_nb_bytes)
979 l_nb_read = p_nb_bytes;
980 memcpy(p_buffer, pbuf->data + pbuf->pos, l_nb_read);
981 pbuf->pos += l_nb_read;
982 return l_nb_read ? l_nb_read : (OPJ_SIZE_T) - 1;
986opj_write_from_buffer(
const void *p_buffer, OPJ_SIZE_T p_nb_bytes,
988 size_t newpos = pbuf->pos + p_nb_bytes;
989 if (newpos > pbuf->size) {
990 size_t oldsize = pbuf->size;
991 size_t newsize = oldsize * 2;
992 if (newsize < newpos)
995 L_ERROR(
"buffer too large\n", __func__);
999 l_uint8 *newdata = (l_uint8 *)LEPT_REALLOC(pbuf->data, newsize);
1001 L_ERROR(
"out of memory\n", __func__);
1006 memset(newdata + oldsize, 0, newsize - oldsize);
1007 pbuf->data = newdata;
1008 pbuf->size = newsize;
1011 memcpy(pbuf->data + pbuf->pos, p_buffer, p_nb_bytes);
1013 if (pbuf->len < newpos)
1019opj_skip_from_buffer(OPJ_OFF_T offset, OpjBuffer *pbuf) {
1020 pbuf->pos += offset;
1025opj_seek_from_buffer(OPJ_OFF_T offset, OpjBuffer *pbuf) {
1034static opj_stream_t *
1035opjCreateMemoryStream(OpjBuffer *pbuf,
1036 l_int32 is_read_stream)
1038opj_stream_t *l_stream;
1041 return (opj_stream_t *)ERROR_PTR(
"pbuf not defined", __func__, NULL);
1043 l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, is_read_stream);
1045 return (opj_stream_t *)ERROR_PTR(
"stream not made", __func__, NULL);
1047 opj_stream_set_user_data(l_stream, pbuf,
1048 (opj_stream_free_user_data_fn)NULL);
1049 opj_stream_set_user_data_length(l_stream, pbuf->len);
1050 opj_stream_set_read_function(l_stream,
1051 (opj_stream_read_fn)opj_read_from_buffer);
1052 opj_stream_set_skip_function(l_stream,
1053 (opj_stream_skip_fn)opj_skip_from_buffer);
1054 opj_stream_set_seek_function(l_stream,
1055 (opj_stream_seek_fn)opj_seek_from_buffer);
1060 opj_stream_set_write_function(l_stream,
1061 (opj_stream_write_fn)opj_write_from_buffer);
1070opj_get_user_data_length(FILE *fp) {
1071 OPJ_OFF_T length = 0;
1072 fseek(fp, 0, SEEK_END);
1073 length = (OPJ_OFF_T)ftell(fp);
1074 fseek(fp, 0, SEEK_SET);
1075 return (l_uint64)length;
1079opj_read_from_file(
void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *fp) {
1080 OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, fp);
1081 return l_nb_read ? l_nb_read : (OPJ_SIZE_T) - 1;
1085opj_write_from_file(
void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *fp)
1087 return fwrite(p_buffer, 1, p_nb_bytes, fp);
1091opj_skip_from_file(OPJ_OFF_T offset, FILE *fp) {
1092 if (fseek(fp, offset, SEEK_CUR)) {
1099opj_seek_from_file(OPJ_OFF_T offset, FILE *fp) {
1100 if (fseek(fp, offset, SEEK_SET)) {
1110static opj_stream_t *
1111opjCreateStream(FILE *fp,
1112 l_int32 is_read_stream)
1114opj_stream_t *l_stream;
1117 return (opj_stream_t *)ERROR_PTR(
"fp not defined", __func__, NULL);
1119 l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, is_read_stream);
1121 return (opj_stream_t *)ERROR_PTR(
"stream not made", __func__, NULL);
1123 opj_stream_set_user_data(l_stream, fp,
1124 (opj_stream_free_user_data_fn)NULL);
1125 opj_stream_set_user_data_length(l_stream, opj_get_user_data_length(fp));
1126 opj_stream_set_read_function(l_stream,
1127 (opj_stream_read_fn)opj_read_from_file);
1128 opj_stream_set_write_function(l_stream,
1129 (opj_stream_write_fn)opj_write_from_file);
1130 opj_stream_set_skip_function(l_stream,
1131 (opj_stream_skip_fn)opj_skip_from_file);
1132 opj_stream_set_seek_function(l_stream,
1133 (opj_stream_seek_fn)opj_seek_from_file);
#define GET_DATA_BYTE(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
@ REMOVE_CMAP_BASED_ON_SRC