Module: Omnizip::Formats::Lzip

Defined in:
lib/omnizip/formats/lzip.rb

Overview

LZIP (.lz) compression format

Lzip is a file compression format that uses LZMA compression with a simple container format. It was created as an alternative to the legacy .lzma format with better integrity checking.

This is DIFFERENT from both XZ and .lzma (LZMA_Alone) formats:

  • XZ (.xz): Container format with stream header/footer/index, LZMA2 compression
  • LZIP (.lz): Standalone format with "LZIP" magic and CRC32 footer, LZMA1 compression
  • LZMA_Alone (.lzma): Legacy standalone format with properties byte, LZMA1 compression

Format structure:

  • Header (6 bytes):
    • Magic bytes: "LZIP" (0x4C 0x5A 0x49 0x50)
    • Version (1 byte): 0 or 1
    • Dictionary size (1 byte): encoded format
  • LZMA1 compressed stream (with fixed LC=3, LP=0, PB=2)
  • Footer:
    • Version 0 (12 bytes): CRC32 (4) + Uncompressed size (8)
    • Version 1 (20 bytes): CRC32 (4) + Uncompressed size (8) + Member size (8)

Reference: /Users/mulgogi/src/external/xz/src/liblzma/common/lzip_decoder.c

Constant Summary collapse

MAGIC =

Lzip magic bytes: "LZIP" in ASCII Reference: lzip_decoder.c:106

[0x4C, 0x5A, 0x49, 0x50].pack("C*")
LZIP_LC =

Fixed LC/LP/PB values for lzip format Reference: lzip_decoder.c:23-26

3
LZIP_LP =
0
LZIP_PB =
2
MIN_DICT_SIZE =

Minimum and maximum dictionary sizes (in bytes) Reference: lzip_decoder.c:197-198

4096
MAX_DICT_SIZE =

4 KiB

(512 << 20)

Class Method Summary collapse

Class Method Details

.compress(input_path, output_path, options = {}) ⇒ Object

Compress a file with LZIP

Parameters:

  • input_path (String)

    Input file path

  • output_path (String)

    Output LZIP file path

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

    Compression options

Options Hash (options):

  • :level (Integer)

    Compression level (0-9, default: 6)

  • :dict_size (Integer)

    Dictionary size (default: auto from level)

  • :version (Integer)

    LZIP version (0 or 1, default: 1)



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/omnizip/formats/lzip.rb', line 56

def compress(input_path, output_path, options = {})
  input_data = File.binread(input_path)

  File.open(output_path, "wb") do |output|
    compress_stream(
      StringIO.new(input_data),
      output,
      options,
    )
  end
end

.compress_stream(input_io, _output_io, _options = {}) ⇒ Object

Compress data stream with LZIP

Parameters:

  • input_io (IO)

    Input stream

  • output_io (IO)

    Output stream

  • options (Hash)

    Compression options

Raises:

  • (NotImplementedError)


106
107
108
109
110
111
112
# File 'lib/omnizip/formats/lzip.rb', line 106

def compress_stream(input_io, _output_io, _options = {})
  input_io.read

  # TODO: Implement LZIP encoder
  raise NotImplementedError,
        "LZIP encoding not yet implemented. Use decompression only."
end

.decode(input) ⇒ String

Decode LZIP data (alias for decompress with no output)

Parameters:

  • input (String, IO)

    Input LZIP data or file path

Returns:

  • (String)

    Decompressed data



97
98
99
# File 'lib/omnizip/formats/lzip.rb', line 97

def decode(input)
  decompress(input)
end

.decompress(input, output = nil, options = {}) ⇒ String?

Decompress LZIP data

Parameters:

  • input (String, IO)

    Input data, file path, or IO object

  • output (String, IO, nil) (defaults to: nil)

    Output file path or IO object

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

    Options

Options Hash (options):

  • :ignore_check (Boolean)

    If true, skip CRC32 verification (default: false)

  • :concatenated (Boolean)

    If true, decode concatenated .lz members (default: false)

Returns:

  • (String, nil)

    Decompressed data (if output is nil)



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/omnizip/formats/lzip.rb', line 76

def decompress(input, output = nil, options = {})
  data = Omnizip::IO::Source.for(input).read

  # Decode using LzipDecoder
  decoder = Omnizip::Algorithms::LZMA::LzipDecoder.new(
    StringIO.new(data),
    options,
  )
  result = decoder.decode_stream

  if output
    Omnizip::IO::Sink.for(output).write(result)
  else
    result
  end
end

.decompress_stream(input_io, output_io, options = {}) ⇒ Hash

Decompress LZIP stream

Parameters:

  • input_io (IO)

    Input stream

  • output_io (IO)

    Output stream

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

    Options

Returns:

  • (Hash)

    Metadata (version, dict_size, member_size)



120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/omnizip/formats/lzip.rb', line 120

def decompress_stream(input_io, output_io, options = {})
  decoder = Omnizip::Algorithms::LZMA::LzipDecoder.new(input_io,
                                                       options)
  result = decoder.decode_stream

  output_io.write(result)

  # Return metadata
  {
    version: decoder.version,
    dict_size: decoder.dict_size,
    member_size: decoder.member_size,
  }
end

.lzip_file?(data) ⇒ Boolean

Detect if data is LZIP format

Parameters:

  • data (String)

    Data to check

Returns:

  • (Boolean)

    true if data has LZIP magic bytes



145
146
147
# File 'lib/omnizip/formats/lzip.rb', line 145

def lzip_file?(data)
  data.start_with?(MAGIC)
end

.register!Object

Register LZIP format when loaded



136
137
138
139
# File 'lib/omnizip/formats/lzip.rb', line 136

def register!
  FormatRegistry.register(".lz", Omnizip::Formats::Lzip)
  FormatRegistry.register(".lzip", Omnizip::Formats::Lzip)
end