From d5be8eb6b5193a123cbc87ac86bb0a923967e79b Mon Sep 17 00:00:00 2001 From: Teus Benschop Date: Sat, 10 Nov 2018 20:58:48 +0700 Subject: Import sword_1.8.1+dfsg.orig.tar.gz [dgit import orig sword_1.8.1+dfsg.orig.tar.gz] --- src/modules/common/xzcomprs.cpp | 213 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/modules/common/xzcomprs.cpp (limited to 'src/modules/common/xzcomprs.cpp') diff --git a/src/modules/common/xzcomprs.cpp b/src/modules/common/xzcomprs.cpp new file mode 100644 index 0000000..d29057d --- /dev/null +++ b/src/modules/common/xzcomprs.cpp @@ -0,0 +1,213 @@ +/****************************************************************************** + * + * xzcomprs.cpp - XzCompress, a driver class that provides xz (LZMA2) + * compression + * + * $Id: xzcomprs.cpp 3515 2017-11-01 11:38:09Z scribe $ + * + * Copyright 2000-2014 CrossWire Bible Society (http://www.crosswire.org) + * CrossWire Bible Society + * P. O. Box 2528 + * Tempe, AZ 85280-2528 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#include +#include +#include +#include + +#define LZMA_API_STATIC +#include + +SWORD_NAMESPACE_START + +/****************************************************************************** + * XzCompress Constructor - Initializes data for instance of XzCompress + * + */ + +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; +} + + +/****************************************************************************** + * XzCompress Destructor - Cleans up instance of XzCompress + */ + +XzCompress::~XzCompress() { +} + + +/****************************************************************************** + * XzCompress::Encode - This function "encodes" the input stream into the + * output stream. + * The GetChars() and SendChars() functions are + * used to separate this method from the actual + * i/o. + * NOTE: must set zlen for parent class to know length of + * compressed buffer. + */ + +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 occurred during compression.\n"); break; + } + } + else + { + fprintf(stderr, "ERROR: no buffer to compress\n"); + } + delete [] zbuf; + free (buf); +} + + +/****************************************************************************** + * XzCompress::Decode - This function "decodes" the input stream into the + * output stream. + * The GetChars() and SendChars() functions are + * used to separate this method from the actual + * i/o. + */ + +void XzCompress::Decode(void) +{ + direct = 1; // set direction needed by parent [Get|Send]Chars() + + // get buffer + char chunk[1024]; + char *zbuf = (char *)calloc(1, 1024); + char *chunkbuf = zbuf; + int chunklen; + unsigned long zlen = 0; + while((chunklen = GetChars(chunk, 1023))) { + memcpy(chunkbuf, chunk, chunklen); + zlen += chunklen; + if (chunklen < 1023) + break; + else zbuf = (char *)realloc(zbuf, zlen + 1024); + chunkbuf = zbuf + zlen; + } + + //printf("Decoding complength{%ld} uncomp{%ld}\n", zlen, blen); + if (zlen) { + unsigned long blen = zlen*20; // trust compression is less than 2000% + char *buf = new char[blen]; + //printf("Doing decompress {%s}\n", zbuf); + slen = 0; + 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; + } + else { + fprintf(stderr, "ERROR: no buffer to decompress!\n"); + } + //printf("Finished decoding\n"); + 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