1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
*
* Copyright (c) 2003 by Joergen Ibsen / Jibz
* All Rights Reserved
*
* http://www.ibsensoftware.com/
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* Optimised for MicroPython:
* Copyright (c) 2023 by Jim Mussared
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software
* for any purpose, including commercial applications,
* and to alter it and redistribute it freely, subject to
* the following restrictions:
*
* 1. The origin of this software must not be
* misrepresented; you must not claim that you
* wrote the original software. If you use this
* software in a product, an acknowledgment in
* the product documentation would be appreciated
* but is not required.
*
* 2. Altered source versions must be plainly marked
* as such, and must not be misrepresented as
* being the original software.
*
* 3. This notice may not be removed or altered from
* any source distribution.
*/
#include "uzlib.h"
#define FTEXT 1
#define FHCRC 2
#define FEXTRA 4
#define FNAME 8
#define FCOMMENT 16
void tinf_skip_bytes(uzlib_uncomp_t *d, int num);
uint16_t tinf_get_uint16(uzlib_uncomp_t *d);
void tinf_skip_bytes(uzlib_uncomp_t *d, int num)
{
while (num--) uzlib_get_byte(d);
}
uint16_t tinf_get_uint16(uzlib_uncomp_t *d)
{
unsigned int v = uzlib_get_byte(d);
v = (uzlib_get_byte(d) << 8) | v;
return v;
}
int uzlib_parse_zlib_gzip_header(uzlib_uncomp_t *d, int *wbits)
{
/* -- check format -- */
unsigned char cmf = uzlib_get_byte(d);
unsigned char flg = uzlib_get_byte(d);
/* check for gzip id bytes */
if (cmf == 0x1f && flg == 0x8b) {
/* check method is deflate */
if (uzlib_get_byte(d) != 8) return UZLIB_DATA_ERROR;
/* get flag byte */
flg = uzlib_get_byte(d);
/* check that reserved bits are zero */
if (flg & 0xe0) return UZLIB_DATA_ERROR;
/* -- find start of compressed data -- */
/* skip rest of base header of 10 bytes */
tinf_skip_bytes(d, 6);
/* skip extra data if present */
if (flg & FEXTRA)
{
unsigned int xlen = tinf_get_uint16(d);
tinf_skip_bytes(d, xlen);
}
/* skip file name if present */
if (flg & FNAME) { while (uzlib_get_byte(d)); }
/* skip file comment if present */
if (flg & FCOMMENT) { while (uzlib_get_byte(d)); }
/* check header crc if present */
if (flg & FHCRC)
{
/*unsigned int hcrc =*/ tinf_get_uint16(d);
// TODO: Check!
// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff))
// return UZLIB_DATA_ERROR;
}
/* initialize for crc32 checksum */
d->checksum_type = UZLIB_CHKSUM_CRC;
d->checksum = ~0;
/* gzip does not include the window size in the header, as it is expected that a
compressor will use wbits=15 (32kiB).*/
*wbits = 15;
return UZLIB_HEADER_GZIP;
} else {
/* check checksum */
if ((256*cmf + flg) % 31) return UZLIB_DATA_ERROR;
/* check method is deflate */
if ((cmf & 0x0f) != 8) return UZLIB_DATA_ERROR;
/* check window size is valid */
if ((cmf >> 4) > 7) return UZLIB_DATA_ERROR;
/* check there is no preset dictionary */
if (flg & 0x20) return UZLIB_DATA_ERROR;
/* initialize for adler32 checksum */
d->checksum_type = UZLIB_CHKSUM_ADLER;
d->checksum = 1;
*wbits = (cmf >> 4) + 8;
return UZLIB_HEADER_ZLIB;
}
}
|