AlcapDAQ  1
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 
42 {
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++) {
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]) {
92  } else {
94  io_buffer_put(output,s->run_length, 24);
95 
96  }
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 {
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