1 /* 2 * (C) Copyright 2000-2006 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <watchdog.h> 10 #include <command.h> 11 #include <image.h> 12 #include <malloc.h> 13 #include <u-boot/zlib.h> 14 15 #define ZALLOC_ALIGNMENT 16 16 #define HEAD_CRC 2 17 #define EXTRA_FIELD 4 18 #define ORIG_NAME 8 19 #define COMMENT 0x10 20 #define RESERVED 0xe0 21 #define DEFLATED 8 22 23 void *gzalloc(void *x, unsigned items, unsigned size) 24 { 25 void *p; 26 27 size *= items; 28 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); 29 30 p = malloc (size); 31 32 return (p); 33 } 34 35 void gzfree(void *x, void *addr, unsigned nb) 36 { 37 free (addr); 38 } 39 40 int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) 41 { 42 int i, flags; 43 44 /* skip header */ 45 i = 10; 46 flags = src[3]; 47 if (src[2] != DEFLATED || (flags & RESERVED) != 0) { 48 puts ("Error: Bad gzipped data\n"); 49 return (-1); 50 } 51 if ((flags & EXTRA_FIELD) != 0) 52 i = 12 + src[10] + (src[11] << 8); 53 if ((flags & ORIG_NAME) != 0) 54 while (src[i++] != 0) 55 ; 56 if ((flags & COMMENT) != 0) 57 while (src[i++] != 0) 58 ; 59 if ((flags & HEAD_CRC) != 0) 60 i += 2; 61 if (i >= *lenp) { 62 puts ("Error: gunzip out of data in header\n"); 63 return (-1); 64 } 65 66 return zunzip(dst, dstlen, src, lenp, 1, i); 67 } 68 69 /* 70 * Uncompress blocks compressed with zlib without headers 71 */ 72 int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp, 73 int stoponerr, int offset) 74 { 75 z_stream s; 76 int r; 77 78 s.zalloc = gzalloc; 79 s.zfree = gzfree; 80 81 r = inflateInit2(&s, -MAX_WBITS); 82 if (r != Z_OK) { 83 printf ("Error: inflateInit2() returned %d\n", r); 84 return -1; 85 } 86 s.next_in = src + offset; 87 s.avail_in = *lenp - offset; 88 s.next_out = dst; 89 s.avail_out = dstlen; 90 do { 91 r = inflate(&s, Z_FINISH); 92 if (r != Z_STREAM_END && r != Z_BUF_ERROR && stoponerr == 1) { 93 printf("Error: inflate() returned %d\n", r); 94 inflateEnd(&s); 95 return -1; 96 } 97 s.avail_in = *lenp - offset - (int)(s.next_out - (unsigned char*)dst); 98 s.avail_out = dstlen; 99 } while (r == Z_BUF_ERROR); 100 *lenp = s.next_out - (unsigned char *) dst; 101 inflateEnd(&s); 102 103 return 0; 104 } 105