Module: JXL::Bit::Field
- Defined in:
- lib/jxl/bit/field.rb
Defined Under Namespace
Classes: Distribution
Class Method Summary collapse
- .bits(count) ⇒ Object
- .bits_offset(count, offset) ⇒ Object
- .enum(reader) ⇒ Object
- .f16(reader) ⇒ Object
- .read_bool(reader) ⇒ Object
- .skip_extensions(reader) ⇒ Object
- .string(reader) ⇒ Object
- .u32(reader, *distributions) ⇒ Object
- .u64(reader) ⇒ Object
- .val(value) ⇒ Object
- .write_u32(writer, value, *distributions) ⇒ Object
- .write_u64(writer, value) ⇒ Object
Class Method Details
.bits(count) ⇒ Object
11 |
# File 'lib/jxl/bit/field.rb', line 11 def bits(count) = bits_offset(count, 0) |
.bits_offset(count, offset) ⇒ Object
12 |
# File 'lib/jxl/bit/field.rb', line 12 def bits_offset(count, offset) = Distribution.new(bits: count, offset:, value: nil) |
.enum(reader) ⇒ Object
91 |
# File 'lib/jxl/bit/field.rb', line 91 def enum(reader) = u32(reader, val(0), val(1), bits_offset(4, 2), bits_offset(6, 18)) |
.f16(reader) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/jxl/bit/field.rb', line 76 def f16(reader) bits = reader.read(16) sign = bits[15].zero? ? 1.0 : -1.0 exponent = (bits >> 10) & 0x1F mantissa = bits & 0x3FF raise FormatError, "F16 infinity or NaN" if exponent == 0x1F magnitude = if exponent.zero? mantissa * (2.0**-24) else (1024 + mantissa) * (2.0**(exponent - 25)) end sign * magnitude end |
.read_bool(reader) ⇒ Object
92 |
# File 'lib/jxl/bit/field.rb', line 92 def read_bool(reader) = !reader.read(1).zero? |
.skip_extensions(reader) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/jxl/bit/field.rb', line 99 def skip_extensions(reader) extensions = u64(reader) lengths = [] bit = 0 until extensions.zero? lengths << u64(reader) unless extensions[bit].zero? extensions &= ~(1 << bit) bit += 1 end reader.skip(lengths.sum) end |
.string(reader) ⇒ Object
94 95 96 97 |
# File 'lib/jxl/bit/field.rb', line 94 def string(reader) length = u32(reader, val(0), bits(4), bits_offset(5, 16), bits_offset(10, 48)) Array.new(length) { reader.read(8) }.pack("C*").force_encoding(Encoding::UTF_8) end |
.u32(reader, *distributions) ⇒ Object
14 15 16 17 18 19 20 21 |
# File 'lib/jxl/bit/field.rb', line 14 def u32(reader, *distributions) raise ArgumentError, "U32 requires four distributions" unless distributions.length == 4 distribution = distributions.fetch(reader.read(2)) return distribution.value unless distribution.value.nil? reader.read(distribution.bits) + distribution.offset end |
.u64(reader) ⇒ Object
38 39 40 41 42 43 44 45 |
# File 'lib/jxl/bit/field.rb', line 38 def u64(reader) case reader.read(2) when 0 then 0 when 1 then reader.read(4) + 1 when 2 then reader.read(8) + 17 else read_large_u64(reader) end end |
.val(value) ⇒ Object
10 |
# File 'lib/jxl/bit/field.rb', line 10 def val(value) = Distribution.new(bits: nil, offset: nil, value:) |
.write_u32(writer, value, *distributions) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/jxl/bit/field.rb', line 23 def write_u32(writer, value, *distributions) raise ArgumentError, "U32 requires four distributions" unless distributions.length == 4 selector = distributions.index do |distribution| distribution.value == value || (distribution.bits && value >= distribution.offset && (value - distribution.offset).bit_length <= distribution.bits) end raise ArgumentError, "value is not representable by U32" unless selector distribution = distributions[selector] writer.write(2, selector) writer.write(distribution.bits, value - distribution.offset) if distribution.bits writer end |
.write_u64(writer, value) ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/jxl/bit/field.rb', line 47 def write_u64(writer, value) case value when 0 then writer.write(2, 0) when 1..16 then writer.write(2, 1).write(4, value - 1) when 17..272 then writer.write(2, 2).write(8, value - 17) else write_large_u64(writer, value) end end |