diff --git a/libretro-common/formats/png/rpng_decode_common.h b/libretro-common/formats/png/rpng_decode_common.h index a1cda8b186..0ddecfb43a 100644 --- a/libretro-common/formats/png/rpng_decode_common.h +++ b/libretro-common/formats/png/rpng_decode_common.h @@ -90,7 +90,7 @@ static void deinterlace_pass(uint32_t *data, const struct png_ihdr *ihdr, } static bool png_reverse_filter(uint32_t *data, const struct png_ihdr *ihdr, - const uint8_t *inflate_buf, size_t inflate_buf_size, + const uint8_t *inflate_buf, struct rpng_process_t *pngp, const uint32_t *palette) { unsigned i, h; @@ -103,7 +103,7 @@ static bool png_reverse_filter(uint32_t *data, const struct png_ihdr *ihdr, png_pass_geom(ihdr, ihdr->width, ihdr->height, &bpp, &pitch, &pass_size); - if (inflate_buf_size < pass_size) + if (pngp->total_out < pass_size) return false; prev_scanline = (uint8_t*)calloc(1, pitch); @@ -184,7 +184,7 @@ end: static bool png_reverse_filter_adam7(uint32_t *data, const struct png_ihdr *ihdr, - const uint8_t *inflate_buf, size_t inflate_buf_size, + const uint8_t *inflate_buf, struct rpng_process_t *pngp, const uint32_t *palette) { unsigned pass; @@ -227,21 +227,21 @@ static bool png_reverse_filter_adam7(uint32_t *data, png_pass_geom(&tmp_ihdr, pass_width, pass_height, NULL, NULL, &pass_size); - if (pass_size > inflate_buf_size) + if (pass_size > pngp->total_out) { free(tmp_data); return false; } if (!png_reverse_filter(tmp_data, - &tmp_ihdr, inflate_buf, pass_size, palette)) + &tmp_ihdr, inflate_buf, pngp, palette)) { free(tmp_data); return false; } inflate_buf += pass_size; - inflate_buf_size -= pass_size; + pngp->total_out -= pass_size; deinterlace_pass(data, ihdr, tmp_data, pass_width, pass_height, &passes[pass]); diff --git a/libretro-common/formats/png/rpng_decode_fbio.c b/libretro-common/formats/png/rpng_decode_fbio.c index 35d0857d02..5d3bd3795d 100644 --- a/libretro-common/formats/png/rpng_decode_fbio.c +++ b/libretro-common/formats/png/rpng_decode_fbio.c @@ -215,6 +215,7 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, char header[8]; z_stream stream = {0}; struct rpng_t rpng = {0}; + struct rpng_process_t process = {0}; bool ret = true; *data = NULL; @@ -337,14 +338,16 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, if (!*data) GOTO_END_ERROR(); + process.total_out = stream.total_out; + if (rpng.ihdr.interlace == 1) { if (!png_reverse_filter_adam7(*data, - &rpng.ihdr, rpng.inflate_buf, stream.total_out, rpng.palette)) + &rpng.ihdr, rpng.inflate_buf, &process, rpng.palette)) GOTO_END_ERROR(); } else if (!png_reverse_filter(*data, - &rpng.ihdr, rpng.inflate_buf, stream.total_out, rpng.palette)) + &rpng.ihdr, rpng.inflate_buf, &process, rpng.palette)) GOTO_END_ERROR(); end: diff --git a/libretro-common/formats/png/rpng_decode_fnbio.c b/libretro-common/formats/png/rpng_decode_fnbio.c index c2af8af2dd..438a4beba3 100644 --- a/libretro-common/formats/png/rpng_decode_fnbio.c +++ b/libretro-common/formats/png/rpng_decode_fnbio.c @@ -257,6 +257,7 @@ bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng) bool rpng_nbio_load_image_argb_process(struct rpng_t *rpng, uint32_t **data, unsigned *width, unsigned *height) { + struct rpng_process_t process = {0}; z_stream stream = {0}; if (inflateInit(&stream) != Z_OK) @@ -296,14 +297,16 @@ bool rpng_nbio_load_image_argb_process(struct rpng_t *rpng, if (!*data) return false; + process.total_out = stream.total_out; + if (rpng->ihdr.interlace == 1) { if (!png_reverse_filter_adam7(*data, - &rpng->ihdr, rpng->inflate_buf, stream.total_out, rpng->palette)) + &rpng->ihdr, rpng->inflate_buf, &process, rpng->palette)) return false; } else if (!png_reverse_filter(*data, - &rpng->ihdr, rpng->inflate_buf, stream.total_out, rpng->palette)) + &rpng->ihdr, rpng->inflate_buf, &process, rpng->palette)) return false; return true; diff --git a/libretro-common/include/formats/rpng.h b/libretro-common/include/formats/rpng.h index a36661dd4c..3729e63336 100644 --- a/libretro-common/include/formats/rpng.h +++ b/libretro-common/include/formats/rpng.h @@ -60,6 +60,11 @@ struct png_ihdr uint8_t interlace; }; +struct rpng_process_t +{ + size_t total_out; +}; + struct rpng_t { bool has_ihdr;