ckolivas / lrzip

Long Range Zip
http://lrzip.kolivas.org
GNU General Public License v2.0
612 stars 76 forks source link

Compress failed in compthread #1

Closed gotti-zz closed 13 years ago

gotti-zz commented 13 years ago

I tried to compress a Windows 7 VMware vmdk file with 25 GByte which worked with the standard LZMA as expected. But then I tried bzip2 and gzip mode and both failed with the above error.

I took a short look at the source and found following solution for me, with this I could go further and have now a malloc problem which I will try to solve later.

--- lrzip-0.551/stream.c    2010-12-12 07:49:00.000000000 +0100
+++ lrzip-0.551/stream.c.new    2010-12-14 15:23:51.192320814 +0100
@@ -213,6 +213,7 @@
 {
    u32 dlen = cthread->s_len;
    uchar *c_buf;
+   int bzip2_ret;

    if (!lzo_compresses(cthread->s_buf, cthread->s_len))
        return 0;
@@ -223,9 +224,21 @@
        return -1;
    }

-   if (BZ2_bzBuffToBuffCompress((char *)c_buf, &dlen,
+   bzip2_ret = BZ2_bzBuffToBuffCompress((char *)c_buf, &dlen,
        (char *)cthread->s_buf, cthread->s_len,
-       control.compression_level, 0, control.compression_level * 10) != BZ_OK) {
+       control.compression_level, 0, control.compression_level * 10);
+
+   /* if compressed data is bigger then original data leave
+           as CTYPE_NONE */
+
+   if (bzip2_ret == BZ_OUTBUFF_FULL) {
+       print_maxverbose("Incompressible block\n");
+       /* Incompressible, leave as CTYPE_NONE */
+       free(c_buf);
+       return 0;
+   }
+
+   if (bzip2_ret != BZ_OK) {
            free(c_buf);
            print_maxverbose("BZ2 compress failed\n");
            return -1;
@@ -249,6 +262,7 @@
 {
    unsigned long dlen = cthread->s_len;
    uchar *c_buf;
+   int gzip_ret;

    c_buf = malloc(dlen);
    if (!c_buf) {
@@ -256,8 +270,20 @@
        return -1;
    }

-   if (compress2(c_buf, &dlen, cthread->s_buf, cthread->s_len,
-       control.compression_level) != Z_OK) {
+   gzip_ret = compress2(c_buf, &dlen, cthread->s_buf, cthread->s_len,
+   control.compression_level);
+
+   /* if compressed data is bigger then original data leave 
+      as CTYPE_NONE */
+
+   if (gzip_ret == Z_BUF_ERROR) {
+       print_maxverbose("Incompressible block\n");
+       /* Incompressible, leave as CTYPE_NONE */
+       free(c_buf);
+       return 0;
+   }
+
+   if (gzip_ret != Z_OK) {
            free(c_buf);
            print_maxverbose("compress2 failed\n");
            return -1;
ckolivas commented 13 years ago

That looks good and consistent with the rest of the code, thanks! I'll apply it when I get a chance.