5c43ae2576679c6c7fcfcf2c6e51bdcd41fd2620
[openwrt.git] / target / linux / ar71xx / patches-3.10 / 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 @@ -89,6 +89,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);