Parent

Included Modules

Class/Module Index [+]

Quicksearch

Origami::Filter::CCITTFax

Class representing a Filter used to encode and decode data with CCITT-facsimile compression algorithm.

Public Class Methods

new(parameters = {}) click to toggle source

Creates a new CCITT Fax Filter.

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

Public Instance Methods

decode(stream) click to toggle source

Decodes data using CCITT-facsimile compression method.

# File lib/origami/filters/ccitt.rb, line 348
def decode(stream)
  mode = @params.has_key?(:K) ? @params.K.value : 0 

  unless mode.is_a?(::Integer) and mode <= 0
    raise NotImplementedError, "CCITT encoding scheme not supported"
  end

  columns = @params.has_key?(:Columns) ? @params.Columns.value : 1728
  unless columns.is_a?(::Integer) and columns > 0 #and columns % 8 == 0
    raise CCITTFaxFilterError, "Invalid value for parameter `Columns'"
  end

  colors = (@params.BlackIs1 == true) ? [0,1] : [1,0]
  white, _black = colors
  params = 
  {
    :is_aligned? => (@params.EncodedByteAlign == true),
    :has_eob? => (@params.EndOfBlock.nil? or @params.EndOfBlock == true),
    :has_eol? => (@params.EndOfLine == true)
  }

  unless params[:has_eob?]
    unless @params.has_key?(:Rows) and @params.Rows.is_a?(::Integer) and @params.Rows.value > 0
      raise CCITTFaxFilterError, "Invalid value for parameter `Rows'"
    end

    rows = @params.Rows.to_i
  end

  bitr = Utils::BitReader.new(stream)
  bitw = Utils::BitWriter.new

  # Group 4 requires an imaginary white line
  if mode < 0
    prev_line = Utils::BitWriter.new
    write_bit_range(prev_line, white, columns)
    prev_line = Utils::BitReader.new(prev_line.final.to_s)
  end

  until bitr.eod? or rows == 0
    # realign the read line on a 8-bit boundary if required
    if params[:is_aligned?] and bitr.pos % 8 != 0
      bitr.pos += 8 - (bitr.pos % 8)          
    end

    # received return-to-control code 
    if params[:has_eob?] and bitr.peek(RTC[1]) == RTC[0]
      bitr.pos += RTC[1]
      break
    end

    # checking for the presence of EOL
    if bitr.peek(EOL[1]) != EOL[0]
      raise InvalidCCITTFaxDataError.new(
        "No end-of-line pattern found (at bit pos #{bitr.pos}/#{bitr.size}})",
        bitw.final.to_s
      ) if params[:has_eol?]
    else
      bitr.pos += EOL[1]
    end

    case
      when mode == 0
        decode_one_dimensional_line(bitr, bitw, columns, colors)
      when mode < 0
        decode_two_dimensional_line(bitr, bitw, columns, colors, prev_line)
    end 


    rows -= 1 unless params[:has_eob?]
  end

  bitw.final.to_s
end
encode(stream) click to toggle source

Encodes data using CCITT-facsimile compression method.

# File lib/origami/filters/ccitt.rb, line 302
def encode(stream)
  mode = @params.has_key?(:K) ? @params.K.value : 0 

  unless mode.is_a?(::Integer) and mode <= 0
    raise NotImplementedError, "CCITT encoding scheme not supported"
  end

  columns = @params.has_key?(:Columns) ? @params.Columns.value : (stream.size << 3)
  unless columns.is_a?(::Integer) and columns > 0 #and columns % 8 == 0
    raise CCITTFaxFilterError, "Invalid value for parameter `Columns'"
  end

  if stream.size % (columns >> 3) != 0
    raise CCITTFaxFilterError, "Data size is not a multiple of image width"
  end

  colors = (@params.BlackIs1 == true) ? [0,1] : [1,0]
  white, _black = colors
  bitr = Utils::BitReader.new(stream)
  bitw = Utils::BitWriter.new

  # Group 4 requires an imaginary white line
  if mode < 0
    prev_line = Utils::BitWriter.new
    write_bit_range(prev_line, white, columns)
    prev_line = Utils::BitReader.new(prev_line.final.to_s)
  end

  until bitr.eod?
    case
      when mode == 0
        encode_one_dimensional_line(bitr, bitw, columns, colors)  
      when mode < 0
        encode_two_dimensional_line(bitr, bitw, columns, colors, prev_line)
    end
  end

  # Emit return-to-control code
  bitw.write(*RTC)

  bitw.final.to_s
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.