|
@@ -0,0 +1,70 @@
|
|
|
+// #include "simple/support/debug.hpp"
|
|
|
+
|
|
|
+#include "simple/compress/lz77.hpp"
|
|
|
+#include "simple/compress/huffman.hpp"
|
|
|
+#include "simple/compress/iterator.hpp" // out_bits
|
|
|
+#include "simple/support/iterator.hpp" // offset_expander
|
|
|
+
|
|
|
+#include <cassert>
|
|
|
+#include <vector>
|
|
|
+#include <string>
|
|
|
+#include <cstdio>
|
|
|
+
|
|
|
+using namespace simple::compress;
|
|
|
+
|
|
|
+void Endecode(std::string text)
|
|
|
+{
|
|
|
+ std::vector<std::byte> lzed;
|
|
|
+ lzed.reserve(text.size());
|
|
|
+
|
|
|
+ lz77_encode(text.begin(), text.end(), out_bits(simple::support::offset_expander(lzed)));
|
|
|
+
|
|
|
+ std::vector<std::byte> huffed;
|
|
|
+ huffed.reserve(lzed.size());
|
|
|
+
|
|
|
+ auto code = huffman_code(lzed.begin(), lzed.end());
|
|
|
+
|
|
|
+#if defined SIMPLE_SUPPORT_DEBUG_HPP
|
|
|
+ simple::support::print('\n');
|
|
|
+ simple::support::println("CODE: ");
|
|
|
+ code.for_each([](auto && kv) { using std::to_string; if(bit_count(kv.second) != 0) simple::support::println(to_string((int)kv.first) + " - " + to_string(kv.second)); });
|
|
|
+ simple::support::print('\n');
|
|
|
+#endif
|
|
|
+
|
|
|
+ huffman_encode(code, lzed.begin(), lzed.end(), out_bits(simple::support::offset_expander(huffed)));
|
|
|
+
|
|
|
+#if defined SIMPLE_SUPPORT_DEBUG_HPP
|
|
|
+ simple::support::print('\n');
|
|
|
+
|
|
|
+ simple::support::print("INPUT SIZE: ", text.size(), '\n');
|
|
|
+ simple::support::print("COMPRESSED SIZE: ", huffed.size(), '\n');
|
|
|
+#endif
|
|
|
+
|
|
|
+ std::vector<std::byte> unhuffed;
|
|
|
+ unhuffed.resize(lzed.size());
|
|
|
+ huffman_decode(code, huffed.begin(), unhuffed.begin(), unhuffed.end());
|
|
|
+
|
|
|
+ std::string decoded;
|
|
|
+ decoded.resize(text.size());
|
|
|
+ lz77_decode(lzed.begin(), decoded.begin(), decoded.end());
|
|
|
+
|
|
|
+ assert(text == decoded);
|
|
|
+}
|
|
|
+
|
|
|
+int main(int argc, char const* argv[])
|
|
|
+{
|
|
|
+ std::string text = "abcd aaaa bbbb cccc aaaa abcd aaaa aaaa aaaa aaaaa aaaa aaaaaaaaaaa aaaaaaaaaaaaa aaaaaaaaaaaaaa aaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
|
+ if(argc > 1)
|
|
|
+ {
|
|
|
+ auto f = std::fopen(argv[1], "rb");
|
|
|
+ std::fseek(f,0,SEEK_END);
|
|
|
+ text.resize(std::ftell(f));
|
|
|
+ std::fseek(f,0,SEEK_SET);
|
|
|
+ auto unused [[maybe_unused]] = std::fread(text.data(), text.size(), 1 ,f);
|
|
|
+#if defined SIMPLE_SUPPORT_DEBUG_HPP
|
|
|
+ simple::support::print("s: ", text.size(), '\n');
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ Endecode(std::move(text));
|
|
|
+ return 0;
|
|
|
+}
|