Class: JXL::VarDCT::LFGroup

Inherits:
Data
  • Object
show all
Defined in:
lib/jxl/vardct/lf_group.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#dcObject (readonly)

Returns the value of attribute dc

Returns:

  • (Object)

    the current value of dc



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def dc
  @dc
end

#quant_dcObject (readonly)

Returns the value of attribute quant_dc

Returns:

  • (Object)

    the current value of quant_dc



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def quant_dc
  @quant_dc
end

#quant_fieldObject (readonly)

Returns the value of attribute quant_field

Returns:

  • (Object)

    the current value of quant_field



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def quant_field
  @quant_field
end

#sharpnessObject (readonly)

Returns the value of attribute sharpness

Returns:

  • (Object)

    the current value of sharpness



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def sharpness
  @sharpness
end

#strategiesObject (readonly)

Returns the value of attribute strategies

Returns:

  • (Object)

    the current value of strategies



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def strategies
  @strategies
end

#strategy_firstObject (readonly)

Returns the value of attribute strategy_first

Returns:

  • (Object)

    the current value of strategy_first



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def strategy_first
  @strategy_first
end

#used_strategiesObject (readonly)

Returns the value of attribute used_strategies

Returns:

  • (Object)

    the current value of used_strategies



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def used_strategies
  @used_strategies
end

#xObject (readonly)

Returns the value of attribute x

Returns:

  • (Object)

    the current value of x



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def x
  @x
end

#yObject (readonly)

Returns the value of attribute y

Returns:

  • (Object)

    the current value of y



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def y
  @y
end

#ytob_mapObject (readonly)

Returns the value of attribute ytob_map

Returns:

  • (Object)

    the current value of ytob_map



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def ytob_map
  @ytob_map
end

#ytox_mapObject (readonly)

Returns the value of attribute ytox_map

Returns:

  • (Object)

    the current value of ytox_map



5
6
7
# File 'lib/jxl/vardct/lf_group.rb', line 5

def ytox_map
  @ytox_map
end

Class Method Details

.merge(groups, frame) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/jxl/vardct/lf_group.rb', line 131

def self.merge(groups, frame)
  return groups.first if groups.one?

  width = frame.blocks_width
  height = frame.blocks_height
  dc = frame.chroma_subsampling.map do |hshift, vshift|
    Plane.new(width >> hshift, height >> vshift)
  end
  quant_dc = Plane.new(width, height)
  strategies = Array.new(width * height)
  strategy_first = Array.new(width * height, false)
  quant_field = Plane.new(width, height)
  sharpness = Plane.new(width, height)
  ytox_map = Plane.new(Num.ceil_div(width, 8), Num.ceil_div(height, 8))
  ytob_map = Plane.new(ytox_map.width, ytox_map.height)
  groups.each do |group|
    group.dc.each_with_index do |plane, channel|
      hshift, vshift = frame.chroma_subsampling[channel]
      blit_plane!(plane, dc[channel], group.x >> hshift, group.y >> vshift)
    end
    blit_plane!(group.quant_dc, quant_dc, group.x, group.y)
    blit_plane!(group.quant_field, quant_field, group.x, group.y)
    blit_plane!(group.sharpness, sharpness, group.x, group.y)
    blit_plane!(group.ytox_map, ytox_map, group.x / 8, group.y / 8)
    blit_plane!(group.ytob_map, ytob_map, group.x / 8, group.y / 8)
    group.strategies.each_with_index do |strategy, index|
      local_x = index % group.quant_field.width
      local_y = index / group.quant_field.width
      target = ((group.y + local_y) * width) + group.x + local_x
      strategies[target] = strategy
      strategy_first[target] = group.strategy_first[index]
    end
  end
  new(dc:, quant_dc:, strategies:, strategy_first:, quant_field:, sharpness:, ytox_map:, ytob_map:,
      used_strategies: groups.flat_map(&:used_strategies).uniq.sort.freeze, x: 0, y: 0)
end

.read(reader, frame, metadata, global, group_index: 0, group_count: 1, dc_frame: nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/jxl/vardct/lf_group.rb', line 7

def self.read(reader, frame, , global, group_index: 0, group_count: 1, dc_frame: nil)
  group_dim = 128 << frame.group_size_shift
  groups_x = Num.ceil_div(frame.blocks_width, group_dim)
  x = (group_index % groups_x) * group_dim
  y = (group_index / groups_x) * group_dim
  width = [group_dim, frame.blocks_width - x].min
  height = [group_dim, frame.blocks_height - y].min
  dc, quant_dc = if frame.flags.anybits?(32)
                   dc_from_frame(dc_frame, frame, width, height, x, y)
                 else
                   read_dc(reader, frame, , global, group_index, width, height)
                 end
  if global.modular_group
    Modular::Decoder.decode_grouped_dc!(reader, global.modular_group,
                                        group_index:, groups_x:, stream_id: 1 + group_count + group_index)
  end
  stream_id = 1 + (2 * group_count) + group_index
   = (reader, width, height, , global.modular_state, stream_id)
  build(dc, quant_dc, .channels, width, height, x, y)
end

.smooth!(group, dc_factors) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/jxl/vardct/lf_group.rb', line 168

def self.smooth!(group, dc_factors)
  width = group.dc.first.width
  height = group.dc.first.height
  return group if width <= 2 || height <= 2

  w1 = 0.20345139757231578
  w2 = 0.0334829185968739
  w0 = 1.0 - (4.0 * (w1 + w2))
  output = group.dc.map do |source|
    Plane.new(width, height).tap { |target| target.data.replace(source.data) }
  end
  1.upto(height - 2) do |y|
    1.upto(width - 2) do |x|
      centres = group.dc.map { _1[x, y] }
      smoothed = group.dc.map do |plane|
        corners = plane[x - 1, y - 1] + plane[x + 1, y - 1] +
                  plane[x - 1, y + 1] + plane[x + 1, y + 1]
        sides = plane[x - 1, y] + plane[x + 1, y] + plane[x, y - 1] + plane[x, y + 1]
        (w2 * corners) + (w1 * sides) + (w0 * plane[x, y])
      end
      gap = 3.times.reduce(0.5) do |value, channel|
        [value, ((centres[channel] - smoothed[channel]) /
                                                       dc_factors[channel]).abs].max
      end
      factor = [0.0, 3.0 - (4.0 * gap)].max
      3.times do |channel|
        output[channel][x, y] = centres[channel] +
                                ((smoothed[channel] - centres[channel]) * factor)
      end
    end
  end
  group.dc.each_index { |channel| group.dc[channel].data.replace(output[channel].data) }
  group
end