STATIC mp_obj_t mod_zlibd_decompress(uint n_args, mp_obj_t *args) { mp_obj_t data = args[0]; mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); tinfl_decompressor *decomp = m_new_obj(tinfl_decompressor); tinfl_init(decomp); DEBUG_printf("sizeof(tinfl_decompressor)=" UINT_FMT "\n", sizeof(tinfl_decompressor)); byte *out = m_new(byte, bufinfo.len); size_t out_len = bufinfo.len; size_t in_buf_ofs = 0, dst_buf_ofs = 0; size_t dst_buf_sz = bufinfo.len; while (1) { size_t in_buf_sz = bufinfo.len - in_buf_ofs; DEBUG_printf("tinfl in: in_ofs=%d in_sz=%d dst_ofs=%d, dst_sz=%d\n", in_buf_ofs, in_buf_sz, dst_buf_ofs, dst_buf_sz); tinfl_status st = tinfl_decompress(decomp, (mz_uint8*) bufinfo.buf + in_buf_ofs, &in_buf_sz, out, out + dst_buf_ofs, &dst_buf_sz, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | TINFL_FLAG_PARSE_ZLIB_HEADER); DEBUG_printf("tinfl out: st=%d, in_sz=%d, out_sz=%d\n", st, in_buf_sz, dst_buf_sz); in_buf_ofs += in_buf_sz; dst_buf_ofs += dst_buf_sz; if (st != TINFL_STATUS_HAS_MORE_OUTPUT) { break; } out = m_renew(byte, out, out_len, dst_buf_ofs + 256); out_len = dst_buf_ofs + 256; dst_buf_sz = out_len - dst_buf_ofs; } m_del_obj(tinfl_decompressor, decomp); return mp_obj_new_bytearray_by_ref(dst_buf_ofs, out); }
static void adapt_sink_inflator_write(struct adapt_sink* sink, size_t file_offset, const unsigned char* buf, size_t length) { struct adapt_sink_inflator* self = (struct adapt_sink_inflator*)sink; struct adapt_sink* next = self->next; size_t count = 0; size_t buf_size; size_t tmp_size; int status; if (!self->buffer && length > 0) { self->buffer = (unsigned char *)malloc(INFLATOR_BUFFER_SIZE); } while (1) { tmp_size = INFLATOR_BUFFER_SIZE - self->buffer_offset; buf_size = length - count; status = tinfl_decompress(&self->inflator, buf + count, &buf_size, self->buffer, self->buffer + self->buffer_offset, &tmp_size, length > 0 ? TINFL_FLAG_HAS_MORE_INPUT : 0); if (buf_size > 0) { count += buf_size; } if (tmp_size > 0 || length == 0) { next->write(next, self->inflated_file_offset, self->buffer + self->buffer_offset, tmp_size); self->inflated_file_offset += tmp_size; self->buffer_offset = (self->buffer_offset + tmp_size + INFLATOR_BUFFER_SIZE) % INFLATOR_BUFFER_SIZE; } if (status == TINFL_STATUS_DONE || (buf_size == 0 && tmp_size == 0)) { break; } } if (self->buffer && length == 0) { // End of stream free(self->buffer); self->buffer = NULL; } }
static int lmz_decompress(lua_State *L, int start, lmz_Decomp *d) { size_t len, offset = 0, output = 0; const char *s = luaL_checklstring(L, start, &len); luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { size_t in_size = len - offset; size_t out_size = TINFL_LZ_DICT_SIZE - (d->curr - d->dict); tinfl_status status = tinfl_decompress(&d->decomp, (void*)(s + offset), &in_size, d->dict, d->curr, &out_size, d->flags & ~TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); offset += in_size; output += out_size; if (out_size != 0) luaL_addlstring(&b, (char*)d->curr, out_size); if (offset == len || status == TINFL_STATUS_DONE) { luaL_pushresult(&b); lua_pushboolean(L, status == TINFL_STATUS_DONE); lua_pushinteger(L, len); lua_pushinteger(L, output); return 4; } else if (status < 0) luaL_error(L, "decompress failure (%d)", status); d->curr = &d->dict[(d->curr+out_size - d->dict) & (TINFL_LZ_DICT_SIZE-1)]; } }
char* decompress_file_to_buffer(const char* filename, size_t& len) { len = 0; const size_t OUTPUT_START_SIZE = 1024 * 1024; // 1MB char* output = (char*)malloc(OUTPUT_START_SIZE); size_t output_size = OUTPUT_START_SIZE; size_t output_len = 0; const int DECOMPRESS_FAIL = 1; int error = 0; size_t avail_in = 0; size_t avail_out = OUT_BUF_SIZE; const void* next_in = inbuf; void* next_out = outbuf; size_t total_out = 0; size_t total_in = 0; // Open input file. FILE* infile = fopen(filename, "rb"); if (infile == NULL) { printf("Failed opening input file \"%s\"\n", filename); return NULL; } // Determine input file's size. fseek(infile, 0, SEEK_END); size_t infile_size = ftell(infile); fseek(infile, 0, SEEK_SET); // Decompression. size_t infile_remaining = infile_size; tinfl_decompressor inflator; tinfl_init(&inflator); for (;;) { size_t in_bytes, out_bytes; tinfl_status status; if (!avail_in) { // Input buffer is empty, so read more bytes from input file. size_t n = GS_MIN(IN_BUF_SIZE, infile_remaining); if (fread(inbuf, 1, n, infile) != n) { printf("Failed reading from input file \"%s\"\n", filename); return NULL; } next_in = inbuf; avail_in = n; infile_remaining -= n; } in_bytes = avail_in; out_bytes = avail_out; status = tinfl_decompress(&inflator, (const mz_uint8*)next_in, &in_bytes, outbuf, (mz_uint8*)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER); avail_in -= in_bytes; next_in = (const mz_uint8*)next_in + in_bytes; total_in += in_bytes; avail_out -= out_bytes; next_out = (mz_uint8*)next_out + out_bytes; total_out += out_bytes; if ((status <= TINFL_STATUS_DONE) || (!avail_out)) { // Output buffer is full, or decompression is done, so write buffer to output file. size_t n = OUT_BUF_SIZE - (size_t)avail_out; // TODO -- convert this to a memcpy + resize size_t new_size = output_size; while ((output_len + n) >= new_size) new_size *= 2; if (new_size != output_size) { char* _output = (char*)realloc(output, new_size); if (_output == NULL) { printf("Failed to realloc output buffer\n"); error = DECOMPRESS_FAIL; break; } output = _output; output_size = new_size; } memcpy(&output[output_len], outbuf, n); output_len += n; next_out = outbuf; avail_out = OUT_BUF_SIZE; } // If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong. if (status <= TINFL_STATUS_DONE) { if (status == TINFL_STATUS_DONE) { // Decompression completed successfully. break; } else { // Decompression failed. printf("tinfl_decompress() failed with status %i!\n", status); error = DECOMPRESS_FAIL; break; } } } int closed = fclose(infile); if (closed) printf("Failed to close file \"%s\"\n", filename); if (error) { free(output); len = 0; return NULL; } len = output_len; if (!output_len) { free(output); return NULL; } else if (output_len != output_size) { char* _output = (char*)realloc(output, output_len * sizeof(*output)); if (_output == NULL) printf("Failed to decrease output buffer size\n"); else output = _output; } return output; }
u8_t* get_file_data(const char* filename, int* file_size, int can_be_compressed, int* is_compressed) { FILE *inFile; size_t fsize = 0; u8_t* buf; size_t r; int rs; inFile = fopen(filename, "rb"); if (inFile == NULL) { printf("Failed to open file \"%s\"\n", filename); exit(-1); } fseek(inFile, 0, SEEK_END); rs = ftell(inFile); if (rs < 0) { printf("ftell failed with %d\n", errno); exit(-1); } fsize = (size_t)rs; fseek(inFile, 0, SEEK_SET); buf = (u8_t*)malloc(fsize); LWIP_ASSERT("buf != NULL", buf != NULL); r = fread(buf, 1, fsize, inFile); *file_size = fsize; *is_compressed = 0; #if MAKEFS_SUPPORT_DEFLATE overallDataBytes += fsize; if (deflateNonSsiFiles) { if (can_be_compressed) { if (fsize < OUT_BUF_SIZE) { u8_t* ret_buf; tdefl_status status; size_t in_bytes = fsize; size_t out_bytes = OUT_BUF_SIZE; const void *next_in = buf; void *next_out = s_outbuf; /* create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). */ mz_uint comp_flags = s_tdefl_num_probes[MZ_MIN(10, deflate_level)] | ((deflate_level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); if (!deflate_level) { comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; } status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); if (status != TDEFL_STATUS_OKAY) { printf("tdefl_init() failed!\n"); exit(-1); } memset(s_outbuf, 0, sizeof(s_outbuf)); status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, TDEFL_FINISH); if (status != TDEFL_STATUS_DONE) { printf("deflate failed: %d\n", status); exit(-1); } LWIP_ASSERT("out_bytes <= COPY_BUFSIZE", out_bytes <= OUT_BUF_SIZE); if (out_bytes < fsize) { ret_buf = (u8_t*)malloc(out_bytes); LWIP_ASSERT("ret_buf != NULL", ret_buf != NULL); memcpy(ret_buf, s_outbuf, out_bytes); { /* sanity-check compression be inflating and comparing to the original */ tinfl_status dec_status; tinfl_decompressor inflator; size_t dec_in_bytes = out_bytes; size_t dec_out_bytes = OUT_BUF_SIZE; next_out = s_checkbuf; tinfl_init(&inflator); memset(s_checkbuf, 0, sizeof(s_checkbuf)); dec_status = tinfl_decompress(&inflator, (const mz_uint8 *)ret_buf, &dec_in_bytes, s_checkbuf, (mz_uint8 *)next_out, &dec_out_bytes, 0); LWIP_ASSERT("tinfl_decompress failed", dec_status == TINFL_STATUS_DONE); LWIP_ASSERT("tinfl_decompress size mismatch", fsize == dec_out_bytes); LWIP_ASSERT("decompressed memcmp failed", !memcmp(s_checkbuf, buf, fsize)); } /* free original buffer, use compressed data + size */ free(buf); buf = ret_buf; *file_size = out_bytes; printf(" - deflate: %d bytes -> %d bytes (%.02f%%)" NEWLINE, (int)fsize, (int)out_bytes, (float)((out_bytes*100.0)/fsize)); deflatedBytesReduced += (size_t)(fsize - out_bytes); *is_compressed = 1; } else { printf(" - uncompressed: (would be %d bytes larger using deflate)" NEWLINE, (int)(out_bytes - fsize)); } } else { printf(" - uncompressed: (file is larger than deflate bufer)" NEWLINE); } } else { printf(" - SSI file, cannot be compressed" NEWLINE); } } #else LWIP_UNUSED_ARG(can_be_compressed); #endif fclose(inFile); return buf; }
/* decompress a gz file in memory. returns a pointer to a newly allocated memory chunk (holding uncompressed data), or NULL on error. */ unsigned char *ungz(unsigned char *memgz, long memgzlen, long *resultlen) { #define buffinsize 64 * 1024 /* the input buffer must be at least 32K, because that's the (usual) dic size in deflate, apparently */ #define buffoutsize 256 * 1024 /* it's better for the output buffer to be significantly larger than the input buffer (we are decompressing here, remember? */ unsigned char *buffout; unsigned char *buffin; unsigned char compmethod; int extract_res, flags; unsigned char *result; long filelen, compressedfilelen, gzpos = 0, resultpos = 0; *resultlen = 0; /* Check the magic bytes of the gz stream before starting anything */ if (memgz[gzpos++] != 0x1F) return(NULL); if (memgz[gzpos++] != 0x8B) return(NULL); /* allocate buffers for data I/O */ buffin = malloc(buffinsize); buffout = malloc(buffoutsize); if ((buffin == NULL) || (buffout == NULL)) { if (buffin != NULL) free(buffin); if (buffout != NULL) free(buffout); return(NULL); } /* read the uncompressed file length */ buffin[0] = memgz[memgzlen - 4]; buffin[1] = memgz[memgzlen - 3]; buffin[2] = memgz[memgzlen - 2]; buffin[3] = memgz[memgzlen - 1]; filelen = buffin[0] | buffin[1] << 8 | buffin[2] << 16 | buffin[3] << 24; /* load the compression method (1 byte) - should be 0 (stored) or 8 (deflate) */ compmethod = memgz[gzpos++]; if ((compmethod != 0) && (compmethod != 8)) return(NULL); /* load flags (1 byte) */ flags = memgz[gzpos++]; /* check that the file is not a continuation of a multipart gzip */ if (flags & GZ_FLAG_MULTIPART_CONTINUTATION) return(NULL); /* check that the file is not encrypted */ if (flags & GZ_FLAG_FILE_IS_ENCRYPTED) return(NULL); /* Discard the file modification timestamp (4 bytes), the extra flags (1 byte) as well as OS type (1 byte) */ gzpos += 6; /* skip the extra field (if present) */ if (flags & GZ_FLAG_EXTRA_FIELD_PRESENT) { int extrafieldlen; /* load the length of the extra field (2 bytes) */ extrafieldlen = memgz[gzpos++]; extrafieldlen <<= 8; extrafieldlen |= memgz[gzpos++]; /* skip the extra field */ gzpos += extrafieldlen; } /* skip the filename, if present (null terminated string) */ if (flags & GZ_FLAG_ORIG_FILENAME_PRESENT) { for (;;) if (memgz[gzpos++] == 0) break; } /* skip the file comment, if present (null terminated string) */ if (flags & GZ_FLAG_FILE_COMMENT_PRESENT) { for (;;) if (memgz[gzpos++] == 0) break; } /* compute the length of the compressed stream */ compressedfilelen = memgzlen - (gzpos + 8); /* allocate memory for uncompressed content */ result = malloc(filelen + 1); if (result == NULL) return(NULL); /* failed to open the dst file */ result[filelen] = 0; /* finish the last byte with zero. just in case. */ /* start reading and uncompressing the compressed data, computing CRC32 at the same time */ if (compmethod == 0) { /* if the file is stored, copy it over */ extract_res = 0; /* assume we will succeed */ for (resultpos = 0; resultpos < filelen;) { result[resultpos] = memgz[gzpos++]; } } else if (compmethod == 8) { /* the file is deflated */ size_t total_in = 0, total_out = 0; unsigned int infile_remaining = compressedfilelen; size_t avail_in = 0; tinfl_decompressor *tinflhandler; size_t avail_out = buffoutsize; void *next_out = buffout; const void *next_in = buffin; extract_res = 0; /* assume we will succeed */ tinflhandler = malloc(sizeof(tinfl_decompressor)); if (tinflhandler == NULL) { extract_res = -19; } else { tinfl_init(tinflhandler); } while (extract_res == 0) { size_t in_bytes, out_bytes; tinfl_status status; if (!avail_in) { /* Input buffer is empty, so read more bytes from input file. */ unsigned int n = buffinsize; if (n > infile_remaining) n = infile_remaining; memcpy(buffin, &memgz[gzpos], n); gzpos += n; next_in = buffin; avail_in = n; infile_remaining -= n; } in_bytes = avail_in; out_bytes = avail_out; status = tinfl_decompress(tinflhandler, (const mz_uint8 *)next_in, &in_bytes, buffout, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); avail_in -= in_bytes; next_in = (const mz_uint8 *)next_in + in_bytes; total_in += in_bytes; avail_out -= out_bytes; next_out = (mz_uint8 *)next_out + out_bytes; total_out += out_bytes; if ((status <= TINFL_STATUS_DONE) || (!avail_out)) { /* Output buffer is full, or decompression is done, so write buffer to output file. */ unsigned int n = buffoutsize - (unsigned int)avail_out; memcpy(&result[resultpos], buffout, n); resultpos += n; next_out = buffout; avail_out = buffoutsize; } /* If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong. */ if (status <= TINFL_STATUS_DONE) { if (status == TINFL_STATUS_DONE) { /* Decompression completed successfully. */ extract_res = 0; } else { /* Decompression failed. */ extract_res = -15; } break; } } if (tinflhandler != NULL) free(tinflhandler); } *resultlen = filelen; return(result); }
int main(int argc, char *argv[]) { const char *pMode; FILE *pInfile, *pOutfile; uint infile_size; int level = 9; int p = 1; const char *pSrc_filename; const char *pDst_filename; const void *next_in = s_inbuf; size_t avail_in = 0; void *next_out = s_outbuf; size_t avail_out = OUT_BUF_SIZE; size_t total_in = 0, total_out = 0; long file_loc; assert(COMP_OUT_BUF_SIZE <= OUT_BUF_SIZE); printf("miniz.c example5 (demonstrates tinfl/tdefl)\n"); if (argc < 4) { printf("File to file compression/decompression using the low-level tinfl/tdefl API's.\n"); printf("Usage: example5 [options] [mode:c or d] infile outfile\n"); printf("\nModes:\n"); printf("c - Compresses file infile to a zlib stream in file outfile\n"); printf("d - Decompress zlib stream in file infile to file outfile\n"); printf("\nOptions:\n"); printf("-l[0-10] - Compression level, higher values are slower, 0 is none.\n"); return EXIT_FAILURE; } while ((p < argc) && (argv[p][0] == '-')) { switch (argv[p][1]) { case 'l': { level = atoi(&argv[1][2]); if ((level < 0) || (level > 10)) { printf("Invalid level!\n"); return EXIT_FAILURE; } break; } default: { printf("Invalid option: %s\n", argv[p]); return EXIT_FAILURE; } } p++; } if ((argc - p) < 3) { printf("Must specify mode, input filename, and output filename after options!\n"); return EXIT_FAILURE; } else if ((argc - p) > 3) { printf("Too many filenames!\n"); return EXIT_FAILURE; } pMode = argv[p++]; if (!strchr("cCdD", pMode[0])) { printf("Invalid mode!\n"); return EXIT_FAILURE; } pSrc_filename = argv[p++]; pDst_filename = argv[p++]; printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); // Open input file. pInfile = fopen(pSrc_filename, "rb"); if (!pInfile) { printf("Failed opening input file!\n"); return EXIT_FAILURE; } // Determine input file's size. fseek(pInfile, 0, SEEK_END); file_loc = ftell(pInfile); fseek(pInfile, 0, SEEK_SET); if ((file_loc < 0) || (file_loc > INT_MAX)) { // This is not a limitation of miniz or tinfl, but this example. printf("File is too large to be processed by this example.\n"); return EXIT_FAILURE; } infile_size = (uint)file_loc; // Open output file. pOutfile = fopen(pDst_filename, "wb"); if (!pOutfile) { printf("Failed opening output file!\n"); return EXIT_FAILURE; } printf("Input file size: %u\n", infile_size); if ((pMode[0] == 'c') || (pMode[0] == 'C')) { // The number of dictionary probes to use at each compression level (0-10). 0=implies fastest/minimal possible probing. static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; tdefl_status status; uint infile_remaining = infile_size; // create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). mz_uint comp_flags = TDEFL_WRITE_ZLIB_HEADER | s_tdefl_num_probes[MZ_MIN(10, level)] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; // Initialize the low-level compressor. status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); if (status != TDEFL_STATUS_OKAY) { printf("tdefl_init() failed!\n"); return EXIT_FAILURE; } avail_out = COMP_OUT_BUF_SIZE; // Compression. for ( ; ; ) { size_t in_bytes, out_bytes; if (!avail_in) { // Input buffer is empty, so read more bytes from input file. uint n = my_min(IN_BUF_SIZE, infile_remaining); if (fread(s_inbuf, 1, n, pInfile) != n) { printf("Failed reading from input file!\n"); return EXIT_FAILURE; } next_in = s_inbuf; avail_in = n; infile_remaining -= n; //printf("Input bytes remaining: %u\n", infile_remaining); } in_bytes = avail_in; out_bytes = avail_out; // Compress as much of the input as possible (or all of it) to the output buffer. status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); next_in = (const char *)next_in + in_bytes; avail_in -= in_bytes; total_in += in_bytes; next_out = (char *)next_out + out_bytes; avail_out -= out_bytes; total_out += out_bytes; if ((status != TDEFL_STATUS_OKAY) || (!avail_out)) { // Output buffer is full, or compression is done or failed, so write buffer to output file. uint n = COMP_OUT_BUF_SIZE - (uint)avail_out; if (fwrite(s_outbuf, 1, n, pOutfile) != n) { printf("Failed writing to output file!\n"); return EXIT_FAILURE; } next_out = s_outbuf; avail_out = COMP_OUT_BUF_SIZE; } if (status == TDEFL_STATUS_DONE) { // Compression completed successfully. break; } else if (status != TDEFL_STATUS_OKAY) { // Compression somehow failed. printf("tdefl_compress() failed with status %i!\n", status); return EXIT_FAILURE; } } } else if ((pMode[0] == 'd') || (pMode[0] == 'D')) { // Decompression. uint infile_remaining = infile_size; tinfl_decompressor inflator; tinfl_init(&inflator); for ( ; ; ) { size_t in_bytes, out_bytes; tinfl_status status; if (!avail_in) { // Input buffer is empty, so read more bytes from input file. uint n = my_min(IN_BUF_SIZE, infile_remaining); if (fread(s_inbuf, 1, n, pInfile) != n) { printf("Failed reading from input file!\n"); return EXIT_FAILURE; } next_in = s_inbuf; avail_in = n; infile_remaining -= n; } in_bytes = avail_in; out_bytes = avail_out; status = tinfl_decompress(&inflator, (const mz_uint8 *)next_in, &in_bytes, s_outbuf, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER); avail_in -= in_bytes; next_in = (const mz_uint8 *)next_in + in_bytes; total_in += in_bytes; avail_out -= out_bytes; next_out = (mz_uint8 *)next_out + out_bytes; total_out += out_bytes; if ((status <= TINFL_STATUS_DONE) || (!avail_out)) { // Output buffer is full, or decompression is done, so write buffer to output file. uint n = OUT_BUF_SIZE - (uint)avail_out; if (fwrite(s_outbuf, 1, n, pOutfile) != n) { printf("Failed writing to output file!\n"); return EXIT_FAILURE; } next_out = s_outbuf; avail_out = OUT_BUF_SIZE; } // If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong. if (status <= TINFL_STATUS_DONE) { if (status == TINFL_STATUS_DONE) { // Decompression completed successfully. break; } else { // Decompression failed. printf("tinfl_decompress() failed with status %i!\n", status); return EXIT_FAILURE; } } } } else { printf("Invalid mode!\n"); return EXIT_FAILURE; } fclose(pInfile); if (EOF == fclose(pOutfile)) { printf("Failed writing to output file!\n"); return EXIT_FAILURE; } printf("Total input bytes: %u\n", (mz_uint32)total_in); printf("Total output bytes: %u\n", (mz_uint32)total_out); printf("Success.\n"); return EXIT_SUCCESS; }