Basic gzip/gunzip in memory buffer examples using zlib code.

Dependencies:   mbed-rtos mbed

There are small changes needed to the zconf.h file in the zlib distribution (I used 1.2.7). The zlib license applies to the zlib code - I have only imported a subset of the source.

The MBED has limited memory, so we need the following (near the top of zconf.h) to restrict memory allocation sizes:

#define    MAX_MEM_LEVEL    3
#define    MAX_WBITS        10

Because MAX_MEM_LEVEL and MAX_WBITS are so much lower than the default, there is a danger that the mbed cannot gunzip data compressed by a 'normal' zlib build. My use-case is to gzip on the mbed more than gunzip on the mbed so I have not given much time to this issue.

I also included this (also near the top of zconf.h) to prefix defines with Z_

#define    Z_PREFIX

In zconf.h, in the zlib distribution, the includes for <fcntl.h> and <sys/types.h> need commenting out when using the online compiler. No need when using GCC4MBED.

I also looked at miniz. I chose zlib because I needed the gzip headers and miniz does not implement them.

The sample main.cpp reads source data, compresses it, decompresses it, and finally compares the input data with the output data to confirm they are the same.

    unsigned char input_data[2048];
    unsigned long input_data_length = 0;
    FILE *ifp = fopen("/local/src.txt", "r");
    if (ifp) {
        int br = fread(input_data, 1, sizeof(input_data), ifp);
        fclose(ifp);
        input_data_length = br;
    }
    printf("%s:%d: input_data_length:%lu%s", __FILE__, __LINE__, input_data_length, newline);
 
 
    unsigned char gzip_data[2048];
    unsigned long gzip_data_length = 0;
    if (input_data_length > 0) {
        gzip_data_length = sizeof(gzip_data);
        int rv = gzip(gzip_data, &gzip_data_length, input_data, input_data_length);
        if (Z_OK == rv) {
            FILE *ofp = fopen("/local/dst.gz", "w");
            if (ofp) {
                int bw = fwrite(gzip_data, 1, gzip_data_length, ofp);
                fclose(ofp);
            }
        } else {
            printf("%s:%d: %d%s", __FILE__, __LINE__, rv, newline);
        }
    }
    printf("%s:%d: gzip_data_length:%lu%s", __FILE__, __LINE__, gzip_data_length, newline);
 
 
    unsigned char output_data[2048];
    unsigned long output_data_length = 0;
    if (gzip_data_length > 0) {
        output_data_length = sizeof(output_data);
        int rv = gunzip(output_data, &output_data_length, gzip_data, gzip_data_length);
        if (Z_OK != rv) {
            printf("%s:%d: %d%s", __FILE__, __LINE__, rv, newline);
        }
    }
    printf("%s:%d: output_data_length:%lu%s", __FILE__, __LINE__, output_data_length, newline);
 
 
    if (input_data_length > 0 and input_data_length > 0) {
        bool input_matches_output = false;
        if (input_data_length == output_data_length) {
            input_matches_output = true;
            for ( size_t i = 0 ; input_matches_output && i < input_data_length ; i++ ) {
                if (input_data[i] != output_data[i]) {
                    input_matches_output = false;
                }
            }
        }
        printf("%s:%d: input (%lu bytes) %s output (%lu bytes)%s", __FILE__, __LINE__, input_data_length, input_matches_output?"matches":"does not match", output_data_length, newline);
    } else {
        printf("%s:%d: input and/or output length is 0%s", __FILE__, __LINE__, newline);
    }
Committer:
jonathonfletcher
Date:
Sun Oct 21 07:46:41 2012 +0000
Revision:
0:54f5be781526
initial checkin

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jonathonfletcher 0:54f5be781526 1 /* gzguts.h -- zlib internal header definitions for gz* operations
jonathonfletcher 0:54f5be781526 2 * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
jonathonfletcher 0:54f5be781526 3 * For conditions of distribution and use, see copyright notice in zlib.h
jonathonfletcher 0:54f5be781526 4 */
jonathonfletcher 0:54f5be781526 5
jonathonfletcher 0:54f5be781526 6 #ifdef _LARGEFILE64_SOURCE
jonathonfletcher 0:54f5be781526 7 # ifndef _LARGEFILE_SOURCE
jonathonfletcher 0:54f5be781526 8 # define _LARGEFILE_SOURCE 1
jonathonfletcher 0:54f5be781526 9 # endif
jonathonfletcher 0:54f5be781526 10 # ifdef _FILE_OFFSET_BITS
jonathonfletcher 0:54f5be781526 11 # undef _FILE_OFFSET_BITS
jonathonfletcher 0:54f5be781526 12 # endif
jonathonfletcher 0:54f5be781526 13 #endif
jonathonfletcher 0:54f5be781526 14
jonathonfletcher 0:54f5be781526 15 #ifdef HAVE_HIDDEN
jonathonfletcher 0:54f5be781526 16 # define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
jonathonfletcher 0:54f5be781526 17 #else
jonathonfletcher 0:54f5be781526 18 # define ZLIB_INTERNAL
jonathonfletcher 0:54f5be781526 19 #endif
jonathonfletcher 0:54f5be781526 20
jonathonfletcher 0:54f5be781526 21 #include <stdio.h>
jonathonfletcher 0:54f5be781526 22 #include "zlib.h"
jonathonfletcher 0:54f5be781526 23 #ifdef STDC
jonathonfletcher 0:54f5be781526 24 # include <string.h>
jonathonfletcher 0:54f5be781526 25 # include <stdlib.h>
jonathonfletcher 0:54f5be781526 26 # include <limits.h>
jonathonfletcher 0:54f5be781526 27 #endif
jonathonfletcher 0:54f5be781526 28 //#include <fcntl.h>
jonathonfletcher 0:54f5be781526 29
jonathonfletcher 0:54f5be781526 30 #ifdef _WIN32
jonathonfletcher 0:54f5be781526 31 # include <stddef.h>
jonathonfletcher 0:54f5be781526 32 #endif
jonathonfletcher 0:54f5be781526 33
jonathonfletcher 0:54f5be781526 34 #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
jonathonfletcher 0:54f5be781526 35 # include <io.h>
jonathonfletcher 0:54f5be781526 36 #endif
jonathonfletcher 0:54f5be781526 37
jonathonfletcher 0:54f5be781526 38 #ifdef NO_DEFLATE /* for compatibility with old definition */
jonathonfletcher 0:54f5be781526 39 # define NO_GZCOMPRESS
jonathonfletcher 0:54f5be781526 40 #endif
jonathonfletcher 0:54f5be781526 41
jonathonfletcher 0:54f5be781526 42 #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
jonathonfletcher 0:54f5be781526 43 # ifndef HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 44 # define HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 45 # endif
jonathonfletcher 0:54f5be781526 46 #endif
jonathonfletcher 0:54f5be781526 47
jonathonfletcher 0:54f5be781526 48 #if defined(__CYGWIN__)
jonathonfletcher 0:54f5be781526 49 # ifndef HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 50 # define HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 51 # endif
jonathonfletcher 0:54f5be781526 52 #endif
jonathonfletcher 0:54f5be781526 53
jonathonfletcher 0:54f5be781526 54 #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
jonathonfletcher 0:54f5be781526 55 # ifndef HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 56 # define HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 57 # endif
jonathonfletcher 0:54f5be781526 58 #endif
jonathonfletcher 0:54f5be781526 59
jonathonfletcher 0:54f5be781526 60 #ifndef HAVE_VSNPRINTF
jonathonfletcher 0:54f5be781526 61 # ifdef MSDOS
jonathonfletcher 0:54f5be781526 62 /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
jonathonfletcher 0:54f5be781526 63 but for now we just assume it doesn't. */
jonathonfletcher 0:54f5be781526 64 # define NO_vsnprintf
jonathonfletcher 0:54f5be781526 65 # endif
jonathonfletcher 0:54f5be781526 66 # ifdef __TURBOC__
jonathonfletcher 0:54f5be781526 67 # define NO_vsnprintf
jonathonfletcher 0:54f5be781526 68 # endif
jonathonfletcher 0:54f5be781526 69 # ifdef WIN32
jonathonfletcher 0:54f5be781526 70 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
jonathonfletcher 0:54f5be781526 71 # if !defined(vsnprintf) && !defined(NO_vsnprintf)
jonathonfletcher 0:54f5be781526 72 # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
jonathonfletcher 0:54f5be781526 73 # define vsnprintf _vsnprintf
jonathonfletcher 0:54f5be781526 74 # endif
jonathonfletcher 0:54f5be781526 75 # endif
jonathonfletcher 0:54f5be781526 76 # endif
jonathonfletcher 0:54f5be781526 77 # ifdef __SASC
jonathonfletcher 0:54f5be781526 78 # define NO_vsnprintf
jonathonfletcher 0:54f5be781526 79 # endif
jonathonfletcher 0:54f5be781526 80 # ifdef VMS
jonathonfletcher 0:54f5be781526 81 # define NO_vsnprintf
jonathonfletcher 0:54f5be781526 82 # endif
jonathonfletcher 0:54f5be781526 83 # ifdef __OS400__
jonathonfletcher 0:54f5be781526 84 # define NO_vsnprintf
jonathonfletcher 0:54f5be781526 85 # endif
jonathonfletcher 0:54f5be781526 86 # ifdef __MVS__
jonathonfletcher 0:54f5be781526 87 # define NO_vsnprintf
jonathonfletcher 0:54f5be781526 88 # endif
jonathonfletcher 0:54f5be781526 89 #endif
jonathonfletcher 0:54f5be781526 90
jonathonfletcher 0:54f5be781526 91 #ifndef local
jonathonfletcher 0:54f5be781526 92 # define local static
jonathonfletcher 0:54f5be781526 93 #endif
jonathonfletcher 0:54f5be781526 94 /* compile with -Dlocal if your debugger can't find static symbols */
jonathonfletcher 0:54f5be781526 95
jonathonfletcher 0:54f5be781526 96 /* gz* functions always use library allocation functions */
jonathonfletcher 0:54f5be781526 97 #ifndef STDC
jonathonfletcher 0:54f5be781526 98 extern voidp malloc OF((uInt size));
jonathonfletcher 0:54f5be781526 99 extern void free OF((voidpf ptr));
jonathonfletcher 0:54f5be781526 100 #endif
jonathonfletcher 0:54f5be781526 101
jonathonfletcher 0:54f5be781526 102 /* get errno and strerror definition */
jonathonfletcher 0:54f5be781526 103 #if defined UNDER_CE
jonathonfletcher 0:54f5be781526 104 # include <windows.h>
jonathonfletcher 0:54f5be781526 105 # define zstrerror() gz_strwinerror((DWORD)GetLastError())
jonathonfletcher 0:54f5be781526 106 #else
jonathonfletcher 0:54f5be781526 107 # ifndef NO_STRERROR
jonathonfletcher 0:54f5be781526 108 # include <errno.h>
jonathonfletcher 0:54f5be781526 109 # define zstrerror() strerror(errno)
jonathonfletcher 0:54f5be781526 110 # else
jonathonfletcher 0:54f5be781526 111 # define zstrerror() "stdio error (consult errno)"
jonathonfletcher 0:54f5be781526 112 # endif
jonathonfletcher 0:54f5be781526 113 #endif
jonathonfletcher 0:54f5be781526 114
jonathonfletcher 0:54f5be781526 115 /* provide prototypes for these when building zlib without LFS */
jonathonfletcher 0:54f5be781526 116 #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
jonathonfletcher 0:54f5be781526 117 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
jonathonfletcher 0:54f5be781526 118 ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
jonathonfletcher 0:54f5be781526 119 ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
jonathonfletcher 0:54f5be781526 120 ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
jonathonfletcher 0:54f5be781526 121 #endif
jonathonfletcher 0:54f5be781526 122
jonathonfletcher 0:54f5be781526 123 /* default memLevel */
jonathonfletcher 0:54f5be781526 124 #if MAX_MEM_LEVEL >= 8
jonathonfletcher 0:54f5be781526 125 # define DEF_MEM_LEVEL 8
jonathonfletcher 0:54f5be781526 126 #else
jonathonfletcher 0:54f5be781526 127 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
jonathonfletcher 0:54f5be781526 128 #endif
jonathonfletcher 0:54f5be781526 129
jonathonfletcher 0:54f5be781526 130 /* default i/o buffer size -- double this for output when reading */
jonathonfletcher 0:54f5be781526 131 #define GZBUFSIZE 8192
jonathonfletcher 0:54f5be781526 132
jonathonfletcher 0:54f5be781526 133 /* gzip modes, also provide a little integrity check on the passed structure */
jonathonfletcher 0:54f5be781526 134 #define GZ_NONE 0
jonathonfletcher 0:54f5be781526 135 #define GZ_READ 7247
jonathonfletcher 0:54f5be781526 136 #define GZ_WRITE 31153
jonathonfletcher 0:54f5be781526 137 #define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
jonathonfletcher 0:54f5be781526 138
jonathonfletcher 0:54f5be781526 139 /* values for gz_state how */
jonathonfletcher 0:54f5be781526 140 #define LOOK 0 /* look for a gzip header */
jonathonfletcher 0:54f5be781526 141 #define COPY 1 /* copy input directly */
jonathonfletcher 0:54f5be781526 142 #define GZIP 2 /* decompress a gzip stream */
jonathonfletcher 0:54f5be781526 143
jonathonfletcher 0:54f5be781526 144 /* internal gzip file state data structure */
jonathonfletcher 0:54f5be781526 145 typedef struct {
jonathonfletcher 0:54f5be781526 146 /* exposed contents for gzgetc() macro */
jonathonfletcher 0:54f5be781526 147 struct gzFile_s x; /* "x" for exposed */
jonathonfletcher 0:54f5be781526 148 /* x.have: number of bytes available at x.next */
jonathonfletcher 0:54f5be781526 149 /* x.next: next output data to deliver or write */
jonathonfletcher 0:54f5be781526 150 /* x.pos: current position in uncompressed data */
jonathonfletcher 0:54f5be781526 151 /* used for both reading and writing */
jonathonfletcher 0:54f5be781526 152 int mode; /* see gzip modes above */
jonathonfletcher 0:54f5be781526 153 int fd; /* file descriptor */
jonathonfletcher 0:54f5be781526 154 char *path; /* path or fd for error messages */
jonathonfletcher 0:54f5be781526 155 unsigned size; /* buffer size, zero if not allocated yet */
jonathonfletcher 0:54f5be781526 156 unsigned want; /* requested buffer size, default is GZBUFSIZE */
jonathonfletcher 0:54f5be781526 157 unsigned char *in; /* input buffer */
jonathonfletcher 0:54f5be781526 158 unsigned char *out; /* output buffer (double-sized when reading) */
jonathonfletcher 0:54f5be781526 159 int direct; /* 0 if processing gzip, 1 if transparent */
jonathonfletcher 0:54f5be781526 160 /* just for reading */
jonathonfletcher 0:54f5be781526 161 int how; /* 0: get header, 1: copy, 2: decompress */
jonathonfletcher 0:54f5be781526 162 z_off64_t start; /* where the gzip data started, for rewinding */
jonathonfletcher 0:54f5be781526 163 int eof; /* true if end of input file reached */
jonathonfletcher 0:54f5be781526 164 int past; /* true if read requested past end */
jonathonfletcher 0:54f5be781526 165 /* just for writing */
jonathonfletcher 0:54f5be781526 166 int level; /* compression level */
jonathonfletcher 0:54f5be781526 167 int strategy; /* compression strategy */
jonathonfletcher 0:54f5be781526 168 /* seek request */
jonathonfletcher 0:54f5be781526 169 z_off64_t skip; /* amount to skip (already rewound if backwards) */
jonathonfletcher 0:54f5be781526 170 int seek; /* true if seek request pending */
jonathonfletcher 0:54f5be781526 171 /* error information */
jonathonfletcher 0:54f5be781526 172 int err; /* error code */
jonathonfletcher 0:54f5be781526 173 char *msg; /* error message */
jonathonfletcher 0:54f5be781526 174 /* zlib inflate or deflate stream */
jonathonfletcher 0:54f5be781526 175 z_stream strm; /* stream structure in-place (not a pointer) */
jonathonfletcher 0:54f5be781526 176 } gz_state;
jonathonfletcher 0:54f5be781526 177 typedef gz_state FAR *gz_statep;
jonathonfletcher 0:54f5be781526 178
jonathonfletcher 0:54f5be781526 179 /* shared functions */
jonathonfletcher 0:54f5be781526 180 void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
jonathonfletcher 0:54f5be781526 181 #if defined UNDER_CE
jonathonfletcher 0:54f5be781526 182 char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
jonathonfletcher 0:54f5be781526 183 #endif
jonathonfletcher 0:54f5be781526 184
jonathonfletcher 0:54f5be781526 185 /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
jonathonfletcher 0:54f5be781526 186 value -- needed when comparing unsigned to z_off64_t, which is signed
jonathonfletcher 0:54f5be781526 187 (possible z_off64_t types off_t, off64_t, and long are all signed) */
jonathonfletcher 0:54f5be781526 188 #ifdef INT_MAX
jonathonfletcher 0:54f5be781526 189 # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
jonathonfletcher 0:54f5be781526 190 #else
jonathonfletcher 0:54f5be781526 191 unsigned ZLIB_INTERNAL gz_intmax OF((void));
jonathonfletcher 0:54f5be781526 192 # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
jonathonfletcher 0:54f5be781526 193 #endif