From 445a785e10d3beb025dfe565e58603930ea09edc Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Wed, 13 Apr 2011 11:31:36 +0200 Subject: [PATCH] Fix compression of large repetitions * src/misc/intvcomp.cc (stream_compression_base::run): Limit repeatitions to 40, not 42. (stream_decompression_base::refill): Refill the end of the stream with 0. (stream_decompression_base::look_n_bits): Add assertion. * src/tgbatest/intvcomp.cc: Add a new test case. --- ChangeLog | 11 +++++++++++ src/misc/intvcomp.cc | 10 +++++----- src/tgbatest/intvcomp.cc | 13 +++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c8a5aca2..6d51e28b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-04-13 Alexandre Duret-Lutz + + Fix compression of large repetitions + + * src/misc/intvcomp.cc (stream_compression_base::run): Limit + repeatitions to 40, not 42. + (stream_decompression_base::refill): Refill the end of the stream + with 0. + (stream_decompression_base::look_n_bits): Add assertion. + * src/tgbatest/intvcomp.cc: Add a new test case. + 2011-04-12 Alexandre Duret-Lutz More interfaces to the int array compression routines. diff --git a/src/misc/intvcomp.cc b/src/misc/intvcomp.cc index 35aec14ec..98022e82c 100644 --- a/src/misc/intvcomp.cc +++ b/src/misc/intvcomp.cc @@ -97,7 +97,7 @@ namespace spot if (val == last_val) { unsigned int count = 1; - while (count <= 41 && self().skip_if(val)) + while (count < 40 && self().skip_if(val)) ++count; if ((val == 0 && count < 3) || (val == 1 && count == 1)) @@ -376,9 +376,10 @@ namespace spot buffer_ &= buffer_mask_; look_bits_ += fill_size; - if (buffer_bits_ == 0 && self().have_comp_data()) + if (buffer_bits_ == 0) { - buffer_ = self().next_comp_data(); + if (self().have_comp_data()) + buffer_ = self().next_comp_data(); buffer_bits_ = max_bits; buffer_mask_ = -1U; if (look_bits_ != max_bits) @@ -399,12 +400,11 @@ namespace spot } } - // 010 00 00 010 00 101:011 010 00 101:010 010 - // 010 00010000001000010010000100000 unsigned int look_n_bits(unsigned int n) { if (look_bits_ < n) refill(); + assert(n <= look_bits_); return look_ >> (look_bits_ - n); } diff --git a/src/tgbatest/intvcomp.cc b/src/tgbatest/intvcomp.cc index 2aa507c4b..99564c50e 100644 --- a/src/tgbatest/intvcomp.cc +++ b/src/tgbatest/intvcomp.cc @@ -205,5 +205,18 @@ int main() int comp9[] = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; errors += check(comp9, sizeof(comp9) / sizeof(*comp9)); + int comp10[] = { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, + 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 9 }; + errors += check(comp10, sizeof(comp10) / sizeof(*comp10)); + return errors; }