xref: /rk3399_rockchip-uboot/lib/gzip.c (revision 88d52c6affa69971caad651e26dcac88a1484a4b)
1*88d52c6aSLei Wen /*
2*88d52c6aSLei Wen  * (C) Copyright 2012
3*88d52c6aSLei Wen  * Lei Wen <leiwen@marvell.com>, Marvell Inc.
4*88d52c6aSLei Wen  *
5*88d52c6aSLei Wen  * See file CREDITS for list of people who contributed to this
6*88d52c6aSLei Wen  * project.
7*88d52c6aSLei Wen  *
8*88d52c6aSLei Wen  * This program is free software; you can redistribute it and/or
9*88d52c6aSLei Wen  * modify it under the terms of the GNU General Public License as
10*88d52c6aSLei Wen  * published by the Free Software Foundation; either version 2 of
11*88d52c6aSLei Wen  * the License, or (at your option) any later version.
12*88d52c6aSLei Wen  *
13*88d52c6aSLei Wen  * This program is distributed in the hope that it will be useful,
14*88d52c6aSLei Wen  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*88d52c6aSLei Wen  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*88d52c6aSLei Wen  * GNU General Public License for more details.
17*88d52c6aSLei Wen  *
18*88d52c6aSLei Wen  * You should have received a copy of the GNU General Public License
19*88d52c6aSLei Wen  * along with this program; if not, write to the Free Software
20*88d52c6aSLei Wen  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21*88d52c6aSLei Wen  * MA 02111-1307 USA
22*88d52c6aSLei Wen  */
23*88d52c6aSLei Wen 
24*88d52c6aSLei Wen #include <common.h>
25*88d52c6aSLei Wen #include <watchdog.h>
26*88d52c6aSLei Wen #include <command.h>
27*88d52c6aSLei Wen #include <image.h>
28*88d52c6aSLei Wen #include <malloc.h>
29*88d52c6aSLei Wen #include <u-boot/zlib.h>
30*88d52c6aSLei Wen #include "zlib/zutil.h"
31*88d52c6aSLei Wen 
32*88d52c6aSLei Wen #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ
33*88d52c6aSLei Wen #define CONFIG_GZIP_COMPRESS_DEF_SZ	0x200
34*88d52c6aSLei Wen #endif
35*88d52c6aSLei Wen #define ZALLOC_ALIGNMENT		16
36*88d52c6aSLei Wen 
37*88d52c6aSLei Wen static void *zalloc(void *x, unsigned items, unsigned size)
38*88d52c6aSLei Wen {
39*88d52c6aSLei Wen 	void *p;
40*88d52c6aSLei Wen 
41*88d52c6aSLei Wen 	size *= items;
42*88d52c6aSLei Wen 	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
43*88d52c6aSLei Wen 
44*88d52c6aSLei Wen 	p = malloc (size);
45*88d52c6aSLei Wen 
46*88d52c6aSLei Wen 	return (p);
47*88d52c6aSLei Wen }
48*88d52c6aSLei Wen 
49*88d52c6aSLei Wen static void zfree(void *x, void *addr, unsigned nb)
50*88d52c6aSLei Wen {
51*88d52c6aSLei Wen 	free (addr);
52*88d52c6aSLei Wen }
53*88d52c6aSLei Wen 
54*88d52c6aSLei Wen int gzip(void *dst, unsigned long *lenp,
55*88d52c6aSLei Wen 		unsigned char *src, unsigned long srclen)
56*88d52c6aSLei Wen {
57*88d52c6aSLei Wen 	return zzip(dst, lenp, src, srclen, 1, NULL);
58*88d52c6aSLei Wen }
59*88d52c6aSLei Wen 
60*88d52c6aSLei Wen /*
61*88d52c6aSLei Wen  * Compress blocks with zlib
62*88d52c6aSLei Wen  */
63*88d52c6aSLei Wen int zzip(void *dst, unsigned long *lenp, unsigned char *src,
64*88d52c6aSLei Wen 		unsigned long srclen, int stoponerr,
65*88d52c6aSLei Wen 		int (*func)(unsigned long, unsigned long))
66*88d52c6aSLei Wen {
67*88d52c6aSLei Wen 	z_stream s;
68*88d52c6aSLei Wen 	int r, flush, orig, window;
69*88d52c6aSLei Wen 	unsigned long comp_len, left_len;
70*88d52c6aSLei Wen 
71*88d52c6aSLei Wen 	if (!srclen)
72*88d52c6aSLei Wen 		return 0;
73*88d52c6aSLei Wen 
74*88d52c6aSLei Wen #ifndef CONFIG_GZIP
75*88d52c6aSLei Wen 	window = MAX_WBITS;
76*88d52c6aSLei Wen #else
77*88d52c6aSLei Wen 	window = 2 * MAX_WBITS;
78*88d52c6aSLei Wen #endif
79*88d52c6aSLei Wen 	orig = *lenp;
80*88d52c6aSLei Wen 	s.zalloc = zalloc;
81*88d52c6aSLei Wen 	s.zfree = zfree;
82*88d52c6aSLei Wen 	s.opaque = Z_NULL;
83*88d52c6aSLei Wen 
84*88d52c6aSLei Wen 	r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED,	window,
85*88d52c6aSLei Wen 			DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
86*88d52c6aSLei Wen 			ZLIB_VERSION, sizeof(z_stream));
87*88d52c6aSLei Wen 	if (r != Z_OK) {
88*88d52c6aSLei Wen 		printf ("Error: deflateInit2_() returned %d\n", r);
89*88d52c6aSLei Wen 		return -1;
90*88d52c6aSLei Wen 	}
91*88d52c6aSLei Wen 
92*88d52c6aSLei Wen 	while (srclen > 0) {
93*88d52c6aSLei Wen 		comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
94*88d52c6aSLei Wen 				CONFIG_GZIP_COMPRESS_DEF_SZ : srclen;
95*88d52c6aSLei Wen 
96*88d52c6aSLei Wen 		s.next_in = src;
97*88d52c6aSLei Wen 		s.avail_in = comp_len;
98*88d52c6aSLei Wen 		flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)?
99*88d52c6aSLei Wen 			Z_NO_FLUSH : Z_FINISH;
100*88d52c6aSLei Wen 
101*88d52c6aSLei Wen 		do {
102*88d52c6aSLei Wen 			left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
103*88d52c6aSLei Wen 					CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp;
104*88d52c6aSLei Wen 			s.next_out = dst;
105*88d52c6aSLei Wen 			s.avail_out = left_len;
106*88d52c6aSLei Wen 			r = deflate(&s, flush);
107*88d52c6aSLei Wen 			if (r == Z_STREAM_ERROR && stoponerr == 1) {
108*88d52c6aSLei Wen 				printf("Error: deflate() returned %d\n", r);
109*88d52c6aSLei Wen 				r = -1;
110*88d52c6aSLei Wen 				goto bail;
111*88d52c6aSLei Wen 			}
112*88d52c6aSLei Wen 			if (!func) {
113*88d52c6aSLei Wen 				dst += (left_len - s.avail_out);
114*88d52c6aSLei Wen 				*lenp -= (left_len - s.avail_out);
115*88d52c6aSLei Wen 			} else if (left_len - s.avail_out > 0) {
116*88d52c6aSLei Wen 				r = func((unsigned long)dst,
117*88d52c6aSLei Wen 					left_len - s.avail_out);
118*88d52c6aSLei Wen 				if (r < 0)
119*88d52c6aSLei Wen 					goto bail;
120*88d52c6aSLei Wen 			}
121*88d52c6aSLei Wen 		} while (s.avail_out == 0 && (*lenp > 0));
122*88d52c6aSLei Wen 		if (s.avail_in) {
123*88d52c6aSLei Wen 			printf("Deflate failed to consume %u bytes", s.avail_in);
124*88d52c6aSLei Wen 			r = -1;
125*88d52c6aSLei Wen 			goto bail;
126*88d52c6aSLei Wen 		}
127*88d52c6aSLei Wen 		if (*lenp == 0) {
128*88d52c6aSLei Wen 			printf("Deflate need more space to compress "
129*88d52c6aSLei Wen 				"left %lu bytes\n", srclen);
130*88d52c6aSLei Wen 			r = -1;
131*88d52c6aSLei Wen 			goto bail;
132*88d52c6aSLei Wen 		}
133*88d52c6aSLei Wen 		srclen -= comp_len;
134*88d52c6aSLei Wen 		src += comp_len;
135*88d52c6aSLei Wen 	}
136*88d52c6aSLei Wen 
137*88d52c6aSLei Wen 	r = 0;
138*88d52c6aSLei Wen bail:
139*88d52c6aSLei Wen 	deflateEnd(&s);
140*88d52c6aSLei Wen 	*lenp = orig - *lenp;
141*88d52c6aSLei Wen 	return r;
142*88d52c6aSLei Wen }
143