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

Instance Method Summary collapse

Instance Method Details

#decode(stream) ⇒ Object

Decodes data using RLE decompression method.

stream

The data to decode.



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 93

def decode(stream)
  raise InvalidRunLengthDataError, "No end marker" unless stream.include?(EOD.chr)
  
  i = 0
  result = ""
  until stream[i].ord == EOD do
  
    length = stream[i].ord
    if length < EOD
      result << stream[i + 1, length + 1]
      i = i + length + 2
    else
      result << stream[i + 1,1] * (257 - length)
      i = i + 2
    end
    
  end
  
  result
end

#encode(stream) ⇒ Object

Encodes data using RLE compression method.

stream

The data to encode.



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
79
80
81
82
83
84
85
86
# File 'lib/origami/filters/runlength.rb', line 45

def encode(stream)

  result = ""
  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,1]

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