aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/comp/c_zlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/comp/c_zlib.c')
-rw-r--r--crypto/comp/c_zlib.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c
new file mode 100644
index 0000000000..35ab0c63dc
--- /dev/null
+++ b/crypto/comp/c_zlib.c
@@ -0,0 +1,144 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "objects.h"
+#include "comp.h"
+
+COMP_METHOD *COMP_zlib(void );
+
+#ifndef ZLIB
+
+static COMP_METHOD zlib_method={
+ NID_undef,
+ "(null)",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+
+#else
+
+#include <zlib.h>
+
+static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen);
+static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen);
+
+static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
+ uLong sourceLen);
+
+static COMP_METHOD zlib_method={
+ NID_zlib_compression,
+ LN_zlib_compression,
+ NULL,
+ NULL,
+ zlib_compress_block,
+ zlib_expand_block,
+ NULL,
+ };
+
+static int zlib_compress_block(ctx,out,olen,in,ilen)
+COMP_CTX *ctx;
+unsigned char *out;
+unsigned int olen;
+unsigned char *in;
+unsigned int ilen;
+ {
+ unsigned long l;
+ int i;
+ int clear=1;
+
+ if (ilen > 128)
+ {
+ out[0]=1;
+ l=olen-1;
+ i=compress(&(out[1]),&l,in,(unsigned long)ilen);
+ if (i != Z_OK)
+ return(-1);
+ if (ilen > l)
+ {
+ clear=0;
+ l++;
+ }
+ }
+ if (clear)
+ {
+ out[0]=0;
+ memcpy(&(out[1]),in,ilen);
+ l=ilen+1;
+ }
+fprintf(stderr,"compress(%4d)->%4d %s\n",ilen,(int)l,(clear)?"clear":"zlib");
+ return((int)l);
+ }
+
+static int zlib_expand_block(ctx,out,olen,in,ilen)
+COMP_CTX *ctx;
+unsigned char *out;
+unsigned int olen;
+unsigned char *in;
+unsigned int ilen;
+ {
+ unsigned long l;
+ int i;
+
+ if (in[0])
+ {
+ l=olen;
+ i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
+ if (i != Z_OK)
+ return(-1);
+ }
+ else
+ {
+ memcpy(out,&(in[1]),ilen-1);
+ l=ilen-1;
+ }
+ fprintf(stderr,"expand (%4d)->%4d %s\n",ilen,(int)l,in[0]?"zlib":"clear");
+ return((int)l);
+ }
+
+static int zz_uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
+
+#endif
+
+COMP_METHOD *COMP_zlib()
+ {
+ return(&zlib_method);
+ }
+