Parent

Included Modules

Class/Module Index [+]

Quicksearch

Origami::Filter::LZW

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

Public Class Methods

new(parameters = {}) click to toggle source

Creates a new LZW Filter.

parameters

A hash of filter options (ignored).

# File lib/origami/filters/lzw.rb, line 59
def initialize(parameters = {})
  super(DecodeParms.new(parameters))
end

Public Instance Methods

decode(string) click to toggle source

Decodes given data using LZW compression method.

stream

The data to decode.

# 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) click to toggle source

Encodes given data using LZW compression method.

stream

The data to encode.

# 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.