diff options
author | Chris Johns <chrisj@rtems.org> | 2012-11-29 19:04:12 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-11-29 19:04:12 +1100 |
commit | 5c716ef1d1ed1962ffe2470a6d702759718f9875 (patch) | |
tree | 0c711871a387fa1047bb1570edd5fcd742525dc5 /rld-compression.cpp | |
parent | 51be43d7946da7a545fb7ee91fb94a79bb1b186a (diff) |
Compress as blocks.
The LZ77 compressor works with blocks. Each block is prefixed with
a header that defines the output size of the block being compressed.
Diffstat (limited to 'rld-compression.cpp')
-rw-r--r-- | rld-compression.cpp | 101 |
1 files changed, 44 insertions, 57 deletions
diff --git a/rld-compression.cpp b/rld-compression.cpp index 42c11fe..55e7a6c 100644 --- a/rld-compression.cpp +++ b/rld-compression.cpp @@ -53,6 +53,9 @@ namespace rld total (0), total_compressed (0) { + if (size > 0xffff) + throw rld::error ("Size too big, 16 bits only", "compression"); + buffer = new uint8_t[size]; io = new uint8_t[size + (size / 10)]; } @@ -69,39 +72,21 @@ namespace rld { const uint8_t* data = static_cast <const uint8_t*> (data_); - if (compress) + while (length) { - while (length) - { - size_t appending; - - if (length > (size - level)) - appending = size - level; - else - appending = length; - - ::memcpy ((void*) (buffer + level), data, appending); + size_t appending; - level += appending; - length -= appending; - total += appending; + if (length > (size - level)) + appending = size - level; + else + appending = length; - if (level >= size) - { - int writing = - ::fastlz_compress (buffer, level, io); + ::memcpy ((void*) (buffer + level), data, appending); - image.write (io, writing); + level += appending; + length -= appending; - total_compressed += writing; - level = 0; - } - } - } - else - { - image.write (data, length); - total += length; + output (); } } @@ -123,42 +108,15 @@ namespace rld level += appending; length -= appending; - total += appending; - - if (level >= size) - { - if (compress) - { - int writing = - ::fastlz_compress (buffer, level, io); - - image.write (io, writing); - - total_compressed += writing; - } - else - { - image.write (buffer, length); - } - level = 0; - } + output (); } } void compressor::flush () { - if (level) - { - int writing = - ::fastlz_compress (buffer, level, io); - - image.write (io, writing); - - total_compressed += writing; - level = 0; - } + output (true); } size_t @@ -173,5 +131,34 @@ namespace rld return total_compressed; } + void + compressor::output (bool forced) + { + if ((forced && level) || (level >= size)) + { + total += level; + + if (compress) + { + int writing = ::fastlz_compress (buffer, level, io); + uint8_t header[2]; + + header[0] = writing >> 8; + header[1] = writing; + + image.write (header, 2); + image.write (io, writing); + + total_compressed += 2 + writing; + } + else + { + image.write (buffer, level); + } + + level = 0; + } + } + } } |