Class: Origami::Filter::LZW

Inherits:
Object
  • Object
show all
Includes:
Origami::Filter, Predictor
Defined in:
lib/origami/filters/lzw.rb

Overview

Class representing a filter used to encode and decode data with LZW compression algorithm.

Constant Summary collapse

EOD =

:nodoc:

257
CLEARTABLE =

:nodoc:

256

Constants included from Predictor

Predictor::NONE, Predictor::PNG_AVERAGE, Predictor::PNG_NONE, Predictor::PNG_OPTIMUM, Predictor::PNG_PAETH, Predictor::PNG_SUB, Predictor::PNG_UP, Predictor::TIFF

Constants included from Origami::Filter

A85, AHx, CCF, Fl, RL

Instance Method Summary collapse

Methods included from Predictor

included, #initialize

Methods included from Origami::Filter

included, #initialize

Instance Method Details

#decode(string) ⇒ Object

Decodes given data using LZW compression method.

stream

The data to decode.


82
83
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/lzw.rb', line 82

def decode(string)
    result = "".b
    bstring = Utils::BitReader.new(string)
    table, codesize = reset_state
    prevbyte = nil

    until bstring.eod? do
        byte = bstring.read(codesize)
        break if byte == EOD

        if byte == CLEARTABLE
            table, codesize = reset_state
            prevbyte = nil
            redo
        end

        begin
            codesize = decode_codeword_size(table)
            result << decode_byte(table, prevbyte, byte, codesize)
        rescue InvalidLZWDataError => error
            error.message.concat " (bit pos #{bstring.pos - codesize})"
            error.input_data = string
            error.decoded_data = result
            raise(error)
        end

        prevbyte = byte
    end

    post_prediction(result)
end

#encode(string) ⇒ Object

Encodes given data using LZW compression method.

stream

The data to encode.


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
# File 'lib/origami/filters/lzw.rb', line 44

def encode(string)
    input = pre_prediction(string)

    table, codesize = reset_state
    result = Utils::BitWriter.new
    result.write(CLEARTABLE, codesize)

    s = ''
    input.each_byte do |byte|
        char = byte.chr

        if table.size == 4096
            result.write(CLEARTABLE, codesize)
            table, _ = reset_state
        end

        codesize = table.size.bit_length

        it = s + char
        if table.has_key?(it)
            s = it
        else
            result.write(table[s], codesize)
            table[it] = table.size
            s = char
        end
    end

    result.write(table[s], codesize) unless s.empty?
    result.write(EOD, codesize)

    result.final.to_s
end