From 6f4d4fbc6cd9979f46849243890bd8fb2eff0da3 Mon Sep 17 00:00:00 2001 From: Edward Hartnett <38856240+edwardhartnett@users.noreply.github.com> Date: Mon, 18 Apr 2022 07:46:50 -0600 Subject: [PATCH] correct usage of jasper by using jas_image_encode()/jas_image_decode() instead of jpc_encode()/jpc_decode(), also initialize and finalize jasper (#250) * using jas_image_encode() instead of jpc_encode() * cleanup and documentation * converted jpc_decode() to jas_image_decode() * cleanup * cleaned up documentation * cleaned up documentation * cleaned up documentation --- src/dec_jpeg2000.c | 43 +++++++++++++++++++++++++++---------------- src/enc_jpeg2000.c | 34 +++++++++++++++++++++++----------- src/grib2.h.in | 5 +++++ src/grib2_int.h | 8 +++++--- 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/dec_jpeg2000.c b/src/dec_jpeg2000.c index ff7480e7..34dcbfa3 100644 --- a/src/dec_jpeg2000.c +++ b/src/dec_jpeg2000.c @@ -11,10 +11,14 @@ /** * This Function decodes a JPEG2000 code stream specified in the - * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer - * Software written by the University of British Columbia and Image - * Power Inc, and others. JasPer is available at - * http://www.ece.uvic.ca/~mdadams/jasper/. + * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using [JasPer + * Software](https://github.com/jasper-software/jasper). + * + * ### Program History Log + * Date | Programmer | Comments + * -----|------------|--------- + * 2002-12-02 | Gilbert | Initial + * 2022-04-15 | Hartnett | Converted to use jas_ instead of jpc_ functions. * * @param injpc Input JPEG2000 code stream. * @param bufsize Length (in bytes) of the input JPEG2000 code stream. @@ -22,11 +26,13 @@ * * @return * - 0 Successful decode - * - -3 Error decode jpeg2000 code stream. - * - -5 decoded image had multiple color components. Only grayscale is - * expected. + * - ::G2_JASPER_DECODE Error decode jpeg2000 code stream. + * - ::G2_JASPER_DECODE_COLOR decoded image had multiple color + * components. Only grayscale is expected. + * - ::G2_JASPER_INIT Error inializing Jasper library. * * @author Stephen Gilbert @date 2002-12-02 + * @author Ed Hartnett */ int dec_jpeg2000(char *injpc, g2int bufsize, g2int *outfld) @@ -37,17 +43,22 @@ dec_jpeg2000(char *injpc, g2int bufsize, g2int *outfld) jas_image_cmpt_t *pcmpt; char *opts = NULL; jas_matrix_t *data; + int fmt; + + /* Initialize Jasper. */ + if (jas_init()) + return G2_JASPER_INIT; /* Create jas_stream_t containing input JPEG200 codestream in * memory. */ jpcstream = jas_stream_memopen(injpc, bufsize); + /* Get jasper ID of JPEG encoder. */ + fmt = jas_image_strtofmt(G2C_JASPER_JPEG_FORMAT_NAME); + /* Decode JPEG200 codestream into jas_image_t structure. */ - if (!(image = jpc_decode(jpcstream, opts))) - { - printf(" jpc_decode return\n"); - return -3; - } + if (!(image = jas_image_decode(jpcstream, fmt, opts))) + return G2_JASPER_DECODE; pcmpt = image->cmpts_[0]; /* @@ -75,10 +86,7 @@ dec_jpeg2000(char *injpc, g2int bufsize, g2int *outfld) /* Expecting jpeg2000 image to be grayscale only. No color components. */ if (image->numcmpts_ != 1) - { - printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); - return -5; - } + return G2_JASPER_DECODE_COLOR; /* Create a data matrix of grayscale image values decoded from the * jpeg2000 codestream. */ @@ -97,5 +105,8 @@ dec_jpeg2000(char *injpc, g2int bufsize, g2int *outfld) jas_stream_close(jpcstream); jas_image_destroy(image); + /* Finalize jasper. */ + jas_cleanup(); + return 0; } diff --git a/src/enc_jpeg2000.c b/src/enc_jpeg2000.c index 7ff584e3..671f691d 100644 --- a/src/enc_jpeg2000.c +++ b/src/enc_jpeg2000.c @@ -13,15 +13,14 @@ /** * This Function encodes a grayscale image into a JPEG2000 code stream * specified in the JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) - * using JasPer Software version 1.500.4 (or 1.700.2) written by the - * University of British Columbia, Image Power Inc, and others. - * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. + * using [JasPer Software](https://github.com/jasper-software/jasper). * * ### Program History Log * Date | Programmer | Comments * -----|------------|--------- * 2002-12-02 | Gilbert | Initial * 2004-12-16 | Gilbert | Added retry argument allowing increased guard bits. + * 2022-04-15 | Hartnett | Converted to use jas_ instead of jpc_ functions. * * @param cin Packed matrix of Grayscale image values to encode. * @param width width of image. @@ -41,11 +40,13 @@ * * @return * - > 0 = Length in bytes of encoded JPEG2000 code stream - * - -3 = Error encode jpeg2000 code stream. + * - ::G2_JASPER_INIT Error initializing jasper library. + * - ::G2_JASPER_ENCODE Error encode jpeg2000 code stream. * * @note Requires JasPer Software version 1.500.4 or 1.700.2 or later. * * @author Stephen Gilbert @date 2002-12-02 + * @author Ed Hartnett */ int enc_jpeg2000(unsigned char *cin, g2int width, g2int height, g2int nbits, @@ -57,6 +58,7 @@ enc_jpeg2000(unsigned char *cin, g2int width, g2int height, g2int nbits, jas_stream_t *jpcstream, *istream; jas_image_cmpt_t cmpt, *pcmpt; char opts[MAXOPTSSIZE]; + int fmt; /* Set lossy compression options, if requested. */ if (ltype != 1) @@ -92,6 +94,10 @@ enc_jpeg2000(unsigned char *cin, g2int width, g2int height, g2int nbits, pcmpt = &cmpt; image.cmpts_ = &pcmpt; + /* Initialize Jasper. */ + if (jas_init()) + return G2_JASPER_INIT; + /* Open a JasPer stream containing the input grayscale values. */ istream = jas_stream_memopen((char *)cin, height * width * cmpt.cps_); cmpt.stream_ = istream; @@ -100,18 +106,24 @@ enc_jpeg2000(unsigned char *cin, g2int width, g2int height, g2int nbits, * code stream. */ jpcstream = jas_stream_memopen(outjpc, (int)jpclen); + /* Get jasper ID of JPEG encoder. */ + fmt = jas_image_strtofmt(G2C_JASPER_JPEG_FORMAT_NAME); + /* Encode image. */ - if ((ier = jpc_encode(&image, jpcstream, opts))) - { - printf(" jpc_encode return = %d \n",ier); - return -3; - } + if ((ier = jas_image_encode(&image, jpcstream, fmt, opts))) + return G2_JASPER_ENCODE; - /* Clean up JasPer work structures. */ + /* Rememeber the length in bytes of the encoded JPEG code + * stream. */ rwcnt = jpcstream->rwcnt_; + + /* Clean up JasPer work structures. */ ier = jas_stream_close(istream); ier = jas_stream_close(jpcstream); + /* Finalize jasper. */ + jas_cleanup(); + /* Return size of jpeg2000 code stream. */ - return (rwcnt); + return rwcnt; } diff --git a/src/grib2.h.in b/src/grib2.h.in index 9b64fb5b..0ac7afd8 100644 --- a/src/grib2.h.in +++ b/src/grib2.h.in @@ -7,6 +7,7 @@ * 2002-10-25 | Gilbert | Initial * 2009-01-14 | Vuong | Changed struct template to gtemplate * 2021-11-9 | Ed Hartnett | Moved many prototypes to new internal header grib2_int.h. + * 2022-04-15 | Ed Hartnett | Added error codes related to JPEG. * * @author Stephen Gilbert @date 2002-10-25 */ @@ -288,6 +289,10 @@ g2int g2_gribend(unsigned char *cgrib); #define G2_ADDGRID_BAD_GDT -5 /**< In g2_addgrid() Could not find requested Grid Definition Template. */ #define G2_JPCUNPACK_MEM 1 /**< In jpcunpack() or other unpack function: out of memory. */ #define G2_SPECUNPACK_TYPE -3 /**< In specunpack() Can't handle 64 or 128 bit floats. */ +#define G2_JASPER_INIT -2 /**< In enc_jpeg2000()/dec_jpeg2000() error initializing jasper library. */ +#define G2_JASPER_ENCODE -3 /**< In enc_jpeg2000() error encoding image with jasper. */ +#define G2_JASPER_DECODE -3 /**< In dec_jpeg2000() error decoding image with jasper. */ +#define G2_JASPER_DECODE_COLOR -5 /**< In dec_jpeg2000() decoded image had multiple color components. */ /* These are the new error codes. */ #define G2C_NO_ERROR 0 /**< No error. */ diff --git a/src/grib2_int.h b/src/grib2_int.h index fd7c8eb0..b3bc2cdc 100644 --- a/src/grib2_int.h +++ b/src/grib2_int.h @@ -20,6 +20,8 @@ #define ALOG2 (0.69314718) /**< ln(2.0) */ +#define G2C_JASPER_JPEG_FORMAT_NAME "jpc" /**< Name of JPEG codec in Jasper. */ + /** * Struct for GRIB template. */ @@ -67,7 +69,7 @@ gtemplate *getgridtemplate(g2int number); gtemplate *extgridtemplate(g2int number, g2int *list); /* Packing and unpacking data. */ -void simpack(g2float *fld, g2int ndpts, g2int *idrstmpl, +void simpack(g2float *fld, g2int ndpts, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack); g2int simunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, g2float *fld); @@ -80,7 +82,7 @@ void misspack(g2float *fld, g2int ndpts, g2int idrsnum, g2int *idrstmpl, void cmplxpack(g2float *fld, g2int ndpts, g2int idrsnum, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack); g2int getpoly(unsigned char *csec3, g2int *jj, g2int *kk, g2int *mm); -void specpack(g2float *fld, g2int ndpts, g2int JJ, g2int KK, g2int MM, +void specpack(g2float *fld, g2int ndpts, g2int JJ, g2int KK, g2int MM, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack); g2int specunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, g2int JJ, g2int KK, g2int MM, g2float *fld); @@ -90,7 +92,7 @@ int enc_png(unsigned char *data, g2int width, g2int height, g2int nbits, unsigned char *pngbuf); int dec_png(unsigned char *pngbuf, g2int *width, g2int *height, unsigned char *cout); -void pngpack(g2float *fld, g2int width, g2int height, g2int *idrstmpl, +void pngpack(g2float *fld, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack); g2int pngunpack(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts, g2float *fld);