압축 데이터는 한개 이상의 Block으로 구성됩니다. Block는 동일한 압축 레벨과 압축 방법을 사용합니다. deflateParams 함수로 압축 레벨과 압축 방법을 지정하면 새로운 Block이 만들어집니다. deflateParams 함수는 기존 avail_in에 0이 아니면 기존 방식대로 데이터를 압축하고, 마지막에 새로운 Block 헤더를 추가합니다.
압축을 푸는 과정은 inflate(&stream, Z_BLOCK)를 사용합니다. 만약 Block에 있는 데이터를 구분할 필요가 없다면 inflate(&stream, Z_NO_FLUSH)로 읽어가면 됩니다. 하지만 Block 별 데이터를 구분해서 읽고 싶다면 Z_BLOCK으로 읽어가야 합니다. 읽어진 정보는 data_type 변수로 상태 정보를 체크할 수 있습니다.
//stream.data_type
// 첫번째 비트가 1이면 block를 읽었음 의미
// 두번째 비트가 1이면 block를 읽고 있는 중..
// valil_in ==0 이고 두번째 비트가 1이면 모든 데이터를 읽어드림.
//
#include "stdafx.h"
#include <LibZ/zlib.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
Bytef m1[]="test1";
Bytef m2[]="test2";
const int BUF=4096;
//압축된 데이터와 길이
Bytef deflate_data[BUF];
int deflate_size(0);
//해제된 데이터와 길이
Bytef inflate_data[BUF];
int inflate_size(0);
//압축 코딩
do{
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
int ret = deflateInit(&stream,Z_DEFAULT_COMPRESSION);//블락 1
if( Z_OK != ret) break;
stream.next_out = deflate_data;
stream.avail_out = BUF;
stream.avail_in =0;//
deflateParams(&stream,Z_BEST_COMPRESSION,Z_HUFFMAN_ONLY);//블락 2
stream.avail_in = strlen((const char*)m1);
stream.next_in = m1;
do {
deflate(&stream, Z_NO_FLUSH);
} while( 0!= stream.avail_in);
deflateParams(&stream, Z_BEST_SPEED,Z_RLE);//블락 3
stream.avail_in = strlen( (const char*) m2);
stream.next_in = m2;
do {
deflate(&stream, Z_NO_FLUSH);
} while( 0!= stream.avail_in);
deflate(&stream, Z_FINISH);//블락 4
deflate_size = BUF- stream.avail_out;
std::cout<<"Deflate Size:"<<deflate_size<<std::endl;
deflateEnd(&stream);
}while(false);
//해제하기
do{
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
int ret = inflateInit(&stream);
if (Z_OK != ret) break;
stream.next_out = inflate_data;
stream.avail_out= BUF;
stream.next_in = deflate_data;
stream.avail_in = deflate_size;
do{
ret = inflate(&stream,Z_BLOCK);
inflate_size = BUF-stream.avail_out;
inflate_data[inflate_size]=NULL;
std::cout<<"////////////////////////"<<std::endl;
std::cout<<"Block Readed OK:"<< ( ( stream.data_type & 128 )?1:0 )<<std::endl;
std::cout<<"Block Reading:"<< ( ( stream.data_type & 64 )?1:0 )<<std::endl;
std::cout<<"Return:"<< ret<<std::endl;
std::cout<<"avail_in:"<<stream.avail_in<<std::endl;
std::cout<<"NOW Data:"<<(const char*)inflate_data<<std::endl;
std::cout<<"NOW Data Len:"<<inflate_size<<std::endl;
}while(Z_STREAM_END !=ret);
inflateEnd(&stream);
}while( false);
system("pause");
return 0;
}