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 err = 0; 77 int r; 78 79 s.zalloc = gzalloc; 80 s.zfree = gzfree; 81 82 r = inflateInit2(&s, -MAX_WBITS); 83 if (r != Z_OK) { 84 printf ("Error: inflateInit2() returned %d\n", r); 85 return -1; 86 } 87 s.next_in = src + offset; 88 s.avail_in = *lenp - offset; 89 s.next_out = dst; 90 s.avail_out = dstlen; 91 do { 92 r = inflate(&s, Z_FINISH); 93 if (stoponerr == 1 && r != Z_STREAM_END && 94 (s.avail_out == 0 || r != Z_BUF_ERROR)) { 95 printf("Error: inflate() returned %d\n", r); 96 err = -1; 97 break; 98 } 99 s.avail_in = *lenp - offset - (int)(s.next_out - (unsigned char*)dst); 100 } while (r == Z_BUF_ERROR); 101 *lenp = s.next_out - (unsigned char *) dst; 102 inflateEnd(&s); 103 104 return err; 105 } 106