// don't inline, to be friendly to js engine osr void __attribute__ ((noinline)) doit(char *buffer, int size, int i) { static char *buffer2 = NULL; static char *buffer3 = NULL; unsigned long maxCompressedSize = lzma_stream_buffer_bound(size); if (!buffer2) buffer2 = (char*)malloc(maxCompressedSize); if (!buffer3) buffer3 = (char*)malloc(size); size_t compressedSize = 0; int ret = lzma_easy_buffer_encode(LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64, NULL, (const uint8_t*)buffer, size, (uint8_t*)buffer2, &compressedSize, maxCompressedSize); assert(ret == LZMA_OK); if (i == 0) printf("sizes: %d,%d\n", size, compressedSize); lzma_stream strm = LZMA_STREAM_INIT; ret = lzma_stream_decoder(&strm, UINT64_MAX, 0); assert(ret == LZMA_OK); strm.next_in = (const uint8_t*)buffer2; strm.avail_in = compressedSize; strm.next_out = (uint8_t*)buffer3; strm.avail_out = size; ret = lzma_code (&strm, LZMA_FINISH); assert(ret == LZMA_OK || ret == LZMA_STREAM_END); size_t decompressedSize = size - strm.avail_out; assert(decompressedSize == size); if (i == 0) assert(strcmp(buffer, buffer3) == 0); }
void XzCompress::Encode(void) { direct = 0; // set direction needed by parent [Get|Send]Chars() // get buffer char chunk[1024]; char *buf = (char *)calloc(1, 1024); char *chunkbuf = buf; unsigned long chunklen; unsigned long len = 0; while((chunklen = GetChars(chunk, 1023))) { memcpy(chunkbuf, chunk, chunklen); len += chunklen; if (chunklen < 1023) break; else buf = (char *)realloc(buf, len + 1024); chunkbuf = buf+len; } zlen = (long)lzma_stream_buffer_bound(len); char *zbuf = new char[zlen+1]; size_t zpos = 0; if (len) { //printf("Doing compress\n"); switch (lzma_easy_buffer_encode(level | LZMA_PRESET_EXTREME, LZMA_CHECK_CRC64, NULL, (const uint8_t*)buf, (size_t)len, (uint8_t*)zbuf, &zpos, (size_t)zlen)) { case LZMA_OK: SendChars(zbuf, zpos); break; case LZMA_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during compression.\n"); break; case LZMA_UNSUPPORTED_CHECK: fprintf(stderr, "ERROR: unsupported_check error encountered during decompression.\n"); break; case LZMA_OPTIONS_ERROR: fprintf(stderr, "ERROR: options error encountered during decompression.\n"); break; case LZMA_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during compression.\n"); break; case LZMA_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during compression.\n"); break; case LZMA_PROG_ERROR: fprintf(stderr, "ERROR: program error encountered during decompression.\n"); break; default: fprintf(stderr, "ERROR: an unknown error occured during compression.\n"); break; } } else { fprintf(stderr, "ERROR: no buffer to compress\n"); } delete [] zbuf; free (buf); }
Array<uint8_t> compress(RawArray<const uint8_t> data, int level, event_t event) { thread_time_t time(compress_kind,event); if (level<20) { // zlib size_t dest_size = compressBound(data.size()); Array<uint8_t> compressed(CHECK_CAST_INT(dest_size),uninit); int z = compress2(compressed.data(),&dest_size,(uint8_t*)data.data(),data.size(),level); if (z!=Z_OK) THROW(IOError,"zlib failure in compress_and_write: %s",zlib_error(z)); return compressed.slice_own(0,CHECK_CAST_INT(dest_size)); } else { // lzma size_t dest_size = lzma_stream_buffer_bound(data.size()); Array<uint8_t> compressed(CHECK_CAST_INT(dest_size),uninit); size_t pos = 0; lzma_ret r = lzma_easy_buffer_encode(level-20,LZMA_CHECK_CRC64,0,data.data(),data.size(),compressed.data(),&pos,dest_size); if (r!=LZMA_OK) THROW(RuntimeError,"lzma compression error: %s (%d)",lzma_error(r),r); return compressed.slice_own(0,CHECK_CAST_INT(pos)); } }
bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) { lzma_ret ret; size_t out_pos = 0; assert(src); assert(src_size > 0); assert(dst); assert(dst_size); /* Returns false if we couldn't compress the data or the * compressed result is longer than the original */ ret = lzma_easy_buffer_encode(LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE, NULL, src, src_size, dst, &out_pos, src_size); if (ret != LZMA_OK) return false; /* Is it actually shorter? */ if (out_pos == src_size) return false; *dst_size = out_pos; return true; }