From 52eefc35ffca10709374ca091ca79c77e4ae314d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 14 Mar 2015 21:51:56 +0100 Subject: [PATCH] (RPNG) Inflate process should be nonblocking now too --- libretro-common/formats/png/rpng_decode.c | 92 ++++++++++++++--------- libretro-common/formats/png/rpng_fbio.c | 8 ++ libretro-common/formats/png/rpng_nbio.c | 10 +++ libretro-common/include/formats/rpng.h | 4 + 4 files changed, 77 insertions(+), 37 deletions(-) diff --git a/libretro-common/formats/png/rpng_decode.c b/libretro-common/formats/png/rpng_decode.c index 23cfb02138..c965d446e6 100644 --- a/libretro-common/formats/png/rpng_decode.c +++ b/libretro-common/formats/png/rpng_decode.c @@ -577,10 +577,64 @@ int png_reverse_filter_iterate(struct rpng_t *rpng, return png_reverse_filter_regular_iterate(data, &rpng->ihdr, &rpng->process); } -bool rpng_load_image_argb_process_init(struct rpng_t *rpng, +int rpng_load_image_argb_process_inflate_init(struct rpng_t *rpng, uint32_t **data, unsigned *width, unsigned *height) { int zstatus; + bool to_continue = (rpng->process.stream.avail_in > 0 + && rpng->process.stream.avail_out > 0); + + if (!to_continue) + goto end; + + zstatus = inflate(&rpng->process.stream, Z_NO_FLUSH); + + if (zstatus == Z_STREAM_END) + goto end; + + if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) + goto error; + + return 0; + +end: + inflateEnd(&rpng->process.stream); + + *width = rpng->ihdr.width; + *height = rpng->ihdr.height; +#ifdef GEKKO + /* we often use these in textures, make sure they're 32-byte aligned */ + *data = (uint32_t*)memalign(32, rpng->ihdr.width * + rpng->ihdr.height * sizeof(uint32_t)); +#else + *data = (uint32_t*)malloc(rpng->ihdr.width * + rpng->ihdr.height * sizeof(uint32_t)); +#endif + if (!*data) + goto false_end; + + rpng->process.adam7_restore_buf_size = 0; + rpng->process.restore_buf_size = 0; + rpng->process.palette = rpng->palette; + + if (rpng->ihdr.interlace != 1) + if (png_reverse_filter_init(&rpng->ihdr, &rpng->process) == -1) + goto false_end; + + rpng->process.inflate_initialized = true; + return 1; + +error: + inflateEnd(&rpng->process.stream); + +false_end: + rpng->process.inflate_initialized = false; + return -1; +} + +bool rpng_load_image_argb_process_init(struct rpng_t *rpng, + uint32_t **data, unsigned *width, unsigned *height) +{ rpng->process.inflate_buf_size = 0; rpng->process.inflate_buf = NULL; @@ -601,42 +655,6 @@ bool rpng_load_image_argb_process_init(struct rpng_t *rpng, rpng->process.stream.avail_out = rpng->process.inflate_buf_size; rpng->process.stream.next_out = rpng->process.inflate_buf; - do - { - zstatus = inflate(&rpng->process.stream, Z_NO_FLUSH); - if (zstatus == Z_STREAM_END) - break; - if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) - { - inflateEnd(&rpng->process.stream); - return false; - } - } while(rpng->process.stream.avail_in > 0 - && rpng->process.stream.avail_out > 0); - - inflateEnd(&rpng->process.stream); - - *width = rpng->ihdr.width; - *height = rpng->ihdr.height; -#ifdef GEKKO - /* we often use these in textures, make sure they're 32-byte aligned */ - *data = (uint32_t*)memalign(32, rpng->ihdr.width * - rpng->ihdr.height * sizeof(uint32_t)); -#else - *data = (uint32_t*)malloc(rpng->ihdr.width * - rpng->ihdr.height * sizeof(uint32_t)); -#endif - if (!*data) - return false; - - rpng->process.adam7_restore_buf_size = 0; - rpng->process.restore_buf_size = 0; - rpng->process.palette = rpng->palette; - - if (rpng->ihdr.interlace != 1) - if (png_reverse_filter_init(&rpng->ihdr, &rpng->process) == -1) - return false; - rpng->process.initialized = true; return true; diff --git a/libretro-common/formats/png/rpng_fbio.c b/libretro-common/formats/png/rpng_fbio.c index cb41213d45..89bf6877a5 100644 --- a/libretro-common/formats/png/rpng_fbio.c +++ b/libretro-common/formats/png/rpng_fbio.c @@ -262,6 +262,14 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, height)) GOTO_END_ERROR(); + do{ + retval = rpng_load_image_argb_process_inflate_init(&rpng, data, + width, height); + }while(retval == 0); + + if (retval == -1) + GOTO_END_ERROR(); + do{ retval = png_reverse_filter_iterate(&rpng, data); }while(retval == PNG_PROCESS_NEXT); diff --git a/libretro-common/formats/png/rpng_nbio.c b/libretro-common/formats/png/rpng_nbio.c index 8f626f10fb..0a58767e74 100644 --- a/libretro-common/formats/png/rpng_nbio.c +++ b/libretro-common/formats/png/rpng_nbio.c @@ -199,6 +199,16 @@ int rpng_nbio_load_image_argb_process(struct rpng_t *rpng, if (!rpng_load_image_argb_process_init(rpng, data, width, height)) return PNG_PROCESS_ERROR; + return 0; + } + + if (!rpng->process.inflate_initialized) + { + int ret = rpng_load_image_argb_process_inflate_init(rpng, data, + width, height); + if (ret == -1) + return PNG_PROCESS_ERROR; + return 0; } return png_reverse_filter_iterate(rpng, data); diff --git a/libretro-common/include/formats/rpng.h b/libretro-common/include/formats/rpng.h index 6dc60150c8..57d8f8b7be 100644 --- a/libretro-common/include/formats/rpng.h +++ b/libretro-common/include/formats/rpng.h @@ -64,6 +64,7 @@ struct png_ihdr struct rpng_process_t { bool initialized; + bool inflate_initialized; bool adam7_pass_initialized; bool pass_initialized; uint32_t *data; @@ -116,6 +117,9 @@ bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, int rpng_nbio_load_image_argb_process(struct rpng_t *rpng, uint32_t **data, unsigned *width, unsigned *height); +int rpng_load_image_argb_process_inflate_init(struct rpng_t *rpng, + uint32_t **data, unsigned *width, unsigned *height); + bool rpng_nbio_load_image_argb_start(struct rpng_t *rpng); #ifdef HAVE_ZLIB_DEFLATE