xref: /linux/lib/decompress.c (revision 889c92d21db40be0b7d22a59395060237895bb85)
1*889c92d2SH. Peter Anvin /*
2*889c92d2SH. Peter Anvin  * decompress.c
3*889c92d2SH. Peter Anvin  *
4*889c92d2SH. Peter Anvin  * Detect the decompression method based on magic number
5*889c92d2SH. Peter Anvin  */
6*889c92d2SH. Peter Anvin 
7*889c92d2SH. Peter Anvin #include <linux/decompress/generic.h>
8*889c92d2SH. Peter Anvin 
9*889c92d2SH. Peter Anvin #include <linux/decompress/bunzip2.h>
10*889c92d2SH. Peter Anvin #include <linux/decompress/unlzma.h>
11*889c92d2SH. Peter Anvin #include <linux/decompress/inflate.h>
12*889c92d2SH. Peter Anvin 
13*889c92d2SH. Peter Anvin #include <linux/types.h>
14*889c92d2SH. Peter Anvin #include <linux/string.h>
15*889c92d2SH. Peter Anvin 
16*889c92d2SH. Peter Anvin static const struct compress_format {
17*889c92d2SH. Peter Anvin 	unsigned char magic[2];
18*889c92d2SH. Peter Anvin 	const char *name;
19*889c92d2SH. Peter Anvin 	decompress_fn decompressor;
20*889c92d2SH. Peter Anvin } compressed_formats[] = {
21*889c92d2SH. Peter Anvin #ifdef CONFIG_DECOMPRESS_GZIP
22*889c92d2SH. Peter Anvin 	{ {037, 0213}, "gzip", gunzip },
23*889c92d2SH. Peter Anvin 	{ {037, 0236}, "gzip", gunzip },
24*889c92d2SH. Peter Anvin #endif
25*889c92d2SH. Peter Anvin #ifdef CONFIG_DECOMPRESS_BZIP2
26*889c92d2SH. Peter Anvin 	{ {0x42, 0x5a}, "bzip2", bunzip2 },
27*889c92d2SH. Peter Anvin #endif
28*889c92d2SH. Peter Anvin #ifdef CONFIG_DECOMPRESS_LZMA
29*889c92d2SH. Peter Anvin 	{ {0x5d, 0x00}, "lzma", unlzma },
30*889c92d2SH. Peter Anvin #endif
31*889c92d2SH. Peter Anvin 	{ {0, 0}, NULL, NULL }
32*889c92d2SH. Peter Anvin };
33*889c92d2SH. Peter Anvin 
34*889c92d2SH. Peter Anvin decompress_fn decompress_method(const unsigned char *inbuf, int len,
35*889c92d2SH. Peter Anvin 				const char **name)
36*889c92d2SH. Peter Anvin {
37*889c92d2SH. Peter Anvin 	const struct compress_format *cf;
38*889c92d2SH. Peter Anvin 
39*889c92d2SH. Peter Anvin 	if (len < 2)
40*889c92d2SH. Peter Anvin 		return NULL;	/* Need at least this much... */
41*889c92d2SH. Peter Anvin 
42*889c92d2SH. Peter Anvin 	for (cf = compressed_formats; cf->decompressor; cf++) {
43*889c92d2SH. Peter Anvin 		if (!memcmp(inbuf, cf->magic, 2))
44*889c92d2SH. Peter Anvin 			break;
45*889c92d2SH. Peter Anvin 
46*889c92d2SH. Peter Anvin 	}
47*889c92d2SH. Peter Anvin 	if (name)
48*889c92d2SH. Peter Anvin 		*name = cf->name;
49*889c92d2SH. Peter Anvin 	return cf->decompressor;
50*889c92d2SH. Peter Anvin }
51