Linux下C语言的zlib压缩

本文最后更新于2017年8月5日,已超过 1 年没有更新,如果文章内容失效,还请反馈给我,谢谢!

=Start=

缘由:

学习需要

正文:

参考解答:

字符串压缩

#include <stdio.h>
#include <string.h>  // for strlen
#include <assert.h>
#include "zlib.h"
/*
*/
int main(int argc, char* argv[])
{  
    // original string len = 36
    char a[50] = "Hello Hello Hello Hello Hello Hello!";
    // placeholder for the compressed (deflated) version of "a"
    char b[50];
    // placeholder for the UNcompressed (inflated) version of "b"
    char c[50];
     
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("sizeof(c) = %d\n", sizeof(c));
    printf("Original size is: %lu\n", strlen(a));
    printf("Original string is: %s\n", a);
    printf("\n----------\n\n");
    // STEP 1.
    // deflate a into b. (that is, compress a into b)
    
    // zlib struct
    z_stream defstream;
    defstream.zalloc = Z_NULL;
    defstream.zfree = Z_NULL;
    defstream.opaque = Z_NULL;
    // setup "a" as the input and "b" as the compressed output
    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
    
    // the actual compression work.
    deflateInit(&defstream, Z_BEST_COMPRESSION);
    deflate(&defstream, Z_FINISH);
    deflateEnd(&defstream);
     
    // This is one way of getting the size of the output
    printf("Compressed size is: %lu\n", strlen(b));
    printf("Compressed string is: %s\n", b);
    
    printf("\n----------\n\n");
    // STEP 2.
    // inflate b into c
    // zlib struct
    z_stream infstream;
    infstream.zalloc = Z_NULL;
    infstream.zfree = Z_NULL;
    infstream.opaque = Z_NULL;
    // setup "b" as the input and "c" as the compressed output
    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
     
    // the actual DE-compression work.
    inflateInit(&infstream);
    inflate(&infstream, Z_NO_FLUSH);
    inflateEnd(&infstream);
     
    printf("Uncompressed size is: %lu\n", strlen(c));
    printf("Uncompressed string is: %s\n", c);
    
    // make sure uncompressed is exactly equal to original.
    assert(strcmp(a,c)==0);
    return 0;
}

&

#include <stdio.h>
#include <zlib.h>
#include <stdlib.h>
#include <string.h>
/* CHUNK is the size of the memory chunk used by the zlib routines. */
#define CHUNK 0x4000
/* The following macro calls a zlib routine and checks the return
   value. If the return value ("status") is not OK, it prints an error
   message and exits the program. Zlib's error statuses are all less
   than zero. */
#define CALL_ZLIB(x) {                                                  \
        int status;                                                     \
        status = x;                                                     \
        if (status < 0) {                                               \
            fprintf (stderr,                                            \
                     "%s:%d: %s returned a bad status of %d.\n",        \
                     __FILE__, __LINE__, #x, status);                   \
            exit (EXIT_FAILURE);                                        \
        }                                                               \
    }
/* These are parameters to deflateInit2. See
   http://zlib.net/manual.html for the exact meanings. */
#define windowBits 15
#define GZIP_ENCODING 16
static void strm_init (z_stream * strm)
{
    strm->zalloc = Z_NULL;
    strm->zfree  = Z_NULL;
    strm->opaque = Z_NULL;
    CALL_ZLIB (deflateInit2 (strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
                             windowBits | GZIP_ENCODING, 8,
                             Z_DEFAULT_STRATEGY));
}
/* Example text to print out. */
static const char * message =
"Shall I compare thee to a summer's day?\n"
"Thou art more lovely and more temperate:\n"
"Rough winds do shake the darling buds of May,\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
"And summer's lease hath all too short a date;\n"
;
/*
$ ./a.out | wc
       2       6     160
$ ./a.out | gzip -d | wc
      23     204    1047
 */
/*
static const char * message =
"Shall I compare thee to a summer's day?\n"
"Thou art more lovely and more temperate:\n"
"Rough winds do shake the darling buds of May,\n"
"And summer's lease hath all too short a date;\n"
;
$ ./a.out | wc
       1       5     150
$ ./a.out | gzip -d | wc
       4      33     173
 */
int main ()
{
    unsigned char out[CHUNK];
    z_stream strm;
    strm_init (& strm);
    strm.next_in = (unsigned char *) message;
    strm.avail_in = strlen (message);
    do {
        int have;
        strm.avail_out = CHUNK;
        strm.next_out = out;
        CALL_ZLIB (deflate (& strm, Z_FINISH));
        have = CHUNK - strm.avail_out;
        fwrite (out, sizeof (char), have, stdout);
    }
    while (strm.avail_out == 0);
    deflateEnd (& strm);
    return 0;
}
/*
$ gcc compress_with_zlib.c -lz
*/
参考链接:

=END=

声明: 除非注明,ixyzero.com文章均为原创,转载请以链接形式标明本文地址,谢谢!
https://ixyzero.com/blog/archives/3488.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注