我正在使用Zlib v1.2.7读取文本文件,然后将其压缩并将其写入输出文件。我的问题是在以下示例中,如何根据输入大小确定输出缓冲区的大小? (在示例gz_length
中)
我正在将该库用于STM32设备。我添加了unzip方法,但对于未压缩的数据长度也有这个问题。
#include "zlib.h"
int unzip(unsigned char *dst, unsigned long *dst_length, unsigned char *src, unsigned long src_length)
{
z_stream stream;
memset(&stream, 0, sizeof(stream));
stream.next_in = src;
stream.avail_in = src_length;
stream.next_out = dst;
stream.avail_out = *dst_length;
int rv = inflateInit2(&stream, 15 + 16);
if (Z_OK == rv) {
rv = inflate(&stream, Z_NO_FLUSH);
if (Z_STREAM_END == rv) {
inflateEnd(&stream);
rv = Z_OK;
}
}
if (Z_OK == rv) {
*dst_length = stream.total_out;
} else {
*dst_length = 0;
}
return rv;
}
int zip(unsigned char *dst, unsigned long *dst_length, unsigned char *src, unsigned long src_length)
{
z_stream stream;
memset(&stream, 0, sizeof(stream));
stream.next_in = src;
stream.avail_in = src_length;
stream.next_out = Z_NULL;
stream.avail_out = 0;
/* add 16 to MAX_WBITS to specify gzip format - it gets taken off again in defaultInit2 */
int rv = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 16 + MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
if (Z_OK == rv) {
unsigned long dst_bound = deflateBound(&stream, stream.avail_in) + 12; /* 12 bytes for the gzip header */
if (dst_bound > *dst_length) {
rv = Z_MEM_ERROR;
} else {
stream.next_out = dst;
stream.avail_out = dst_bound;
}
}
if (Z_OK == rv) {
gz_header header;
memset(&header, 0, sizeof(header));
rv = deflateSetHeader(&stream, &header);
}
if (Z_OK == rv) {
rv = deflate(&stream, Z_FINISH);
if (Z_STREAM_END == rv) {
rv = deflateEnd(&stream);
}
}
if (Z_OK == rv) {
*dst_length = stream.total_out;
} else {
*dst_length = 0;
}
return rv;
}
int main()
{
unsigned long read_size;
unsigned char *buffer = NULL;
unsigned char *gz_buffer = NULL;
unsigned long input_size = 0;
/* Open your_file in read-only mode */
FILE *fp = fopen("/local/new.txt", "r");
fseek(fp, 0, SEEK_END); /* Go to end of file */
input_size = ftell(fp); /* How many bytes did we pass ? */
printf("Filesize: %ld\n", input_size);
/* Set position of stream to the beginning */
rewind(fp);
/* Allocate the buffer (no need to initialize it with calloc) */
buffer = (unsigned char*) malloc((input_size + 1) * sizeof(*buffer)); /* input_size + 1 byte for the \0 */
/* Read the file into the buffer */
fread(buffer, input_size, 1, fp); /* Read 1 chunk of input_size bytes from fp into buffer */
/* NULL-terminate the buffer */
buffer[input_size] = '\0';
/* Print it ! */
printf("FileData: %s\n", buffer);
fclose(fp);
//PROBLEM HERE how to determine valid gz_length for output based on input_size
unsigned long gz_length = input_size + 50;
gz_buffer = (unsigned char*) malloc((gz_length) * sizeof(*gz_buffer));
if (input_size > 0)
{
int rv = zip(gz_buffer, &gz_length, buffer, input_size);
if (Z_OK == rv)
{
FILE *ofp = fopen("/local/out.gz", "w");
if (ofp)
{
int bw = fwrite(gz_buffer, 1, gz_length, ofp);
fclose(ofp);
}
}
else
{
printf("%s:%d: %d%s", __FILE__, __LINE__, rv, newline);
}
}
free(buffer);
free(gz_buffer);
return 0;
}
答案 0 :(得分:1)
如果您想在单个deflate()
调用中进行压缩(这并不是必须的),则zlib为此目的提供了功能deflateBound()
。
在另一个方向上没有有用的界限。所谓无用的意思是说,解压缩输出的大小的界限是压缩输入的大小的一千倍以上。