// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
use crate ::{
frame::{
modular::{ModularChannel, predict::clamped_gradient},
quantizer::NUM_QUANT_TABLES,
},
headers::frame_header::FrameHeader,
image::Image,
};
use num_traits::abs;
#[ derive(Debug)]
pub enum ModularStreamId {
GlobalData,
VarDCTLF(usize),
ModularLF(usize),
LFMeta(usize),
QuantTable(usize),
ModularHF { pass: usize, group: usize },
}
impl ModularStreamId {
pub fn get_id(&self , frame_header: &FrameHeader) -> usize {
match self {
Self ::GlobalData => 0 ,
Self ::VarDCTLF(g) => 1 + g,
Self ::ModularLF(g) => 1 + frame_header.num_lf_groups() + g,
Self ::LFMeta(g) => 1 + frame_header.num_lf_groups() * 2 + g,
Self ::QuantTable(q) => 1 + frame_header.num_lf_groups() * 3 + q,
Self ::ModularHF { pass, group } => {
1 + frame_header.num_lf_groups() * 3
+ NUM_QUANT_TABLES
+ frame_header.num_groups() * *pass
+ *group
}
}
}
}
pub (super ) fn precompute_references(
buffers: &mut [&mut ModularChannel],
chan: usize,
y: usize,
references: &mut Image<i32>,
) {
if references.size().0 == 0 {
return ;
}
references.fill(0 );
let mut offset = 0 ;
let num_extra_props = references.size().0 ;
for i in 0 ..chan {
if offset >= num_extra_props {
break ;
}
let j = chan - i - 1 ;
if buffers[j].data.size() != buffers[chan].data.size()
|| buffers[j].shift != buffers[chan].shift
{
continue ;
}
let ref_chan_row = buffers[j].data.row(y);
let ref_chan_prev = buffers[j].data.row(y.saturating_sub(1 ));
for x in 0 ..buffers[chan].data.size().0 {
let ref_row = references.row_mut(x);
let v = ref_chan_row[x];
ref_row[offset] = abs(v);
ref_row[offset + 1 ] = v;
let vleft = if x > 0 { ref_chan_row[x - 1 ] } else { 0 };
let vtop = if y > 0 { ref_chan_prev[x] } else { vleft };
let vtopleft = if x > 0 && y > 0 {
ref_chan_prev[x - 1 ]
} else {
vleft
};
let vpredicted = clamped_gradient(vleft as i64, vtop as i64, vtopleft as i64);
ref_row[offset + 2 ] = abs(v as i64 - vpredicted) as i32;
ref_row[offset + 3 ] = (v as i64 - vpredicted) as i32;
}
offset += 4 ;
}
}
#[ inline(always)]
pub (super ) fn make_pixel(dec: i32, mul: u32, guess: i64) -> i32 {
(guess + (mul as i64) * (dec as i64)) as i32
}
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland