From 1d0ff54794b5edea7cdf1d2d66710a0fa885bcc5 Mon Sep 17 00:00:00 2001 From: Teus Benschop Date: Sun, 28 Oct 2018 11:51:26 +0100 Subject: New upstream version 1.8.1 --- src/modules/common/xzcomprs.cpp | 130 +++++++++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 49 deletions(-) (limited to 'src/modules/common/xzcomprs.cpp') diff --git a/src/modules/common/xzcomprs.cpp b/src/modules/common/xzcomprs.cpp index 513e170..d29057d 100644 --- a/src/modules/common/xzcomprs.cpp +++ b/src/modules/common/xzcomprs.cpp @@ -3,7 +3,7 @@ * xzcomprs.cpp - XzCompress, a driver class that provides xz (LZMA2) * compression * - * $Id: xzcomprs.cpp 3156 2014-04-17 03:50:37Z greg.hellings $ + * $Id: xzcomprs.cpp 3515 2017-11-01 11:38:09Z scribe $ * * Copyright 2000-2014 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society @@ -21,12 +21,13 @@ * */ - #include #include #include #include -#include + +#define LZMA_API_STATIC +#include SWORD_NAMESPACE_START @@ -36,6 +37,24 @@ SWORD_NAMESPACE_START */ XzCompress::XzCompress() : SWCompress() { + level = 3; + + // start with the estimated memory usage for our preset + memlimit = lzma_easy_decoder_memusage(level | LZMA_PRESET_EXTREME); + + // and round up to a power of 2-- + // bit twiddle hack to determine next greatest power of 2 from: + // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + memlimit--; + memlimit |= memlimit >> 1; + memlimit |= memlimit >> 2; + memlimit |= memlimit >> 4; + memlimit |= memlimit >> 8; + memlimit |= memlimit >> 16; + memlimit++; + + // double that for safety's sake + memlimit <<= 1; } @@ -59,20 +78,6 @@ XzCompress::~XzCompress() { void XzCompress::Encode(void) { -/* -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least 0.1% larger than - sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ direct = 0; // set direction needed by parent [Get|Send]Chars() // get buffer @@ -90,18 +95,22 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, chunkbuf = buf+len; } - - zlen = (long) (len*1.001)+15; + zlen = (long)lzma_stream_buffer_bound(len); char *zbuf = new char[zlen+1]; + size_t zpos = 0; + if (len) { //printf("Doing compress\n"); - if (compress((Bytef*)zbuf, &zlen, (const Bytef*)buf, len) != Z_OK) - { - printf("ERROR in compression\n"); - } - else { - SendChars(zbuf, zlen); + 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 occurred during compression.\n"); break; } } else @@ -123,23 +132,7 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, void XzCompress::Decode(void) { -/* -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ + direct = 1; // set direction needed by parent [Get|Send]Chars() // get buffer char chunk[1024]; @@ -158,16 +151,25 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, //printf("Decoding complength{%ld} uncomp{%ld}\n", zlen, blen); if (zlen) { - unsigned long blen = zlen*20; // trust compression is less than 1000% + unsigned long blen = zlen*20; // trust compression is less than 2000% char *buf = new char[blen]; //printf("Doing decompress {%s}\n", zbuf); slen = 0; - switch (uncompress((Bytef*)buf, &blen, (Bytef*)zbuf, zlen)){ - case Z_OK: SendChars(buf, blen); slen = blen; break; - case Z_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break; - case Z_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break; - case Z_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during decompression.\n"); break; - default: fprintf(stderr, "ERROR: an unknown error occured during decompression.\n"); break; + size_t zpos = 0; + size_t bpos = 0; + + switch (lzma_stream_buffer_decode((uint64_t *)&memlimit, 0, NULL, (const uint8_t*)zbuf, &zpos, (size_t)zlen, (uint8_t*)buf, &bpos, (size_t)&blen)){ + case LZMA_OK: SendChars(buf, bpos); slen = bpos; break; + case LZMA_FORMAT_ERROR: fprintf(stderr, "ERROR: format error encountered during decompression.\n"); break; + case LZMA_OPTIONS_ERROR: fprintf(stderr, "ERROR: options error encountered during decompression.\n"); break; + case LZMA_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during decompression.\n"); break; + case LZMA_NO_CHECK: fprintf(stderr, "ERROR: no_check error encountered during decompression.\n"); break; + case LZMA_UNSUPPORTED_CHECK: fprintf(stderr, "ERROR: unsupported_check error encountered during decompression.\n"); break; + case LZMA_MEMLIMIT_ERROR: fprintf(stderr, "ERROR: memlimit error encountered during decompression.\n"); break; + case LZMA_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break; + case LZMA_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break; + case LZMA_PROG_ERROR: fprintf(stderr, "ERROR: program error encountered during decompression.\n"); break; + default: fprintf(stderr, "ERROR: an unknown error occurred during decompression.\n"); break; } delete [] buf; } @@ -178,4 +180,34 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, free (zbuf); } + +/****************************************************************************** + * XzCompress::SetLevel - This function sets the compression level of the + * compressor. + */ + +void XzCompress::setLevel(int l) { + level = l; + + // having changed the compression level, we need to adjust our memlimit accordingly, + // as in the constructor: + + // start with the estimated memory usage for our preset + memlimit = lzma_easy_decoder_memusage(level | LZMA_PRESET_EXTREME); + + // and round up to a power of 2-- + // bit twiddle hack to determine next greatest power of 2 from: + // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + memlimit--; + memlimit |= memlimit >> 1; + memlimit |= memlimit >> 2; + memlimit |= memlimit >> 4; + memlimit |= memlimit >> 8; + memlimit |= memlimit >> 16; + memlimit++; + + // double that for safety's sake + memlimit <<= 1; +}; + SWORD_NAMESPACE_END -- cgit v1.2.3