Blame view

lib/gzip.c 2.6 KB
88d52c6af   Lei Wen   lib: add gzip lib...
1
2
3
4
  /*
   * (C) Copyright 2012
   * Lei Wen <leiwen@marvell.com>, Marvell Inc.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
88d52c6af   Lei Wen   lib: add gzip lib...
6
7
8
9
10
11
12
   */
  
  #include <common.h>
  #include <watchdog.h>
  #include <command.h>
  #include <image.h>
  #include <malloc.h>
6e295186c   Simon Glass   Move malloc_cache...
13
  #include <memalign.h>
88d52c6af   Lei Wen   lib: add gzip lib...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  #include <u-boot/zlib.h>
  #include "zlib/zutil.h"
  
  #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ
  #define CONFIG_GZIP_COMPRESS_DEF_SZ	0x200
  #endif
  #define ZALLOC_ALIGNMENT		16
  
  static void *zalloc(void *x, unsigned items, unsigned size)
  {
  	void *p;
  
  	size *= items;
  	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
4519668b2   Marcel Ziswiler   mtd/nand/ubi: ass...
28
  	p = malloc_cache_aligned(size);
88d52c6af   Lei Wen   lib: add gzip lib...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  
  	return (p);
  }
  
  static void zfree(void *x, void *addr, unsigned nb)
  {
  	free (addr);
  }
  
  int gzip(void *dst, unsigned long *lenp,
  		unsigned char *src, unsigned long srclen)
  {
  	return zzip(dst, lenp, src, srclen, 1, NULL);
  }
  
  /*
   * Compress blocks with zlib
   */
  int zzip(void *dst, unsigned long *lenp, unsigned char *src,
  		unsigned long srclen, int stoponerr,
  		int (*func)(unsigned long, unsigned long))
  {
  	z_stream s;
  	int r, flush, orig, window;
  	unsigned long comp_len, left_len;
  
  	if (!srclen)
  		return 0;
  
  #ifndef CONFIG_GZIP
  	window = MAX_WBITS;
  #else
  	window = 2 * MAX_WBITS;
  #endif
  	orig = *lenp;
  	s.zalloc = zalloc;
  	s.zfree = zfree;
  	s.opaque = Z_NULL;
  
  	r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED,	window,
  			DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  			ZLIB_VERSION, sizeof(z_stream));
  	if (r != Z_OK) {
  		printf ("Error: deflateInit2_() returned %d
  ", r);
  		return -1;
  	}
  
  	while (srclen > 0) {
  		comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
  				CONFIG_GZIP_COMPRESS_DEF_SZ : srclen;
  
  		s.next_in = src;
  		s.avail_in = comp_len;
  		flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)?
  			Z_NO_FLUSH : Z_FINISH;
  
  		do {
  			left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
  					CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp;
  			s.next_out = dst;
  			s.avail_out = left_len;
  			r = deflate(&s, flush);
  			if (r == Z_STREAM_ERROR && stoponerr == 1) {
  				printf("Error: deflate() returned %d
  ", r);
  				r = -1;
  				goto bail;
  			}
  			if (!func) {
  				dst += (left_len - s.avail_out);
  				*lenp -= (left_len - s.avail_out);
  			} else if (left_len - s.avail_out > 0) {
  				r = func((unsigned long)dst,
  					left_len - s.avail_out);
  				if (r < 0)
  					goto bail;
  			}
  		} while (s.avail_out == 0 && (*lenp > 0));
  		if (s.avail_in) {
  			printf("Deflate failed to consume %u bytes", s.avail_in);
  			r = -1;
  			goto bail;
  		}
  		if (*lenp == 0) {
  			printf("Deflate need more space to compress "
  				"left %lu bytes
  ", srclen);
  			r = -1;
  			goto bail;
  		}
  		srclen -= comp_len;
  		src += comp_len;
  	}
  
  	r = 0;
  bail:
  	deflateEnd(&s);
  	*lenp = orig - *lenp;
  	return r;
  }