int rpng_load_image_argb_process_inflate_init(struct rpng_t *rpng, uint32_t **data, unsigned *width, unsigned *height) { int zstatus; bool to_continue = (zlib_stream_get_avail_in(rpng->process.stream) > 0 && zlib_stream_get_avail_out(rpng->process.stream) > 0); if (!to_continue) goto end; zstatus = zlib_inflate_data_to_file_iterate(rpng->process.stream); switch (zstatus) { case 1: goto end; case -1: goto error; default: break; } return 0; end: zlib_stream_free(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: zlib_stream_free(rpng->process.stream); false_end: rpng->process.inflate_initialized = false; return -1; }
/** * zlib_inflate_data_to_file: * @path : filename path of archive. * @valid_exts : Valid extensions of archive to be parsed. * If NULL, allow all. * @cdata : input data. * @csize : size of input data. * @size : output file size * @checksum : CRC32 checksum from input data. * * Decompress data to file. * * Returns: true (1) on success, otherwise false (0). **/ int zlib_inflate_data_to_file(zlib_file_handle_t *handle, int ret, const char *path, const char *valid_exts, const uint8_t *cdata, uint32_t csize, uint32_t size, uint32_t checksum) { if (handle) { zlib_stream_free(handle->stream); free(handle->stream); } if (!handle || ret == -1) { ret = 0; goto end; } handle->real_checksum = zlib_crc32_calculate(handle->data, size); #if 0 if (handle->real_checksum != checksum) { /* File CRC difers from ZIP CRC. */ printf("File CRC differs from ZIP CRC. File: 0x%x, ZIP: 0x%x.\n", (unsigned)handle->real_checksum, (unsigned)checksum); } #endif if (!zlib_write_file(path, handle->data, size)) GOTO_END_ERROR(); end: if (handle->data) free(handle->data); return ret; }
bool zlib_inflate_data_to_file_init( zlib_file_handle_t *handle, const uint8_t *cdata, uint32_t csize, uint32_t size) { z_stream *stream = NULL; if (!handle) return false; if (!(handle->stream = (z_stream*)zlib_stream_new())) goto error; if (!(zlib_inflate_init2(handle->stream))) goto error; handle->data = (uint8_t*)malloc(size); if (!handle->data) goto error; stream = (z_stream*)handle->stream; if (!stream) goto error; zlib_set_stream(stream, csize, size, (const uint8_t*)cdata, handle->data ); return true; error: if (handle->stream) zlib_stream_free(handle->stream); if (handle->data) free(handle->data); return false; }
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; }