Last active
August 29, 2015 14:01
-
-
Save hitxiang/6fc2fa47abaa86f63c51 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include "zlib.h" | |
//#define CHUNK 16384 | |
#define CHUNK 1024 | |
#define INFLAT_RATE 16 | |
#define DEFLAT_RATE 1.2 | |
/* | |
* Please use compressBound + compress2 instead. | |
*/ | |
/* | |
Compress from in-memory buffer to another in-memory buffer. | |
atl_zlib_def() returns Z_OK on success, | |
Z_MEM_ERROR if memory could not be allocated for processing, | |
Z_DATA_ERROR if the deflate data is invalid or incomplete, | |
Z_VERSION_ERROR if the version of zlib.h and the version of the library linked do not match | |
*/ | |
int atl_zlib_def(char **dest, size_t *dest_len, const char *source, size_t src_len, int level) | |
{ | |
if (!source || src_len == 0) { | |
*dest = ""; | |
*dest_len = 0; | |
return Z_OK; | |
} | |
int ret, flush; | |
size_t in_avail_len, in_left_len = src_len, out_done_len=0; | |
size_t comp_inc = src_len * DEFLAT_RATE; | |
const char *in_ptr = source; | |
char *out_ptr = NULL, *out_tmp_ptr; | |
/* allocate deflate state */ | |
z_stream strm; | |
strm.zalloc = Z_NULL; | |
strm.zfree = Z_NULL; | |
strm.opaque = Z_NULL; | |
ret = deflateInit(&strm, level); | |
if (ret != Z_OK) | |
return ret; | |
do { | |
if ( in_left_len > CHUNK ) { | |
in_avail_len = CHUNK; | |
in_left_len -= CHUNK; | |
} else { | |
in_avail_len = in_left_len; | |
in_left_len = 0; | |
} | |
flush = (in_left_len == 0) ? Z_FINISH : Z_NO_FLUSH; | |
strm.avail_in = in_avail_len; | |
strm.next_in = (Bytef *)in_ptr; | |
/* run deflate() on input until output buffer not full, finish | |
compression if all of source has been read in */ | |
do { | |
if (out_ptr == NULL) { | |
out_ptr = (char*) calloc( sizeof(char), comp_inc ); | |
} else { | |
out_tmp_ptr = (char*) calloc( sizeof(char), out_done_len + comp_inc ); | |
memcpy(out_tmp_ptr, out_ptr, out_done_len); | |
free(out_ptr); | |
out_ptr = out_tmp_ptr; | |
} | |
strm.avail_out = comp_inc; | |
strm.next_out = (Bytef *)(out_ptr + out_done_len); | |
ret = deflate(&strm, flush); /* no bad return value */ | |
assert(ret != Z_STREAM_ERROR); /* state not clobbered */ | |
out_done_len += (comp_inc - strm.avail_out); | |
} while (strm.avail_out == 0); | |
assert(strm.avail_in == 0); /* all input will be used */ | |
in_ptr += in_avail_len; | |
} while (flush != Z_FINISH); | |
assert(ret == Z_STREAM_END); /* stream will be complete */ | |
*dest_len = out_done_len; | |
*dest = out_ptr; | |
/* clean up and return */ | |
(void)deflateEnd(&strm); | |
return Z_OK; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include "zlib.h" | |
//#define CHUNK 16384 | |
#define CHUNK 1024 | |
#define INFLAT_RATE 16 | |
#define DEFLAT_RATE 1.2 | |
/* | |
Decompress from in-memory buffer to another in-memory buffer. | |
atl_zlib_inf() returns Z_OK on success, | |
Z_MEM_ERROR if memory could not be allocated for processing, | |
Z_DATA_ERROR if the deflate data is invalid or incomplete, | |
Z_VERSION_ERROR if the version of zlib.h and the version of the library linked do not match | |
*/ | |
int atl_zlib_inf(char **dest, size_t *dest_len, const char *source, size_t src_len) | |
{ | |
if (!source || src_len == 0) { | |
*dest = ""; | |
*dest_len = 0; | |
return Z_OK; | |
} | |
int ret; | |
size_t in_avail_len, in_left_len = src_len, out_done_len=0; | |
size_t uncomp_inc = src_len * INFLAT_RATE; | |
const char *in_ptr = source; | |
char *out_ptr = NULL, *out_tmp_ptr; | |
/* allocate inflate state */ | |
z_stream strm; | |
strm.zalloc = Z_NULL; | |
strm.zfree = Z_NULL; | |
strm.opaque = Z_NULL; | |
ret = inflateInit(&strm); | |
if (ret != Z_OK) | |
return ret; | |
/* decompress until deflate stream ends or end of file */ | |
do { | |
if ( in_left_len > CHUNK ) { | |
in_avail_len = CHUNK; | |
in_left_len -= CHUNK; | |
} else { | |
in_avail_len = in_left_len; | |
in_left_len = 0; | |
} | |
if (in_avail_len == 0) | |
break; | |
strm.avail_in = in_avail_len; | |
strm.next_in = (Bytef *)in_ptr; | |
/* run inflate() on input until output buffer not full */ | |
do { | |
if (out_ptr == NULL) { | |
out_ptr = (char*) calloc( sizeof(char), uncomp_inc ); | |
} else { | |
out_tmp_ptr = (char*) calloc( sizeof(char), out_done_len + uncomp_inc ); | |
memcpy(out_tmp_ptr, out_ptr, out_done_len); | |
free(out_ptr); | |
out_ptr = out_tmp_ptr; | |
} | |
strm.avail_out = uncomp_inc; | |
strm.next_out = (Bytef *)(out_ptr + out_done_len); | |
ret = inflate(&strm, Z_NO_FLUSH); | |
assert(ret != Z_STREAM_ERROR); /* state not clobbered */ | |
switch (ret) { | |
case Z_NEED_DICT: | |
ret = Z_DATA_ERROR; /* and fall through */ | |
case Z_DATA_ERROR: | |
case Z_MEM_ERROR: | |
(void)inflateEnd(&strm); | |
return ret; | |
} | |
out_done_len += (uncomp_inc - strm.avail_out); | |
} while (strm.avail_out == 0); | |
in_ptr += in_avail_len; | |
/* done when inflate() says it's done */ | |
} while (ret != Z_STREAM_END); | |
*dest_len = out_done_len; | |
*dest = out_ptr; | |
/* clean up and return */ | |
(void)inflateEnd(&strm); | |
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void zerr(int ret) | |
{ | |
fputs("atl_zlib: ", stderr); | |
switch (ret) { | |
case Z_ERRNO: | |
if (ferror(stdin)) | |
fputs("error reading stdin\n", stderr); | |
if (ferror(stdout)) | |
fputs("error writing stdout\n", stderr); | |
break; | |
case Z_STREAM_ERROR: | |
fputs("invalid compression level\n", stderr); | |
break; | |
case Z_DATA_ERROR: | |
fputs("invalid or incomplete deflate data\n", stderr); | |
break; | |
case Z_MEM_ERROR: | |
fputs("out of memory\n", stderr); | |
break; | |
case Z_VERSION_ERROR: | |
fputs("zlib version mismatch!\n", stderr); | |
} | |
} | |
/* compress or decompress from stdin to stdout */ | |
int main(int argc, char **argv) | |
{ | |
int ret; | |
size_t buffer_len = 1024*512; | |
char buffer[buffer_len]; | |
char *rslt_str; | |
size_t rslt_len; | |
/* do compression if no arguments */ | |
if (argc == 1) { | |
size_t real_len = fread(buffer, 1, buffer_len, stdin); | |
if (real_len == buffer_len) | |
fputs("Please increase buffer", stderr); | |
//ret = atl_zlib_def(&rslt_str, &rslt_len, buffer, real_len, Z_DEFAULT_COMPRESSION); | |
rslt_len = compressBound(real_len); | |
rslt_str = (char*)malloc(rslt_len); | |
ret = compress2((Bytef*)rslt_str, &rslt_len , (Bytef*)buffer, real_len, Z_DEFAULT_COMPRESSION); | |
if (ret != Z_OK) | |
zerr(ret); | |
fwrite(rslt_str, 1, rslt_len, stdout); | |
free(rslt_str); | |
return ret; | |
} | |
/* do decompression if -d specified */ | |
else if (argc == 2 && strcmp(argv[1], "-d") == 0) { | |
size_t real_len = fread(buffer, 1, buffer_len, stdin); | |
if (real_len == buffer_len) | |
fputs("Please increase buffer\n", stderr); | |
ret = atl_zlib_inf(&rslt_str, &rslt_len , buffer, real_len); | |
if (ret != Z_OK) | |
zerr(ret); | |
fwrite(rslt_str, 1, rslt_len, stdout); | |
free(rslt_str); | |
return ret; | |
} | |
/* otherwise, report usage */ | |
else { | |
fputs("atl_zlib usage: atl_zlib [-d] < source > dest\n", stderr); | |
return 1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment