size_t ZlibRecompress(unsigned char *src, size_t src_len, size_t size_leanified /*= 0*/) { if (!is_fast) { size_t s = 0; unsigned char *buffer = (unsigned char *)tinfl_decompress_mem_to_heap(src, src_len, &s, TINFL_FLAG_PARSE_ZLIB_HEADER); if (!buffer) { std::cerr << "Decompress Zlib data failed." << std::endl; } else { ZopfliOptions zopfli_options; ZopfliInitOptions(&zopfli_options); zopfli_options.numiterations = iterations; size_t new_size = 0; unsigned char *out_buffer = NULL; ZopfliZlibCompress(&zopfli_options, buffer, s, &out_buffer, &new_size); mz_free(buffer); if (new_size < src_len) { memcpy(src - size_leanified, out_buffer, new_size); delete[] out_buffer; return new_size; } delete[] out_buffer; } } memmove(src - size_leanified, src, src_len); return src_len; }
/* --- GATEWAY FUNCTION --- */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char *action; unsigned char *IN = NULL, *OUT = NULL; size_t INlen, OUTlen; /* Check for proper number of arguments */ if (nrhs < 2) mexErrMsgTxt("Not enough input arguments."); else if (nrhs > 2) mexErrMsgTxt("Too many input arguments."); else if (nlhs > 1) mexErrMsgTxt("Too many output arguments."); /* The input ACTION must be a string */ if (!mxIsChar(prhs[0])) mexErrMsgTxt("Input ACTION must be a string."); action = mxArrayToString(prhs[0]); /* The input IN must be a real uint8 array */ if (!mxIsUint8(prhs[1]) || mxIsComplex(prhs[1])) mexErrMsgTxt("Input IN must be a real uint8 array."); INlen = mxGetNumberOfElements(prhs[1]); IN = mxGetData(prhs[1]); if (!strcmp(action,"D")) { /* Decompress data */ OUT = tinfl_decompress_mem_to_heap(IN, INlen, &OUTlen, TINFL_FLAG_PARSE_ZLIB_HEADER); if (OUT == NULL) mexErrMsgTxt("Error when decompressing data."); } else if (!strcmp(action,"C")) { /* Compress data */ OUT = tdefl_compress_mem_to_heap(IN, INlen, &OUTlen, TDEFL_WRITE_ZLIB_HEADER); if (OUT == NULL) mexErrMsgTxt("Error when compressing data."); } else { mexErrMsgTxt("Unknown ACTION type."); } /* */ plhs[0] = mxCreateNumericMatrix(OUTlen,1,mxUINT8_CLASS,mxREAL); if (plhs[0] == NULL) mexErrMsgTxt("Error when creating output variable."); memcpy(mxGetData(plhs[0]), OUT, OUTlen); mxFree(action); mz_free(OUT); }
static int ltinfl(lua_State* L) { size_t in_len; const char* in_buf = luaL_checklstring(L, 1, &in_len); size_t out_len; int flags = luaL_optint(L, 2, 0); char* out_buf = tinfl_decompress_mem_to_heap(in_buf, in_len, &out_len, flags); lua_pushlstring(L, out_buf, out_len); free(out_buf); return 1; }
size_t Gz::Leanify(size_t size_leanified /*= 0*/) { // written according to this specification // http://www.gzip.org/zlib/rfc-gzip.html if (size <= 18) { std::cerr << "Not a valid GZ file." << std::endl; return Format::Leanify(size_leanified); } depth++; char flags = *(fp + 3); // set the flags to 0, remove all unnecessary section *(fp + 3 - size_leanified) = 0; char *p_read = fp + 10; char *p_write = p_read - size_leanified; *(p_write - 2) = 2; // XFL if (flags & (1 << 2)) // FEXTRA { p_read += *(uint16_t *)p_read + 2; } std::string filename; if (flags & (1 << 3)) // FNAME { for (int i = 1; i < depth; i++) { std::cout << "-> "; } std::cout << p_read << std::endl; filename = std::string(p_read); while (p_read < fp + size && *p_read++) { // skip string } } if (flags & (1 << 4)) // FCOMMENT { while (p_read < fp + size && *p_read++) { // skip string } } if (flags & (1 << 1)) // FHCRC { p_read += 2; } if (p_read >= fp + size) { return Format::Leanify(size_leanified); } if (size_leanified) { memmove(fp - size_leanified, fp, 10); } if (is_fast) { memmove(p_write, p_read, fp + size - p_read); return size - (p_read - p_write); } uint32_t uncompressed_size = *(uint32_t *)(fp + size - 4); uint32_t crc = *(uint32_t *)(fp + size - 8); size_t original_size = fp + size - 8 - p_read; size_t s = 0; unsigned char *buffer = (unsigned char *)tinfl_decompress_mem_to_heap(p_read, original_size, &s, 0); if (!buffer || s != uncompressed_size || crc != mz_crc32(0, buffer, uncompressed_size)) { std::cerr << "GZ corrupted!" << std::endl; mz_free(buffer); memmove(p_write, p_read, original_size + 8); return size - (p_read - p_write); } uncompressed_size = LeanifyFile(buffer, uncompressed_size, 0, filename); ZopfliOptions options; ZopfliInitOptions(&options); options.numiterations = iterations; unsigned char bp = 0, *out = NULL; size_t outsize = 0; ZopfliDeflate(&options, 2, 1, buffer, uncompressed_size, &bp, &out, &outsize); if (outsize < original_size) { memcpy(p_write, out, outsize); p_write += outsize; *(uint32_t *)p_write = mz_crc32(0, buffer, uncompressed_size); *(uint32_t *)(p_write + 4) = uncompressed_size; } else { memmove(p_write, p_read, original_size + 8); p_write += original_size; } mz_free(buffer); delete[] out; depth--; fp -= size_leanified; return p_write + 8 - fp; }