Class: Omnizip::Implementations::SevenZip::LZMA2::Encoder

Inherits:
Base::LZMA2EncoderBase show all
Includes:
Algorithms::LZMA2Const
Defined in:
lib/omnizip/implementations/seven_zip/lzma2/encoder.rb

Overview

7-Zip SDK LZMA2 encoder implementation.

This encoder produces LZMA2 compressed data compatible with 7-Zip format. It uses the same LZMA encoding logic as XZ Utils, but with 7-Zip format requirements (no EOS marker, no padding).

Key differences from XZ Utils implementation:

  • No EOS marker (raw LZMA2 data ends with 0x00 control byte)
  • No chunk padding (XZ pads to 4-byte boundary)
  • No LZMA2 property byte in data stream (method ID only in container)

Based on LZMA SDK by Igor Pavlov Reference: https://www.7-zip.org/sdk.html

LZMA2 format (as used by 7-Zip):

  • Control byte specifies chunk type and dictionary reset
  • Dictionary size follows in some chunk types
  • Uncompressed size follows in some chunk types
  • Compressed data follows

Defined Under Namespace

Modules: StringCompat

Constant Summary collapse

MAX_UNCOMPRESSED_CHUNK =

Maximum chunk sizes (from LZMA2 specification)

2 * 1024 * 1024
MAX_COMPRESSED_CHUNK =

2MB

64 * 1024
UINT32_MAX =

Encoding constants

0xFFFFFFFF
REPS =
4
MATCH_LEN_MIN =
2

Constants included from Algorithms::LZMA2Const

Algorithms::LZMA2Const::CHUNK_MAX, Algorithms::LZMA2Const::CONTROL_END, Algorithms::LZMA2Const::CONTROL_LZMA_MIN, Algorithms::LZMA2Const::CONTROL_UNCOMPRESSED, Algorithms::LZMA2Const::CONTROL_UNCOMPRESSED_RESET, Algorithms::LZMA2Const::DICT_SIZE_MAX, Algorithms::LZMA2Const::DICT_SIZE_MIN, Algorithms::LZMA2Const::FLAG_RESET_DICT, Algorithms::LZMA2Const::FLAG_RESET_PROPERTIES, Algorithms::LZMA2Const::FLAG_RESET_STATE, Algorithms::LZMA2Const::FLAG_UNCOMPRESSED_SIZE, Algorithms::LZMA2Const::HEADER_MAX, Algorithms::LZMA2Const::HEADER_UNCOMPRESSED, Algorithms::LZMA2Const::UNCOMPRESSED_MAX

Constants inherited from Base::LZMA2EncoderBase

Base::LZMA2EncoderBase::COMPRESSED_MAX, Base::LZMA2EncoderBase::UNCOMPRESSED_MAX

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base::LZMA2EncoderBase

#standalone?

Constructor Details

#initialize(dict_size:, lc: 3, lp: 0, pb: 2, standalone: false) ⇒ Encoder

Initialize 7-Zip SDK LZMA2 encoder

Parameters:

  • dict_size (Integer)

    Dictionary size (must be power of 2)

  • lc (Integer) (defaults to: 3)

    Literal context bits (0-8)

  • lp (Integer) (defaults to: 0)

    Literal position bits (0-4)

  • pb (Integer) (defaults to: 2)

    Position bits (0-4)

  • standalone (Boolean) (defaults to: false)

    Include property byte (false for 7-Zip)



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 69

def initialize(dict_size:, lc: 3, lp: 0, pb: 2, standalone: false)
  super

  # Initialize shared state across all chunks
  # Using XZ Utils components (tested and working)

  @dictionary = Omnizip::Algorithms::LZMA::Dictionary.new(dict_size)
  @state = Omnizip::Algorithms::LZMA::LZMAState.new(0)
  @models = Omnizip::Algorithms::LZMA::XzProbabilityModels.new(lc,
                                                               lp, pb)
  @match_finder = Omnizip::Algorithms::LZMA::MatchFinder.new(@dictionary)
  @optimal = Omnizip::Algorithms::LZMA::OptimalEncoder.new(mode: :fast)

  # Track previous byte for literal context
  @prev_byte = 0

  # First chunk always resets dictionary (7-Zip compatibility)
  @need_dictionary_reset = true
  @need_state_reset = false
  @need_properties = true
end

Instance Attribute Details

#dict_sizeObject (readonly)

Returns the value of attribute dict_size.



60
61
62
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 60

def dict_size
  @dict_size
end

#lcObject (readonly)

Returns the value of attribute lc.



60
61
62
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 60

def lc
  @lc
end

#lpObject (readonly)

Returns the value of attribute lp.



60
61
62
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 60

def lp
  @lp
end

#pbObject (readonly)

Returns the value of attribute pb.



60
61
62
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 60

def pb
  @pb
end

#standaloneObject (readonly)

Returns the value of attribute standalone.



60
61
62
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 60

def standalone
  @standalone
end

Instance Method Details

#encode(data) ⇒ String

Encode data with LZMA2 compression

Parameters:

  • data (String)

    Input data to compress

Returns:

  • (String)

    LZMA2 compressed data (7-Zip format)



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 95

def encode(data)
  return "" if data.empty?

  output = StringIO.new
  output.set_encoding(Encoding::BINARY)

  # Write property byte if standalone mode
  if @standalone
    prop_byte = encode_dict_size(@dict_size)
    output.putc(prop_byte)
  end

  # Reset match finder state for each encoding session
  @match_finder.reset

  # Process in chunks
  input = StringIO.new(data)
  input.set_encoding(Encoding::BINARY)

  while !input.eof?
    chunk_data = input.read(MAX_UNCOMPRESSED_CHUNK)
    break if chunk_data.nil? || chunk_data.empty?

    chunk = encode_chunk(chunk_data)
    output.write(chunk)

    # Update reset flags for next chunk
    @need_dictionary_reset = false
    @need_state_reset = false
    @need_properties = false
  end

  # End of stream marker (0x00)
  output.write(Omnizip::Algorithms::LZMA2::LZMA2Chunk.end_chunk.to_bytes)

  output.string
end

#implementation_nameSymbol

Get implementation identifier

Returns:

  • (Symbol)

    :seven_zip_sdk



136
137
138
# File 'lib/omnizip/implementations/seven_zip/lzma2/encoder.rb', line 136

def implementation_name
  :seven_zip_sdk
end