2 * Copyright (c) 2013, The Chromium Authors
4 * SPDX-License-Identifier: GPL-2.0+
13 #include <u-boot/zlib.h>
16 #include <lzma/LzmaTypes.h>
17 #include <lzma/LzmaDec.h>
18 #include <lzma/LzmaTools.h>
20 #include <linux/lzo.h>
22 static const char plain[] =
23 "I am a highly compressable bit of text.\n"
24 "I am a highly compressable bit of text.\n"
25 "I am a highly compressable bit of text.\n"
26 "There are many like me, but this one is mine.\n"
27 "If I were any shorter, there wouldn't be much sense in\n"
28 "compressing me in the first place. At least with lzo, anyway,\n"
29 "which appears to behave poorly in the face of short text\n"
32 /* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
33 static const char bzip2_compressed[] =
34 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
35 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
36 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
37 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
38 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
39 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
40 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
41 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
42 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
43 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
44 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
45 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
46 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
47 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
48 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
49 static const unsigned long bzip2_compressed_size = 240;
51 /* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
52 static const char lzma_compressed[] =
53 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
54 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
55 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
56 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
57 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
58 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
59 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
60 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
61 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
62 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
63 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
64 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
65 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
66 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
67 "\xfd\xf5\x50\x8d\xca";
68 static const unsigned long lzma_compressed_size = 229;
70 /* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
71 static const char lzo_compressed[] =
72 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
73 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
74 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
75 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
76 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
77 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
78 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
79 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
80 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
81 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
82 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
83 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
84 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
85 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
86 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
87 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
88 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
89 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
90 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
91 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
92 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
93 static const unsigned long lzo_compressed_size = 334;
96 #define TEST_BUFFER_SIZE 512
98 typedef int (*mutate_func)(void *, unsigned long, void *, unsigned long,
101 static int compress_using_gzip(void *in, unsigned long in_size,
102 void *out, unsigned long out_max,
103 unsigned long *out_size)
106 unsigned long inout_size = out_max;
108 ret = gzip(out, &inout_size, in, in_size);
110 *out_size = inout_size;
115 static int uncompress_using_gzip(void *in, unsigned long in_size,
116 void *out, unsigned long out_max,
117 unsigned long *out_size)
120 unsigned long inout_size = in_size;
122 ret = gunzip(out, out_max, in, &inout_size);
124 *out_size = inout_size;
129 static int compress_using_bzip2(void *in, unsigned long in_size,
130 void *out, unsigned long out_max,
131 unsigned long *out_size)
133 /* There is no bzip2 compression in u-boot, so fake it. */
134 assert(in_size == strlen(plain));
135 assert(memcmp(plain, in, in_size) == 0);
137 if (bzip2_compressed_size > out_max)
140 memcpy(out, bzip2_compressed, bzip2_compressed_size);
142 *out_size = bzip2_compressed_size;
147 static int uncompress_using_bzip2(void *in, unsigned long in_size,
148 void *out, unsigned long out_max,
149 unsigned long *out_size)
152 unsigned int inout_size = out_max;
154 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
155 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
157 *out_size = inout_size;
159 return (ret != BZ_OK);
162 static int compress_using_lzma(void *in, unsigned long in_size,
163 void *out, unsigned long out_max,
164 unsigned long *out_size)
166 /* There is no lzma compression in u-boot, so fake it. */
167 assert(in_size == strlen(plain));
168 assert(memcmp(plain, in, in_size) == 0);
170 if (lzma_compressed_size > out_max)
173 memcpy(out, lzma_compressed, lzma_compressed_size);
175 *out_size = lzma_compressed_size;
180 static int uncompress_using_lzma(void *in, unsigned long in_size,
181 void *out, unsigned long out_max,
182 unsigned long *out_size)
185 SizeT inout_size = out_max;
187 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
189 *out_size = inout_size;
191 return (ret != SZ_OK);
194 static int compress_using_lzo(void *in, unsigned long in_size,
195 void *out, unsigned long out_max,
196 unsigned long *out_size)
198 /* There is no lzo compression in u-boot, so fake it. */
199 assert(in_size == strlen(plain));
200 assert(memcmp(plain, in, in_size) == 0);
202 if (lzo_compressed_size > out_max)
205 memcpy(out, lzo_compressed, lzo_compressed_size);
207 *out_size = lzo_compressed_size;
212 static int uncompress_using_lzo(void *in, unsigned long in_size,
213 void *out, unsigned long out_max,
214 unsigned long *out_size)
217 size_t input_size = in_size;
218 size_t output_size = out_max;
220 ret = lzop_decompress(in, input_size, out, &output_size);
222 *out_size = output_size;
224 return (ret != LZO_E_OK);
227 #define errcheck(statement) if (!(statement)) { \
228 fprintf(stderr, "\tFailed: %s\n", #statement); \
233 static int run_test(char *name, mutate_func compress, mutate_func uncompress)
235 ulong orig_size, compressed_size, uncompressed_size;
237 void *compressed_buf = NULL;
238 void *uncompressed_buf = NULL;
239 void *compare_buf = NULL;
242 printf(" testing %s ...\n", name);
244 orig_buf = (void *)plain;
245 orig_size = strlen(orig_buf); /* Trailing NULL not included. */
246 errcheck(orig_size > 0);
248 compressed_size = uncompressed_size = TEST_BUFFER_SIZE;
249 compressed_buf = malloc(compressed_size);
250 errcheck(compressed_buf != NULL);
251 uncompressed_buf = malloc(uncompressed_size);
252 errcheck(uncompressed_buf != NULL);
253 compare_buf = malloc(uncompressed_size);
254 errcheck(compare_buf != NULL);
256 /* Compress works as expected. */
257 printf("\torig_size:%lu\n", orig_size);
258 memset(compressed_buf, 'A', TEST_BUFFER_SIZE);
259 errcheck(compress(orig_buf, orig_size,
260 compressed_buf, compressed_size,
261 &compressed_size) == 0);
262 printf("\tcompressed_size:%lu\n", compressed_size);
263 errcheck(compressed_size > 0);
264 errcheck(compressed_size < orig_size);
265 errcheck(((char *)compressed_buf)[compressed_size-1] != 'A');
266 errcheck(((char *)compressed_buf)[compressed_size] == 'A');
268 /* Uncompresses with space remaining. */
269 errcheck(uncompress(compressed_buf, compressed_size,
270 uncompressed_buf, uncompressed_size,
271 &uncompressed_size) == 0);
272 printf("\tuncompressed_size:%lu\n", uncompressed_size);
273 errcheck(uncompressed_size == orig_size);
274 errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
276 /* Uncompresses with exactly the right size output buffer. */
277 memset(uncompressed_buf, 'A', TEST_BUFFER_SIZE);
278 errcheck(uncompress(compressed_buf, compressed_size,
279 uncompressed_buf, orig_size,
280 &uncompressed_size) == 0);
281 errcheck(uncompressed_size == orig_size);
282 errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
283 errcheck(((char *)uncompressed_buf)[orig_size] == 'A');
285 /* Make sure compression does not over-run. */
286 memset(compare_buf, 'A', TEST_BUFFER_SIZE);
287 ret = compress(orig_buf, orig_size,
288 compare_buf, compressed_size - 1,
290 errcheck(((char *)compare_buf)[compressed_size] == 'A');
292 printf("\tcompress does not overrun\n");
294 /* Make sure decompression does not over-run. */
295 memset(compare_buf, 'A', TEST_BUFFER_SIZE);
296 ret = uncompress(compressed_buf, compressed_size,
297 compare_buf, uncompressed_size - 1,
299 errcheck(((char *)compare_buf)[uncompressed_size - 1] == 'A');
301 printf("\tuncompress does not overrun\n");
303 /* Got here, everything is fine. */
307 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
310 free(uncompressed_buf);
311 free(compressed_buf);
317 static int do_test_compression(cmd_tbl_t *cmdtp, int flag, int argc,
322 err += run_test("gzip", compress_using_gzip, uncompress_using_gzip);
323 err += run_test("bzip2", compress_using_bzip2, uncompress_using_bzip2);
324 err += run_test("lzma", compress_using_lzma, uncompress_using_lzma);
325 err += run_test("lzo", compress_using_lzo, uncompress_using_lzo);
327 printf("test_compression %s\n", err == 0 ? "ok" : "FAILED");
333 test_compression, 5, 1, do_test_compression,
334 "Basic test of compressors: gzip bzip2 lzma lzo", ""