Class: Omnizip::Formats::Rar::Compression::LZ77Huffman::Decoder

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb

Overview

RAR LZ77+Huffman decoder

Orchestrates the decoding of RAR METHOD_NORMAL compressed data. Combines Huffman coding with LZ77 sliding window compression.

Responsibilities:

  • ONE responsibility: Orchestrate LZ77+Huffman decoding
  • Parse Huffman trees from bit stream
  • Decode symbols using Huffman coder
  • Process LZ77 matches via sliding window
  • Manage decoder state and output

RAR LZ77+Huffman Format:

  1. Block header with Huffman tree definitions
  2. Compressed data stream
  3. Symbols: literals (0-255), matches (length+distance), end marker

Constant Summary collapse

LITERAL_SYMBOLS =

Symbol ranges

(0..255)
END_OF_BLOCK =
256
MATCH_SYMBOLS =
(257..511)
MIN_MATCH_LENGTH =

Match parameters

3
MAX_MATCH_LENGTH =
257
DEFAULT_WINDOW_SIZE =

Window size for RAR4

64 * 1024

Instance Method Summary collapse

Constructor Details

#initialize(input, options = {}) ⇒ Decoder

Initialize LZ77+Huffman decoder

Parameters:

  • input (IO)

    Compressed input stream

  • options (Hash) (defaults to: {})

    Decoding options

Options Hash (options):

  • :window_size (Integer)

    Window size in bytes



62
63
64
65
66
67
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb', line 62

def initialize(input, options = {})
  @bit_stream = BitStream.new(input, :read)
  @window = SlidingWindow.new(options[:window_size] || DEFAULT_WINDOW_SIZE)
  @huffman = HuffmanCoder.new
  @output = String.new(encoding: Encoding::BINARY)
end

Instance Method Details

#decode(max_output = nil) ⇒ String

Decode compressed data

Main decoding loop:

  1. Parse Huffman tree (simplified for MVP)
  2. Decode symbols until end-of-block
  3. Process literals and matches

Parameters:

  • max_output (Integer, nil) (defaults to: nil)

    Maximum output bytes

Returns:

  • (String)

    Decoded data



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb', line 78

def decode(max_output = nil)
  @output.clear

  # Parse Huffman tree (simplified - real RAR has complex structure)
  parse_huffman_trees

  # Decode symbols until end-of-block or max output
  loop do
    break if max_output && @output.bytesize >= max_output

    symbol = @huffman.decode_symbol(@bit_stream)
    break if symbol.nil? || symbol == END_OF_BLOCK

    process_symbol(symbol)
  end

  @output
rescue EOFError
  @output
end

#window_sizeInteger

Get window size

Returns:

  • (Integer)

    Window size in bytes



102
103
104
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb', line 102

def window_size
  @window.size
end