ca198ee9fcaaefe6f47d7e5d8398b484955449db
[openwrt/staging/wigyori.git] / package / utils / rbextract / src / rle.c
1 /*
2 * RLE decoding routine
3 *
4 * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
10
11 #include <stdio.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <stdbool.h>
15 #include <sys/types.h>
16
17 #include "rle.h"
18
19 int rle_decode(const unsigned char *src, size_t srclen,
20 unsigned char *dst, size_t dstlen,
21 size_t *src_done, size_t *dst_done)
22 {
23 size_t srcpos, dstpos;
24 int ret;
25
26 srcpos = 0;
27 dstpos = 0;
28 ret = 1;
29
30 /* sanity checks */
31 if (!src || !srclen || !dst || !dstlen)
32 goto out;
33
34 while (1) {
35 signed char count;
36
37 if (srcpos >= srclen)
38 break;
39
40 count = (signed char) src[srcpos++];
41 if (count == 0) {
42 ret = 0;
43 break;
44 }
45
46 if (count > 0) {
47 unsigned char c;
48
49 if (srcpos >= srclen)
50 break;
51
52 c = src[srcpos++];
53
54 while (count--) {
55 if (dstpos >= dstlen)
56 break;
57
58 dst[dstpos++] = c;
59 }
60 } else {
61 count *= -1;
62
63 while (count--) {
64 if (srcpos >= srclen)
65 break;
66 if (dstpos >= dstlen)
67 break;
68 dst[dstpos++] = src[srcpos++];
69 }
70 }
71 }
72
73 out:
74 if (src_done)
75 *src_done = srcpos;
76 if (dst_done)
77 *dst_done = dstpos;
78
79 return ret;
80 }