Zlib Study Summary

Source: Internet
Author: User
Tags uncompress

Official Handbook:

Http://www.zlib.net/manual.html

Reference connection:

http://blog.csdn.net/zhoudaxia/article/details/8039519

http://www.oschina.net/code/snippet_65636_22542

http://blog.163.com/bh_binghu/blog/static/94553512011626102054571/

Please support the above author ...

In addition, it is recommended to download the source synchronization learning.

Study for a long time zlib, today finally can take a shot. Here to share the experience of using.

BASIC Data Structure

Z_stream: Compression algorithm, compression, and input and output buffer and length are all stored here and can be understood as compression contexts.

Common Functions

Deflateinit: The parameters are relatively small, the implementation of the inside is actually called the DeflateInit2

DEFLATEINIT2: Compression initialization of the underlying function, there are many parameters, the following will focus on

Deflate: compression function.

Deflateend: After the compression is complete, the space is freed, but note that only the space requested in the Deflateinit is released, and the space you are applying for will need to be released yourself.

Inflateinit: Unzip the initialization function, internally called the InflateInit2.

InflateInit2: Unzip the underlying function of the initialization. The following highlights are highlighted.

Infalte: Decompression function

Inflateend: Similar to the deflateend effect.

Compress: All additional options default compression, internal call Compress2

COMPRESS2: Compression mode with level.

Uncompress: Uncompressed.

Introduction to compression functions

DeflateInit2:

function prototypes are: int zexport deflateInit2 (z_streamp strm, int level, int method, int windowbits, int memlevel, int strategy)

Z_stream: This is the compression context, the first thing you need to do before calling DeflateInit2 is to initialize the struct, which is simple, the three callback assignments on it. Even the official given example is set to NULL. So this is initialized directly here, Strm.zalloc = NULL; Strm.zfree = NULL; Strm.opaque = NULL.

Level : This parameter currently has four selectable values (well, in my opinion, there are two useless), as follows:

Z_no_compression: Do not compress

Z_best_speed: Speed first, can be understood as the minimum compression.

Z_best_compression: Compression takes precedence, but the speed is somewhat slower.
Z_default_compression: Did not look carefully at the source code. This option is used in compress.

method : Compression, so the option is only z_deflated

windowbits : This option can be a bit more complicated and important, and the values and compression are as follows:

*-(15 ~ 8): Pure deflate compression
* 15 ~ 8: With zlib head and tail
* > 16: With gzip head and tail

So, whether it's zlib compression or gzip compression, or a pure deflate flow, zlib can handle it. Authentication method:

1. Zlib words can use the command cat to compress file names | Zlib-deflate-uncompress verification (the home computer does not have this command, forget what the inside of the bag.)

2. If the compressed data is pure deflate, only the bytes are written to extract the code. Note This value corresponds when calling InflateInit2.

3. In the case of Gzip, verify directly with Gunzip.

Memlevel : There is currently only one option, Max_mem_level, which is nothing more than a limitation of memory usage during the run.

strategy : direct to default on line Z_default_strategy.

Deflate:

Function prototypes: Zextern int Zexport deflate of ((Z_streamp strm, int flush));

STRM: This parameter is the one that called the DeflateInit2 initialization. Before calling deflate, you need to specify four members for it.

Strm.next_in = Your data to be compressed

strm.next_out = buffer for data storage after compression

strm.avail_in = length of data to be compressed

Strm.avail_out = The length of the compressed data storage buffer.

This next_out does not have a fixed length, it is not that because it is compression, compression after the data must be shorter than the original, so you can give less, generally recommended at least to the length of the next_in.

Flush: No other options have been used,

Z_no_flush: If it's a large file and there's no way to load it into memory at once, this option comes in handy. It tells Zlib I'll give you the data again.

The return value of the deflate corresponding to this parameter is Z_OK.

Z_finish: This tag is telling zlib, I have no data, this is the last one.

The return value of the deflate corresponding to this parameter is Z_stream_end

deflateend :

The above description is clear enough that it has no more effect.

Compress2 :

Function prototypes: Zextern int zexport compress2 of (Bytef *dest, ULONGF *destlen, const BYTEF *source, ULong sourcelen, int level)) ;

If you look at its internal implementation, you will know that this is actually the encapsulation of the above three functions. For the user to use lazy, who do not like one step it. But be clear about its drawbacks:

A) It is very convenient, but it restricts all possibilities, because it can only be compressed once, that is to say, the z_finish of the internal direct call

b) do not feel that the compressed data is saved to the small buffer, there is a blog value is four times times the input buffer. This loss I was eaten, a few days ago with this function, gave the input buffer size, I think enough. But always return z_buf_ ERROR. It dawned on me when I saw the blog post.

Introduction to Decompression functionsCompressed nature also has to have decompression, and are one by one corresponding.

inflateInit2 : Initialization

Function prototypes: InflateInit2 (z_streamp strm, int windowbits)

STRM : As with deflate, you can initialize three callbacks later. Some reference documents say that you also need to initialize the fourth option, which is unclear. But I tried to find out later.

windownbits : The meaning is the same as the deflateInit2, and must correspond.

Inflate : Unzip

Function prototypes: Zextern int Zexport Inflate of ((Z_streamp strm, int flush));

strm : four parameters.

strm.next_in = Your data for decompression

strm.next_out = buffer for data storage after decompression

strm.avail_in = length of data to be decompressed

Strm.avail_out = The length of the uncompressed data storage buffer.

flush : As with deflate, if it is z_no_flush description there is no decompression of data, if it is z_finish Note that this is the last packet to be decompressed data.

inflateend : Release the resources requested in the above two steps.

uncompress :

Function prototypes: ZEXTERN int zexport uncompress of ((Bytef *dest, Ulongf *destlen, const BYTEF *source, ULong Sourcele n));

Dest: Unzip the data after it exists here

Destlen:dest size

Source: Buffer to decompress data

Sourcelen: Length of data to be decompressed

In fact, this function is simply encapsulated inflateinit, inflate, inflateend. Again, this function is only suitable for individual decompression scenarios, not for scenes that require multiple passes.

About return values

It now seems that except for the success of deflate and inflate there will be two return values, the other function return value is Z_OK.

if flush = = Z_no_flush, these two function return values are Z_OK

if flush = = Z_finish, the return value of these two functions is z_stream_end

Be sure to differentiate.

a simple exampleThis example is too much like an official example. But it is still posted, added a few comments, hoping to help understand.

#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <sys/stat.h> #include < fcntl.h> #include <zlib.h> #include <time.h> #include <errno.h> #include <assert.h> #define Read_len 8192//GZIP Head # define GZIP_MAGIC "\037\213"/* MAGIC header for GZIP files, 1F 8B *///Currently only this compression method # define DEF lated 8//tag compression for fast or high quality # define fast 4#define SLOW 2//gzip Format//(U16) MAGIC + (U8) DEFLATE + (U8) flag + (U32) time + (U8) def Late_flag + (U8) os_codeint main (int argc, char **argv) {if (ARGC < 3) {printf ("Usage:%s src_file Dst_fi        Le\n ", argv[1]);    return-1;    } int ret = 0;    int rfd = 0;    uint64_t Read_len = 0;    char *read_buf = NULL;    int WFD = 0;    uint64_t Write_len = 0;    char *write_buf = NULL;    RFD = open (Argv[1], o_rdonly);        if ( -1 = = rfd) {perror ("\ n");    return-1; } WFD = open (argv[2], O_RDWR | O_creat |    O_trunc, 0666);        if (WFD < 0) {perror ("\ n"); Return-1;    } read_buf = (char *) malloc (Read_len);    if (NULL = = read_buf) {return-1;    } Write_len = Read_len * 4;    WRITE_BUF = (char *) malloc (Write_len);    if (NULL = = write_buf) {return-1;    } uint8_t *ptr = (uint8_t*) write_buf;    Z_stream stream;    Stream.zalloc = NULL;    Stream.zfree = NULL;    Stream.opaque = NULL; DeflateInit2 (&stream, Z_default_compression, z_deflated, Max_wbits + 8, z_default_strategy);        Again:while ((Read_len = Read (RfD, Read_buf, Read_len)) >= 0) {int flush = Z_no_flush;        if (Read_len = = 0) {flush = Z_finish;        } stream.next_in = (uint8_t*) read_buf;        stream.avail_in = Read_len;            do {Write_len = 4 * Read_len;            Stream.next_out = (uint8_t*) write_buf;            Stream.avail_out = Write_len;            ret = deflate (&stream, flush);          if (flush = = Z_no_flush && ret! = Z_OK) {      Goto ERROR;            } if (flush = = Z_finish && ret! = z_stream_end) {goto ERROR;            } int avail = 4 * read_len-stream.avail_out;        Write (WFD, write_buf, avail); }while (Stream.avail_out = = 0);        If the avail_out is not enough, it indicates that the input buffer has no compressed part, then continue to compress.        If the input length is not 0, the compression is incomplete and can be exited directly.        ASSERT (stream.avail_in = = 0);        if (Read_len = = 0) {break;        }} if (Read_len < 0) {if (errno = = eintr) {goto AGAIN; }} return 0;    Error:deflateend (&stream);    Close (RFD);    Close (WFD); return-1;}
This code, I use gzip compression method, so if you want to extract, do not need to write a separate code. You can verify that the program is working as long as you gunzip the command.


Postscript:

The distinction between three compression formats.

Deflate: said he is a compressed format is a bit imprecise, in fact, it is the core algorithm of compression.

Zlib:zlib header + deflate + zlib tailer

Gzip:gzip Header + deflate + gzip tailer


In addition, I encapsulated a set of compression and decompression functions of single buffer. Also put here, the students need to refer to.

Compress.h

#ifndef myzip_h#include <unistd.h> #include <stdint.h> #include <zlib.h> #ifdef __cplusplusextern "C" {#endiftypedef z_streamp pzstream;typedef z_stream zstream;/* ===================================================== ====================== * Specify compression (Decompression) type * Official documentation mentions: *-(8): Raw DEFLATE Compression * 15 ~ 8: With zlib head and tail * > 16:  With GZIP head and tail */typedef enum{E_zip_raw =-max_wbits, E_zip_zlib = max_wbits, E_zip_gzip = max_wbits + +} zip_type;// Compression callback function typedef void (*FLATE_CB) (void *buf, int len);/*************************************************************** * * Perform deflate compression * * note:1. This set of functions applies only to small buffer 2. Before calling Deflate_beg, you need to initialize STRM 3 yourself. If deflating fails, the Deflate_end release Resource 4 is to be executed. To be clear, Deflate_end only did the stream internal resource release work, and if the stream is dynamically assigned, it needs to free***************************************************** /int Deflate_beg (Pzstream strm, zip_type type); int deflating (Pzstream strm, uint8_t *inbuf, uint32_t In_len, Uint8_t *outbuf, uint32_t *out_len); int deflate_end (Pzstream strm);/************************************************ * * Perform inflate decompression * * note:1. This set of functions applies only to small buffer 2. Before calling Inflate_beg, you need to initialize STRM 3 yourself. If inflating fails, the Inflate_end release Resource 4 is to be executed. To be clear, Inflate_end only did the stream internal resource release work, and if the stream is dynamically assigned, it needs to free***************************************************** /int Inflate_beg (Pzstream strm, zip_type type); int inflating (Pzstream strm, uint8_t *inbuf, uint32_t In_len, uint8_t *outbuf, uint32_t *outlen); int inflate_end (Pzstream strm); #ifdef __cplusplus} #endif #endif

Compress.c

#include <unistd.h> #include "compress.h"//STRM need to initialize int Deflate_beg (Pzstream strm, Zip_type type) before passing in {int re    t = 0;    int window_bits;    if (NULL = = strm) {goto ERROR;    } strm->zalloc = Z_null;    Strm->zfree = Z_null;    Strm->opaque = Z_null;    strm->next_in = Z_null;    strm->avail_in = 0;    window_bits = (int) type;    ret = DeflateInit2 (STRM, Z_default_compression, z_deflated, Window_bits, 8, z_default_strategy);    if (ret! = Z_OK) {goto ERROR; } return 0; error:return-1;}    int deflating (Pzstream strm, uint8_t *inbuf, uint32_t In_len, uint8_t *outbuf, uint32_t *out_len) {int ret = 0; if (NULL = = STRM | | NULL = = Inbuf | | NULL = = Outbuf | |    NULL = = Out_len) {goto ERROR;    } ret = Deflatereset (STRM);    if (ret! = Z_OK) {goto ERROR;    } strm->next_in = Inbuf;    strm->avail_in = In_len;    Strm->next_out = Outbuf;    Strm->avail_out = *out_len; The application scenario for this function is a small buffer scene,The incoming INBUF here is complete need to compress,//So here directly call z_finish ret = deflate (STRM, z_finish);    if (ret! = z_stream_end) {goto ERROR;    } *out_len = strm->total_out; return 0; error:return-1;}    int Deflate_end (Pzstream strm) {int ret = 0;    ret = Deflateend (STRM);    if (ret! = Z_OK) {goto ERROR; } return 0; error:return-1;}    int Inflate_beg (Pzstream strm, Zip_type type) {int ret = 0;    int window_bits = 0;    if (NULL = = strm) {goto ERROR;    } Strm->zalloc = (alloc_func) 0;    Strm->zfree = (free_func) 0;    Strm->opaque = (VOIDPF) 0;    window_bits = (int) type;    ret = InflateInit2 (STRM, window_bits);    if (ret! = Z_OK) {goto ERROR; } return 0; error:return-1;}    int inflating (Pzstream strm, uint8_t *inbuf, uint32_t In_len, uint8_t *outbuf, uint32_t *outlen) {int ret = 0; if (NULL = = STRM | | NULL = = Inbuf | | NULL = = Outbuf | |    NULL = = Outlen) {goto ERROR;    } ret = Inflatereset (STRM);if (ret! = Z_OK) {goto ERROR;    } strm->next_in = Inbuf;    strm->avail_in = In_len;    Strm->next_out = Outbuf;    Strm->avail_out = *outlen;    ret = Inflate (STRM, z_finish);    if (z_stream_end! = ret) {goto ERROR;    } *outlen = strm->total_out; return 0; error:return-1;}    int Inflate_end (Pzstream strm) {int ret = 0;    ret = Inflateend (STRM);    if (ret! = Z_OK) {goto ERROR; } return 0; error:return-1;}

Zlib Study Summary

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.