@@ -189,7 +189,7 @@ LZSSDecoder::LZSSDecoder(std::function<int()> getc_cbk, std::function<void(const
189
189
190
190
191
191
LZSSDecoder::LZSSDecoder (std::function<void (const uint8_t )> putc_cbk)
192
- : put_char_cbk(putc_cbk), state(FSM_0), available_bits (0 ) {
192
+ : put_char_cbk(putc_cbk), state(FSM_0), available (0 ) {
193
193
for (int i = 0 ; i < N - F; i++) buffer[i] = ' ' ;
194
194
r = N - F;
195
195
}
@@ -242,62 +242,57 @@ LZSSDecoder::status LZSSDecoder::handle_state() {
242
242
}
243
243
244
244
LZSSDecoder::status LZSSDecoder::decompress (const char * buffer, uint32_t size) {
245
- this ->in_buffer = (uint8_t *)buffer;
245
+ if (!get_char_cbk) {
246
+ this ->in_buffer = (uint8_t *)buffer;
247
+ this ->available += size;
248
+ }
246
249
247
- // I won't ever exceed the (2^32)-1 value, since It is impossible to have a buffer of 512MB on an embedded dev
248
- // thus this value fits a 32 bit uint
249
- this ->available_bits += size*8 ;
250
250
status res = IN_PROGRESS;
251
251
252
252
while ((res = handle_state ()) == IN_PROGRESS);
253
253
254
- if (res == NOT_COMPLETED && this ->available_bits > 0 ) {
255
- this ->save_excess ();
256
- }
257
-
258
254
return res;
259
255
}
260
256
261
257
int LZSSDecoder::getbit (int n) { // get n bits from buffer
258
+ static uint32_t buf, buf_size=0 ;
259
+ int x=0 , c;
260
+
261
+ // if the local bit buffer doesn't have enough bit get them
262
+ while (buf_size < n) {
263
+ switch (c=getc ()) {
264
+ case LZSS_EOF:
265
+ case LZSS_BUFFER_EMPTY:
266
+ return c;
267
+ }
268
+ buf <<= 8 ;
262
269
263
- // check that we have all the available bits required
264
- if (in_buffer == nullptr || n > (available_bits+excess_len)) {
265
- return LZSS_BUFFER_EMPTY;
270
+ buf |= (uint8_t )c;
271
+ buf_size += sizeof (uint8_t )*8 ;
266
272
}
267
273
268
- // get the required bits
269
- static int buf, mask=0 ;
270
- int i, x=0 ;
274
+ // the result is the content of the buffer starting from msb to n successive bits
275
+ x = buf >> (buf_size-n);
276
+
277
+ // remove from the buffer the read bits with a mask
278
+ buf &= (1 <<(buf_size-n))-1 ;
279
+
280
+ buf_size-=n;
271
281
272
- // TODO this function couls be improved by extracting bits>1 with a single mask
273
- for (i = 0 ; i < n; i++) {
274
- if (mask == 0 ) {
275
- if ((buf = getc ()) == LZSS_EOF) return LZSS_EOF;// no need to decrement available_bits
276
- mask = 128 ;
277
- }
278
- x <<= 1 ;
279
- if (buf & mask) x++;
280
- mask >>= 1 ;
281
- }
282
- available_bits -= n;
283
282
return x;
284
283
}
285
284
286
285
int LZSSDecoder::getc () {
287
286
int c;
288
- if (excess_len > 0 ) {
289
- c = excess_bits;
290
- excess_len -= 8 ;
287
+
288
+ if (get_char_cbk) {
289
+ c = get_char_cbk ();
290
+ } else if (in_buffer == nullptr || available == 0 ) {
291
+ c = LZSS_BUFFER_EMPTY;
291
292
} else {
292
293
c = *in_buffer;
293
294
in_buffer++;
295
+ available--;
294
296
}
295
297
return c;
296
298
}
297
-
298
- void LZSSDecoder::save_excess () { // TODO Explain that
299
- if (this ->available_bits >= 8 ) {
300
- this ->excess_bits = *this ->in_buffer ;
301
- this ->excess_len = 8 ;
302
- }
303
- }
0 commit comments