class Origami::Filter::CCF
Class representing a Filter
used to encode and decode data with CCITT-facsimile compression algorithm.
Constants
- BLACK_CONFIGURATION_DECODE_TABLE
- BLACK_CONFIGURATION_ENCODE_TABLE
- BLACK_TERMINAL_DECODE_TABLE
- BLACK_TERMINAL_ENCODE_TABLE
- EOL
- RTC
- WHITE_CONFIGURATION_DECODE_TABLE
- WHITE_CONFIGURATION_ENCODE_TABLE
- WHITE_TERMINAL_DECODE_TABLE
- WHITE_TERMINAL_ENCODE_TABLE
Public Class Methods
new(parameters = {})
click to toggle source
Creates a new CCITT Fax Filter
.
Calls superclass method
Origami::Filter::new
# File lib/origami/filters/ccitt.rb, line 58 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 117 def decode(stream) mode = @params.key?(:K) ? @params.K.value : 0 unless mode.is_a?(::Integer) and mode <= 0 raise NotImplementedError.new("CCITT encoding scheme not supported", input_data: stream) end columns = @params.has_key?(:Columns) ? @params.Columns.value : 1728 unless columns.is_a?(::Integer) and columns >= 0 raise CCITTFaxFilterError.new("Invalid value for parameter `Columns'", input_data: stream) 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?] rows = @params.key?(:Rows) ? @params.Rows.value : 0 unless rows.is_a?(::Integer) and rows >= 0 raise CCITTFaxFilterError.new("Invalid value for parameter `Rows'", input_data: stream) end end bitr = Utils::BitReader.new(stream) bitw = Utils::BitWriter.new # Group 4 requires an imaginary white line if columns > 0 and 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 break if columns == 0 # 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}})", input_data: stream, decoded_data: bitw.final.to_s ) if params[:has_eol?] else bitr.pos += EOL[1] end begin 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 rescue DecodeError => error error.input_data = stream error.decoded_data = bitw.final.to_s raise error 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 65 def encode(stream) mode = @params.key?(:K) ? @params.K.value : 0 colors = (@params.BlackIs1 == true) ? [0,1] : [1,0] use_eob = (@params.EndOfBlock.nil? or @params.EndOfBlock == true) use_eol = (@params.EndOfLine == true) white, _black = colors bitr = Utils::BitReader.new(stream) bitw = Utils::BitWriter.new unless mode.is_a?(::Integer) and mode <= 0 raise NotImplementedError.new("CCITT encoding scheme not supported", input_data: stream) end # Use a single row if no width has been set. @params[:Columns] ||= stream.size * 8 columns = @params.Columns.value unless columns.is_a?(::Integer) and columns >= 0 raise CCITTFaxFilterError.new("Invalid value for parameter `Columns'", input_data: stream) end if columns > 0 # 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? # Emit line synchronization code. bitw.write(*EOL) if use_eol 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 end # Emit return-to-control code. bitw.write(*RTC) if use_eob bitw.final.to_s end
Private Instance Methods
lookup_bits(table, codeword, length)
click to toggle source
# File lib/origami/filters/ccitt.rb, line 311 def lookup_bits(table, codeword, length) table.rassoc [codeword, length] end