lz77_huffman.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // #include "simple/support/debug.hpp"
  2. #include "simple/compress/lz77.hpp"
  3. #include "simple/compress/huffman.hpp"
  4. #include "simple/compress/iterator.hpp" // out_bits
  5. #include "simple/support/iterator.hpp" // offset_expander
  6. #include <cassert>
  7. #include <vector>
  8. #include <string>
  9. #include <cstdio>
  10. using namespace simple::compress;
  11. void Endecode(std::string text)
  12. {
  13. std::vector<std::byte> lzed;
  14. lzed.reserve(text.size());
  15. lz77_encode(text.begin(), text.end(), out_bits(simple::support::offset_expander(lzed)));
  16. std::vector<std::byte> huffed;
  17. huffed.reserve(lzed.size());
  18. auto code = huffman_code(lzed.begin(), lzed.end());
  19. #if defined SIMPLE_SUPPORT_DEBUG_HPP
  20. simple::support::print('\n');
  21. simple::support::println("CODE: ");
  22. 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)); });
  23. simple::support::print('\n');
  24. #endif
  25. huffman_encode(code, lzed.begin(), lzed.end(), out_bits(simple::support::offset_expander(huffed)));
  26. #if defined SIMPLE_SUPPORT_DEBUG_HPP
  27. simple::support::print('\n');
  28. simple::support::print("INPUT SIZE: ", text.size(), '\n');
  29. simple::support::print("COMPRESSED SIZE: ", huffed.size(), '\n');
  30. #endif
  31. std::vector<std::byte> unhuffed;
  32. unhuffed.resize(lzed.size());
  33. huffman_decode(code, huffed.begin(), unhuffed.begin(), unhuffed.end());
  34. std::string decoded;
  35. decoded.resize(text.size());
  36. lz77_decode(lzed.begin(), decoded.begin(), decoded.end());
  37. assert(text == decoded);
  38. }
  39. int main(int argc, char const* argv[])
  40. {
  41. std::string text = "abcd aaaa bbbb cccc aaaa abcd aaaa aaaa aaaa aaaaa aaaa aaaaaaaaaaa aaaaaaaaaaaaa aaaaaaaaaaaaaa aaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa";
  42. if(argc > 1)
  43. {
  44. auto f = std::fopen(argv[1], "rb");
  45. std::fseek(f,0,SEEK_END);
  46. text.resize(std::ftell(f));
  47. std::fseek(f,0,SEEK_SET);
  48. auto unused [[maybe_unused]] = std::fread(text.data(), text.size(), 1 ,f);
  49. #if defined SIMPLE_SUPPORT_DEBUG_HPP
  50. simple::support::print("s: ", text.size(), '\n');
  51. #endif
  52. }
  53. Endecode(std::move(text));
  54. return 0;
  55. }