From 90b54e96a44d45dfd95d91e183c50f32f0e9b139 Mon Sep 17 00:00:00 2001 From: AlysonStahl-NOAA <166434581+AlysonStahl-NOAA@users.noreply.github.com> Date: Fri, 1 Nov 2024 13:38:21 -0600 Subject: [PATCH] added g2c_ versions of png and openjpeg enc/dec functions (#545) * added g2c_ functions with int inputs for png and openjpeg enc/dec functions * fixing some inputs * debug * debug * Update tst_png.c * debugging * debugging casting pointers * debug * debugging * more pointer debugging * more debug * Update decenc_png.c * applying requested changes --- src/decenc_openjpeg.c | 72 +++++++++++++++++++++++++++++++++++++++++++ src/decenc_png.c | 41 ++++++++++++++++++++++++ src/grib2.h.in | 4 +++ tests/tst_png.c | 28 +++++++++++++++++ 4 files changed, 145 insertions(+) diff --git a/src/decenc_openjpeg.c b/src/decenc_openjpeg.c index 124d7831..a1097104 100644 --- a/src/decenc_openjpeg.c +++ b/src/decenc_openjpeg.c @@ -236,6 +236,33 @@ opj_stream_create_default_memory_stream(opj_memory_stream *memoryStream, OPJ_BOO return stream; } +/** + * This Function decodes a JPEG2000 code stream specified in the + * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using OpenJPEG. + * + * PROGRAM HISTORY LOG: + * - 2002-12-02 Gilbert + * - 2016-06-08 Jovic + * + * @param injpc Input JPEG2000 code stream. + * @param bufsize Length (in bytes) of the input JPEG2000 code stream. + * @param outfld Output matrix of grayscale image values. + * + * @return + * - 0 Successful decode + * - -3 Error decode jpeg2000 code stream. + * - -5 decoded image had multiple color components. Only grayscale is expected. + * + * @note Requires OpenJPEG Version 2. + * + * @author Alyson Stahl + */ +int +g2c_dec_jpeg2000(char *injpc, size_t bufsize, int *outfld) +{ + return dec_jpeg2000(injpc, bufsize, (g2int *)outfld); +} + /** * This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using OpenJPEG. @@ -342,6 +369,51 @@ dec_jpeg2000(char *injpc, g2int bufsize, g2int *outfld) return iret; } +/** + * 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 OpenJPEG library. + * + * PROGRAM HISTORY LOG: + * - 2002-12-02 Gilbert + * - 2016-06-08 Jovic + * + * @param cin Packed matrix of Grayscale image values to encode. + * @param width width of image + * @param height height of image + * @param nbits depth (in bits) of image.i.e number of bits used to + * hold each data value + * @param ltype indicator of lossless or lossy compression = 1, for + * lossy compression != 1, for lossless compression. + * @param ratio target compression ratio. (ratio:1) Used only when + * ltype == 1. + * @param retry Pointer to option type. 1 = try increasing number of + * guard bits otherwise, no additional options. + * @param outjpc Output encoded JPEG2000 code stream. + * @param jpclen Number of bytes allocated for new JPEG2000 code + * stream in outjpc. + * + * @return + * - > 0 Length in bytes of encoded JPEG2000 code stream + * - -3 Error decode jpeg2000 code stream. + * - -5 decoded image had multiple color components. Only grayscale is expected. + * + * @note Requires OpenJPEG Version 2. + * + * @author Alyson Stahl + */ +int +g2c_enc_jpeg2000(unsigned char *cin, int width, int height, int nbits, + int ltype, int ratio, int retry, char *outjpc, + size_t jpclen) +{ + g2int width8 = width, height8 = height, nbits8 = nbits, ltype8 = ltype; + g2int ratio8 = ratio, retry8 = retry, jpclen8 = jpclen; + + return enc_jpeg2000(cin, width8, height8, nbits8, ltype8, ratio8, retry8, + outjpc, jpclen8); +} + /** * This Function encodes a grayscale image into a JPEG2000 code stream * specified in the JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) diff --git a/src/decenc_png.c b/src/decenc_png.c index 98d7e03c..a69ab558 100644 --- a/src/decenc_png.c +++ b/src/decenc_png.c @@ -84,6 +84,25 @@ user_flush_data(png_structp png_ptr) { } +/** + * Decode PNG. + * + * @param pngbuf Pointer to PNG buffer. + * @param width Pointer to width. + * @param height Pointer to height. + * @param cout Output buffer. + * + * @return 0 for success, error code otherwise. + * + * @author Alyson Stahl + */ +int +g2c_dec_png(unsigned char *pngbuf, int *width, int *height, + unsigned char *cout) +{ + return dec_png(pngbuf, (g2int *)&width, (g2int *)&height, cout); +} + /** * Decode PNG. * @@ -190,6 +209,28 @@ dec_png(unsigned char *pngbuf, g2int *width, g2int *height, return 0; } +/** + * Encode PNG. + * + * @param data data. + * @param width width. + * @param height height. + * @param nbits number of bits. + * @param pngbuf PNG buffer. + * + * @return PNG length, or negative number for error. + * + * @author Alyson Stahl + */ +int +g2c_enc_png(unsigned char *data, int width, int height, int nbits, + unsigned char *pngbuf) +{ + g2int width8 = width, height8 = height, nbits8 = nbits; + + return enc_png(data, width8, height8, nbits8, pngbuf); +} + /** * Encode PNG. * diff --git a/src/grib2.h.in b/src/grib2.h.in index 0f80388d..3f12474c 100644 --- a/src/grib2.h.in +++ b/src/grib2.h.in @@ -376,6 +376,10 @@ int g2c_enc_jpeg2000(unsigned char *cin, int width, int height, int nbits, int ltype, int ratio, int retry, char *outjpc, size_t jpclen); int g2c_dec_jpeg2000(char *injpc, size_t bufsize, int *outfld); +int g2c_enc_png(unsigned char *data, int width, int height, int nbits, + unsigned char *pngbuf); +int g2c_dec_png(unsigned char *pngbuf, int *width, int *height, + unsigned char *cout); int g2c_aecpackf(float *fld, size_t width, size_t height, int *idrstmpl, unsigned char *cpack, size_t *lcpack); int g2c_aecpackd(double *fld, size_t width, size_t height, int *idrstmpl, diff --git a/tests/tst_png.c b/tests/tst_png.c index 370b5a96..434dc427 100644 --- a/tests/tst_png.c +++ b/tests/tst_png.c @@ -44,6 +44,34 @@ main() return G2C_ERROR; } printf("ok!\n"); + printf("Testing g2c_enc_png()/g2c_dec_png() calls..."); + { + unsigned char data[4] = {1, 2, 3, 4}; + int width = 1, height = 1, nbits = 32; + int width_in, height_in; + unsigned char pngbuf[200]; + unsigned char cout[200]; + int i, ret; + + /* Encode some data. */ + if ((ret = g2c_enc_png(data, width, height, nbits, pngbuf)) != 70) + { + printf("%d\n", ret); + return G2C_ERROR; + } + + /* Now decode it. */ + if ((ret = g2c_dec_png((unsigned char *)pngbuf, &width_in, &height_in, cout))) + { + printf("%d\n", ret); + return G2C_ERROR; + } + + for (i = 0; i < 4; i++) + if (cout[i] != data[i]) + return G2C_ERROR; + } + printf("ok!\n"); printf("Testing pngpack()/pngunpack() calls..."); { g2int height = 2, width = 2, ndpts = DATA_LEN, len = PACKED_LEN;