[sword-svn] r3051 - in trunk: include src/modules/common

chrislit at crosswire.org chrislit at crosswire.org
Mon Mar 3 05:47:28 MST 2014


Author: chrislit
Date: 2014-03-03 05:47:28 -0700 (Mon, 03 Mar 2014)
New Revision: 3051

Modified:
   trunk/include/xzcomprs.h
   trunk/src/modules/common/xzcomprs.cpp
Log:
fixed xz (lzma2) compression such that it compiles, mod2zmod can compress, and diatheke can decompress


Modified: trunk/include/xzcomprs.h
===================================================================
--- trunk/include/xzcomprs.h	2014-03-02 11:49:22 UTC (rev 3050)
+++ trunk/include/xzcomprs.h	2014-03-03 12:47:28 UTC (rev 3051)
@@ -42,7 +42,7 @@
 	virtual void Encode(void);
 	virtual void Decode(void);
 private:
-	lzma_block block;
+	uint64_t memlimit; // memory usage limit during decompression
 };
 
 SWORD_NAMESPACE_END

Modified: trunk/src/modules/common/xzcomprs.cpp
===================================================================
--- trunk/src/modules/common/xzcomprs.cpp	2014-03-02 11:49:22 UTC (rev 3050)
+++ trunk/src/modules/common/xzcomprs.cpp	2014-03-03 12:47:28 UTC (rev 3051)
@@ -27,6 +27,8 @@
 #include <stdio.h>
 #include <xzcomprs.h>
 
+#define XZ_PRESET 3 | LZMA_PRESET_EXTREME
+
 SWORD_NAMESPACE_START
 
 /******************************************************************************
@@ -35,6 +37,22 @@
  */
 
 XzCompress::XzCompress() : SWCompress() {
+	// start with the estimated memory usage for our preset
+	memlimit = lzma_easy_decoder_memusage(XZ_PRESET);
+	
+	// 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;
 }
 
 
@@ -75,20 +93,23 @@
 		chunkbuf = buf+len;
 	}
 
-
-	zlen = (long) (len*1.001)+15;  // TODO: check that this is sufficient
+	zlen = (long)lzma_stream_buffer_bound(len);
 	char *zbuf = new char[zlen+1];
 	size_t zpos = 0;
+
 	if (len)
 	{
 		//printf("Doing compress\n");
-		if (lzma_block_buffer_encode(&block, NULL, (const uint8_t*)buf, (size_t)len, (uint8_t*)zbuf, &zpos, (size_t)zlen) != LZMA_OK)
-		{
-			printf("ERROR in compression\n");
+		switch (lzma_easy_buffer_encode(XZ_PRESET, 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 {
-			SendChars(zbuf, zlen);
-		}
 	}
 	else
 	{
@@ -126,18 +147,24 @@
 
 	//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;
 		size_t zpos = 0;
 		size_t bpos = 0;
 
-		switch (lzma_block_buffer_decode(&block, NULL, (const uint8_t*)zbuf, &zpos, (size_t)zlen, (uint8_t*)buf, &bpos, (size_t)&blen)){
-			case LZMA_OK: SendChars(buf, blen); slen = blen; break;
+		switch (lzma_stream_buffer_decode(&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_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data 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 occured during decompression.\n"); break;
 		}
 		delete [] buf;




More information about the sword-cvs mailing list