3 #define rle_read_col(OUT, IDX) \
4 for(OUT=0, i=0; i<bpp;++i) {OUT |= (q[bpp*(IDX)+i] << (i*8));}
6 unsigned char *data
, unsigned data_size
,
7 unsigned bpp
, unsigned char** result
)
9 /* worst case length: entire file consisting of sequences of 2
10 identical, and one different pixel, resulting in
11 1 byte flag + 1 pixel + 1 byte flag + 1 pixel. in the case of
12 8 bit, that's 1 byte overhead every 3 pixels. */
13 unsigned char *out
= malloc(data_size
+ 1 + (data_size
/bpp
/3));
15 unsigned char *p
= out
, *q
= data
;
16 unsigned i
, count
= 0, togo
= data_size
/bpp
, repcol
= 0;
17 unsigned mode
= 0; /* 0: stateless, 1: series: 2: repetition */
21 unsigned col
[2] = {0};
23 rle_read_col(col
[0], count
);
24 if(togo
>1 && mode
< 2) rle_read_col(col
[1], count
+1);
26 if(count
) goto write_series
;
32 if(col
[0] == col
[1]) {
47 if(col
[0] == col
[1]) {
54 *(p
++) = ((mode
- 1) << 7) | (count
- 1);
55 if(mode
== 1) for(i
=0;i
<count
*bpp
;++i
)
59 *(p
++) = (repcol
& (0xff << i
)) >> i
;
63 if(jump_flag
== 1) goto start_rep
;
64 if(jump_flag
== 2) goto start_series
;
72 if(col
[0] == repcol
) goto advance
;
85 /* caller needs to provide result buffer of w*h*bpp size. */
87 unsigned char *data
, unsigned data_size
,
88 unsigned bpp
, unsigned char* result
, unsigned result_size
) {
90 *p
= result
, *p_e
= p
+ result_size
,
91 *q
= data
, *q_e
= q
+ data_size
;
92 while(q
+1+bpp
<= q_e
) {
93 unsigned count
= (*q
& 127) + 1;
94 unsigned rep
= *q
& 128;
95 unsigned color
= 0, i
, j
;
98 for(i
= 0; i
< bpp
; ++i
)
99 color
= (color
<< 8) | *(q
++);
100 for(i
= 0; i
< count
&& p
+bpp
<= p_e
; ++i
)
102 *(p
++) = (color
>> ((bpp
-j
-1)*8)) & 0xff;
104 for(i
= 0; i
< count
&& p
+bpp
<= p_e
&& q
+bpp
<= q_e
; ++i
)
105 for(j
=0; j
<bpp
; j
++) *(p
++) = *(q
++);