class Origami::Filter::RL
Class representing a Filter
used to encode and decode data using RLE compression algorithm.
Public Instance Methods
decode(stream)
click to toggle source
Decodes data using RLE decompression method.
- stream
-
The data to decode.
# File lib/origami/filters/runlength.rb, line 72 def decode(stream) result = "".b 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)
click to toggle source
Encodes data using RLE compression method.
- stream
-
The data to encode.
# 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 = compute_run_length(stream, i) # If more than 1, then compress them. if length > 1 result << (257 - length).chr << stream[i] i += length # Otherwise how many different bytes to copy? else next_pos = find_next_run(stream, i) length = next_pos - i result << (length - 1).chr << stream[i, length] i += length end end result << EOD.chr end
Private Instance Methods
compute_run_length(input, pos)
click to toggle source
Computes the length of the run at the given position.
# File lib/origami/filters/runlength.rb, line 116 def compute_run_length(input, pos) run_length = 1 while pos + 1 < input.size and run_length < EOD and input[pos] == input[pos + 1] run_length += 1 pos += 1 end run_length end
find_next_run(input, pos)
click to toggle source
Find the position of the next byte at which a new run starts.
# File lib/origami/filters/runlength.rb, line 106 def find_next_run(input, pos) start = pos pos += 1 while pos + 1 < input.size and (pos - start + 1) < EOD and input[pos] != input[pos + 1] pos + 1 end