103 #include "config_auto.h" 107 #include "allheaders.h" 114 #ifdef LIBJP2K_HEADER 115 #include LIBJP2K_HEADER 117 #include <openjpeg.h> 121 #ifndef OPJ_VERSION_MINOR 122 #define OPJ_VERSION_MINOR 0 131 static opj_stream_t *opjCreateStream(FILE *fp, l_int32 is_read);
135 static opj_image_t *pixConvertToOpjImage(
PIX *
pix);
140 static void error_callback(
const char *msg,
void *client_data) {
142 fprintf(stdout,
"[ERROR] %s", msg);
145 static void warning_callback(
const char *msg,
void *client_data) {
147 fprintf(stdout,
"[WARNING] %s", msg);
150 static void info_callback(
const char *msg,
void *client_data) {
152 fprintf(stdout,
"[INFO] %s", msg);
199 pixReadJp2k(
const char *filename,
208 PROCNAME(
"pixReadJp2k");
211 return (
PIX *)ERROR_PTR(
"filename not defined", procName, NULL);
214 return (
PIX *)ERROR_PTR(
"image file not found", procName, NULL);
215 pix = pixReadStreamJp2k(fp, reduction, box, hint, debug);
219 return (
PIX *)ERROR_PTR(
"image not returned", procName, NULL);
240 pixReadStreamJp2k(FILE *fp,
246 const char *opjVersion;
247 l_int32 i, j, index, bx, by, bw, bh, val, rval, gval, bval, aval;
248 l_int32
w,
h, wpl, bps, spp, xres, yres, reduce, prec, colorspace;
250 l_uint32 *data, *line;
251 opj_dparameters_t parameters;
252 opj_image_t *image = NULL;
253 opj_codec_t *l_codec = NULL;
254 opj_stream_t *l_stream = NULL;
257 PROCNAME(
"pixReadStreamJp2k");
260 return (
PIX *)ERROR_PTR(
"fp not defined", procName, NULL);
262 opjVersion = opj_version();
263 if (opjVersion[0] !=
'2') {
264 L_ERROR(
"version is %s; must be 2.0 or higher\n", procName, opjVersion);
267 if ((opjVersion[2] - 0x30) != OPJ_VERSION_MINOR) {
268 L_ERROR(
"version %s: differs from minor = %d\n",
269 procName, opjVersion, OPJ_VERSION_MINOR);
275 fgetJp2kResolution(fp, &xres, &yres);
280 L_ERROR(
"found %d bps; can only handle 8 bps\n", procName, bps);
285 opj_set_default_decoder_parameters(¶meters);
292 for (reduce = 0; (1L << reduce) < reduction; reduce++) { }
293 if ((1L << reduce) != reduction) {
294 L_ERROR(
"invalid reduction %d; not power of 2\n", procName, reduction);
297 parameters.cp_reduce = reduce;
300 if ((l_codec = opj_create_decompress(OPJ_CODEC_JP2)) == NULL) {
301 L_ERROR(
"failed to make the codec\n", procName);
307 opj_set_info_handler(l_codec, info_callback, NULL);
308 opj_set_warning_handler(l_codec, warning_callback, NULL);
309 opj_set_error_handler(l_codec, error_callback, NULL);
313 if (!opj_setup_decoder(l_codec, ¶meters)){
314 L_ERROR(
"failed to set up decoder\n", procName);
315 opj_destroy_codec(l_codec);
322 if ((l_stream = opjCreateStream(fp, 1)) == NULL) {
323 L_ERROR(
"failed to open the stream\n", procName);
324 opj_destroy_codec(l_codec);
330 if(!opj_read_header(l_stream, l_codec, &image)){
331 L_ERROR(
"failed to read the header\n", procName);
332 opj_stream_destroy(l_stream);
333 opj_destroy_codec(l_codec);
334 opj_image_destroy(image);
341 if (!opj_set_decode_area(l_codec, image, bx, by,
343 L_ERROR(
"failed to set the region for decoding\n", procName);
344 opj_stream_destroy(l_stream);
345 opj_destroy_codec(l_codec);
346 opj_image_destroy(image);
352 if (!(opj_decode(l_codec, l_stream, image) &&
353 opj_end_decompress(l_codec, l_stream))) {
354 L_ERROR(
"failed to decode the image\n", procName);
355 opj_destroy_codec(l_codec);
356 opj_stream_destroy(l_stream);
357 opj_image_destroy(image);
362 opj_stream_destroy(l_stream);
363 opj_destroy_codec(l_codec);
366 spp = image->numcomps;
367 w = image->comps[0].w;
368 h = image->comps[0].h;
369 prec = image->comps[0].prec;
371 L_WARNING(
"precision %d != bps %d!\n", procName, prec, bps);
373 L_INFO(
"w = %d, h = %d, bps = %d, spp = %d\n",
374 procName,
w,
h, bps, spp);
375 colorspace = image->color_space;
376 if (colorspace == OPJ_CLRSPC_SRGB)
377 L_INFO(
"colorspace is sRGB\n", procName);
378 else if (colorspace == OPJ_CLRSPC_GRAY)
379 L_INFO(
"colorspace is grayscale\n", procName);
380 else if (colorspace == OPJ_CLRSPC_SYCC)
381 L_INFO(
"colorspace is YUV\n", procName);
389 pixSetInputFormat(
pix, IFF_JP2);
392 wpl = pixGetWpl(
pix);
395 for (i = 0; i <
h; i++) {
396 line = data + i * wpl;
397 for (j = 0; j <
w; j++) {
398 val = image->comps[0].data[index];
403 }
else if (spp == 2) {
404 for (i = 0; i <
h; i++) {
405 line = data + i * wpl;
406 for (j = 0; j <
w; j++) {
407 val = image->comps[0].data[index];
408 aval = image->comps[1].data[index];
414 }
else if (spp >= 3) {
415 for (i = 0; i <
h; i++) {
416 line = data + i * wpl;
417 for (j = 0; j <
w; j++) {
418 rval = image->comps[0].data[index];
419 gval = image->comps[1].data[index];
420 bval = image->comps[2].data[index];
424 aval = image->comps[3].data[index];
434 opj_image_destroy(image);
472 pixWriteJp2k(
const char *filename,
481 PROCNAME(
"pixWriteJp2k");
484 return ERROR_INT(
"pix not defined", procName, 1);
486 return ERROR_INT(
"filename not defined", procName, 1);
489 return ERROR_INT(
"stream not opened", procName, 1);
491 if (pixWriteStreamJp2k(fp,
pix, quality, nlevels, hint, debug)) {
493 return ERROR_INT(
"pix not written to stream", procName, 1);
519 pixWriteStreamJp2k(FILE *fp,
526 l_int32
w,
h, d, success, snr;
527 const char *opjVersion;
529 opj_cparameters_t parameters;
530 opj_stream_t *l_stream = NULL;
531 opj_codec_t* l_codec = NULL;;
532 opj_image_t *image = NULL;
534 PROCNAME(
"pixWriteStreamJp2k");
537 return ERROR_INT(
"stream not open", procName, 1);
539 return ERROR_INT(
"pix not defined", procName, 1);
541 return ERROR_INT(
"quality must be >= 0", procName, 1);
542 if (quality > 0 && quality < 27)
543 L_WARNING(
"SNR = %d < 27; very low\n", procName, quality);
545 L_WARNING(
"SNR = %d > 45; nearly lossless\n", procName, quality);
546 snr = (l_float32)quality;
548 if (nlevels <= 0) nlevels = 5;
550 L_WARNING(
"nlevels = %d > 10; setting to 10\n", procName, nlevels);
554 opjVersion = opj_version();
555 if (opjVersion[0] !=
'2') {
556 L_ERROR(
"version is %s; must be 2.0 or higher\n", procName, opjVersion);
559 if ((opjVersion[2] - 0x30) != OPJ_VERSION_MINOR) {
560 L_ERROR(
"version %s: differs from minor = %d\n",
561 procName, opjVersion, OPJ_VERSION_MINOR);
569 }
else if (d == 32) {
571 }
else if (pixGetColormap(
pix) == NULL) {
574 L_INFO(
"removing colormap; may be better to compress losslessly\n",
581 image = pixConvertToOpjImage(pixs);
586 opj_set_default_encoder_parameters(¶meters);
587 parameters.cp_fixed_quality = 1;
588 parameters.cp_disto_alloc = 0;
589 parameters.cp_fixed_alloc = 0;
590 parameters.tcp_distoratio[0] = snr;
591 parameters.tcp_numlayers = 1;
592 parameters.numresolution = nlevels + 1;
595 if (parameters.cp_comment == NULL) {
596 const char comment1[] =
"Created by Leptonica, version ";
597 const char comment2[] =
"; using OpenJPEG, version ";
598 size_t len1 = strlen(comment1);
599 size_t len2 = strlen(comment2);
601 const char *version2 = opj_version();
602 len1 += len2 + strlen(version1) + strlen(version2) + 1;
603 parameters.cp_comment = (
char *)LEPT_MALLOC(len1);
604 snprintf(parameters.cp_comment, len1,
"%s%s%s%s", comment1, version1,
610 if ((l_codec = opj_create_compress(OPJ_CODEC_JP2)) == NULL) {
611 opj_image_destroy(image);
612 LEPT_FREE(parameters.cp_comment);
613 return ERROR_INT(
"failed to get the encoder handle\n", procName, 1);
618 opj_set_info_handler(l_codec, info_callback, NULL);
619 opj_set_warning_handler(l_codec, warning_callback, NULL);
620 opj_set_error_handler(l_codec, error_callback, NULL);
624 if (!opj_setup_encoder(l_codec, ¶meters, image)) {
625 opj_destroy_codec(l_codec);
626 opj_image_destroy(image);
627 LEPT_FREE(parameters.cp_comment);
628 return ERROR_INT(
"failed to set up the encoder\n", procName, 1);
635 if ((l_stream = opjCreateStream(fp, 0)) == NULL) {
636 opj_destroy_codec(l_codec);
637 opj_image_destroy(image);
638 LEPT_FREE(parameters.cp_comment);
639 return ERROR_INT(
"failed to open l_stream\n", procName, 1);
643 if (!opj_start_compress(l_codec, image, l_stream)) {
644 opj_stream_destroy(l_stream);
645 opj_destroy_codec(l_codec);
646 opj_image_destroy(image);
647 LEPT_FREE(parameters.cp_comment);
648 return ERROR_INT(
"opj_start_compress failed\n", procName, 1);
650 if (!opj_encode(l_codec, l_stream)) {
651 opj_stream_destroy(l_stream);
652 opj_destroy_codec(l_codec);
653 opj_image_destroy(image);
654 LEPT_FREE(parameters.cp_comment);
655 return ERROR_INT(
"opj_encode failed\n", procName, 1);
657 success = opj_end_compress(l_codec, l_stream);
660 opj_stream_destroy(l_stream);
661 opj_destroy_codec(l_codec);
662 opj_image_destroy(image);
663 LEPT_FREE(parameters.cp_comment);
667 return ERROR_INT(
"opj_end_compress failed\n", procName, 1);
684 pixConvertToOpjImage(
PIX *
pix)
686 l_int32 i, j, k,
w,
h, d, spp, wpl;
687 OPJ_COLOR_SPACE colorspace;
692 l_uint32 *line, *data;
694 opj_image_cmptparm_t cmptparm[4];
696 PROCNAME(
"pixConvertToOpjImage");
699 return (opj_image_t *)ERROR_PTR(
"pix not defined", procName, NULL);
701 if (d != 8 && d != 32) {
702 L_ERROR(
"invalid depth: %d\n", procName, d);
707 spp = pixGetSpp(
pix);
708 memset(&cmptparm[0], 0, 4 *
sizeof(opj_image_cmptparm_t));
709 for (i = 0; i < spp; i++) {
710 cmptparm[i].prec = 8;
712 cmptparm[i].sgnd = 0;
718 colorspace = (spp == 1) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
719 if ((image = opj_image_create(spp, &cmptparm[0], colorspace)) == NULL)
720 return (opj_image_t *)ERROR_PTR(
"image not made", procName, NULL);
727 ir = image->comps[0].data;
729 ig = image->comps[1].data;
730 ib = image->comps[2].data;
733 ia = image->comps[3].data;
737 wpl = pixGetWpl(
pix);
738 for (i = 0, k = 0; i <
h; i++) {
739 line = data + i * wpl;
740 for (j = 0; j <
w; j++, k++) {
743 }
else if (spp > 1) {
782 pixReadMemJp2k(
const l_uint8 *data,
792 PROCNAME(
"pixReadMemJp2k");
795 return (
PIX *)ERROR_PTR(
"data not defined", procName, NULL);
798 return (
PIX *)ERROR_PTR(
"stream not opened", procName, NULL);
799 pix = pixReadStreamJp2k(fp, reduction, box, hint, debug);
801 if (!
pix) L_ERROR(
"pix not read\n", procName);
825 pixWriteMemJp2k(l_uint8 **pdata,
836 PROCNAME(
"pixWriteMemJp2k");
838 if (pdata) *pdata = NULL;
839 if (psize) *psize = 0;
841 return ERROR_INT(
"&data not defined", procName, 1 );
843 return ERROR_INT(
"&size not defined", procName, 1 );
845 return ERROR_INT(
"&pix not defined", procName, 1 );
848 if ((fp = open_memstream((
char **)pdata, psize)) == NULL)
849 return ERROR_INT(
"stream not opened", procName, 1);
850 ret = pixWriteStreamJp2k(fp,
pix, quality, nlevels, hint, debug);
852 L_INFO(
"work-around: writing to a temp file\n", procName);
855 return ERROR_INT(
"tmpfile stream not opened", procName, 1);
857 if ((fp = tmpfile()) == NULL)
858 return ERROR_INT(
"tmpfile stream not opened", procName, 1);
860 ret = pixWriteStreamJp2k(fp,
pix, quality, nlevels, hint, debug);
873 opj_get_user_data_length(FILE *fp) {
874 OPJ_OFF_T length = 0;
875 fseek(fp, 0, SEEK_END);
876 length = (OPJ_OFF_T)ftell(fp);
877 fseek(fp, 0, SEEK_SET);
878 return (l_uint64)length;
882 opj_read_from_file(
void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *fp) {
883 OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, fp);
884 return l_nb_read ? l_nb_read : (OPJ_SIZE_T) - 1;
888 opj_write_from_file(
void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *fp)
890 return fwrite(p_buffer, 1, p_nb_bytes, fp);
894 opj_skip_from_file(OPJ_OFF_T offset, FILE *fp) {
895 if (fseek(fp, offset, SEEK_CUR)) {
902 opj_seek_from_file(OPJ_OFF_T offset, FILE *fp) {
903 if (fseek(fp, offset, SEEK_SET)) {
910 static opj_stream_t *
911 opjCreateStream(FILE *fp,
912 l_int32 is_read_stream)
914 opj_stream_t *l_stream;
916 PROCNAME(
"opjCreateStream");
919 return (opj_stream_t *)ERROR_PTR(
"fp not defined", procName, NULL);
921 l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, is_read_stream);
923 return (opj_stream_t *)ERROR_PTR(
"stream not made", procName, NULL);
925 #if OPJ_VERSION_MINOR == 0 926 opj_stream_set_user_data(l_stream, fp);
928 opj_stream_set_user_data(l_stream, fp,
929 (opj_stream_free_user_data_fn)NULL);
931 opj_stream_set_user_data_length(l_stream, opj_get_user_data_length(fp));
932 opj_stream_set_read_function(l_stream,
933 (opj_stream_read_fn)opj_read_from_file);
934 opj_stream_set_write_function(l_stream,
935 (opj_stream_write_fn)opj_write_from_file);
936 opj_stream_set_skip_function(l_stream,
937 (opj_stream_skip_fn)opj_skip_from_file);
938 opj_stream_set_seek_function(l_stream,
939 (opj_stream_seek_fn)opj_seek_from_file);
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
PIX * pixConvert24To32(PIX *pixs)
pixConvert24To32()
char * getLeptonicaVersion()
getLeptonicaVersion()
l_ok composeRGBAPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_int32 aval, l_uint32 *ppixel)
composeRGBAPixel()
#define SET_DATA_BYTE(pdata, n, val)
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
#define GET_DATA_BYTE(pdata, n)
PIX * pixClone(PIX *pixs)
pixClone()
void pixDestroy(PIX **ppix)
pixDestroy()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
FILE * fopenReadStream(const char *filename)
fopenReadStream()
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
l_ok pixSetResolution(PIX *pix, l_int32 xres, l_int32 yres)
pixSetResolution()
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()