2011-09-24 5 views
6

char 배열 (파일 아님)을 압축하고 압축을 풀 수있는 zlib.h deflate 및 inflate 함수를 구현하려고합니다.deflate and inflate (zlib.h) in C

다음 구문이 올바른지 알고 싶습니다. 뭔가 빠졌거나 잘못 정의 했습니까?

char a[50] = "Hello World!"; 
char b[50]; 
char c[50]; 

// deflate 
// zlib struct 
z_stream defstream; 
defstream.zalloc = Z_NULL; 
defstream.zfree = Z_NULL; 
defstream.opaque = Z_NULL; 
defstream.avail_in = (uInt)sizeof(a); // size of input 
defstream.next_in = (Bytef *)a; // input char array 
defstream.avail_out = (uInt)sizeof(b); // size of output 
defstream.next_out = (Bytef *)b; // output char array 

deflateInit(&defstream, Z_DEFAULT_COMPRESSION); 
deflate(&defstream, Z_FINISH); 
deflateEnd(&defstream); 

printf("Deflate:\n%lu\n%s\n", strlen(b), b); 

// inflate 
// zlib struct 
z_stream infstream; 
infstream.zalloc = Z_NULL; 
infstream.zfree = Z_NULL; 
infstream.opaque = Z_NULL; 
infstream.avail_in = (uInt)sizeof(b); // size of input 
infstream.next_in = (Bytef *)b; // input char array 
infstream.avail_out = (uInt)sizeof(c); // size of output 
infstream.next_out = (Bytef *)c; // output char array 

inflateInit(&infstream); 
inflate(&infstream, Z_NO_FLUSH); 
inflateEnd(&infstream); 

printf("Inflate:\n%lu\n%s\n", strlen(c), c); 
+0

작동하지 않기 때문에 묻는 중입니까? 어떤 종류의 오류 메시지가 나타 납니까? – larsks

+0

@larsks 경고없이 컴파일되지만 필자가 선택한 함수와 정의가 의미가 있는지 또는 다른 함수를 사용해야하는지 알고 싶습니다. –

+0

알았어요. 질문을 명확히 해 주셔서 감사합니다. – larsks

답변

6

이렇게 수축 된 출력을 인쇄 할 수 없습니다. null로 끝나지 않았습니다. 당신도 그것을 strlen 수 없습니다.

null 종결자를 포함하여 문자열의 내용 만 전달하려고하지만 입력 내용이 문자열이기 때문에. 따라서 avail_in을 strlen (a) + 1로 설정하십시오.

출력 버퍼에 얼마나 많은 양의 데이터가 기록되었는지 보려면 deflate를 호출 한 후 next_out 및 avail_out 필드를 검사해야합니다.

deflate 문의 문서 here을 참조하십시오.

수정 된 코드는 다음과 같습니다. 스트링이 아닌 무언가를 압축하는 경우 이것을 변경해야하고 스트링과 함께 끝나는 제로없이 압축하고 압축 해제 한 후에 다시 추가 할 수도 있습니다.

char a[50] = "Hello World!"; 
char b[50]; 
char c[50]; 

// deflate 
// zlib struct 
z_stream defstream; 
defstream.zalloc = Z_NULL; 
defstream.zfree = Z_NULL; 
defstream.opaque = Z_NULL; 
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator 
defstream.next_in = (Bytef *)a; // input char array 
defstream.avail_out = (uInt)sizeof(b); // size of output 
defstream.next_out = (Bytef *)b; // output char array 

deflateInit(&defstream, Z_DEFAULT_COMPRESSION); 
deflate(&defstream, Z_FINISH); 
deflateEnd(&defstream); 

// This is one way of getting the size of the output 
printf("Deflated size is: %lu\n", (char*)defstream.next_out - b); 

// inflate 
// zlib struct 
z_stream infstream; 
infstream.zalloc = Z_NULL; 
infstream.zfree = Z_NULL; 
infstream.opaque = Z_NULL; 
infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input 
infstream.next_in = (Bytef *)b; // input char array 
infstream.avail_out = (uInt)sizeof(c); // size of output 
infstream.next_out = (Bytef *)c; // output char array 

inflateInit(&infstream); 
inflate(&infstream, Z_NO_FLUSH); 
inflateEnd(&infstream); 

printf("Inflate:\n%lu\n%s\n", strlen(c), c); 
2

zpipe 예 (http://zlib.net/zpipe.c) 거의 바로 파일 작전을합니다 (f는 기능을 접두사)를 제거하고, 당신이 당신의 인 -로 inout 교체를 커버 메모리 버퍼를 사용하지만, 사용량에 따라 in 만 바꾸거나 버퍼를 그대로 유지하는 것으로 충분할 수 있습니다. 그냥 당신이 알 수없는 크기의 덩어리를

21

ZLIB있는에 계획하는 경우/이미 간단한 부풀려을 가지고 임의의 크기의 데이터의 압축 해제에 계정에 밖으로 버퍼 크기를 재조정 할 필요가 사용할 수있는 기능을 수축 않습니다.

char a[50] = "Hello, world!"; 
char b[50]; 
char c[50]; 

uLong ucompSize = strlen(a)+1; // "Hello, world!" + NULL delimiter. 
uLong compSize = compressBound(ucompSize); 

// Deflate 
compress((Bytef *)b, &compSize, (Bytef *)a, ucompSize); 

// Inflate 
uncompress((Bytef *)c, &ucompSize, (Bytef *)b, compSize); 

의심스러운 경우 zlib manual을 확인하십시오. 내 코드가 엉망입니다. =/

+2

+1 아마 엉터리지만, 그것은 항상 선호하는 마음 마비 솔루션을 가리 킵니다. 'compress()'와'uncompress()'는 얻을 수있는 가장 간단한 형태이며, 적절하게 제시하는 것 이상으로 표현합니다. – WhozCraig

+2

이 유틸리티 메서드의 문제점은 압축 된 내용의 크기를 어떻게 든 알아야한다는 것입니다./ – Johannes

+0

압축되지 않은 내용에 sizeof()를 사용할 수 있습니다. 이것은 좋은 시작 인 compress() 및 uncompress() 메소드의 기본 사용법이지만 더 효율적인 기법이 있습니다. –