1 /* 2 * (C) Copyright 2000-2006 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <watchdog.h> 26 #include <command.h> 27 #include <image.h> 28 #include <malloc.h> 29 #include <u-boot/zlib.h> 30 31 #define ZALLOC_ALIGNMENT 16 32 #define HEAD_CRC 2 33 #define EXTRA_FIELD 4 34 #define ORIG_NAME 8 35 #define COMMENT 0x10 36 #define RESERVED 0xe0 37 #define DEFLATED 8 38 39 void *gzalloc(void *x, unsigned items, unsigned size) 40 { 41 void *p; 42 43 size *= items; 44 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); 45 46 p = malloc (size); 47 48 return (p); 49 } 50 51 void gzfree(void *x, void *addr, unsigned nb) 52 { 53 free (addr); 54 } 55 56 int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) 57 { 58 int i, flags; 59 60 /* skip header */ 61 i = 10; 62 flags = src[3]; 63 if (src[2] != DEFLATED || (flags & RESERVED) != 0) { 64 puts ("Error: Bad gzipped data\n"); 65 return (-1); 66 } 67 if ((flags & EXTRA_FIELD) != 0) 68 i = 12 + src[10] + (src[11] << 8); 69 if ((flags & ORIG_NAME) != 0) 70 while (src[i++] != 0) 71 ; 72 if ((flags & COMMENT) != 0) 73 while (src[i++] != 0) 74 ; 75 if ((flags & HEAD_CRC) != 0) 76 i += 2; 77 if (i >= *lenp) { 78 puts ("Error: gunzip out of data in header\n"); 79 return (-1); 80 } 81 82 return zunzip(dst, dstlen, src, lenp, 1, i); 83 } 84 85 /* 86 * Uncompress blocks compressed with zlib without headers 87 */ 88 int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp, 89 int stoponerr, int offset) 90 { 91 z_stream s; 92 int r; 93 94 s.zalloc = gzalloc; 95 s.zfree = gzfree; 96 97 r = inflateInit2(&s, -MAX_WBITS); 98 if (r != Z_OK) { 99 printf ("Error: inflateInit2() returned %d\n", r); 100 return -1; 101 } 102 s.next_in = src + offset; 103 s.avail_in = *lenp - offset; 104 s.next_out = dst; 105 s.avail_out = dstlen; 106 do { 107 r = inflate(&s, Z_FINISH); 108 if (r != Z_STREAM_END && r != Z_BUF_ERROR && stoponerr == 1) { 109 printf("Error: inflate() returned %d\n", r); 110 inflateEnd(&s); 111 return -1; 112 } 113 s.avail_in = *lenp - offset - (int)(s.next_out - (unsigned char*)dst); 114 s.avail_out = dstlen; 115 } while (r == Z_BUF_ERROR); 116 *lenp = s.next_out - (unsigned char *) dst; 117 inflateEnd(&s); 118 119 return 0; 120 } 121