1 /**
2 * @file lv_rle.c
3 */
4
5 /*********************
6 * INCLUDES
7 *********************/
8
9 #include "../../stdlib/lv_string.h"
10 #include "lv_rle.h"
11
12 #if LV_USE_RLE
13
14 /*********************
15 * DEFINES
16 *********************/
17
18 /**********************
19 * TYPEDEFS
20 **********************/
21
22 /**********************
23 * STATIC PROTOTYPES
24 **********************/
25
26 /**********************
27 * STATIC VARIABLES
28 **********************/
29
30 /**********************
31 * MACROS
32 **********************/
33
34 /**********************
35 * GLOBAL FUNCTIONS
36 **********************/
37
lv_rle_decompress(const uint8_t * input,uint32_t input_buff_len,uint8_t * output,uint32_t output_buff_len,uint8_t blk_size)38 uint32_t lv_rle_decompress(const uint8_t * input,
39 uint32_t input_buff_len, uint8_t * output,
40 uint32_t output_buff_len, uint8_t blk_size)
41 {
42 uint32_t ctrl_byte;
43 uint32_t rd_len = 0;
44 uint32_t wr_len = 0;
45
46 while(rd_len < input_buff_len) {
47 ctrl_byte = input[0];
48 rd_len++;
49 input++;
50 if(rd_len > input_buff_len)
51 return 0;
52
53 if(ctrl_byte & 0x80) {
54 /* copy directly from input to output */
55 uint32_t bytes = blk_size * (ctrl_byte & 0x7f);
56 rd_len += bytes;
57 if(rd_len > input_buff_len)
58 return 0;
59
60 wr_len += bytes;
61 if(wr_len > output_buff_len) {
62 if(wr_len > output_buff_len + blk_size)
63 return 0; /* Error */
64 lv_memcpy(output, input, output_buff_len - (wr_len - bytes));
65 return output_buff_len;
66 }
67
68 lv_memcpy(output, input, bytes);
69 output += bytes;
70 input += bytes;
71 }
72 else {
73 rd_len += blk_size;
74 if(rd_len > input_buff_len)
75 return 0;
76
77 wr_len += blk_size * ctrl_byte;
78 if(wr_len > output_buff_len) {
79 if(wr_len > output_buff_len + blk_size)
80 return 0; /* Error happened */
81
82 /* Skip the last pixel, which could overflow output buffer.*/
83 for(uint32_t i = 0; i < ctrl_byte - 1; i++) {
84 lv_memcpy(output, input, blk_size);
85 output += blk_size;
86 }
87 return output_buff_len;
88 }
89
90 if(blk_size == 1) {
91 /* optimize the most common case. */
92 lv_memset(output, input[0], ctrl_byte);
93 output += ctrl_byte;
94 }
95 else {
96 for(uint32_t i = 0; i < ctrl_byte; i++) {
97 lv_memcpy(output, input, blk_size);
98 output += blk_size;
99 }
100 }
101 input += blk_size;
102 }
103 }
104
105 return wr_len;
106 }
107
108 /**********************
109 * STATIC FUNCTIONS
110 **********************/
111
112 #endif /*LV_USE_RLE*/
113