static int lmz_compress(lua_State* L) { int level, ret; size_t in_len, out_len; const unsigned char *inb; unsigned char *outb; in_len = 0; inb = (const unsigned char *)luaL_checklstring(L, 1, &in_len); level = luaL_optint(L, 1, MZ_DEFAULT_COMPRESSION); if (level < MZ_DEFAULT_COMPRESSION || level > MZ_BEST_COMPRESSION) { luaL_error(L, "Compression level must be between -1 and 9"); } out_len = mz_compressBound(in_len); outb = malloc(out_len); ret = mz_compress2(outb, &out_len, inb, in_len, level); switch (ret) { case MZ_OK: lua_pushlstring(L, (const char*)outb, out_len); ret = 1; break; default: lua_pushnil(L); lua_pushstring(L, mz_error(ret)); ret = 2; break; } free(outb); return ret; }
static int lmz_uncompress(lua_State* L) { int ret; size_t in_len, out_len; const unsigned char* inb; unsigned char* outb; in_len = 0; inb = (const unsigned char*)luaL_checklstring(L, 1, &in_len); out_len = in_len; outb = malloc(out_len); ret = mz_uncompress(outb, &out_len, inb, in_len); switch (ret) { case MZ_OK: lua_pushlstring(L, (const char*)outb, out_len); ret = 1; break; default: lua_pushnil(L); lua_pushstring(L, mz_error(ret)); ret = 2; break; } free(outb); return ret; }
static int lmz_inflator_deflator_impl(lua_State* L, lmz_stream_t* stream) { mz_streamp miniz_stream = &(stream->stream); size_t data_size; const char* data = luaL_checklstring(L, 2, &data_size); int flush = luaL_checkoption(L, 3, "no", flush_types); miniz_stream->avail_in = data_size; miniz_stream->next_in = (const unsigned char*)data; luaL_Buffer buf; luaL_buffinit(L, &buf); while (1) { char* buffer = luaL_prepbuffer(&buf); memset(buffer, 0, LUAL_BUFFERSIZE); miniz_stream->avail_out = LUAL_BUFFERSIZE; miniz_stream->next_out = (unsigned char*)buffer; size_t before = miniz_stream->total_out; int status; if (stream->mode) { status = mz_inflate(miniz_stream, flush); } else { status = mz_deflate(miniz_stream, flush); } size_t added = miniz_stream->total_out - before; luaL_addsize(&buf, added); switch (status) { case MZ_OK: case MZ_STREAM_END: luaL_pushresult(&buf); return 1; case MZ_STREAM_ERROR: case MZ_DATA_ERROR: case MZ_PARAM_ERROR: luaL_pushresult(&buf); lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, mz_error(status)); lua_insert(L, -2); return 3; case MZ_BUF_ERROR: if (stream->mode) { // not enough input luaL_pushresult(&buf); lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, "Not enough input data"); lua_insert(L, -2); return 3; } break; } } }
static inline bool decode(std::vector<uint8_t>& decompressed, const uint8_t* src, size_t length) { const SWF::Header* header = (const SWF::Header*) src; decompressed.resize(header->fileLength); uint8_t* pBuff = &decompressed[0]; memcpy(pBuff, src, sizeof(SWF::Header)); mz_ulong sz = header->fileLength - sizeof(SWF::Header); int ret = mz_uncompress(pBuff + sizeof(SWF::Header), &sz, (const unsigned char*)(header+1), length - sizeof(SWF::Header)); if (ret) { puts(mz_error(ret)); return false; } pBuff[0] = 'F'; return true; }
static int lmz_inflator_init(lua_State* L) { lmz_stream_t* stream = lua_newuserdata(L, sizeof(*stream)); mz_streamp miniz_stream = &(stream->stream); luaL_getmetatable(L, "miniz_inflator"); lua_setmetatable(L, -2); memset(miniz_stream, 0, sizeof(*miniz_stream)); int status = mz_inflateInit(miniz_stream); if (status != MZ_OK) { const char* msg = mz_error(status); if (msg) { luaL_error(L, "Problem initializing stream: %s", msg); } else { luaL_error(L, "Problem initializing stream"); } } stream->mode = 1; return 1; }
static int l_compress(lua_State *L) { size_t in_length; const unsigned char *in = (unsigned char *)luaL_checklstring(L, 1, &in_length); mz_ulong out_length = mz_compressBound(in_length); unsigned char *out = malloc(out_length); int status = mz_compress(out, &out_length, in, in_length); if (status) { free(out); lua_pushnil(L); lua_pushstring(L, mz_error(status)); return 2; } lua_pushlstring(L, (const char*)out, out_length); free(out); return 1; }
static int lmz_deflator_init(lua_State* L) { int level = luaL_optint(L, 1, MZ_DEFAULT_COMPRESSION); if (level < MZ_DEFAULT_COMPRESSION || level > MZ_BEST_COMPRESSION) { luaL_error(L, "Compression level must be between -1 and 9"); } lmz_stream_t* stream = lua_newuserdata(L, sizeof(*stream)); mz_streamp miniz_stream = &(stream->stream); luaL_getmetatable(L, "miniz_deflator"); lua_setmetatable(L, -2); memset(miniz_stream, 0, sizeof(*miniz_stream)); int status = mz_deflateInit(miniz_stream, level); if (status != MZ_OK) { const char* msg = mz_error(status); if (msg) { luaL_error(L, "Problem initializing stream: %s", msg); } else { luaL_error(L, "Problem initializing stream"); } } stream->mode = 0; return 1; }
std::string getErrorString(const int errorCode) { return mz_error(errorCode); }
void Message::uncompress() { if (!isCompressed()) return; std::string errorStr = "Unsupported compression"; size_t actualSize; std::string comprType; std::string comprIdent = _meta["um.compressed"]; size_t colon = comprIdent.find_first_of(':'); if (colon == std::string::npos) { errorStr = "No colon found in um.compressed meta field"; goto DECOMPRESS_ERROR; } actualSize = strTo<size_t>(comprIdent.substr(0, colon)); comprType = comprIdent.substr(colon + 1); _meta["um.compressRatio"] = toStr((double)_size / (double)actualSize); // std::cout << _size << " vs " << actualSize << std::endl; if (false) {} #ifdef BUILD_WITH_COMPRESSION_MINIZ else if (comprType == "miniz") { int cmp_status; uint8_t *pUncmp; pUncmp = (mz_uint8 *)malloc((size_t)actualSize); cmp_status = mz_uncompress(pUncmp, (mz_ulong*)&actualSize, (const unsigned char *)_data.get(), _size); if (cmp_status != MZ_OK) { errorStr = mz_error(cmp_status); goto DECOMPRESS_ERROR; } _size = actualSize; _data = SharedPtr<char>((char*)pUncmp); _meta.erase("um.compressed"); return; } #endif #ifdef BUILD_WITH_COMPRESSION_FASTLZ else if (comprType == "fastlz") { void* uncompressed = malloc((size_t)actualSize); // returns the size of the decompressed block. actualSize = fastlz_decompress(_data.get(), _size, uncompressed, actualSize); // If error occurs, e.g. the compressed data is corrupted or the output buffer is not large enough, then 0 if (actualSize == 0) { errorStr = "fastlz_decompress returned 0"; goto DECOMPRESS_ERROR; } _size = actualSize; _data = SharedPtr<char>((char*)uncompressed); _meta.erase("um.compressed"); return; } #endif #ifdef BUILD_WITH_COMPRESSION_LZ4 else if (comprType == "lz4") { #ifdef LZ4_FRAME LZ4F_errorCode_t n; LZ4F_decompressionContext_t ctx; void* uncompressed = malloc((size_t)actualSize); n = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION); if (LZ4F_isError(n)) { errorStr = LZ4F_getErrorName(n); goto DECOMPRESS_ERROR; } n = LZ4F_decompress(ctx, uncompressed, &actualSize, _data.get(), &_size, NULL); if (LZ4F_isError(n)) { errorStr = LZ4F_getErrorName(n); goto DECOMPRESS_ERROR; } _size = actualSize; _data = SharedPtr<char>((char*)uncompressed); _meta.erase("um.compressed"); LZ4F_freeDecompressionContext(ctx); #else char* uncompressed = (char*)malloc((size_t)actualSize); int n = LZ4_decompress_fast(_data.get(), uncompressed, actualSize); if (n < 0) { errorStr = "Decompression failed"; goto DECOMPRESS_ERROR; } _size = actualSize; _data = SharedPtr<char>((char*)uncompressed); _meta.erase("um.compressed"); #endif return; } #endif DECOMPRESS_ERROR: UM_LOG_WARN("Could not decompress message: %s", errorStr.c_str()); }