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/lzma1_encoder.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, Lzma1Encoder, 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

compress, decompress, 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)



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

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



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

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



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

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)



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
164
165
# File 'lib/omnizip/algorithms/lzma.rb', line 138

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

  # 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
  # allowed: options is a public parameter; the body needs #key? and #[]
  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