zlib解压
#include "zlib.h"
#include <stdio.h>
#ifdef STDC
# include <string.h>
# include <stdlib.h>
#endif
#ifdef USE_MMAP
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/stat.h>
#endif
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# ifdef UNDER_CE
# include <stdlib.h>
# endif
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
# define snprintf _snprintf
#endif
#ifdef VMS
# define unlink delete
# define GZ_SUFFIX "-gz"
#endif
#ifdef RISCOS
# define unlink remove
# define GZ_SUFFIX "-gz"
# define fileno(file) file->__file
#endif
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h>
#endif
#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
#ifndef WIN32
extern int unlink
OF((const char *));
#endif
#endif
#if defined(UNDER_CE)
# include <windows.h>
# define perror(s) pwinerror(s)
static char *strwinerror
(error
)
DWORD error
;
{
static char buf
[1024];
wchar_t
*msgbuf
;
DWORD lasterr
= GetLastError();
DWORD chars
= FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
NULL,
error
,
0,
(LPVOID
)&msgbuf
,
0,
NULL);
if (chars
!= 0) {
if (chars
>= 2
&& msgbuf
[chars
- 2] == '\r' && msgbuf
[chars
- 1] == '\n') {
chars
-= 2;
msgbuf
[chars
] = 0;
}
if (chars
> sizeof (buf
) - 1) {
chars
= sizeof (buf
) - 1;
msgbuf
[chars
] = 0;
}
wcstombs(buf
, msgbuf
, chars
+ 1);
LocalFree(msgbuf
);
}
else {
sprintf(buf
, "unknown win32 error (%ld)", error
);
}
SetLastError(lasterr
);
return buf
;
}
static void pwinerror
(s
)
const char *s
;
{
if (s
&& *s
)
fprintf(stderr, "%s: %s\n", s
, strwinerror(GetLastError
()));
else
fprintf(stderr, "%s\n", strwinerror(GetLastError
()));
}
#endif
#ifndef GZ_SUFFIX
# define GZ_SUFFIX ".gz"
#endif
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
#define BUFLEN 16384
#define MAX_NAME_LEN 1024
#ifdef MAXSEG_64K
# define local static
#else
# define local
#endif
#ifdef Z_SOLO
#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
# include <unistd.h>
#endif
void *myalloc
OF((void *, unsigned, unsigned));
void myfree
OF((void *, void *));
void *myalloc(q
, n
, m
)
void *q
;
unsigned n
, m
;
{
(void)q
;
return calloc(n
, m
);
}
void myfree(q
, p
)
void *q
, *p
;
{
(void)q
;
free(p
);
}
typedef struct gzFile_s
{
FILE
*file
;
int write
;
int err
;
char *msg
;
z_stream strm
;
} *gzFile
;
gzFile gzopen
OF((const char *, const char *));
gzFile gzdopen
OF((int, const char *));
gzFile gz_open
OF((const char *, int, const char *));
gzFile
gzopen(path
, mode
)
const char *path
;
const char *mode
;
{
return gz_open(path
, -1, mode
);
}
gzFile
gzdopen(fd
, mode
)
int fd
;
const char *mode
;
{
return gz_open(NULL, fd
, mode
);
}
gzFile
gz_open(path
, fd
, mode
)
const char *path
;
int fd
;
const char *mode
;
{
gzFile gz
;
int ret
;
gz
= malloc(sizeof(struct gzFile_s
));
if (gz
== NULL)
return NULL;
gz
->write
= strchr(mode
, 'w') != NULL;
gz
->strm
.zalloc
= myalloc
;
gz
->strm
.zfree
= myfree
;
gz
->strm
.opaque
= Z_NULL
;
if (gz
->write
)
ret
= deflateInit2(&(gz
->strm
), -1, 8, 15 + 16, 8, 0);
else {
gz
->strm
.next_in
= 0;
gz
->strm
.avail_in
= Z_NULL
;
ret
= inflateInit2(&(gz
->strm
), 15 + 16);
}
if (ret
!= Z_OK
) {
free(gz
);
return NULL;
}
gz
->file
= path
== NULL ? fdopen(fd
, gz
->write
? "wb" : "rb") :
fopen(path
, gz
->write
? "wb" : "rb");
if (gz
->file
== NULL) {
gz
->write
? deflateEnd(&(gz
->strm
)) : inflateEnd(&(gz
->strm
));
free(gz
);
return NULL;
}
gz
->err
= 0;
gz
->msg
= "";
return gz
;
}
int gzwrite
OF((gzFile
, const void *, unsigned));
int gzwrite(gz
, buf
, len
)
gzFile gz
;
const void *buf
;
unsigned len
;
{
z_stream
*strm
;
unsigned char out
[BUFLEN
];
if (gz
== NULL || !gz
->write
)
return 0;
strm
= &(gz
->strm
);
strm
->next_in
= (void *)buf
;
strm
->avail_in
= len
;
do {
strm
->next_out
= out
;
strm
->avail_out
= BUFLEN
;
(void)deflate(strm
, Z_NO_FLUSH
);
fwrite(out
, 1, BUFLEN
- strm
->avail_out
, gz
->file
);
} while (strm
->avail_out
== 0);
return len
;
}
int gzread
OF((gzFile
, void *, unsigned));
int gzread(gz
, buf
, len
)
gzFile gz
;
void *buf
;
unsigned len
;
{
int ret
;
unsigned got
;
unsigned char in
[1];
z_stream
*strm
;
if (gz
== NULL || gz
->write
)
return 0;
if (gz
->err
)
return 0;
strm
= &(gz
->strm
);
strm
->next_out
= (void *)buf
;
strm
->avail_out
= len
;
do {
got
= fread(in
, 1, 1, gz
->file
);
if (got
== 0)
break;
strm
->next_in
= in
;
strm
->avail_in
= 1;
ret
= inflate(strm
, Z_NO_FLUSH
);
if (ret
== Z_DATA_ERROR
) {
gz
->err
= Z_DATA_ERROR
;
gz
->msg
= strm
->msg
;
return 0;
}
if (ret
== Z_STREAM_END
)
inflateReset(strm
);
} while (strm
->avail_out
);
return len
- strm
->avail_out
;
}
int gzclose
OF((gzFile
));
int gzclose(gz
)
gzFile gz
;
{
z_stream
*strm
;
unsigned char out
[BUFLEN
];
if (gz
== NULL)
return Z_STREAM_ERROR
;
strm
= &(gz
->strm
);
if (gz
->write
) {
strm
->next_in
= Z_NULL
;
strm
->avail_in
= 0;
do {
strm
->next_out
= out
;
strm
->avail_out
= BUFLEN
;
(void)deflate(strm
, Z_FINISH
);
fwrite(out
, 1, BUFLEN
- strm
->avail_out
, gz
->file
);
} while (strm
->avail_out
== 0);
deflateEnd(strm
);
}
else
inflateEnd(strm
);
fclose(gz
->file
);
free(gz
);
return Z_OK
;
}
const char *gzerror
OF((gzFile
, int *));
const char *gzerror(gz
, err
)
gzFile gz
;
int *err
;
{
*err
= gz
->err
;
return gz
->msg
;
}
#endif
static char *prog
;
void error
OF((const char *msg
));
void gz_compress
OF((FILE
*in
, gzFile out
));
#ifdef USE_MMAP
int gz_compress_mmap
OF((FILE
*in
, gzFile out
));
#endif
void gz_uncompress
OF((gzFile in
, FILE
*out
));
void file_compress
OF((char *file
, char *mode
));
void file_uncompress
OF((char *file
));
int main
OF((int argc
, char *argv
[]));
void error(msg
)
const char *msg
;
{
fprintf(stderr, "%s: %s\n", prog
, msg
);
exit(1);
}
void gz_compress(in
, out
)
FILE
*in
;
gzFile out
;
{
local
char buf
[BUFLEN
];
int len
;
int err
;
#ifdef USE_MMAP
if (gz_compress_mmap(in
, out
) == Z_OK
) return;
#endif
for (;;) {
len
= (int)fread(buf
, 1, sizeof(buf
), in
);
if (ferror(in
)) {
perror("fread");
exit(1);
}
if (len
== 0) break;
if (gzwrite(out
, buf
, (unsigned)len
) != len
) error(gzerror(out
, &err
));
}
fclose(in
);
if (gzclose(out
) != Z_OK
) error("failed gzclose");
}
#ifdef USE_MMAP
int gz_compress_mmap(in
, out
)
FILE
*in
;
gzFile out
;
{
int len
;
int err
;
int ifd
= fileno(in
);
caddr_t buf
;
off_t buf_len
;
struct stat sb
;
if (fstat(ifd
, &sb
) < 0) return Z_ERRNO
;
buf_len
= sb
.st_size
;
if (buf_len
<= 0) return Z_ERRNO
;
buf
= mmap((caddr_t
) 0, buf_len
, PROT_READ
, MAP_SHARED
, ifd
, (off_t
)0);
if (buf
== (caddr_t
)(-1)) return Z_ERRNO
;
len
= gzwrite(out
, (char *)buf
, (unsigned)buf_len
);
if (len
!= (int)buf_len
) error(gzerror(out
, &err
));
munmap(buf
, buf_len
);
fclose(in
);
if (gzclose(out
) != Z_OK
) error("failed gzclose");
return Z_OK
;
}
#endif
void gz_uncompress(in
, out
)
gzFile in
;
FILE
*out
;
{
local
char buf
[BUFLEN
];
int len
;
int err
;
for (;;) {
len
= gzread(in
, buf
, sizeof(buf
));
if (len
< 0) error
(gzerror(in
, &err
));
if (len
== 0) break;
if ((int)fwrite(buf
, 1, (unsigned)len
, out
) != len
) {
error("failed fwrite");
}
}
if (fclose(out
)) error("failed fclose");
if (gzclose(in
) != Z_OK
) error("failed gzclose");
}
void file_compress(file
, mode
)
char *file
;
char *mode
;
{
local
char outfile
[MAX_NAME_LEN
];
FILE
*in
;
gzFile out
;
if (strlen(file
) + strlen(GZ_SUFFIX
) >= sizeof(outfile
)) {
fprintf(stderr, "%s: filename too long\n", prog
);
exit(1);
}
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(outfile
, sizeof(outfile
), "%s%s", file
, GZ_SUFFIX
);
#else
strcpy(outfile
, file
);
strcat(outfile
, GZ_SUFFIX
);
#endif
in
= fopen(file
, "rb");
if (in
== NULL) {
perror(file
);
exit(1);
}
out
= gzopen(outfile
, mode
);
if (out
== NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog
, outfile
);
exit(1);
}
gz_compress(in
, out
);
unlink(file
);
}
void file_uncompress(file
)
char *file
;
{
local
char buf
[MAX_NAME_LEN
];
char *infile
, *outfile
;
FILE
*out
;
gzFile in
;
unsigned len
= strlen(file
);
if (len
+ strlen(GZ_SUFFIX
) >= sizeof(buf
)) {
fprintf(stderr, "%s: filename too long\n", prog
);
exit(1);
}
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(buf
, sizeof(buf
), "%s", file
);
#else
strcpy(buf
, file
);
#endif
if (len
> SUFFIX_LEN
&& strcmp(file
+len
-SUFFIX_LEN
, GZ_SUFFIX
) == 0) {
infile
= file
;
outfile
= buf
;
outfile
[len
-3] = '\0';
} else {
outfile
= file
;
infile
= buf
;
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(buf
+ len
, sizeof(buf
) - len
, "%s", GZ_SUFFIX
);
#else
strcat(infile
, GZ_SUFFIX
);
#endif
}
in
= gzopen(infile
, "rb");
if (in
== NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog
, infile
);
exit(1);
}
out
= fopen(outfile
, "wb");
if (out
== NULL) {
perror(file
);
exit(1);
}
gz_uncompress(in
, out
);
unlink(infile
);
}
int main(argc
, argv
)
int argc
;
char *argv
[];
{
int copyout
= 0;
int uncompr
= 0;
gzFile file
;
char *bname
, outmode
[20];
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(outmode
, sizeof(outmode
), "%s", "wb6 ");
#else
strcpy(outmode
, "wb6 ");
#endif
prog
= argv
[0];
bname
= strrchr(argv
[0], '/');
if (bname
)
bname
++;
else
bname
= argv
[0];
argc
--, argv
++;
if (!strcmp(bname
, "gunzip"))
uncompr
= 1;
else if (!strcmp(bname
, "zcat"))
copyout
= uncompr
= 1;
while (argc
> 0) {
if (strcmp(*argv
, "-c") == 0)
copyout
= 1;
else if (strcmp(*argv
, "-d") == 0)
uncompr
= 1;
else if (strcmp(*argv
, "-f") == 0)
outmode
[3] = 'f';
else if (strcmp(*argv
, "-h") == 0)
outmode
[3] = 'h';
else if (strcmp(*argv
, "-r") == 0)
outmode
[3] = 'R';
else if ((*argv
)[0] == '-' && (*argv
)[1] >= '1' && (*argv
)[1] <= '9' &&
(*argv
)[2] == 0)
outmode
[2] = (*argv
)[1];
else
break;
argc
--, argv
++;
}
if (outmode
[3] == ' ')
outmode
[3] = 0;
if (argc
== 0) {
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
if (uncompr
) {
file
= gzdopen(fileno(stdin), "rb");
if (file
== NULL) error("can't gzdopen stdin");
gz_uncompress(file
, stdout);
} else {
file
= gzdopen(fileno(stdout), outmode
);
if (file
== NULL) error("can't gzdopen stdout");
gz_compress(stdin, file
);
}
} else {
if (copyout
) {
SET_BINARY_MODE(stdout);
}
do {
if (uncompr
) {
if (copyout
) {
file
= gzopen(*argv
, "rb");
if (file
== NULL)
fprintf(stderr, "%s: can't gzopen %s\n", prog
, *argv
);
else
gz_uncompress(file
, stdout);
} else {
file_uncompress(*argv
);
}
} else {
if (copyout
) {
FILE
* in
= fopen(*argv
, "rb");
if (in
== NULL) {
perror(*argv
);
} else {
file
= gzdopen(fileno(stdout), outmode
);
if (file
== NULL) error("can't gzdopen stdout");
gz_compress(in
, file
);
}
} else {
file_compress(*argv
, outmode
);
}
}
} while (argv
++, --argc
);
}
return 0;
}
装上zlib-dev这个包后
执行gcc -zlib_decompress.c -o zlib_decompress -lz即可
zlib压缩
代码如下
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
int gzcompress(Bytef
*data
, uLong dlen
, Bytef
*zdata
, uLong
*zdlen
)
{
int err
= 0;
z_stream c_stream
;
printf("%s: data=%p, dlen=%lu, zdata=%p, *zdlen=%lu\n",
__func__, data
, dlen
, zdata
, *zdlen
);
if(data
&& dlen
> 0)
{
c_stream
.zalloc
= NULL;
c_stream
.zfree
= NULL;
c_stream
.opaque
= NULL;
if(deflateInit2(&c_stream
, Z_DEFAULT_COMPRESSION
, Z_DEFLATED
,
MAX_WBITS
+ 16, 8, Z_DEFAULT_STRATEGY
) != Z_OK
)
{
printf("%s: deflateinit2 failed!\n",__func__);
return -1;
}
c_stream
.next_in
= data
;
c_stream
.avail_in
= dlen
;
c_stream
.next_out
= zdata
;
c_stream
.avail_out
= *zdlen
;
while(c_stream
.avail_in
!= 0 && c_stream
.total_out
< *zdlen
)
{
if(deflate(&c_stream
, Z_NO_FLUSH
) != Z_OK
) {
printf("%s: deflate failed!\n",__func__);
return -1;
}
}
if(c_stream
.avail_in
!= 0) {
printf("%s: avail_in not zero!\n",__func__);
return c_stream
.avail_in
;
}
for(;;)
{
if((err
= deflate(&c_stream
, Z_FINISH
)) == Z_STREAM_END
)
break;
if(err
!= Z_OK
) {
printf("%s: deflate finish fail: %d\n",__func__, err
);
return -1;
}
}
if(deflateEnd(&c_stream
) != Z_OK
) {
printf("%s: deflate end failed!\n",__func__);
return -1;
}
*zdlen
= c_stream
.total_out
;
return 0;
}
return -1;
}
int compress_file_to_gzip(char * input_name
, char * output_name
)
{
FILE
*fp
= NULL;
uLong flen
, clen
;
unsigned char * fbuf
= NULL;
unsigned char * cbuf
= NULL;
char def_output_name
[PATH_MAX
] = {0};
if((fp
= fopen(input_name
, "rb")) == NULL)
{
printf("%s: can not open %s!\n", __func__, input_name
);
return -1;
}
fseek(fp
, 0L, SEEK_END);
flen
= ftell(fp
);
fseek(fp
, 0L, SEEK_SET);
fbuf
= (unsigned char *)malloc(flen
* sizeof(unsigned char));
if(NULL == fbuf
){
printf("%s: no enough memory!\n", __func__);
goto __error
;
}
fread(fbuf
, sizeof(unsigned char), flen
, fp
);
fclose(fp
);
fp
= NULL;
clen
= compressBound(flen
);
cbuf
= (unsigned char *)malloc(clen
* sizeof(unsigned char));
if(NULL == cbuf
) {
printf("%s: no enough memory!\n", __func__);
goto __error
;
}
if(gzcompress(fbuf
, flen
, cbuf
, &clen
))
{
printf("%s: compress %s failed!\n", __func__, input_name
);
goto __error
;
}
if(NULL == output_name
) {
snprintf(def_output_name
, sizeof(def_output_name
),
"%s.gz", input_name
);
output_name
= def_output_name
;
}
if((fp
= fopen(output_name
, "wb")) == NULL)
{
printf("%s: can not open %s!\n", __func__, output_name
);
goto __error
;
}
fwrite(cbuf
, sizeof(unsigned char), clen
, fp
);
fclose(fp
);
free(fbuf
);
free(cbuf
);
return 0;
__error
:
if(fp
) fclose(fp
);
if(fbuf
) free(fbuf
);
if(cbuf
) free(cbuf
);
return -1;
}
int main(int argc
, char * argv
[])
{
if(argc
< 2) {
printf("too few args!\n");
return 0;
}
if(argc
< 3) {
return compress_file_to_gzip(argv
[1],NULL);
}
return compress_file_to_gzip(argv
[1], argv
[2]);
}
装上zlib-dev后
gcc zlib_compress.c -o zlib_compress -lz即可