Module: JXL::Bit::Field

Defined in:
lib/jxl/bit/field.rb

Defined Under Namespace

Classes: Distribution

Class Method Summary collapse

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

Raises:



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

Raises:

  • (ArgumentError)


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

Raises:

  • (ArgumentError)


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