URI: 
       tcompress.c - mixmaster - mixmaster 3.0 patched for libressl
  HTML git clone git://parazyd.org/mixmaster.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
       tcompress.c (4790B)
       ---
            1 /* Mixmaster version 3.0  --  (C) 1999 - 2006 Anonymizer Inc. and others.
            2 
            3    Mixmaster may be redistributed and modified under certain conditions.
            4    This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
            5    ANY KIND, either express or implied. See the file COPYRIGHT for
            6    details.
            7 
            8    Buffer compression (interface to zlib)
            9    $Id: compress.c 934 2006-06-24 13:40:39Z rabbi $ */
           10 
           11 
           12 #include "mix3.h"
           13 #include <stdio.h>
           14 #include <assert.h>
           15 
           16 static byte gz_magic[2] =
           17 {0x1f, 0x8b};                        /* gzip magic header */
           18 
           19 /* gzip flag byte */
           20 #define ASCII_FLAG   0x01
           21 #define HEAD_CRC     0x02
           22 #define EXTRA_FIELD  0x04
           23 #define ORIG_NAME    0x08
           24 #define COMMENT      0x10
           25 #define RESERVED     0xE0
           26 #define Z_DEFLATED   8
           27 
           28 #ifdef USE_ZLIB
           29 #include "zlib.h"
           30 
           31 int buf_unzip(BUFFER *in, int type)
           32 {
           33   BUFFER *out;
           34   z_stream s;
           35   long outstart;
           36   int err;
           37   int ret = 0;
           38 
           39   out = buf_new();
           40 
           41   s.zalloc = (alloc_func) 0;
           42   s.zfree = (free_func) 0;
           43   s.opaque = (voidpf) 0;
           44 
           45   s.next_in = in->data + in->ptr;
           46   s.avail_in = in->length + 1 - in->ptr;        /* terminating 0 byte as "dummy" */
           47   s.next_out = NULL;
           48 
           49   if (type == 1)
           50     err = inflateInit(&s);    /* zlib */
           51   else
           52     err = inflateInit2(&s, -MAX_WBITS);
           53   if (err != Z_OK) {
           54     ret = -1;
           55     goto end;
           56   }
           57   outstart = 0;
           58   buf_append(out, NULL, in->length * 15 / 10);
           59 
           60   for (;;) {
           61     s.next_out = out->data + s.total_out + outstart;
           62     s.avail_out = out->length - outstart - s.total_out;
           63     err = inflate(&s, Z_PARTIAL_FLUSH);
           64     out->length -= s.avail_out;
           65     if (err != Z_OK)
           66       break;
           67     buf_append(out, NULL, BUFSIZE);
           68   }
           69   if (err != Z_STREAM_END)
           70     errlog(WARNING, "Decompression error %d\n", err);
           71 
           72   err = inflateEnd(&s);
           73   if (err != Z_OK)
           74     ret = -1;
           75 end:
           76   if (ret != 0)
           77     switch (err) {
           78     case Z_STREAM_ERROR:
           79       errlog(ERRORMSG, "Decompression error Z_STREAM_ERROR.\n", err);
           80       break;
           81     case Z_MEM_ERROR:
           82       errlog(ERRORMSG, "Decompression error Z_MEM_ERROR.\n", err);
           83       break;
           84     case Z_BUF_ERROR:
           85       errlog(ERRORMSG, "Decompression error Z_BUF_ERROR.\n", err);
           86       break;
           87     case Z_VERSION_ERROR:
           88       errlog(ERRORMSG, "Decompression error Z_VERSION_ERROR.\n", err);
           89       break;
           90     default:
           91       errlog(ERRORMSG, "Decompression error %d.\n", err);
           92     }
           93   buf_move(in, out);
           94   buf_free(out);
           95   return (ret);
           96 }
           97 
           98 int buf_zip(BUFFER *out, BUFFER *in, int bits)
           99 {
          100   z_stream s;
          101   long outstart;
          102   int err = -1;
          103 
          104   assert(in != out);
          105 
          106   s.zalloc = (alloc_func) 0;
          107   s.zfree = (free_func) 0;
          108   s.opaque = (voidpf) 0;
          109   s.next_in = NULL;
          110 
          111   if (bits == 0)
          112     bits = MAX_WBITS;
          113 
          114   if (deflateInit2(&s, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -bits, 8, 0) != Z_OK)
          115     goto end;
          116 
          117   outstart = out->length;
          118   /* 12 is overhead, 1.01 is maximum expansion, and 1 is there to force a round-up */
          119   buf_append(out, NULL, (int)13+in->length*1.01); /* fit it in one chunk */
          120 
          121   s.next_in = in->data;
          122   s.avail_in = in->length;
          123 
          124   for (;;) {
          125     s.next_out = out->data + s.total_out + outstart;
          126     s.avail_out = out->length - outstart - s.total_out;
          127     err = deflate(&s, Z_FINISH);
          128     out->length -= s.avail_out;
          129     if (err != Z_OK)
          130       break;
          131     errlog(ERRORMSG, "Compressed data did not fit in one chunk.\n");
          132     buf_append(out, NULL, BUFSIZE);
          133   }
          134   if (deflateEnd(&s) != Z_OK || err != Z_STREAM_END)
          135     err = -1;
          136   else
          137     err = 0;
          138 end:
          139   if (err != 0)
          140     errlog(ERRORMSG, "Compression error.\n");
          141   return (err);
          142 }
          143 
          144 #else /* end of USE_ZLIB */
          145 int buf_zip(BUFFER *out, BUFFER *in, int bits)
          146 {
          147   return (-1);
          148 }
          149 
          150 int buf_unzip(BUFFER *b, int type)
          151 {
          152   errlog(ERRORMSG, "Can't uncompress: no zlib\n");
          153   return (-1);
          154 }
          155 #endif /* else not USE_ZLIB */
          156 
          157 int compressed(BUFFER *b)
          158 {
          159   return (b->length >= 10 && b->data[0] == gz_magic[0] &&
          160           b->data[1] == gz_magic[1]);
          161 }
          162 
          163 int buf_uncompress(BUFFER *in)
          164 {
          165   int type;
          166   int err = -1;
          167   unsigned int len;
          168 
          169   if (!compressed(in))
          170     return (0);
          171   type = in->data[3];
          172   if (in->data[2] != Z_DEFLATED || (type & RESERVED) == 0) {
          173     in->ptr = 10;
          174     if ((type & EXTRA_FIELD) != 0) {
          175       len = buf_geti(in);
          176       in->ptr += len;
          177     }
          178     if ((type & ORIG_NAME) != 0)
          179       while (buf_getc(in) > 0) ;
          180     if ((type & COMMENT) != 0)
          181       while (buf_getc(in) > 0) ;
          182     if ((type & HEAD_CRC) != 0)
          183       buf_geti(in);
          184     err = buf_unzip(in, 0);
          185   }
          186   return (err);
          187 }
          188 
          189 int buf_compress(BUFFER *in)
          190 {
          191   BUFFER *out;
          192   int err;
          193 
          194   if (compressed(in))
          195     return (0);
          196 
          197   out = buf_new();
          198   buf_appendc(out, gz_magic[0]);
          199   buf_appendc(out, gz_magic[1]);
          200   buf_appendc(out, Z_DEFLATED);
          201   buf_appendc(out, 0);                /* flags */
          202   buf_appendl(out, 0);                /* time */
          203   buf_appendc(out, 0);                /* xflags */
          204   buf_appendc(out, 3);                /* Unix */
          205   err = buf_zip(out, in, 0);
          206   if (err == 0)
          207     buf_move(in, out);
          208   buf_free(out);
          209   return (err);
          210 }