d81fdd8f193b2a4e9a37c745f290a636ca78b784
[openwrt/svn-archive/archive.git] / target / linux / ar71xx / patches-3.8 / 310-lib-add-rle-decompression.patch
1 --- a/lib/Kconfig
2 +++ b/lib/Kconfig
3 @@ -197,6 +197,9 @@ config LZMA_COMPRESS
4 config LZMA_DECOMPRESS
5 tristate
6
7 +config RLE_DECOMPRESS
8 + tristate
9 +
10 #
11 # These all provide a common interface (hence the apparent duplication with
12 # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
13 --- a/lib/Makefile
14 +++ b/lib/Makefile
15 @@ -86,6 +86,7 @@ obj-$(CONFIG_XZ_DEC) += xz/
16 obj-$(CONFIG_RAID6_PQ) += raid6/
17 obj-$(CONFIG_LZMA_COMPRESS) += lzma/
18 obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/
19 +obj-$(CONFIG_RLE_DECOMPRESS) += rle.o
20
21 lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
22 lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
23 --- /dev/null
24 +++ b/include/linux/rle.h
25 @@ -0,0 +1,8 @@
26 +#ifndef _RLE_H_
27 +#define _RLE_H_
28 +
29 +int rle_decode(const unsigned char *src, size_t srclen,
30 + unsigned char *dst, size_t dstlen,
31 + size_t *src_done, size_t *dst_done);
32 +
33 +#endif /* _RLE_H_ */
34 --- /dev/null
35 +++ b/lib/rle.c
36 @@ -0,0 +1,78 @@
37 +/*
38 + * RLE decoding routine
39 + *
40 + * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
41 + *
42 + * This program is free software; you can redistribute it and/or modify it
43 + * under the terms of the GNU General Public License version 2 as published
44 + * by the Free Software Foundation.
45 + */
46 +
47 +#include <linux/kernel.h>
48 +#include <linux/module.h>
49 +#include <linux/rle.h>
50 +
51 +int rle_decode(const unsigned char *src, size_t srclen,
52 + unsigned char *dst, size_t dstlen,
53 + size_t *src_done, size_t *dst_done)
54 +{
55 + size_t srcpos, dstpos;
56 + int ret;
57 +
58 + srcpos = 0;
59 + dstpos = 0;
60 + ret = -EINVAL;
61 +
62 + /* sanity checks */
63 + if (!src || !srclen || !dst || !dstlen)
64 + goto out;
65 +
66 + while (1) {
67 + char count;
68 +
69 + if (srcpos >= srclen)
70 + break;
71 +
72 + count = (char) src[srcpos++];
73 + if (count == 0) {
74 + ret = 0;
75 + break;
76 + }
77 +
78 + if (count > 0) {
79 + unsigned char c;
80 +
81 + if (srcpos >= srclen)
82 + break;
83 +
84 + c = src[srcpos++];
85 +
86 + while (count--) {
87 + if (dstpos >= dstlen)
88 + break;
89 +
90 + dst[dstpos++] = c;
91 + }
92 + } else {
93 + count *= -1;
94 +
95 + while (count--) {
96 + if (srcpos >= srclen)
97 + break;
98 + if (dstpos >= dstlen)
99 + break;
100 + dst[dstpos++] = src[srcpos++];
101 + }
102 + }
103 + }
104 +
105 +out:
106 + if (src_done)
107 + *src_done = srcpos;
108 + if (dst_done)
109 + *dst_done = dstpos;
110 +
111 + return ret;
112 +}
113 +
114 +EXPORT_SYMBOL_GPL(rle_decode);