lz77_bwt_obh_string.pl 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #!/usr/bin/perl
  2. # LZ77 + BWT + OBH compressor/decompressor, for compressing a given string.
  3. use 5.036;
  4. use lib qw(../lib);
  5. use Compression::Util qw(:all);
  6. local $Compression::Util::VERBOSE = 0;
  7. local $Compression::Util::LZ_MIN_LEN = 7;
  8. local $Compression::Util::LZ_MAX_LEN = ~0;
  9. foreach my $file (__FILE__, $^X) {
  10. say "Compressing: $file";
  11. my $str = do {
  12. local $/;
  13. open my $fh, '<:raw', $file;
  14. <$fh>;
  15. };
  16. # Compression
  17. my $enc = do {
  18. my ($uncompressed, $distances, $lengths, $matches) = lz77_encode($str);
  19. bwt_compress(symbols2string($uncompressed))
  20. . fibonacci_encode($lengths)
  21. . create_huffman_entry($matches)
  22. . obh_encode($distances, \&mrl_compress_symbolic);
  23. };
  24. # Decompression
  25. my $dec = do {
  26. open my $fh, '<:raw', \$enc;
  27. my $uncompressed = string2symbols(bwt_decompress($fh));
  28. my $lengths = fibonacci_decode($fh);
  29. my $matches = decode_huffman_entry($fh);
  30. my $distances = obh_decode($fh, \&mrl_decompress_symbolic);
  31. lz77_decode($uncompressed, $distances, $lengths, $matches);
  32. };
  33. say "Original size : ", length($str);
  34. say "Compressed size: ", length($enc);
  35. if ($str ne $dec) {
  36. die "Decompression error";
  37. }
  38. say '';
  39. }