310-lib-add-rle-decompression.patch 2.5 KB

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