Class: Origami::Filter::RunLength
- Inherits:
-
Object
- Object
- Origami::Filter::RunLength
- Includes:
- Origami::Filter
- Defined in:
- lib/origami/filters/runlength.rb
Overview
Class representing a Filter used to encode and decode data using RLE compression algorithm.
Constant Summary collapse
- EOD =
:nodoc:
128
Constants included from Origami::Filter
Instance Method Summary collapse
-
#decode(stream) ⇒ Object
Decodes data using RLE decompression method.
-
#encode(stream) ⇒ Object
Encodes data using RLE compression method.
Methods included from Origami::Filter
Instance Method Details
#decode(stream) ⇒ Object
Decodes data using RLE decompression method.
- stream
-
The data to decode.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/origami/filters/runlength.rb', line 84 def decode(stream) result = "".b return result if stream.empty? i = 0 until i >= stream.length or stream[i].ord == EOD do # At least two bytes are required. if i > stream.length - 2 raise InvalidRunLengthDataError.new("Truncated run-length data", input_data: stream, decoded_data: result) end length = stream[i].ord if length < EOD result << stream[i + 1, length + 1] i = i + length + 2 else result << stream[i + 1] * (257 - length) i = i + 2 end end # Check if offset is beyond the end of data. if i >= stream.length raise InvalidRunLengthDataError.new("Truncated run-length data", input_data: stream, decoded_data: result) end result end |
#encode(stream) ⇒ Object
Encodes data using RLE compression method.
- stream
-
The data to encode.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/origami/filters/runlength.rb', line 40 def encode(stream) result = "".b i = 0 while i < stream.size # # How many identical bytes coming? # length = 1 while i+1 < stream.size and length < EOD and stream[i] == stream[i+1] length = length + 1 i = i + 1 end # # If more than 1, then compress them. # if length > 1 result << (257 - length).chr << stream[i] # # Otherwise how many different bytes to copy? # else j = i while j+1 < stream.size and (j - i + 1) < EOD and stream[j] != stream[j+1] j = j + 1 end length = j - i result << length.chr << stream[i, length+1] i = j end i = i + 1 end result << EOD.chr end |