int rpng_process_image(rpng_t *rpng, void **_data, size_t size, unsigned *width, unsigned *height) { uint32_t **data = (uint32_t**)_data; (void)size; if (!rpng->process) { struct rpng_process *process = rpng_process_init( rpng, width, height); if (!process) goto error; rpng->process = process; return IMAGE_PROCESS_NEXT; } if (!rpng->process->inflate_initialized) { if (rpng_load_image_argb_process_inflate_init(rpng, data, width, height) == -1) goto error; return IMAGE_PROCESS_NEXT; } return png_reverse_filter_iterate(rpng, data); error: if (rpng->process) { if (rpng->process->inflate_buf) free(rpng->process->inflate_buf); if (rpng->process->stream) rpng->process->stream_backend->stream_free(rpng->process->stream); free(rpng->process); } return IMAGE_PROCESS_ERROR; }
int rpng_nbio_load_image_argb_process(struct rpng_t *rpng, uint32_t **data, unsigned *width, unsigned *height) { if (!rpng->process.initialized) { 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); }
bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height) { long pos, file_len; FILE *file; char header[8] = {0}; rpng_t rpng = {{0}}; bool ret = true; int retval = 0; *data = NULL; *width = 0; *height = 0; file = fopen(path, "rb"); if (!file) return false; fseek(file, 0, SEEK_END); file_len = ftell(file); rewind(file); if (fread(header, 1, sizeof(header), file) != sizeof(header)) GOTO_END_ERROR(); if (memcmp(header, png_magic, sizeof(png_magic)) != 0) GOTO_END_ERROR(); /* feof() apparently isn't triggered after a seek (IEND). */ for (pos = ftell(file); pos < file_len && pos >= 0; pos = ftell(file)) { if (!rpng_load_image_argb_iterate(&file, &rpng)) GOTO_END_ERROR(); } if (!rpng.has_ihdr || !rpng.has_idat || !rpng.has_iend) GOTO_END_ERROR(); if (!rpng_load_image_argb_process_init(&rpng, data, width, 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); if (retval == PNG_PROCESS_ERROR || retval == PNG_PROCESS_ERROR_END) GOTO_END_ERROR(); end: if (file) fclose(file); if (!ret) free(*data); free(rpng.idat_buf.data); free(rpng.process.inflate_buf); if (rpng.process.stream) { zlib_stream_free(rpng.process.stream); free(rpng.process.stream); } return ret; }