Class: Omnizip::Algorithms::LZMA2::Properties
- Inherits:
-
Object
- Object
- Omnizip::Algorithms::LZMA2::Properties
- Includes:
- Omnizip::Algorithms::LZMA2Const
- Defined in:
- lib/omnizip/algorithms/lzma2/properties.rb
Overview
LZMA2 Properties - handles dictionary size encoding/decoding
The LZMA2 format uses a single property byte that encodes the dictionary size. This is more compact than LZMA's multiple property bytes.
Dictionary size encoding formula:
dictSize = (2 | (props & 1)) << (props / 2 + 11)
This gives sizes from 4KB (props=0) to 4GB (props=40)
Note: In XZ format, the LZMA2 filter properties byte contains ONLY the dictionary size encoding. The lc/lp/pb parameters are encoded in the LZMA chunk properties (inside the compressed data).
Constant Summary
Constants included from Omnizip::Algorithms::LZMA2Const
Omnizip::Algorithms::LZMA2Const::CHUNK_MAX, Omnizip::Algorithms::LZMA2Const::CONTROL_END, Omnizip::Algorithms::LZMA2Const::CONTROL_LZMA_MIN, Omnizip::Algorithms::LZMA2Const::CONTROL_UNCOMPRESSED, Omnizip::Algorithms::LZMA2Const::CONTROL_UNCOMPRESSED_RESET, Omnizip::Algorithms::LZMA2Const::DICT_SIZE_MAX, Omnizip::Algorithms::LZMA2Const::DICT_SIZE_MIN, Omnizip::Algorithms::LZMA2Const::FLAG_RESET_DICT, Omnizip::Algorithms::LZMA2Const::FLAG_RESET_PROPERTIES, Omnizip::Algorithms::LZMA2Const::FLAG_RESET_STATE, Omnizip::Algorithms::LZMA2Const::FLAG_UNCOMPRESSED_SIZE, Omnizip::Algorithms::LZMA2Const::HEADER_MAX, Omnizip::Algorithms::LZMA2Const::HEADER_UNCOMPRESSED, Omnizip::Algorithms::LZMA2Const::UNCOMPRESSED_MAX
Instance Attribute Summary collapse
-
#dict_size ⇒ Object
readonly
Returns the value of attribute dict_size.
-
#prop_byte ⇒ Object
readonly
Returns the value of attribute prop_byte.
Class Method Summary collapse
-
.decode_dict_size(prop) ⇒ Integer
Decode property byte to dictionary size.
-
.encode(dict_size, _lc = 3, _lp = 0, _pb = 2) ⇒ Integer
Encode properties to property byte This is for standalone LZMA2 files where the property byte encodes both dictionary size and lc/lp/pb parameters.
-
.encode_dict_size_to_byte(dict_size) ⇒ Integer
Encode dictionary size to property byte.
-
.from_byte(prop_byte) ⇒ Properties
Create properties from property byte.
-
.validate_prop_byte(prop) ⇒ void
Validate property byte.
-
.validate_prop_byte_range(size) ⇒ Object
Validate dictionary size for property byte encoding.
Instance Method Summary collapse
-
#actual_dict_size ⇒ Integer
Get the actual dictionary size (may differ from requested).
-
#encode_dict_size(dict_size) ⇒ Integer
Encode dictionary size to property byte.
-
#initialize(dict_size) ⇒ Properties
constructor
Initialize properties from dictionary size.
Constructor Details
#initialize(dict_size) ⇒ Properties
Initialize properties from dictionary size
48 49 50 51 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 48 def initialize(dict_size) @dict_size = validate_dict_size(dict_size) @prop_byte = encode_dict_size(@dict_size) end |
Instance Attribute Details
#dict_size ⇒ Object (readonly)
Returns the value of attribute dict_size.
43 44 45 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 43 def dict_size @dict_size end |
#prop_byte ⇒ Object (readonly)
Returns the value of attribute prop_byte.
43 44 45 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 43 def prop_byte @prop_byte end |
Class Method Details
.decode_dict_size(prop) ⇒ Integer
Decode property byte to dictionary size
XZ Utils formula from lzma_lzma2_props_decode (lzma2_decoder.c:290-302):
dict_size = (2 | (props & 1)) << (props / 2 + 11)
For even props: dict_size = 2 * 2^((props/2) + 11) = 2^((props/2) + 12) For odd props: dict_size = 3 * 2^((props-1)/2 + 11)
89 90 91 92 93 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 89 def self.decode_dict_size(prop) # XZ Utils formula: dict_size = (2 | (prop & 1)) << (prop / 2 + 11) base = 2 | (prop & 1) base << ((prop / 2) + 11) end |
.encode(dict_size, _lc = 3, _lp = 0, _pb = 2) ⇒ Integer
Encode properties to property byte This is for standalone LZMA2 files where the property byte encodes both dictionary size and lc/lp/pb parameters
104 105 106 107 108 109 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 104 def self.encode(dict_size, _lc = 3, _lp = 0, _pb = 2) # For standalone LZMA2 files, we only encode the dictionary size # The lc/lp/pb parameters are encoded in the LZMA chunk properties instead validate_prop_byte_range(dict_size) encode_dict_size_to_byte(dict_size) end |
.encode_dict_size_to_byte(dict_size) ⇒ Integer
Encode dictionary size to property byte
115 116 117 118 119 120 121 122 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 115 def self.encode_dict_size_to_byte(dict_size) # Find the smallest prop value that gives >= dict_size (0..40).each do |prop| size = decode_dict_size(prop) return prop if size >= dict_size end 40 end |
.from_byte(prop_byte) ⇒ Properties
Create properties from property byte
57 58 59 60 61 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 57 def self.from_byte(prop_byte) validate_prop_byte(prop_byte) dict_size = decode_dict_size(prop_byte) new(dict_size) end |
.validate_prop_byte(prop) ⇒ void
This method returns an undefined value.
Validate property byte
170 171 172 173 174 175 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 170 def self.validate_prop_byte(prop) return if prop.between?(0, 40) raise ArgumentError, "Property byte must be between 0 and 40" end |
.validate_prop_byte_range(size) ⇒ Object
Validate dictionary size for property byte encoding
128 129 130 131 132 133 134 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 128 def self.validate_prop_byte_range(size) unless size.between?(DICT_SIZE_MIN, DICT_SIZE_MAX) raise ArgumentError, "Dictionary size must be between #{DICT_SIZE_MIN} " \ "and #{DICT_SIZE_MAX}" end end |
Instance Method Details
#actual_dict_size ⇒ Integer
Get the actual dictionary size (may differ from requested)
139 140 141 142 143 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 139 def actual_dict_size # Cap at 64MB to prevent memory exhaustion from malformed files max_dict = 64 * 1024 * 1024 [self.class.decode_dict_size(@prop_byte), max_dict].min end |
#encode_dict_size(dict_size) ⇒ Integer
Encode dictionary size to property byte
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/omnizip/algorithms/lzma2/properties.rb', line 67 def encode_dict_size(dict_size) # Find the smallest prop value that gives >= dict_size # Valid range for property byte is 0-40 (per XZ spec) (0..40).each do |prop| size = self.class.decode_dict_size(prop) return prop if size >= dict_size end # If we couldn't find a suitable prop, use maximum 40 end |