diff --git a/CMakeLists.txt b/CMakeLists.txt index 441680be..844e4b51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,9 @@ if(USE_PNG) find_package(ZLIB REQUIRED) find_package(PkgConfig REQUIRED) find_package(PNG REQUIRED) + set(PNG_WIDTH_MAX 100000000 CACHE STRING "Default width of PNG grid.") + set(PNG_HEIGHT_MAX 100000 CACHE STRING "Default height of PNG grid.") + message(STATUS "\tWill build with PNG grid width = ${PNG_WIDTH_MAX} and height = ${PNG_HEIGHT_MAX}") else() message(STATUS "Will not build PNG support") endif() diff --git a/src/decenc_png.c b/src/decenc_png.c index a69ab558..754df1ec 100644 --- a/src/decenc_png.c +++ b/src/decenc_png.c @@ -100,7 +100,15 @@ int g2c_dec_png(unsigned char *pngbuf, int *width, int *height, unsigned char *cout) { - return dec_png(pngbuf, (g2int *)&width, (g2int *)&height, cout); + g2int width8 = *width, height8 = *height; + int ret; + + ret = dec_png(pngbuf, &width8, &height8, cout); + + *width = (g2int)width8; + *height = (g2int)height8; + + return ret; } /** @@ -162,6 +170,9 @@ dec_png(unsigned char *pngbuf, g2int *width, g2int *height, /* Set new custom read function. */ png_set_read_fn(png_ptr, (png_voidp)&read_io_ptr, (png_rw_ptr)user_read_data); + /* support for larger grids */ + png_set_user_limits(png_ptr, G2C_PNG_WIDTH_MAX, G2C_PNG_HEIGHT_MAX); + /* Read and decode PNG stream. */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); diff --git a/src/grib2.h.in b/src/grib2.h.in index 3f12474c..d8049c56 100644 --- a/src/grib2.h.in +++ b/src/grib2.h.in @@ -423,6 +423,8 @@ int g2c_param_all(int param_idx, int *g1ver, int *g1val, int *g2disc, int *g2cat #define G2C_JASPER_MAX_MEM @JASPER_MAX_MEM@ /**< Maximum size for the Jasper memory buffer. */ +#define G2C_PNG_WIDTH_MAX @PNG_WIDTH_MAX@ /**< Maximum width of PNG grid */ +#define G2C_PNG_HEIGHT_MAX @PNG_HEIGHT_MAX@ /**< Maximum height of PNG grid */ /* Error codes for G2 API. */ #define G2_NO_ERROR 0 /**< Function succeeded. */ #define G2_CREATE_GRIB_VERSION -1 /**< Wrong GRIB version for g2_create(), must be 2. */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5314f32f..fcffffbc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -72,6 +72,7 @@ set(REF_FILES "gdaswave.t00z.wcoast.0p16.f000.grib2.idx" "ref_testgrib2.grb2.degrib2" "ref_gdaswave_2.grib1.idx" "ref_tst_jasper_warning.txt" + "ref_large_png.grib2" ) # Copy large files if needed. @@ -223,6 +224,7 @@ endif() if(USE_PNG) g2c_test(tst_png) g2c_test(tst_addfield2) + g2c_test(tst_large_png) endif() # Run these tests only if Jasper or OpenJPEG are linked. diff --git a/tests/data/ref_large_png.grib2 b/tests/data/ref_large_png.grib2 new file mode 100644 index 00000000..167d27e9 Binary files /dev/null and b/tests/data/ref_large_png.grib2 differ diff --git a/tests/tst_large_png.c b/tests/tst_large_png.c new file mode 100644 index 00000000..322d2751 --- /dev/null +++ b/tests/tst_large_png.c @@ -0,0 +1,48 @@ +/* This is a test for the NCEPLIBS-g2c project. This test is for + * the PNG decode function on a large test file. + * + * Alyson Stahl 11/21/24 + */ + +#include "grib2_int.h" +#include +#include + +#define TEST_FILE "data/ref_large_png.grib2" + +int +main() +{ + printf("Testing dec_png() on large test file...\n"); + { + float *data; + int g2cid, num_data_points; + int ret = G2C_NOERROR; + + /* Open the data file. */ + if ((ret = g2c_open(TEST_FILE, 0, &g2cid))) + return ret; + + /* Get the size of the data from message 0, product 0. */ + if ((ret = g2c_get_prod(g2cid, 0, 0, &num_data_points, NULL))) + return ret; + + /* Allocate storage for the data. */ + if (!(data = malloc(num_data_points * sizeof(float)))) + return G2C_ERROR; + + /* Get the data from message 0, product 0. */ + if ((ret = g2c_get_prod(g2cid, 0, 0, NULL, data))) + return ret; + + /* Close the data file. */ + if ((ret = g2c_close(g2cid))) + return ret; + + /* Free the memory allocated to hold the data. */ + free(data); + } + printf("ok!\n"); + printf("SUCCESS!\n"); + return 0; +} diff --git a/tests/tst_png.c b/tests/tst_png.c index 434dc427..4a455de8 100644 --- a/tests/tst_png.c +++ b/tests/tst_png.c @@ -67,6 +67,13 @@ main() return G2C_ERROR; } + /* Check that width and height are returned correctly. */ + if (width_in != 1 || height_in != 1) + { + printf("png size mismatch: width = %d, height = %d", width_in, height_in); + return G2C_ERROR; + } + for (i = 0; i < 4; i++) if (cout[i] != data[i]) return G2C_ERROR;