Class: Origami::Filter::LZW
- Inherits:
-
Object
- Object
- Origami::Filter::LZW
- Includes:
- Origami::Filter
- Defined in:
- lib/origami/filters/lzw.rb
Overview
Class representing a filter used to encode and decode data with LZW compression algorithm.
Defined Under Namespace
Classes: DecodeParms
Constant Summary collapse
- EOD =
:nodoc:
257
- CLEARTABLE =
:nodoc:
256
Constants included from Origami::Filter
Instance Method Summary collapse
-
#decode(string) ⇒ Object
Decodes given data using LZW compression method.
-
#encode(string) ⇒ Object
Encodes given data using LZW compression method.
-
#initialize(parameters = {}) ⇒ LZW
constructor
Creates a new LZW Filter.
Methods included from Origami::Filter
Constructor Details
#initialize(parameters = {}) ⇒ LZW
Creates a new LZW Filter.
- parameters
-
A hash of filter options (ignored).
59 60 61 |
# File 'lib/origami/filters/lzw.rb', line 59 def initialize(parameters = {}) super(DecodeParms.new(parameters)) end |
Instance Method Details
#decode(string) ⇒ Object
Decodes given data using LZW compression method.
- stream
-
The data to decode.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/origami/filters/lzw.rb', line 116 def decode(string) result = "" bstring = Utils::BitReader.new(string) codesize = 9 table = clear(Hash.new) prevbyte = nil until bstring.eod? do byte = bstring.read(codesize) case table.size when 510 then codesize = 10 when 1022 then codesize = 11 when 2046 then codesize = 12 when 4095 if byte != CLEARTABLE then raise InvalidLZWDataError.new( "LZW table is full and no clear flag was set (codeword #{byte.to_s(2).rjust(codesize,'0')} at bit #{bstring.pos - codesize}/#{bstring.size})", result ) end end if byte == CLEARTABLE codesize = 9 code = EOD clear table prevbyte = nil redo elsif byte == EOD break else if prevbyte.nil? prevbyte = byte result << table.key(byte) redo else raise InvalidLZWDataError.new( "No entry for codeword #{prevbyte.to_s(2).rjust(codesize,'0')}.", result ) unless table.key(prevbyte) if table.has_value?(byte) entry = table.key(byte) else entry = table.key(prevbyte) entry += entry[0,1] end result << entry table[table.key(prevbyte) + entry[0,1]] = table.size prevbyte = byte end end end if @params.Predictor.is_a?(Integer) colors = @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1 bpc = @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8 columns = @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1 result = Predictor.do_post_prediction(result, @params.Predictor.to_i, colors, bpc, columns) end result end |
#encode(string) ⇒ Object
Encodes given data using LZW compression method.
- stream
-
The data to encode.
67 68 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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/origami/filters/lzw.rb', line 67 def encode(string) if @params.Predictor.is_a?(Integer) colors = @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1 bpc = @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8 columns = @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1 string = Predictor.do_pre_prediction(string, @params.Predictor.to_i, colors, bpc, columns) end codesize = 9 result = Utils::BitWriter.new result.write(CLEARTABLE, codesize) table = clear({}) s = '' string.each_byte do |byte| char = byte.chr case table.size when 512 then codesize = 10 when 1024 then codesize = 11 when 2048 then codesize = 12 when 4096 result.write(CLEARTABLE, codesize) codesize = 9 clear table redo end 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) result.write(EOD, codesize) result.final.to_s end |