Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot
[platform/kernel/u-boot.git] / lib / gzip.c
1 /*
2  * (C) Copyright 2012
3  * Lei Wen <leiwen@marvell.com>, Marvell Inc.
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 <memalign.h>
14 #include <u-boot/zlib.h>
15 #include "zlib/zutil.h"
16
17 #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ
18 #define CONFIG_GZIP_COMPRESS_DEF_SZ     0x200
19 #endif
20 #define ZALLOC_ALIGNMENT                16
21
22 static void *zalloc(void *x, unsigned items, unsigned size)
23 {
24         void *p;
25
26         size *= items;
27         size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
28
29         p = malloc_cache_aligned(size);
30
31         return (p);
32 }
33
34 static void zfree(void *x, void *addr, unsigned nb)
35 {
36         free (addr);
37 }
38
39 int gzip(void *dst, unsigned long *lenp,
40                 unsigned char *src, unsigned long srclen)
41 {
42         return zzip(dst, lenp, src, srclen, 1, NULL);
43 }
44
45 /*
46  * Compress blocks with zlib
47  */
48 int zzip(void *dst, unsigned long *lenp, unsigned char *src,
49                 unsigned long srclen, int stoponerr,
50                 int (*func)(unsigned long, unsigned long))
51 {
52         z_stream s;
53         int r, flush, orig, window;
54         unsigned long comp_len, left_len;
55
56         if (!srclen)
57                 return 0;
58
59 #ifndef CONFIG_GZIP
60         window = MAX_WBITS;
61 #else
62         window = 2 * MAX_WBITS;
63 #endif
64         orig = *lenp;
65         s.zalloc = zalloc;
66         s.zfree = zfree;
67         s.opaque = Z_NULL;
68
69         r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window,
70                         DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
71                         ZLIB_VERSION, sizeof(z_stream));
72         if (r != Z_OK) {
73                 printf ("Error: deflateInit2_() returned %d\n", r);
74                 return -1;
75         }
76
77         while (srclen > 0) {
78                 comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
79                                 CONFIG_GZIP_COMPRESS_DEF_SZ : srclen;
80
81                 s.next_in = src;
82                 s.avail_in = comp_len;
83                 flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)?
84                         Z_NO_FLUSH : Z_FINISH;
85
86                 do {
87                         left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
88                                         CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp;
89                         s.next_out = dst;
90                         s.avail_out = left_len;
91                         r = deflate(&s, flush);
92                         if (r == Z_STREAM_ERROR && stoponerr == 1) {
93                                 printf("Error: deflate() returned %d\n", r);
94                                 r = -1;
95                                 goto bail;
96                         }
97                         if (!func) {
98                                 dst += (left_len - s.avail_out);
99                                 *lenp -= (left_len - s.avail_out);
100                         } else if (left_len - s.avail_out > 0) {
101                                 r = func((unsigned long)dst,
102                                         left_len - s.avail_out);
103                                 if (r < 0)
104                                         goto bail;
105                         }
106                 } while (s.avail_out == 0 && (*lenp > 0));
107                 if (s.avail_in) {
108                         printf("Deflate failed to consume %u bytes", s.avail_in);
109                         r = -1;
110                         goto bail;
111                 }
112                 if (*lenp == 0) {
113                         printf("Deflate need more space to compress "
114                                 "left %lu bytes\n", srclen);
115                         r = -1;
116                         goto bail;
117                 }
118                 srclen -= comp_len;
119                 src += comp_len;
120         }
121
122         r = 0;
123 bail:
124         deflateEnd(&s);
125         *lenp = orig - *lenp;
126         return r;
127 }