From c1c7cd34275573dec244f125a037784b4f50b46c Mon Sep 17 00:00:00 2001 From: eleksir Date: Sun, 23 Sep 2018 14:39:28 +0300 Subject: [PATCH] Initial commit --- LICENSE | 22 ++++++++++++++ README.md | 8 ++++++ rle.pl | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ unrle.pl | 69 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 rle.pl create mode 100644 unrle.pl diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..21423b1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright 2010 Sergei Fedosov + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..25d88b4 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +## RLE + +Another simplified implementation of the ideas of Run Length Encoding +algorhythm. Instead of bit manipulation, it manipulates bytes. Output +data stream have no header or tail where metadata can be stored, so +no integrity checks are implemented. + +This code licensed under BSD 2 clause license. \ No newline at end of file diff --git a/rle.pl b/rle.pl new file mode 100644 index 0000000..02a6770 --- /dev/null +++ b/rle.pl @@ -0,0 +1,86 @@ +#!/usr/bin/perl + +use strict; +use warnings "all"; +use Fcntl; + +my $fname = undef; + +if(defined($ARGV[0])){ + if($ARGV[0] eq "--help"){ + syswrite STDOUT, "Usage: $0 \n"; + syswrite STDOUT, "or pipe data thrugh $0's STDIN to $0 STDOUT\n"; + exit 0; + } + $fname = $ARGV[0]; +} + +my $byte; +my $counter = 1; +my $block_size = 65536; +my $first_remembered_byte = undef; +my $second_remembered_byte = undef; + +if (defined($fname)){ + sysopen(STDIN, $fname, O_RDONLY) or die "Can not open file $fname!\n"; + sysopen(STDOUT, "$fname.rle", O_WRONLY|O_TRUNC|O_CREAT) or die "Can not open file $fname.rle!\n"; +} +binmode(STDIN); +binmode(STDOUT); + +exit 0 if ((sysread(STDIN, $byte, 1)) == 0); + +$first_remembered_byte = $byte; +my $output_buf_byte_counter = 0; +my $output_buf = ''; +my $input_buf = ''; + +while ( 1 ) { + my $read_bytes = sysread(STDIN, $input_buf, $block_size); + last if($read_bytes == 0); + my $i = 0; + for ( $i = 0; $i < $read_bytes; $i++ ) { + $byte = substr( $input_buf, $i, 1); + last unless(defined($byte)); + $second_remembered_byte = $first_remembered_byte; + $first_remembered_byte = $byte; + + if(($first_remembered_byte eq $second_remembered_byte) and ($counter <= 254)){ + $counter++; + next; + } + + if ($output_buf_byte_counter == $block_size){ + syswrite STDOUT, $output_buf || die "Cannot write output stream!\n"; + $output_buf = ''; + $output_buf_byte_counter = 0; + }else{ + $output_buf_byte_counter++; + } + + $output_buf .= chr($counter) . $second_remembered_byte; + $second_remembered_byte = $first_remembered_byte; + $counter = 1; + } + undef $i; + undef $read_bytes; +} +close(STDIN); +# 0-byte string +exit 0 unless (defined($first_remembered_byte)); +# 1-byte string +unless(defined($second_remembered_byte)){ + $output_buf = chr($counter) . $first_remembered_byte; +}else{ +# 2+ bytes string + $output_buf .= chr($counter) . $second_remembered_byte; +} +syswrite STDOUT, $output_buf || die "Cannot write output stream!\n"; +close(STDOUT); +undef $fname; +undef $counter; +undef $first_remembered_byte; +undef $second_remembered_byte; +undef $byte; +undef $input_buf; +undef $output_buf; diff --git a/unrle.pl b/unrle.pl new file mode 100644 index 0000000..cbe7d1f --- /dev/null +++ b/unrle.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl + +use strict; +use warnings "all"; +use Fcntl; + +my $fname = undef; +if(defined($ARGV[0])){ + if($ARGV[0] eq "--help"){ + syswrite STDOUT, "Usage: $0 \n"; + syswrite STDOUT, "or pipe data thrugh $0's STDIN to $0 STDOUT\n"; + exit 0; + } + exit unless ($ARGV[0] =~ /\.rle$/); + $fname = $ARGV[0]; + $fname = substr($fname, 0, -4); +} + +my $byte = ''; +my $dbyte = ''; +my $block_size = 65536; + +if (defined($fname)){ + sysopen(STDIN, "$fname.rle", O_RDONLY) or die "Can not open file $fname!\n"; + sysopen(STDOUT, $fname, O_WRONLY|O_TRUNC|O_CREAT) or die "Can not open file $fname.rle!\n"; +} +binmode(STDIN); +binmode(STDOUT); + +my $output_buf_byte_counter = 0; +my $output_buf = ''; +my $input_buf =''; + +while ( 1 ) { + my $read_bytes = sysread(STDIN, $input_buf, $block_size); + last unless(defined($read_bytes)); + last if($read_bytes == 0); + my $i = 0; + for ( $i = 0; $i < $read_bytes; $i++ ) { + $dbyte = substr( $input_buf, $i, 1); + last unless(defined($dbyte)); + $i++; + $byte = substr( $input_buf, $i, 1); + last unless(defined($byte)); + + for(my $i = 0; $i < ord($dbyte); $i++){ + if ($output_buf_byte_counter == $block_size){ + syswrite STDOUT, $output_buf || die "Cannot write output stream!\n"; + $output_buf = ''; + $output_buf_byte_counter = 0; + }else{ + $output_buf_byte_counter++; + } + $output_buf .= $byte; + } + } + undef $i; + undef $read_bytes; +} +close(STDIN); +syswrite STDOUT, $output_buf || die "Cannot write output stream!\n"; +close(STDOUT); +undef $fname; +undef $byte; +undef $dbyte; +undef $block_size; +undef $output_buf_byte_counter; +undef $output_buf; +undef $input_buf;