Class: Omnizip::Formats::Rar::Rar5::Compression::Lzss

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

Overview

RAR5 LZSS compression method

RAR5 compression methods 1-5 use a proprietary LZSS-based algorithm with Huffman coding. This is the algorithm used by official RAR tools.

Based on libarchive/archive_read_support_format_rar5.c

Defined Under Namespace

Classes: BitReader, Decoder, HuffmanTable

Constant Summary collapse

METHOD_STORE =

Compression method identifiers

0
METHOD_FASTEST =
1
METHOD_FAST =
2
METHOD_NORMAL =
3
METHOD_GOOD =
4
METHOD_BEST =
5
HUFF_BC =

Huffman code constants (from libarchive)

20
HUFF_NC =

Number of bit length codes

306
HUFF_DC =

Number of literal/length codes

64
HUFF_LDC =

Number of distance codes

16
HUFF_RC =

Number of low distance codes

44
HUFF_TABLE_SIZE =

Number of repeat codes

HUFF_NC + HUFF_DC + HUFF_LDC + HUFF_RC
DIST_CACHE_SIZE =

Distance cache size

4
MIN_MATCH =

Minimum match length

3

Class Method Summary collapse

Class Method Details

.available?Boolean

Check if LZSS compression is available for official RAR compatibility

Returns:

  • (Boolean)

    true if implemented



44
45
46
47
48
# File 'lib/omnizip/formats/rar/rar5/compression/lzss.rb', line 44

def available?
  # Full LZSS decoder is now implemented
  # Encoder is not yet compatible with official RAR tools
  true
end

.compress(data, options = {}) ⇒ Hash

Compress data using RAR5 LZSS

Parameters:

  • data (String)

    Data to compress

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

    Compression options

Options Hash (options):

  • :level (Integer)

    Compression level (1-5)

  • :dict_size (Integer)

    Dictionary size

Returns:

  • (Hash)

    Hash with :data, :properties, and :method



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/omnizip/formats/rar/rar5/compression/lzss.rb', line 57

def compress(data, options = {})
  level = options[:level] || METHOD_NORMAL
  options[:dict_size] || dictionary_size_for_level(level)

  # For now, use STORE method until encoder is compatible
  # with official RAR tools
  {
    data: data,
    properties: nil,
    method: METHOD_STORE,
  }
end

.compression_info(level = METHOD_NORMAL) ⇒ Integer

Get compression info VINT value

Parameters:

  • level (Integer) (defaults to: METHOD_NORMAL)

    Compression level (1-5)

Returns:

  • (Integer)

    Compression info value



97
98
99
100
# File 'lib/omnizip/formats/rar/rar5/compression/lzss.rb', line 97

def compression_info(level = METHOD_NORMAL)
  method = method_id(level)
  method & 0x3F
end

.decompress(data, options = {}) ⇒ String

Decompress RAR5 LZSS data

Parameters:

  • data (String)

    Compressed data

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

    Decompression options

Options Hash (options):

  • :uncompressed_size (Integer)

    Expected size

  • :window_size (Integer)

    Dictionary size

Returns:

  • (String)

    Decompressed data



77
78
79
80
81
82
83
# File 'lib/omnizip/formats/rar/rar5/compression/lzss.rb', line 77

def decompress(data, options = {})
  uncompressed_size = options[:uncompressed_size]
  window_size = options[:window_size] || (1 << 20) # Default 1MB

  decoder = Decoder.new(data, window_size)
  decoder.decode(uncompressed_size)
end

.method_id(level = METHOD_NORMAL) ⇒ Integer

Get compression method identifier

Parameters:

  • level (Integer) (defaults to: METHOD_NORMAL)

    Compression level (1-5)

Returns:

  • (Integer)

    Method ID



89
90
91
# File 'lib/omnizip/formats/rar/rar5/compression/lzss.rb', line 89

def method_id(level = METHOD_NORMAL)
  level.clamp(METHOD_FASTEST, METHOD_BEST)
end