Skip to content

Commit 2f8c324

Browse files
committed
work in progress
1 parent db3fe91 commit 2f8c324

File tree

5 files changed

+92
-72
lines changed

5 files changed

+92
-72
lines changed

src/structs/lepton_decoder.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ fn decode_edge<R: Read, const ALL_PRESENT: bool>(
475475
decode_one_edge::<R, ALL_PRESENT, true>(
476476
model_per_color,
477477
bool_reader,
478-
&curr_horiz_pred.to_array(),
478+
&curr_horiz_pred,
479479
here_mut,
480480
qt,
481481
pt,
@@ -486,7 +486,7 @@ fn decode_edge<R: Read, const ALL_PRESENT: bool>(
486486
decode_one_edge::<R, ALL_PRESENT, false>(
487487
model_per_color,
488488
bool_reader,
489-
&curr_vert_pred.to_array(),
489+
&curr_vert_pred,
490490
here_mut,
491491
qt,
492492
pt,
@@ -504,7 +504,7 @@ fn decode_edge<R: Read, const ALL_PRESENT: bool>(
504504
fn decode_one_edge<R: Read, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
505505
model_per_color: &mut ModelPerColor,
506506
bool_reader: &mut VPXBoolReader<R>,
507-
pred: &[i32; 8],
507+
pred: &i32x8,
508508
here_mut: &mut AlignedBlock,
509509
qt: &QuantizationTables,
510510
pt: &ProbabilityTables,
@@ -516,6 +516,10 @@ fn decode_one_edge<R: Read, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
516516
.read_non_zero_edge_count::<R, HORIZONTAL>(bool_reader, est_eob, num_non_zeros_bin)
517517
.context(here!())?;
518518

519+
if num_non_zeros_edge == 0 {
520+
return Ok(());
521+
}
522+
519523
let delta;
520524
let mut zig15offset;
521525

@@ -529,28 +533,28 @@ fn decode_one_edge<R: Read, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
529533

530534
let mut coord_tr = delta;
531535

532-
for _lane in 0..7 {
533-
if num_non_zeros_edge == 0 {
534-
break;
535-
}
536-
537-
let (best_prior_sign_index, best_prior_abs) =
538-
pt.calc_coefficient_context8_lak::<ALL_PRESENT, HORIZONTAL>(qt, coord_tr, pred);
536+
let (best_prior_sign, best_prior_abs) =
537+
pt.calc_coefficient_context8_lak::<ALL_PRESENT, HORIZONTAL>(qt, pred);
539538

539+
for lane in 0..7 {
540540
let coef = model_per_color.read_edge_coefficient(
541541
bool_reader,
542542
qt,
543543
zig15offset,
544544
num_non_zeros_edge,
545-
best_prior_sign_index,
546-
best_prior_abs,
545+
best_prior_sign.as_array_ref()[lane + 1],
546+
best_prior_abs.as_array_ref()[lane + 1],
547547
)?;
548548

549549
if coef != 0 {
550-
num_non_zeros_edge -= 1;
551550
here_mut.set_coefficient(coord_tr, coef);
552551
raster[coord_tr as usize] =
553552
i32::from(coef) * i32::from(qt.get_quantization_table_transposed()[coord_tr]);
553+
554+
num_non_zeros_edge -= 1;
555+
if num_non_zeros_edge == 0 {
556+
break;
557+
}
554558
}
555559

556560
coord_tr += delta;

src/structs/lepton_encoder.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ fn encode_edge<W: Write, const ALL_PRESENT: bool>(
500500
here_tr,
501501
model_per_color,
502502
bool_writer,
503-
&curr_horiz_pred.to_array(),
503+
&curr_horiz_pred,
504504
qt,
505505
pt,
506506
num_non_zeros_bin,
@@ -512,7 +512,7 @@ fn encode_edge<W: Write, const ALL_PRESENT: bool>(
512512
here_tr,
513513
model_per_color,
514514
bool_writer,
515-
&curr_vert_pred.to_array(),
515+
&curr_vert_pred,
516516
qt,
517517
pt,
518518
num_non_zeros_bin,
@@ -538,7 +538,7 @@ fn encode_one_edge<W: Write, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
538538
block: &AlignedBlock,
539539
model_per_color: &mut ModelPerColor,
540540
bool_writer: &mut VPXBoolWriter<W>,
541-
pred: &[i32; 8],
541+
pred: &i32x8,
542542
qt: &QuantizationTables,
543543
pt: &ProbabilityTables,
544544
num_non_zeros_bin: u8,
@@ -573,6 +573,10 @@ fn encode_one_edge<W: Write, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
573573
)
574574
.context(here!())?;
575575

576+
if num_non_zeros_edge == 0 {
577+
return Ok(());
578+
}
579+
576580
let delta;
577581
let mut zig15offset;
578582

@@ -586,14 +590,10 @@ fn encode_one_edge<W: Write, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
586590

587591
let mut coord_tr = delta;
588592

589-
for _lane in 0..7 {
590-
if num_non_zeros_edge == 0 {
591-
break;
592-
}
593-
594-
let (best_prior_sign_index, best_prior_abs) =
595-
pt.calc_coefficient_context8_lak::<ALL_PRESENT, HORIZONTAL>(qt, coord_tr, pred);
593+
let (best_prior_sign, best_prior_abs) =
594+
pt.calc_coefficient_context8_lak::<ALL_PRESENT, HORIZONTAL>(qt, pred);
596595

596+
for lane in 0..7 {
597597
let coef = block.get_coefficient(coord_tr);
598598

599599
model_per_color
@@ -603,13 +603,16 @@ fn encode_one_edge<W: Write, const ALL_PRESENT: bool, const HORIZONTAL: bool>(
603603
coef,
604604
zig15offset,
605605
num_non_zeros_edge,
606-
best_prior_sign_index,
607-
best_prior_abs,
606+
best_prior_sign.as_array_ref()[lane + 1],
607+
best_prior_abs.as_array_ref()[lane + 1],
608608
)
609609
.context(here!())?;
610610

611611
if coef != 0 {
612612
num_non_zeros_edge -= 1;
613+
if num_non_zeros_edge == 0 {
614+
break;
615+
}
613616
}
614617

615618
coord_tr += delta;

src/structs/model.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::metrics::{ModelComponent, ModelSubComponent};
1515
use crate::structs::branch::Branch;
1616
use default_boxed::DefaultBoxed;
1717

18-
use super::probability_tables::{EdgeSign, ProbabilityTables};
18+
use super::probability_tables::ProbabilityTables;
1919
use super::quantization_tables::QuantizationTables;
2020
use super::vpx_bool_reader::VPXBoolReader;
2121
use super::vpx_bool_writer::VPXBoolWriter;
@@ -333,7 +333,7 @@ impl ModelPerColor {
333333
qt: &QuantizationTables,
334334
zig15offset: usize,
335335
num_non_zeros_edge: u8,
336-
best_prior_sign_index: EdgeSign,
336+
best_prior_sign_index: i32,
337337
best_prior_abs: u32,
338338
) -> Result<i16> {
339339
let num_non_zeros_edge_bin = usize::from(num_non_zeros_edge) - 1;
@@ -428,7 +428,7 @@ impl ModelPerColor {
428428
coef: i16,
429429
zig15offset: usize,
430430
num_non_zeros_edge: u8,
431-
best_prior_sign_index: EdgeSign,
431+
best_prior_sign_index: i32,
432432
best_prior_abs: u32,
433433
) -> Result<()> {
434434
let num_non_zeros_edge_bin = usize::from(num_non_zeros_edge) - 1;

src/structs/probability_tables.rs

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,11 @@ use crate::structs::quantization_tables::*;
1313
use super::block_based_image::AlignedBlock;
1414
use super::block_context::NeighborData;
1515

16+
use bytemuck::cast;
1617
use wide::i16x8;
1718
use wide::i32x8;
18-
19-
pub enum EdgeSign {
20-
Zero = 0,
21-
Positive = 1,
22-
Negative = 2,
23-
}
19+
use wide::u32x8;
20+
use wide::CmpLt;
2421

2522
pub struct ProbabilityTables {
2623
left_present: bool,
@@ -214,34 +211,43 @@ impl ProbabilityTables {
214211
pub fn calc_coefficient_context8_lak<const ALL_PRESENT: bool, const HORIZONTAL: bool>(
215212
&self,
216213
qt: &QuantizationTables,
217-
coefficient_tr: usize,
218-
pred: &[i32; 8],
219-
) -> (EdgeSign, u32) {
220-
if !ALL_PRESENT
221-
&& ((HORIZONTAL && !self.above_present) || (!HORIZONTAL && !self.left_present))
222-
{
223-
return (EdgeSign::Zero, 0);
214+
pred: &i32x8,
215+
) -> (i32x8, u32x8) {
216+
#[inline]
217+
fn mul_hi(lhs: u32x8, rhs: u32x8) -> u32x8 {
218+
let a: [u32; 8] = cast(lhs);
219+
let b: [u32; 8] = cast(rhs);
220+
cast([
221+
((u64::from(a[0]) * u64::from(b[0])) >> 32) as u32,
222+
((u64::from(a[1]) * u64::from(b[1])) >> 32) as u32,
223+
((u64::from(a[2]) * u64::from(b[2])) >> 32) as u32,
224+
((u64::from(a[3]) * u64::from(b[3])) >> 32) as u32,
225+
((u64::from(a[4]) * u64::from(b[4])) >> 32) as u32,
226+
((u64::from(a[5]) * u64::from(b[5])) >> 32) as u32,
227+
((u64::from(a[6]) * u64::from(b[6])) >> 32) as u32,
228+
((u64::from(a[7]) * u64::from(b[7])) >> 32) as u32,
229+
])
224230
}
225231

226-
let best_prior: i32 = pred[if HORIZONTAL {
227-
coefficient_tr >> 3
232+
if !ALL_PRESENT
233+
&& ((HORIZONTAL && !self.is_above_present())
234+
|| (!HORIZONTAL && !self.is_left_present()))
235+
{
236+
(i32x8::ZERO, u32x8::ZERO)
228237
} else {
229-
coefficient_tr
230-
}];
238+
let recip = qt.quantization_table_transposed_recip::<HORIZONTAL>();
231239

232-
let best_prior_abs =
233-
qt.div_quantization_table_transposed_recip(best_prior.unsigned_abs(), coefficient_tr);
240+
let pred_abs = pred.unsigned_abs();
234241

235-
let sign = if best_prior_abs == 0 {
236-
EdgeSign::Zero
237-
} else {
238-
if best_prior > 0 {
239-
EdgeSign::Positive
240-
} else {
241-
EdgeSign::Negative
242-
}
243-
};
244-
(sign, best_prior_abs)
242+
let best_prior_abs: u32x8 = mul_hi(pred_abs, recip) >> 12;
243+
244+
let orig_lt_zero = 1 - pred.cmp_lt(i32x8::ZERO);
245+
let best_prior_is_zero: i32x8 = cast(!best_prior_abs.cmp_eq(u32x8::ZERO));
246+
247+
let best_prior_sign = best_prior_is_zero & orig_lt_zero;
248+
249+
(best_prior_sign, best_prior_abs)
250+
}
245251
}
246252

247253
pub fn adv_predict_dc_pix<const ALL_PRESENT: bool>(

src/structs/quantization_tables.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* This software incorporates material from third parties. See NOTICE.txt for details.
55
*--------------------------------------------------------------------------------------------*/
66

7+
use wide::u32x8;
8+
79
use crate::consts::*;
810
use crate::helpers::*;
911

@@ -13,7 +15,9 @@ pub struct QuantizationTables {
1315
quantization_table: [u16; 64],
1416
quantization_table_transposed: [u16; 64],
1517

16-
quantization_table_transposed_recip: [u32; 64],
18+
quantization_table_transposed_recip_vert: u32x8,
19+
quantization_table_transposed_recip_horiz: u32x8,
20+
1721
// Values for discrimination between "regular" and "noise" part of
1822
// edge AC coefficients, used in `read/write_edge_coefficient`.
1923
// Calculated using approximate maximal magnitudes
@@ -33,7 +37,8 @@ impl QuantizationTables {
3337
quantization_table: [0; 64],
3438
quantization_table_transposed: [0; 64],
3539
min_noise_threshold: [0; 14],
36-
quantization_table_transposed_recip: [0; 64],
40+
quantization_table_transposed_recip_vert: u32x8::default(),
41+
quantization_table_transposed_recip_horiz: u32x8::default(),
3742
};
3843

3944
for pixel_row in 0..8 {
@@ -44,10 +49,18 @@ impl QuantizationTables {
4449

4550
retval.quantization_table[coord] = q;
4651
retval.quantization_table_transposed[coord_tr] = q;
47-
retval.quantization_table_transposed_recip[coord_tr] = QuantizationTables::recip(q);
4852
}
4953
}
5054

55+
for i in 0..8 {
56+
retval
57+
.quantization_table_transposed_recip_horiz
58+
.as_array_mut()[i] = Self::recip(retval.quantization_table[i]);
59+
retval
60+
.quantization_table_transposed_recip_vert
61+
.as_array_mut()[i] = Self::recip(retval.quantization_table_transposed[i]);
62+
}
63+
5164
for i in 0..14 {
5265
let coord = if i < 7 { i + 1 } else { (i - 6) * 8 };
5366
if retval.quantization_table[coord] < 9 {
@@ -78,18 +91,12 @@ impl QuantizationTables {
7891
return retval;
7992
}
8093

81-
pub fn div_quantization_table_transposed_recip(&self, v: u32, index: usize) -> u32 {
82-
// no need to round negative towards zero since this is unsigened division
83-
let result = ((u64::from(v) * u64::from(self.quantization_table_transposed_recip[index]))
84-
>> 31 + 13) as u32;
85-
86-
debug_assert_eq!(
87-
result,
88-
(v / (u32::from(self.quantization_table_transposed[index])) / (1 << 13)),
89-
"right shift"
90-
);
91-
92-
result
94+
pub fn quantization_table_transposed_recip<const HORIZONTAL: bool>(&self) -> u32x8 {
95+
if HORIZONTAL {
96+
self.quantization_table_transposed_recip_horiz
97+
} else {
98+
self.quantization_table_transposed_recip_vert
99+
}
93100
}
94101

95102
pub fn get_quantization_table(&self) -> &[u16; 64] {

0 commit comments

Comments
 (0)