18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/zlib.h> 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci/* bits taken from ppc */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ciextern void *avail_ram, *end_avail; 78c2ecf20Sopenharmony_civoid gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistatic void exit(void) 108c2ecf20Sopenharmony_ci{ 118c2ecf20Sopenharmony_ci for (;;); 128c2ecf20Sopenharmony_ci} 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic void *zalloc(unsigned int size) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci void *p = avail_ram; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci size = (size + 7) & -8; 198c2ecf20Sopenharmony_ci avail_ram += size; 208c2ecf20Sopenharmony_ci if (avail_ram > end_avail) { 218c2ecf20Sopenharmony_ci //puts("oops... out of memory\n"); 228c2ecf20Sopenharmony_ci //pause(); 238c2ecf20Sopenharmony_ci exit (); 248c2ecf20Sopenharmony_ci } 258c2ecf20Sopenharmony_ci return p; 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define HEAD_CRC 2 298c2ecf20Sopenharmony_ci#define EXTRA_FIELD 4 308c2ecf20Sopenharmony_ci#define ORIG_NAME 8 318c2ecf20Sopenharmony_ci#define COMMENT 0x10 328c2ecf20Sopenharmony_ci#define RESERVED 0xe0 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define DEFLATED 8 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_civoid gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci z_stream s; 398c2ecf20Sopenharmony_ci int r, i, flags; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci /* skip header */ 428c2ecf20Sopenharmony_ci i = 10; 438c2ecf20Sopenharmony_ci flags = src[3]; 448c2ecf20Sopenharmony_ci if (src[2] != DEFLATED || (flags & RESERVED) != 0) { 458c2ecf20Sopenharmony_ci //puts("bad gzipped data\n"); 468c2ecf20Sopenharmony_ci exit(); 478c2ecf20Sopenharmony_ci } 488c2ecf20Sopenharmony_ci if ((flags & EXTRA_FIELD) != 0) 498c2ecf20Sopenharmony_ci i = 12 + src[10] + (src[11] << 8); 508c2ecf20Sopenharmony_ci if ((flags & ORIG_NAME) != 0) 518c2ecf20Sopenharmony_ci while (src[i++] != 0) 528c2ecf20Sopenharmony_ci ; 538c2ecf20Sopenharmony_ci if ((flags & COMMENT) != 0) 548c2ecf20Sopenharmony_ci while (src[i++] != 0) 558c2ecf20Sopenharmony_ci ; 568c2ecf20Sopenharmony_ci if ((flags & HEAD_CRC) != 0) 578c2ecf20Sopenharmony_ci i += 2; 588c2ecf20Sopenharmony_ci if (i >= *lenp) { 598c2ecf20Sopenharmony_ci //puts("gunzip: ran out of data in header\n"); 608c2ecf20Sopenharmony_ci exit(); 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci s.workspace = zalloc(zlib_inflate_workspacesize()); 648c2ecf20Sopenharmony_ci r = zlib_inflateInit2(&s, -MAX_WBITS); 658c2ecf20Sopenharmony_ci if (r != Z_OK) { 668c2ecf20Sopenharmony_ci //puts("inflateInit2 returned "); puthex(r); puts("\n"); 678c2ecf20Sopenharmony_ci exit(); 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci s.next_in = src + i; 708c2ecf20Sopenharmony_ci s.avail_in = *lenp - i; 718c2ecf20Sopenharmony_ci s.next_out = dst; 728c2ecf20Sopenharmony_ci s.avail_out = dstlen; 738c2ecf20Sopenharmony_ci r = zlib_inflate(&s, Z_FINISH); 748c2ecf20Sopenharmony_ci if (r != Z_OK && r != Z_STREAM_END) { 758c2ecf20Sopenharmony_ci //puts("inflate returned "); puthex(r); puts("\n"); 768c2ecf20Sopenharmony_ci exit(); 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci *lenp = s.next_out - (unsigned char *) dst; 798c2ecf20Sopenharmony_ci zlib_inflateEnd(&s); 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 82