bwt_vertical_transform.pl 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 05 April 2024
  4. # https://github.com/trizen
  5. # Apply the Burrows-Wheeler transform on each column of an image.
  6. use 5.036;
  7. use GD;
  8. use Getopt::Std qw(getopts);
  9. use Compression::Util qw(bwt_encode_symbolic bwt_decode_symbolic);
  10. GD::Image->trueColor(1);
  11. sub apply_bwt ($file) {
  12. my $image = GD::Image->new($file) || die "Can't open file <<$file>>: $!";
  13. my ($width, $height) = $image->getBounds();
  14. my $new_image = GD::Image->new($width, $height + 1);
  15. foreach my $x (0 .. $width - 1) {
  16. my @row;
  17. foreach my $y (0 .. $height - 1) {
  18. push @row, scalar $new_image->colorAllocate($image->rgb($image->getPixel($x, $y)));
  19. }
  20. my ($encoded, $idx) = bwt_encode_symbolic(\@row);
  21. $new_image->setPixel($x, 0, $idx);
  22. foreach my $y (1 .. $height) {
  23. $new_image->setPixel($x, $y, $encoded->[$y - 1]);
  24. }
  25. }
  26. return $new_image;
  27. }
  28. sub undo_bwt ($file) {
  29. my $image = GD::Image->new($file) || die "Can't open file <<$file>>: $!";
  30. my ($width, $height) = $image->getBounds();
  31. my $new_image = GD::Image->new($width, $height - 1);
  32. foreach my $x (0 .. $width - 1) {
  33. my @row;
  34. my $idx = $image->getPixel($x, 0);
  35. foreach my $y (1 .. $height - 1) {
  36. push @row, $image->getPixel($x, $y);
  37. }
  38. my $decoded = bwt_decode_symbolic(\@row, $idx);
  39. foreach my $y (0 .. $height - 2) {
  40. $new_image->setPixel($x, $y, $decoded->[$y]);
  41. }
  42. }
  43. return $new_image;
  44. }
  45. sub usage ($exit_code = 0) {
  46. print <<"EOT";
  47. usage: $0 [options] [input.png] [output.png]
  48. options:
  49. -d : decode the image
  50. -h : print this message and exit
  51. EOT
  52. exit($exit_code);
  53. }
  54. getopts('dh', \my %opts);
  55. my $input_file = $ARGV[0] // usage(2);
  56. my $output_file = $ARGV[1] // "output.png";
  57. if (not -f $input_file) {
  58. die "Input file <<$input_file>> does not exist!\n";
  59. }
  60. my $img = $opts{d} ? undo_bwt($input_file) : apply_bwt($input_file);
  61. open(my $out_fh, '>:raw', $output_file) or die "can't create output file <<$output_file>>: $!";
  62. print $out_fh $img->png(9);
  63. close $out_fh;