Class: Origami::Filter::RunLength

Inherits:
Object
  • Object
show all
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

A85, AHx, CCF, Fl, RL

Instance Method Summary collapse

Methods included from Origami::Filter

included, #initialize

Instance Method Details

#decode(stream) ⇒ Object

Decodes data using RLE decompression method.

stream

The data to decode.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/origami/filters/runlength.rb', line 69

def decode(stream)
  result = "".b

  i = 0
  until (i >= stream.length) || (stream[i].ord == EOD)

    # 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 += 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.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/origami/filters/runlength.rb', line 38

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]

    # 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]

    end
    i += length
  end

  result << EOD.chr
end