Class: Omnizip::Formats::Rar::Compression::PPMd::Encoder

Inherits:
Algorithms::PPMd7::Encoder show all
Defined in:
lib/omnizip/formats/rar/compression/ppmd/encoder.rb

Overview

RAR PPMd variant H encoder

Implements encoding for RAR's PPMd variant H compression method. This adapts the standard PPMd7 algorithm for RAR-specific requirements:

  • Different memory model initialization
  • RAR-specific escape code handling
  • Modified context order selection
  • Different binary symbol encoding

Responsibilities:

  • ONE responsibility: Encode data using RAR PPMd variant H
  • Manage encoder state and context
  • Transform original bytes to compressed bits
  • Maintain synchronized model state (matches decoder)

Constant Summary collapse

RAR_MAX_ORDER =

RAR variant H specific constants

16
RAR_MIN_ORDER =
2
RAR_DEFAULT_ORDER =
6
RAR_MEM_MULTIPLIER =

RAR memory size multiplier (MB to bytes)

1024 * 1024

Instance Attribute Summary

Attributes inherited from Algorithms::PPMd7::Encoder

#model

Instance Method Summary collapse

Constructor Details

#initialize(output, options = {}) ⇒ Encoder

Initialize the RAR PPMd encoder

Parameters:

  • output (IO)

    Output stream for compressed data

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

    Encoding options

Options Hash (options):

  • :model_order (Integer)

    Maximum context order

  • :mem_size (Integer)

    Memory size in MB for RAR



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/omnizip/formats/rar/compression/ppmd/encoder.rb', line 64

def initialize(output, options = {})
  @output = output
  @options = options

  # RAR uses memory size in MB, convert to bytes
  mem_size_mb = options[:mem_size] || 16
  mem_size_bytes = mem_size_mb * RAR_MEM_MULTIPLIER

  # Initialize model with RAR parameters
  @model = initialize_rar_model(
    options[:model_order] || RAR_DEFAULT_ORDER,
    mem_size_bytes,
  )

  # Use range encoder for bit output
  @range_encoder = Omnizip::Algorithms::LZMA::RangeEncoder.new(output)
end

Instance Method Details

#encode_stream(input, max_bytes = nil) ⇒ Integer

Encode a stream to compressed bytes

RAR variant H encoding process:

  1. Read byte from input
  2. Find symbol in current context
  3. Encode using range coder with probabilities
  4. Update model to stay synchronized with decoder
  5. Handle RAR-specific escape codes if needed

Parameters:

  • input (IO)

    Input stream to compress

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

    Maximum bytes to encode

Returns:

  • (Integer)

    Number of bytes encoded



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/omnizip/formats/rar/compression/ppmd/encoder.rb', line 94

def encode_stream(input, max_bytes = nil)
  bytes_encoded = 0

  loop do
    break if max_bytes && bytes_encoded >= max_bytes

    byte = input.read(1)
    break unless byte

    encode_symbol(byte.ord)
    bytes_encoded += 1
  end

  # Flush encoder to ensure all data is written
  @range_encoder.flush
  bytes_encoded
end

#memory_sizeObject

Accessor for memory size (for testing)



54
55
56
# File 'lib/omnizip/formats/rar/compression/ppmd/encoder.rb', line 54

def memory_size
  @model.mem_size
end