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
-
.compress(input_path, output_path, options = {}) ⇒ Object
Compress a file with LZIP.
-
.compress_stream(input_io, output_io, options = {}) ⇒ Object
Compress data stream with LZIP.
-
.decode(input) ⇒ String
Decode LZIP data (alias for decompress with no output).
-
.decompress(input, output = nil, options = {}) ⇒ String?
Decompress LZIP data.
-
.decompress_stream(input_io, output_io, options = {}) ⇒ Hash
Decompress LZIP stream.
-
.lzip_file?(data) ⇒ Boolean
Detect if data is LZIP format.
Class Method Details
.compress(input_path, output_path, options = {}) ⇒ Object
Compress a file with LZIP
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, = {}) input_data = File.binread(input_path) File.open(output_path, "wb") do |output| compress_stream( StringIO.new(input_data), output, , ) end end |
.compress_stream(input_io, output_io, options = {}) ⇒ Object
Compress data stream with LZIP
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/omnizip/formats/lzip.rb', line 106 def compress_stream(input_io, output_io, = {}) input = input_io.read # Version-1 member: magic + version + dict-size byte, LZMA1 # body (EOPM-terminated), 20-byte trailer (CRC32 + data # size + member size). The dictionary byte uses lzip's # 5-bit exponent / 3-bit fraction encoding; 4 MiB is the # typical default. output_io.write(MAGIC) output_io.write([1].pack("C")) output_io.write([22].pack("C")) # 2^22 = 4 MiB, no fraction dict_size = .fetch(:dict_size, 8 * 1024 * 1024) body = Algorithms::LZMA::Lzma1Encoder .new(dict_size: dict_size).encode(input) member_size = 6 + body.bytesize + 20 output_io.write(body) output_io.write([Checksums::Crc32.calculate(input)].pack("V")) output_io.write([input.bytesize].pack("Q<")) output_io.write([member_size].pack("Q<")) end |
.decode(input) ⇒ String
Decode LZIP data (alias for decompress with no output)
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
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, = {}) data = Omnizip::IO::Source.for(input).read # Decode using LzipDecoder decoder = Omnizip::Algorithms::LZMA::LzipDecoder.new( StringIO.new(data), , ) 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
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/omnizip/formats/lzip.rb', line 135 def decompress_stream(input_io, output_io, = {}) output_io.set_encoding(Encoding::BINARY) decoder = Omnizip::Algorithms::LZMA::LzipDecoder.new(input_io, ) 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
155 156 157 |
# File 'lib/omnizip/formats/lzip.rb', line 155 def lzip_file?(data) data.start_with?(MAGIC) end |