162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/zlib.h> 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci/* bits taken from ppc */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ciextern void *avail_ram, *end_avail; 762306a36Sopenharmony_civoid gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistatic void exit(void) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci for (;;); 1262306a36Sopenharmony_ci} 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic void *zalloc(unsigned int size) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci void *p = avail_ram; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci size = (size + 7) & -8; 1962306a36Sopenharmony_ci avail_ram += size; 2062306a36Sopenharmony_ci if (avail_ram > end_avail) { 2162306a36Sopenharmony_ci //puts("oops... out of memory\n"); 2262306a36Sopenharmony_ci //pause(); 2362306a36Sopenharmony_ci exit (); 2462306a36Sopenharmony_ci } 2562306a36Sopenharmony_ci return p; 2662306a36Sopenharmony_ci} 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define HEAD_CRC 2 2962306a36Sopenharmony_ci#define EXTRA_FIELD 4 3062306a36Sopenharmony_ci#define ORIG_NAME 8 3162306a36Sopenharmony_ci#define COMMENT 0x10 3262306a36Sopenharmony_ci#define RESERVED 0xe0 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define DEFLATED 8 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_civoid gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci z_stream s; 3962306a36Sopenharmony_ci int r, i, flags; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci /* skip header */ 4262306a36Sopenharmony_ci i = 10; 4362306a36Sopenharmony_ci flags = src[3]; 4462306a36Sopenharmony_ci if (src[2] != DEFLATED || (flags & RESERVED) != 0) { 4562306a36Sopenharmony_ci //puts("bad gzipped data\n"); 4662306a36Sopenharmony_ci exit(); 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci if ((flags & EXTRA_FIELD) != 0) 4962306a36Sopenharmony_ci i = 12 + src[10] + (src[11] << 8); 5062306a36Sopenharmony_ci if ((flags & ORIG_NAME) != 0) 5162306a36Sopenharmony_ci while (src[i++] != 0) 5262306a36Sopenharmony_ci ; 5362306a36Sopenharmony_ci if ((flags & COMMENT) != 0) 5462306a36Sopenharmony_ci while (src[i++] != 0) 5562306a36Sopenharmony_ci ; 5662306a36Sopenharmony_ci if ((flags & HEAD_CRC) != 0) 5762306a36Sopenharmony_ci i += 2; 5862306a36Sopenharmony_ci if (i >= *lenp) { 5962306a36Sopenharmony_ci //puts("gunzip: ran out of data in header\n"); 6062306a36Sopenharmony_ci exit(); 6162306a36Sopenharmony_ci } 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci s.workspace = zalloc(zlib_inflate_workspacesize()); 6462306a36Sopenharmony_ci r = zlib_inflateInit2(&s, -MAX_WBITS); 6562306a36Sopenharmony_ci if (r != Z_OK) { 6662306a36Sopenharmony_ci //puts("inflateInit2 returned "); puthex(r); puts("\n"); 6762306a36Sopenharmony_ci exit(); 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci s.next_in = src + i; 7062306a36Sopenharmony_ci s.avail_in = *lenp - i; 7162306a36Sopenharmony_ci s.next_out = dst; 7262306a36Sopenharmony_ci s.avail_out = dstlen; 7362306a36Sopenharmony_ci r = zlib_inflate(&s, Z_FINISH); 7462306a36Sopenharmony_ci if (r != Z_OK && r != Z_STREAM_END) { 7562306a36Sopenharmony_ci //puts("inflate returned "); puthex(r); puts("\n"); 7662306a36Sopenharmony_ci exit(); 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci *lenp = s.next_out - (unsigned char *) dst; 7962306a36Sopenharmony_ci zlib_inflateEnd(&s); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 82