Class: Omnizip::Algorithms::LZMA

Inherits:
Omnizip::Algorithm show all
Defined in:
lib/omnizip/algorithms/lzma.rb,
lib/omnizip/algorithms/lzma/match.rb,
lib/omnizip/algorithms/lzma/state.rb,
lib/omnizip/algorithms/lzma/decoder.rb,
lib/omnizip/algorithms/lzma/encoder.rb,
lib/omnizip/algorithms/lzma/xz_state.rb,
lib/omnizip/algorithms/lzma/bit_model.rb,
lib/omnizip/algorithms/lzma/constants.rb,
lib/omnizip/algorithms/lzma/dictionary.rb,
lib/omnizip/algorithms/lzma/lzma_state.rb,
lib/omnizip/algorithms/lzma/xz_encoder.rb,
lib/omnizip/algorithms/lzma/range_coder.rb,
lib/omnizip/algorithms/lzma/length_coder.rb,
lib/omnizip/algorithms/lzma/lzip_decoder.rb,
lib/omnizip/algorithms/lzma/match_finder.rb,
lib/omnizip/algorithms/lzma/range_decoder.rb,
lib/omnizip/algorithms/lzma/range_encoder.rb,
lib/omnizip/algorithms/lzma/distance_coder.rb,
lib/omnizip/algorithms/lzma/literal_decoder.rb,
lib/omnizip/algorithms/lzma/literal_encoder.rb,
lib/omnizip/algorithms/lzma/optimal_encoder.rb,
lib/omnizip/algorithms/lzma/xz_encoder_fast.rb,
lib/omnizip/algorithms/lzma/xz_range_encoder.rb,
lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb,
lib/omnizip/algorithms/lzma/probability_models.rb,
lib/omnizip/algorithms/lzma/match_finder_config.rb,
lib/omnizip/algorithms/lzma/xz_price_calculator.rb,
lib/omnizip/algorithms/lzma/match_finder_factory.rb,
lib/omnizip/algorithms/lzma/xz_probability_models.rb,
lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb,
lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb,
lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb

Overview

LZMA (Lempel-Ziv-Markov chain Algorithm) compression

LZMA is a lossless data compression algorithm that combines Lempel-Ziv dictionary compression with range coding (a form of arithmetic coding). It achieves high compression ratios by using adaptive probability models.

This implementation uses:

  • LZ77 match finder for finding duplicate sequences
  • Range coding for probability-based encoding
  • Adaptive bit models that adjust based on input data
  • State machine for compression context tracking

The algorithm operates by:

  1. Finding matches using LZ77 dictionary compression
  2. Encoding decisions using range coder with probability models
  3. Maintaining state for optimal compression

Defined Under Namespace

Modules: Constants Classes: BitModel, Decoder, Dictionary, DistanceCoder, Encoder, IntRef, LZMAState, LengthCoder, LengthEncoder, LiteralDecoder, LiteralEncoder, LzipDecoder, LzmaAloneDecoder, Match, MatchFinder, MatchFinderConfig, MatchFinderFactory, OptimalEncoder, ProbabilityModels, RangeCoder, RangeDecoder, RangeEncoder, State, XZRangeEncoder, XzBufferedRangeEncoder, XzEncoder, XzEncoderAdapter, XzEncoderFast, XzMatchFinderAdapter, XzPriceCalculator, XzProbabilityModels, XzRangeEncoder, XzState

Instance Attribute Summary

Attributes inherited from Omnizip::Algorithm

#filter, #options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Omnizip::Algorithm

inherited, #with_filter

Constructor Details

#initialize(options = {}) ⇒ LZMA

Initialize the LZMA algorithm with options

Parameters:

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

    Algorithm options

Options Hash (options):

  • :lc (Integer)

    Literal context bits (default: 3)

  • :lp (Integer)

    Literal position bits (default: 0)

  • :pb (Integer)

    Position bits (default: 2)

  • :dict_size (Integer)

    Dictionary size (default: 4MB)

  • :lzma2_mode (Boolean)

    Raw LZMA mode (no header, for 7-Zip)



97
98
99
100
101
102
103
104
105
# File 'lib/omnizip/algorithms/lzma.rb', line 97

def initialize(options = {})
  super()
  @lc = options[:lc] || 3
  @lp = options[:lp] || 0
  @pb = options[:pb] || 2
  @dict_size = options[:dict_size] || (4 * 1024 * 1024) # 4 MB default
  @lzma2_mode = options[:lzma2_mode]
  @uncompressed_size = options[:uncompressed_size] || options[:size]
end

Class Method Details

.metadataAlgorithmMetadata

Get algorithm metadata

Returns:

  • (AlgorithmMetadata)

    Algorithm information



110
111
112
113
114
115
116
117
# File 'lib/omnizip/algorithms/lzma.rb', line 110

def self.
  Models::AlgorithmMetadata.new.tap do |meta|
    meta.name = "lzma"
    meta.description = "LZMA compression using range coding " \
                       "and dictionary compression"
    meta.version = "1.0.0"
  end
end

Instance Method Details

#compress(input_stream, output_stream, options = nil) ⇒ void

This method returns an undefined value.

Compress data using LZMA algorithm

Parameters:

  • input_stream (IO)

    Input stream to compress

  • output_stream (IO)

    Output stream for compressed data

  • options (Models::CompressionOptions) (defaults to: nil)

    Compression options



125
126
127
128
129
# File 'lib/omnizip/algorithms/lzma.rb', line 125

def compress(input_stream, output_stream, options = nil)
  input_data = input_stream.read
  encoder = Encoder.new(output_stream, build_encoder_options(options))
  encoder.encode_stream(input_data)
end

#decompress(input_stream, output_stream, options = nil) ⇒ IO

Decompress LZMA-compressed data

Parameters:

  • input_stream (IO)

    Input stream of compressed data

  • output_stream (IO)

    Output stream for decompressed data

  • options (Models::CompressionOptions, Hash) (defaults to: nil)

    Decompression options

Returns:

  • (IO)

    The output_stream (for chaining)



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/omnizip/algorithms/lzma.rb', line 137

def decompress(input_stream, output_stream, options = nil)
  # Set binary encoding on output stream for proper byte handling
  output_stream.set_encoding(Encoding::BINARY) if output_stream.respond_to?(:set_encoding)

  # Build decoder options, merging with instance variables as fallbacks
  decoder_opts = build_decoder_options(options)
  if @lzma2_mode && !decoder_opts.key?(:lzma2_mode)
    decoder_opts[:lzma2_mode] =
      @lzma2_mode
  end
  decoder_opts[:lc] = @lc if @lc && !decoder_opts.key?(:lc)
  decoder_opts[:lp] = @lp if @lp && !decoder_opts.key?(:lp)
  decoder_opts[:pb] = @pb if @pb && !decoder_opts.key?(:pb)
  if @dict_size && !decoder_opts.key?(:dict_size)
    decoder_opts[:dict_size] =
      @dict_size
  end
  if @uncompressed_size && !decoder_opts.key?(:uncompressed_size)
    decoder_opts[:uncompressed_size] =
      @uncompressed_size
  end
  decoder_opts[:uncompressed_size] ||= options[:size] if options.respond_to?(:key?) && options.key?(:size)

  decoder = Decoder.new(input_stream, decoder_opts)
  decoder.decode_stream(output_stream)
  output_stream
end