- 전체
- C/C++ 일반
- C/C++ 수학
- C/C++ 그래픽
- C/C++ 자료구조
- C/C++ 인공지능
- C/C++ 인터넷
- wxWidget
- GTK+
- UNIX or LINUX programming
- 리눅스 마스터 - 국가공인자격
- VC++/ MFC
- C#/CLI/.NET
- QT/기타UI
- Boost lib
- 오픈소스 C 분석자료
- MSA (마이크로서비스), Docker, kubernetes
- WSL(windows subsystem linux)
C/C++ 자료구조 zlib 입문
2018.02.23 09:26
zlib 입문
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ
by 오쿠무라 하루히코
공식사이트는 http://zlib.net/ 입니다. 아래의 기술은 꽤 예전것을 급하게 다시 쓴 것입니다. 이상한 곳이 있다면 알려주세요.
zlib이란 것은
zlib은 Zip이나 gzip에 사용되고 있는 압축 알고리즘을 라이브러리화한 것입니다. 작자는 Zip이나 gzip 같이 Jean-loup Gailly와
Mark Adler입니다. 라이센스는 BSD종류입니다. (상세는 zlib배포에 포함되어 있는 zlib.h의 코멘트를 봐주세요.)
[표준으로는 사용되지 않지만 어셈블러판 match.S는 GPL입니다.] 화상 포맷 PNG의 압축도 zlib로 행하고 있습니다.
Java(JDK 1.1 이후)에는 zlib에 상당하는 것이 들어가 있습니다. java.util.zip의 다큐멘트를 봐주세요.
zlib의 압축 알고리즘은 PKZIP 2.x의 deflate 알고리즘으로 원래 오쿠무라 하루히코 선생과 요시자키 하루야스씨가 LHA를 위해
개발한 것을 해쉬로 고속화한 것입니다.(지금 쓰여지는 이 글은 오쿠무라 하루히코 박사가 쓴 글을 번역하고 있는 것입니다.
zlip의 소스코드 중에 아주 약간이지만 그들의 이름이 거론된다고 합니다.by Dart) 그 후 LHA해쉬를 사용하게 되었으므로 LHA와
gzip/zlip/Zip의 실질적인 상이점은 없어졌습니다.
인스톨
UNIX계 OS상에는 이미 /usr/lib/ 부근에 libz.a(스태틱), libz.so 혹은 libz.dylib(다이나믹)이라는 이름으로 들어있을 것입니다.
또한 이 라이브러리를 사용하기 위한 헤더파일 zlib.h와 그 아래 하청의 zconf.h가 /usr/include 부근에 있을 것입니다.
소스에서 만들고 싶은 경우는 다음처럼 합니다.
tar xvzf zlib-1.2.2.tar.gz
cd zlib-1.2.2
./configure --shared --prefix=/usr
make
make test
make install
사용법(기본함수)
여기에 있는 소스중에 old/zlib.html에 zlib1.1.4의 매뉴얼이 있습니다. 최신판의 다큐멘트는 zlib.h의 코맨트안에 있습니다.
표준적인 사용법을 해설해 둡니다. (zlib 1.1.x, 1.2.x 공통)
zlib을 사용하는 프로그램은 머리에
#include <zlib.h>
라고 씁니다. 그리고 우선 z_stream이라는 형의 구조체를 만듭니다. 이름은 무엇이든 좋습니다만 임의로 z라고 해두지요.
z_stream z;
표준적인 압축의 방법은 우선 3개의 변수를
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
와 같이 세트하고서 초기화 루틴 deflateInit (&z, Z_DEFAULT_COMPRESSION) 을 호출합니다. 이 반환값이 Z_OK 가 아니라면
에러입니다. zlib의 에러메시지는 모두 z.msg를 선두번지로 하는 영역에 '
zlib 입문
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ
by 오쿠무라 하루히코
공식사이트는 http://zlib.net/ 입니다. 아래의 기술은 꽤 예전것을 급하게 다시 쓴 것입니다. 이상한 곳이 있다면 알려주세요.
zlib이란 것은
zlib은 Zip이나 gzip에 사용되고 있는 압축 알고리즘을 라이브러리화한 것입니다. 작자는 Zip이나 gzip 같이 Jean-loup Gailly와
Mark Adler입니다. 라이센스는 BSD종류입니다. (상세는 zlib배포에 포함되어 있는 zlib.h의 코멘트를 봐주세요.)
[표준으로는 사용되지 않지만 어셈블러판 match.S는 GPL입니다.] 화상 포맷 PNG의 압축도 zlib로 행하고 있습니다.
Java(JDK 1.1 이후)에는 zlib에 상당하는 것이 들어가 있습니다. java.util.zip의 다큐멘트를 봐주세요.
zlib의 압축 알고리즘은 PKZIP 2.x의 deflate 알고리즘으로 원래 오쿠무라 하루히코 선생과 요시자키 하루야스씨가 LHA를 위해
개발한 것을 해쉬로 고속화한 것입니다.(지금 쓰여지는 이 글은 오쿠무라 하루히코 박사가 쓴 글을 번역하고 있는 것입니다.
zlip의 소스코드 중에 아주 약간이지만 그들의 이름이 거론된다고 합니다.by Dart) 그 후 LHA해쉬를 사용하게 되었으므로 LHA와
gzip/zlip/Zip의 실질적인 상이점은 없어졌습니다.
인스톨
UNIX계 OS상에는 이미 /usr/lib/ 부근에 libz.a(스태틱), libz.so 혹은 libz.dylib(다이나믹)이라는 이름으로 들어있을 것입니다.
또한 이 라이브러리를 사용하기 위한 헤더파일 zlib.h와 그 아래 하청의 zconf.h가 /usr/include 부근에 있을 것입니다.
소스에서 만들고 싶은 경우는 다음처럼 합니다.
tar xvzf zlib-1.2.2.tar.gz
cd zlib-1.2.2
./configure --shared --prefix=/usr
make
make test
make install
사용법(기본함수)
여기에 있는 소스중에 old/zlib.html에 zlib1.1.4의 매뉴얼이 있습니다. 최신판의 다큐멘트는 zlib.h의 코맨트안에 있습니다.
표준적인 사용법을 해설해 둡니다. (zlib 1.1.x, 1.2.x 공통)
zlib을 사용하는 프로그램은 머리에
#include <zlib.h>
라고 씁니다. 그리고 우선 z_stream이라는 형의 구조체를 만듭니다. 이름은 무엇이든 좋습니다만 임의로 z라고 해두지요.
z_stream z;
표준적인 압축의 방법은 우선 3개의 변수를
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
와 같이 세트하고서 초기화 루틴 deflateInit (&z, Z_DEFAULT_COMPRESSION) 을 호출합니다. 이 반환값이 Z_OK 가 아니라면
에러입니다. zlib의 에러메시지는 모두 z.msg를 선두번지로 하는 영역에 '\0'으로 끝나는 문자열로써 기입되어집니다.
다음으로
z.next_in = 입력 포인터;
z.avail_in = 입력 데이터의 잔량;
z.next_out = 출력 포인터;
z.avail_out = 출력 버퍼의 잔량;
과 같이 셋트해서 deflate(&z, Z_NO_FLUSH) 를 호출합니다. 반환값이 Z_OK가 아니라면 에러입니다. deflate(&z, Z_NO_FLUSH)
는 입력을 소비해서 출력을 생산하고 포인터 z.next_in 과 z.next_out 을 진행하여 잔량 z.avail_in 과 z.avail_out 을 줄입니다.
z.avail_in 이 제로가 되면 다음의 입력 데이터를 준비해서 그 선두 어드레스를 z.avail_in, 데이터양을 z.avail_in 에 세트합니다.
동일하게 z.avail_out이 제로가 되면 파일에 쓰거나 해서 z.next_out 과 z.avail_out 을 갱신합니다.
마지막 입력이 되었다면 deflate (&z, Z_FINISH)로써 호출합니다. 이 때는 반환값이 Z_OK 라면 아직 끝마치지 못한게 있다는 의미이
므로 출력 버퍼를 파일에 써내거나 해서 여유를 만들어 재차 deflate(&z, Z_FINISH)를 호출합니다. 이것을 반환값이 Z_STREAM_END
가 될 때까지 계속합니다.
마지막으로 다음 처리를 위해 deflateEnd(&z)를 호출하여 사용한 메모리를 개방합니다. 역시 반환값이 Z_OK 가 아니라면 에러입니다.
압축한 것의 복호(전개)도 거의 동일합니다만 함수의 이름이 deflate....에서 inflate....로 변합니다. 인수의 부여방법등은 압축의 경우보다
약간 간단해집니다.
압축과 전개의 간단한 예로써 comptest.c 라는 간단한 압축 프로그램의 예를 만들어 두었으므로 봐주세요.
zlib을 사용한 프로그램의 컴파일(정확히는 링크)은 예를 들어
gcc comptest.c -o cmptest -lz
와 같이 -lz 옵션을 붙여 행합니다. 이것은 zlib 라이브러리 libz.a를 링크한다는 의미입니다.
완성된 샘플 프로그램 comptest는 comptest c 입력파일명 출력파일명 으로 압축하여
comptest d 입력파일명 출력파일명 으로 전개합니다.
고차함수
이하도 zlib 1.1.x, 1.2.x 공통입니다.
입력파일을 예를 들면 1K바이트마다 구획지어 압축하고 압축파일의 랜덤억세스를 가능하게 하는 방법입니다.
샘플 프로그램 comptest2.c 를 보면서 읽어주세요.
압축파일의 포맷은 압축블록의 사이즈와 압축블록을 임의개 나열한 것으로 합니다. 파일의 마지막을 명시적으로 나타내기 위해
마지막의 압축블록의 사이즈를 0으로 해두기로 합니다.
+----+----+----+----+-...-+-+ |size|data|size|data| ... |0| +----+----+----+----+-...-+-+
우선 zlib.h를 읽어 둡니다.
#include <zlib.h>
다음에 원래 데이터와 압축데이터용의 버퍼를 확보합니다. [압축]하면 사이즈가 늘어나는 일이 있으므로 압축 버퍼 사이즈는
원래 버퍼사이즈의 적어도 0.1% 증가로 하고 다시 관리영역용으로 12바이트를 더한 값으로 합니다.
여유를 봐서 크게 잡아 두면 되겠지요.
#define ORIGBUFSIZ 1024 /* 원래 데이터 버퍼사이즈(임의) */
#define COMPBUFSIZ 1040 /* 압축 데이터 버퍼사이즈(≧위 x 1.001+12) */
unsigned char origbuf[ORIGBUFSIZ]; /* 원래 데이터 버퍼 */
unsigned char compbuf[COMPBUFSIZ]; /* 압축 데이터 버퍼 */
원래 데이터와 압축 데이터의 사이즈(바이트수)를 넣을 변수를 준비해 둡니다.
unsigned long origsize, compsize /* 원래 사이즈, 압축 사이즈*/
이것으로 oribuf에 origsize 만큼의 데이터를 넣어
compsize = COMPBUFSIZ;
compress(compbuf, &compsize, origbuf, origsize);
라고 하면 compbuf에 compsize만큼의 압축데이터가 생성되므로 compsize의 값과 그것에 계속해서 compbuf의 내용을 파일에
출력합니다.
압축을 더욱 좋게 하려면 compress() 의 대신에 다음처럼 compress2()를 호출합니다.
compress2(compbuf, &compsize, origbuf, origsize, 9);
마지막의 수치 9는 1~9까지의 값으로 수가 클수록 압축은 잘 되지만 시간이 걸립니다.
이렇게 출력한 압축 데이터를 원래로 되돌리(복호하)려면
origsize = ORIGBUFSIZ;
uncompress(origbuf, &origsize, compbuf, compsize);
라고 합니다. origsize 에 원래의 사이즈가 들어갑니다.
실제로는 compress(), compress2(), uncompress() 의 반환값을 조사하여 에러가 없는 것을 확인하지 않으면 안됩니다.
반환값은 다음의 것들중 어느것입니다.
- Z_OK 성공
- Z_MEM_ERROR 메모리 부족으로 malloc() 할 수 없었다.
- Z_BUF_ERROR 출력버퍼의 사이즈 부족
# 샘플 다운로드 : comptest2.c comptest.c
다음으로
z.next_in = 입력 포인터;
z.avail_in = 입력 데이터의 잔량;
z.next_out = 출력 포인터;
z.avail_out = 출력 버퍼의 잔량;
과 같이 셋트해서 deflate(&z, Z_NO_FLUSH) 를 호출합니다. 반환값이 Z_OK가 아니라면 에러입니다. deflate(&z, Z_NO_FLUSH)
는 입력을 소비해서 출력을 생산하고 포인터 z.next_in 과 z.next_out 을 진행하여 잔량 z.avail_in 과 z.avail_out 을 줄입니다.
z.avail_in 이 제로가 되면 다음의 입력 데이터를 준비해서 그 선두 어드레스를 z.avail_in, 데이터양을 z.avail_in 에 세트합니다.
동일하게 z.avail_out이 제로가 되면 파일에 쓰거나 해서 z.next_out 과 z.avail_out 을 갱신합니다.
마지막 입력이 되었다면 deflate (&z, Z_FINISH)로써 호출합니다. 이 때는 반환값이 Z_OK 라면 아직 끝마치지 못한게 있다는 의미이
므로 출력 버퍼를 파일에 써내거나 해서 여유를 만들어 재차 deflate(&z, Z_FINISH)를 호출합니다. 이것을 반환값이 Z_STREAM_END
가 될 때까지 계속합니다.
마지막으로 다음 처리를 위해 deflateEnd(&z)를 호출하여 사용한 메모리를 개방합니다. 역시 반환값이 Z_OK 가 아니라면 에러입니다.
압축한 것의 복호(전개)도 거의 동일합니다만 함수의 이름이 deflate....에서 inflate....로 변합니다. 인수의 부여방법등은 압축의 경우보다
약간 간단해집니다.
압축과 전개의 간단한 예로써 comptest.c 라는 간단한 압축 프로그램의 예를 만들어 두었으므로 봐주세요.
zlib을 사용한 프로그램의 컴파일(정확히는 링크)은 예를 들어
gcc comptest.c -o cmptest -lz
와 같이 -lz 옵션을 붙여 행합니다. 이것은 zlib 라이브러리 libz.a를 링크한다는 의미입니다.
완성된 샘플 프로그램 comptest는 comptest c 입력파일명 출력파일명 으로 압축하여
comptest d 입력파일명 출력파일명 으로 전개합니다.
고차함수
이하도 zlib 1.1.x, 1.2.x 공통입니다.
입력파일을 예를 들면 1K바이트마다 구획지어 압축하고 압축파일의 랜덤억세스를 가능하게 하는 방법입니다.
샘플 프로그램 comptest2.c 를 보면서 읽어주세요.
압축파일의 포맷은 압축블록의 사이즈와 압축블록을 임의개 나열한 것으로 합니다. 파일의 마지막을 명시적으로 나타내기 위해
마지막의 압축블록의 사이즈를 0으로 해두기로 합니다.
+----+----+----+----+-...-+-+ |size|data|size|data| ... |0| +----+----+----+----+-...-+-+
우선 zlib.h를 읽어 둡니다.
#include <zlib.h>
다음에 원래 데이터와 압축데이터용의 버퍼를 확보합니다. [압축]하면 사이즈가 늘어나는 일이 있으므로 압축 버퍼 사이즈는
원래 버퍼사이즈의 적어도 0.1% 증가로 하고 다시 관리영역용으로 12바이트를 더한 값으로 합니다.
여유를 봐서 크게 잡아 두면 되겠지요.
#define ORIGBUFSIZ 1024 /* 원래 데이터 버퍼사이즈(임의) */
#define COMPBUFSIZ 1040 /* 압축 데이터 버퍼사이즈(≧위 x 1.001+12) */
unsigned char origbuf[ORIGBUFSIZ]; /* 원래 데이터 버퍼 */
unsigned char compbuf[COMPBUFSIZ]; /* 압축 데이터 버퍼 */
원래 데이터와 압축 데이터의 사이즈(바이트수)를 넣을 변수를 준비해 둡니다.
unsigned long origsize, compsize /* 원래 사이즈, 압축 사이즈*/
이것으로 oribuf에 origsize 만큼의 데이터를 넣어
compsize = COMPBUFSIZ;
compress(compbuf, &compsize, origbuf, origsize);
라고 하면 compbuf에 compsize만큼의 압축데이터가 생성되므로 compsize의 값과 그것에 계속해서 compbuf의 내용을 파일에
출력합니다.
압축을 더욱 좋게 하려면 compress() 의 대신에 다음처럼 compress2()를 호출합니다.
compress2(compbuf, &compsize, origbuf, origsize, 9);
마지막의 수치 9는 1~9까지의 값으로 수가 클수록 압축은 잘 되지만 시간이 걸립니다.
이렇게 출력한 압축 데이터를 원래로 되돌리(복호하)려면
origsize = ORIGBUFSIZ;
uncompress(origbuf, &origsize, compbuf, compsize);
라고 합니다. origsize 에 원래의 사이즈가 들어갑니다.
실제로는 compress(), compress2(), uncompress() 의 반환값을 조사하여 에러가 없는 것을 확인하지 않으면 안됩니다.
반환값은 다음의 것들중 어느것입니다.
- Z_OK 성공
- Z_MEM_ERROR 메모리 부족으로 malloc() 할 수 없었다.
- Z_BUF_ERROR 출력버퍼의 사이즈 부족
# 샘플 다운로드 : comptest2.c comptest.c
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 2 | Qt Creator + Boost on Ubuntu | 졸리운_곰 | 2014.12.26 | 476 |
| 1 | boost lib 라이브러리 On Ubuntu 우분투 | 졸리운_곰 | 2014.12.26 | 570 |

