AlcapDAQ
1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
analyzer
compress
rle.cpp
Go to the documentation of this file.
1
//
3
// Run-length encoding and decoding of bit patterns.
4
//
6
7
#include <stdio.h>
8
9
#include "midas.h"
10
11
#include "
mucap_compress.h
"
12
13
static
int
rle_bits_setup_done
= 0;
14
static
char
num_leading_0
[256];
15
static
char
num_leading_1
[256];
16
static
unsigned
char
ones
[9];
17
18
int
num_leading_bits
(
unsigned
char
n,
int
bit_val)
19
{
20
//
21
// Computes the number of leading 0s or 1s (selected by bit_val) in a
22
// given byte. For example, the number of leading 0s in 00010110 is
23
// 3,
24
// and the number of leading 1s is 0.
25
//
26
27
int
retval = 0;
28
29
for
(
int
i
= 0;
i
< 8;
i
++) {
30
int
bit_i = (n >> (7 -
i
)) & 1;
31
if
(bit_i == bit_val) {
32
retval++;
33
}
else
{
34
break
;
35
}
36
}
37
38
return
retval;
39
}
40
41
void
rle_bits_setup
()
42
{
43
if
(
rle_bits_setup_done
) {
44
return
;
45
}
46
47
//
48
// Cache the number of leading 0s and 1s for all 8-bit values.
49
//
50
for
(
int
i
= 0;
i
< 256;
i
++) {
51
num_leading_0
[
i
] =
num_leading_bits
(
i
, 0);
52
num_leading_1
[
i
] =
num_leading_bits
(
i
, 1);
53
}
54
55
//
56
// Cache the bit-strings consisting of all 1s, with lengths from 1 to
57
// 8.
58
//
59
short
o = 0;
60
for
(
int
i
= 0;
i
< 9;
i
++) {
61
ones
[
i
] = o;
62
o = (o << 1) | 1;
63
}
64
}
65
66
void
rle_put
(
unsigned
char
b,
rle_state
*
s
,
io_buffer
* output)
67
{
68
int
bits = 8;
69
70
while
(bits > 0) {
71
int
nr;
72
73
if
(s->
running_digit
== 0) {
74
nr =
num_leading_0
[b];
75
}
else
{
76
nr =
num_leading_1
[b];
77
}
78
79
if
(nr > bits) {
80
nr = bits;
81
}
82
83
s->
run_length
+= nr;
84
bits -= nr;
85
86
if
(bits != 0 || (!s->
use_extension_word
&&
87
s->
run_length
>= s->
huffman_length
[s->
running_digit
]-8)) {
88
b = b << nr;
89
90
if
(s->
run_length
< s->
huffman_length
[s->
running_digit
]) {
91
huffman_put_symbol
(&s->
huffman
[s->
running_digit
], output, s->
run_length
);
92
}
else
{
93
huffman_put_symbol
(&s->
huffman
[s->
running_digit
], output, s->
huffman_length
[s->
running_digit
]);
94
io_buffer_put
(output,s->
run_length
, 24);
95
96
}
97
s->
running_digit
= !s->
running_digit
;
98
s->
run_length
= 0;
99
}
100
}
101
}
102
103
int
flush_rle
(
rle_state
*
s
,
io_buffer
* output)
104
{
105
if
(s->
run_length
!= 0) {
106
if
(s->
run_length
< s->
huffman_length
[s->
running_digit
]) {
107
huffman_put_symbol
(&s->
huffman
[s->
running_digit
], output, s->
run_length
);
108
}
else
{
109
huffman_put_symbol
(&s->
huffman
[s->
running_digit
], output, s->
huffman_length
[s->
running_digit
]);
110
io_buffer_put
(output, s->
run_length
, 24);
111
}
112
}
113
114
return
flush_output_buffer
(output);
115
}
116
117
int
rle_get
(
io_buffer
* input,
rle_state
*
s
)
118
{
119
//
120
// Reverse the encoding performed by rle_bits.
121
//
122
123
unsigned
char
output_word = 0;
124
int
output_bits = 8;
125
126
while
(1) {
127
if
(s->
run_length
== 0) {
128
s->
running_digit
= !s->
running_digit
;
129
int
run_length =
130
huffman_get_symbol
(&s->
huffman
[s->
running_digit
], input);
131
132
if
(run_length < 0) {
133
return
-1;
134
}
else
if
(run_length == s->
huffman_length
[s->
running_digit
]) {
135
s->
run_length
=
io_buffer_get
(input, 24);
136
}
else
{
137
s->
run_length
= run_length;
138
}
139
}
140
141
while
(s->
run_length
> 0) {
142
143
if
(output_bits > s->
run_length
) {
144
output_word = output_word << s->
run_length
;
145
if
(s->
running_digit
== 1) {
146
output_word |=
ones
[s->
run_length
];
147
}
148
output_bits -= s->
run_length
;
149
s->
run_length
= 0;
150
}
else
{
151
output_word = output_word << output_bits;
152
if
(s->
running_digit
== 1) {
153
output_word |=
ones
[output_bits];
154
}
155
s->
run_length
-= output_bits;
156
157
return
output_word;
158
}
159
}
160
161
}
162
}
163
Generated by
1.8.4