summaryrefslogtreecommitdiff
path: root/rld-compression.cpp
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2012-11-29 19:04:12 +1100
committerChris Johns <chrisj@rtems.org>2012-11-29 19:04:12 +1100
commit5c716ef1d1ed1962ffe2470a6d702759718f9875 (patch)
tree0c711871a387fa1047bb1570edd5fcd742525dc5 /rld-compression.cpp
parent51be43d7946da7a545fb7ee91fb94a79bb1b186a (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.cpp101
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;
+ }
+ }
+
}
}