From a0e04f795f255adbd853e64107fff1b532a7a2b6 Mon Sep 17 00:00:00 2001 From: Kristof Date: Sun, 30 Mar 2025 12:23:57 +0200 Subject: [PATCH 01/12] adding ranged math to avoid bounds checks --- src/consts.rs | 33 ++++++++++++++++------ src/jpeg/block_based_image.rs | 4 +-- src/structs/lepton_decoder.rs | 45 +++++++++++++++++------------- src/structs/lepton_encoder.rs | 31 ++++++++++++-------- src/structs/model.rs | 42 ++++++++++------------------ src/structs/partial_buffer.rs | 6 ++-- src/structs/probability_tables.rs | 6 ++-- src/structs/quantization_tables.rs | 2 +- src/structs/vpx_bool_reader.rs | 5 +++- 9 files changed, 99 insertions(+), 75 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index de9a96c8..1ffbdf5a 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -4,6 +4,8 @@ * This software incorporates material from third parties. See NOTICE.txt for details. *--------------------------------------------------------------------------------------------*/ +use deranged::RangedU8; + use crate::jpeg::jpeg_code; #[derive(PartialEq, Debug)] @@ -22,11 +24,26 @@ pub enum JpegType { pub const COLOR_CHANNEL_NUM_BLOCK_TYPES: usize = 3; -pub const RASTER_TO_ZIGZAG: [u8; 64] = [ +/// Convert a slice of u8 into an array of ConstRangedX. Useful for const initialization, eg +/// ```const CONTARRAY : [ConstRangedX<1,10>;5] = ConstRangedX::<1,10>::into_array([1,2,3,4,5]); +/// will panic if any value is out of range +const fn into_array( + a: [u8; N], +) -> [RangedU8; N] { + let mut r = [RangedU8::::MIN; N]; + let mut i = 0; + while i < N { + r[i] = RangedU8::::new(a[i]).unwrap(); + i += 1; + } + r +} + +pub const RASTER_TO_ZIGZAG: [RangedU8<0, 63>; 64] = into_array([ 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63, -]; +]); // pub const ZIGZAG_TO_RASTER: [u8; 64] = [ // 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, @@ -34,11 +51,11 @@ pub const RASTER_TO_ZIGZAG: [u8; 64] = [ // 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, // ]; -pub const ZIGZAG_TO_TRANSPOSED: [u8; 64] = [ +pub const ZIGZAG_TO_TRANSPOSED: [RangedU8<0, 63>; 64] = into_array([ 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63, -]; +]); // pub const UNZIGZAG_49: [u8; 49] = [ // 9, 10, 17, 25, 18, 11, 12, 19, 26, 33, 41, 34, 27, 20, 13, 14, 21, 28, 35, 42, 49, 57, 50, 43, @@ -46,11 +63,11 @@ pub const ZIGZAG_TO_TRANSPOSED: [u8; 64] = [ // 63, // ]; -pub const UNZIGZAG_49_TR: [u8; 49] = [ +pub const UNZIGZAG_49_TR: [RangedU8<9, 63>; 49] = into_array([ 9, 17, 10, 11, 18, 25, 33, 26, 19, 12, 13, 20, 27, 34, 41, 49, 42, 35, 28, 21, 14, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63, -]; +]); // precalculated int base values for 8x8 IDCT scaled by 8192 // DC coef is zeroed intentionally @@ -69,10 +86,10 @@ pub const NON_ZERO_TO_BIN: [u8; 26] = [ ]; // used to get prediction branches basing on current `num_non_zeros_left_7x7`, 0th element is not used -pub const NON_ZERO_TO_BIN_7X7: [u8; 50] = [ +pub const NON_ZERO_TO_BIN_7X7: [RangedU8<0, 8>; 50] = into_array([ 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -]; +]); //pub const MAX_FILE_SIZE_BYTES : i32 = 128 * 1024 * 1024; pub const MAX_THREADS: usize = 8; diff --git a/src/jpeg/block_based_image.rs b/src/jpeg/block_based_image.rs index c9cc156b..98d47583 100644 --- a/src/jpeg/block_based_image.rs +++ b/src/jpeg/block_based_image.rs @@ -306,12 +306,12 @@ impl AlignedBlock { #[inline(always)] pub fn set_transposed_from_zigzag(&mut self, index: usize, v: i16) { - self.raw_data[usize::from(ZIGZAG_TO_TRANSPOSED[index])] = v; + self.raw_data[usize::from(ZIGZAG_TO_TRANSPOSED[index].get())] = v; } #[inline(always)] pub fn get_transposed_from_zigzag(&self, index: usize) -> i16 { - return self.raw_data[usize::from(ZIGZAG_TO_TRANSPOSED[index])]; + return self.raw_data[usize::from(ZIGZAG_TO_TRANSPOSED[index].get())]; } #[inline(always)] diff --git a/src/structs/lepton_decoder.rs b/src/structs/lepton_decoder.rs index 90523387..b630faca 100644 --- a/src/structs/lepton_decoder.rs +++ b/src/structs/lepton_decoder.rs @@ -9,6 +9,7 @@ use std::io::Read; use bytemuck::cast_mut; use default_boxed::DefaultBoxed; +use deranged::RangedU32; use wide::i32x8; use crate::consts::UNZIGZAG_49_TR; @@ -259,9 +260,8 @@ pub fn read_coefficient_block( let mut eob_x: u32 = 0; let mut eob_y: u32 = 0; - let mut num_non_zeros_7x7_remaining = num_non_zeros_7x7 as usize; - - if num_non_zeros_7x7_remaining > 0 { + if let Some(mut num_non_zeros_7x7_remaining) = RangedU32::<1, 49>::new(num_non_zeros_7x7 as u32) + { let best_priors = pt.calc_coefficient_context_7x7_aavg_block::( neighbor_data.left, neighbor_data.above, @@ -273,33 +273,36 @@ pub fn read_coefficient_block( ProbabilityTables::num_non_zeros_to_bin_7x7(num_non_zeros_7x7_remaining); // now loop through the coefficients in zigzag, terminating once we hit the number of non-zeros - for (zig49, &coord_tr) in UNZIGZAG_49_TR.iter().enumerate() { - let best_prior_bit_length = u16_bit_length(best_priors[coord_tr as usize]); + let mut zig49 = RangedU32::<0, 48>::MIN; + loop { + let coord_tr = UNZIGZAG_49_TR[zig49.get() as usize]; + let best_prior_bit_length = u16_bit_length(best_priors[coord_tr.get() as usize]); let coef = model_per_color.read_coef( bool_reader, zig49, num_non_zeros_bin, - best_prior_bit_length as usize, + RangedU32::<0, 11>::new(best_prior_bit_length.into()).unwrap(), )?; if coef != 0 { // here we calculate the furthest x and y coordinates that have non-zero coefficients // which is later used as a predictor for the number of edge coefficients - let by = u32::from(coord_tr) & 7; - let bx = u32::from(coord_tr) >> 3; + let by = u32::from(coord_tr.get()) & 7; + let bx = u32::from(coord_tr.get()) >> 3; debug_assert!(bx > 0 && by > 0, "this does the DC and the lower 7x7 AC"); eob_x = cmp::max(eob_x, bx); eob_y = cmp::max(eob_y, by); - output.set_coefficient(coord_tr as usize, coef); - raster_col[coord_tr as usize] = i32::from(coef) - * i32::from(qt.get_quantization_table_transposed()[coord_tr as usize]); + output.set_coefficient(coord_tr.get() as usize, coef); + raster_col[coord_tr.get() as usize] = i32::from(coef) + * i32::from(qt.get_quantization_table_transposed()[coord_tr.get() as usize]); - num_non_zeros_7x7_remaining -= 1; - if num_non_zeros_7x7_remaining == 0 { + if let Some(r) = num_non_zeros_7x7_remaining.checked_sub(1) { + num_non_zeros_7x7_remaining = r; + } else { break; } @@ -307,14 +310,16 @@ pub fn read_coefficient_block( num_non_zeros_bin = ProbabilityTables::num_non_zeros_to_bin_7x7(num_non_zeros_7x7_remaining); } - } - } - if num_non_zeros_7x7_remaining > 0 { - return err_exit_code( - ExitCode::StreamInconsistent, - "not enough nonzeros in 7x7 block", - ); + if let Some(r) = zig49.checked_add(1) { + zig49 = r; + } else { + return err_exit_code( + ExitCode::StreamInconsistent, + "not enough nonzeros in 7x7 block", + ); + } + } } // step 2, read the edge coefficients diff --git a/src/structs/lepton_encoder.rs b/src/structs/lepton_encoder.rs index 3350cd8a..9893be23 100644 --- a/src/structs/lepton_encoder.rs +++ b/src/structs/lepton_encoder.rs @@ -9,6 +9,7 @@ use std::io::Write; use bytemuck::cast; use default_boxed::DefaultBoxed; +use deranged::RangedU32; use wide::i32x8; use crate::consts::UNZIGZAG_49_TR; @@ -290,9 +291,8 @@ pub fn write_coefficient_block( let mut eob_x: u32 = 0; let mut eob_y: u32 = 0; - let mut num_non_zeros_7x7_remaining = num_non_zeros_7x7 as usize; - - if num_non_zeros_7x7_remaining > 0 { + if let Some(mut num_non_zeros_7x7_remaining) = RangedU32::<1, 49>::new(num_non_zeros_7x7 as u32) + { let best_priors = pt.calc_coefficient_context_7x7_aavg_block::( neighbors_data.left, neighbors_data.above, @@ -303,10 +303,12 @@ pub fn write_coefficient_block( ProbabilityTables::num_non_zeros_to_bin_7x7(num_non_zeros_7x7_remaining); // now loop through the coefficients in zigzag, terminating once we hit the number of non-zeros - for (zig49, &coord_tr) in UNZIGZAG_49_TR.iter().enumerate() { - let best_prior_bit_length = u16_bit_length(best_priors[coord_tr as usize]); + let mut zig49 = RangedU32::<0, 48>::MIN; + loop { + let coord_tr = UNZIGZAG_49_TR[zig49.get() as usize]; + let best_prior_bit_length = u16_bit_length(best_priors[coord_tr.get() as usize]); - let coef = here_tr.get_coefficient(coord_tr as usize); + let coef = here_tr.get_coefficient(coord_tr.get() as usize); model_per_color .write_coef( @@ -314,23 +316,24 @@ pub fn write_coefficient_block( coef, zig49, num_non_zeros_remaining_bin, - best_prior_bit_length as usize, + RangedU32::<0, 11>::new(best_prior_bit_length.into()).unwrap(), ) .context()?; if coef != 0 { // here we calculate the furthest x and y coordinates that have non-zero coefficients // which is later used as a predictor for the number of edge coefficients - let by = u32::from(coord_tr) & 7; - let bx = u32::from(coord_tr) >> 3; + let by = u32::from(coord_tr.get()) & 7; + let bx = u32::from(coord_tr.get()) >> 3; debug_assert!(bx > 0 && by > 0, "this does the DC and the lower 7x7 AC"); eob_x = cmp::max(eob_x, bx); eob_y = cmp::max(eob_y, by); - num_non_zeros_7x7_remaining -= 1; - if num_non_zeros_7x7_remaining == 0 { + if let Some(r) = num_non_zeros_7x7_remaining.checked_sub(1) { + num_non_zeros_7x7_remaining = r; + } else { break; } @@ -338,6 +341,12 @@ pub fn write_coefficient_block( num_non_zeros_remaining_bin = ProbabilityTables::num_non_zeros_to_bin_7x7(num_non_zeros_7x7_remaining); } + + if let Some(r) = zig49.checked_add(1) { + zig49 = r; + } else { + break; + } } } diff --git a/src/structs/model.rs b/src/structs/model.rs index 5100e97b..68a6f4a3 100644 --- a/src/structs/model.rs +++ b/src/structs/model.rs @@ -8,6 +8,7 @@ use std::cmp; use std::io::{Read, Write}; use default_boxed::DefaultBoxed; +use deranged::{RangedU32, RangedU8}; use crate::consts::*; use crate::helpers::{calc_sign_index, u16_bit_length, u32_bit_length}; @@ -33,7 +34,7 @@ const NUM_NON_ZERO_EDGE_BINS: usize = 7; type NumNonZerosCountsT = [[[Branch; 1 << NON_ZERO_EDGE_COUNT_BITS]; 8]; 8]; const RESIDUAL_THRESHOLD_COUNTS_D1: usize = 1 << (1 + RESIDUAL_NOISE_FLOOR); -// The array was used only on indices [2,7] of [0,7] +// The array was used only on iBndices [2,7] of [0,7] const RESIDUAL_THRESHOLD_COUNTS_D2: usize = 1 + RESIDUAL_NOISE_FLOOR - 2; const RESIDUAL_THRESHOLD_COUNTS_D3: usize = 1 << RESIDUAL_NOISE_FLOOR; @@ -187,9 +188,9 @@ impl ModelPerColor { pub fn read_coef( &mut self, bool_reader: &mut VPXBoolReader, - zig49: usize, - num_non_zeros_bin: usize, - best_prior_bit_len: usize, + zig49: RangedU32<0, 48>, + num_non_zeros_bin: RangedU8<0, 8>, + best_prior_bit_len: RangedU32<0, 11>, ) -> std::io::Result { let (exp, sign, bits) = self.get_coef_branches(num_non_zeros_bin, zig49, best_prior_bit_len); @@ -210,9 +211,9 @@ impl ModelPerColor { &mut self, bool_writer: &mut VPXBoolWriter, coef: i16, - zig49: usize, - num_non_zeros_bin: usize, - best_prior_bit_len: usize, + zig49: RangedU32<0, 48>, + num_non_zeros_bin: RangedU8<0, 8>, + best_prior_bit_len: RangedU32<0, 11>, ) -> Result<()> { let (exp, sign, bits) = self.get_coef_branches(num_non_zeros_bin, zig49, best_prior_bit_len); @@ -233,32 +234,19 @@ impl ModelPerColor { #[inline(always)] fn get_coef_branches( &mut self, - num_non_zeros_bin: usize, - zig49: usize, - best_prior_bit_len: usize, + num_non_zeros_bin: RangedU8<0, 8>, + zig49: RangedU32<0, 48>, + best_prior_bit_len: RangedU32<0, 11>, ) -> ( &mut [Branch; MAX_EXPONENT], &mut Branch, &mut [Branch; COEF_BITS], ) { - // these bounds checks happen anyway, but we can provide more helpful error messages - // and it also means that the compiler can move the actual array references around - // if it helps with performance - assert!( - num_non_zeros_bin < NUM_NON_ZERO_7X7_BINS, - "num_non_zeros_bin {0} too high", - num_non_zeros_bin - ); - assert!(zig49 < 49, "zig49 {0} too high", num_non_zeros_bin); - assert!( - best_prior_bit_len < NUMERIC_LENGTH_MAX, - "best_prior_bit_len {0} too high", - best_prior_bit_len - ); - - let exp = &mut self.counts[num_non_zeros_bin][zig49].exponent_counts[best_prior_bit_len]; + let exp = &mut self.counts[num_non_zeros_bin.get() as usize][zig49.get() as usize] + .exponent_counts[best_prior_bit_len.get() as usize]; let sign = &mut self.sign_counts[0][0]; - let bits = &mut self.counts[num_non_zeros_bin][zig49].residual_noise_counts; + let bits = &mut self.counts[num_non_zeros_bin.get() as usize][zig49.get() as usize] + .residual_noise_counts; (exp, sign, bits) } diff --git a/src/structs/partial_buffer.rs b/src/structs/partial_buffer.rs index 5192ce18..e9773ad7 100644 --- a/src/structs/partial_buffer.rs +++ b/src/structs/partial_buffer.rs @@ -108,12 +108,12 @@ impl<'a> PartialBuffer<'a> { #[test] fn test_taking_simple() { - let mut extra = Vec::new(); + let mut extra: Vec = Vec::new(); let mut pb = PartialBuffer::new(&[1, 2, 3, 4], &mut extra); let taken = pb.take(4, 0).unwrap(); assert_eq!(taken, vec![1, 2, 3, 4]); - assert_eq!(&extra[..], []); + assert!(extra.is_empty()); } #[test] @@ -123,7 +123,7 @@ fn test_taking_simple_n() { let taken = pb.take_n::<4>(0).unwrap(); assert_eq!(taken, [1, 2, 3, 4]); - assert_eq!(&extra[..], []); + assert!(extra.is_empty()); } #[test] diff --git a/src/structs/probability_tables.rs b/src/structs/probability_tables.rs index 30403aef..3fcf31e7 100644 --- a/src/structs/probability_tables.rs +++ b/src/structs/probability_tables.rs @@ -5,6 +5,8 @@ *--------------------------------------------------------------------------------------------*/ use bytemuck::cast; +use deranged::RangedU32; +use deranged::RangedU8; use wide::{i16x8, i32x8, u16x8}; use crate::consts::*; @@ -81,8 +83,8 @@ impl ProbabilityTables { } #[inline(always)] - pub fn num_non_zeros_to_bin_7x7(num_non_zeros: usize) -> usize { - return usize::from(NON_ZERO_TO_BIN_7X7[num_non_zeros]); + pub fn num_non_zeros_to_bin_7x7(num_non_zeros: RangedU32<1, 49>) -> RangedU8<0, 8> { + return NON_ZERO_TO_BIN_7X7[num_non_zeros.get() as usize]; } pub fn calc_num_non_zeros_7x7_context_bin( diff --git a/src/structs/quantization_tables.rs b/src/structs/quantization_tables.rs index 12ffaed8..7673c6a8 100644 --- a/src/structs/quantization_tables.rs +++ b/src/structs/quantization_tables.rs @@ -38,7 +38,7 @@ impl QuantizationTables { for pixel_column in 0..8 { let coord = (pixel_row * 8) + pixel_column; let coord_tr = (pixel_column * 8) + pixel_row; - let q = quantization_table[RASTER_TO_ZIGZAG[coord] as usize]; + let q = quantization_table[RASTER_TO_ZIGZAG[coord].get() as usize]; retval.quantization_table[coord] = q; retval.quantization_table_transposed[coord_tr] = q; diff --git a/src/structs/vpx_bool_reader.rs b/src/structs/vpx_bool_reader.rs index d2aff365..d6c54286 100644 --- a/src/structs/vpx_bool_reader.rs +++ b/src/structs/vpx_bool_reader.rs @@ -57,7 +57,10 @@ impl VPXBoolReader { let mut dummy_branch = Branch::new(); let bit = r.get_bit(&mut dummy_branch, ModelComponent::Dummy)?; // marker false bit if bit { - return err_exit_code(ExitCode::StreamInconsistent, "StreamInconsistent"); + return err_exit_code( + ExitCode::StreamInconsistent, + "Couldnt read marker bit StreamInconsistent", + ); } return Ok(r); From d5d34efd84cb78d7249f7c505d42f662c7490e45 Mon Sep 17 00:00:00 2001 From: Kristof Date: Sun, 30 Mar 2025 14:28:00 +0200 Subject: [PATCH 02/12] work --- src/consts.rs | 4 +- src/structs/lepton_decoder.rs | 82 +++++++++++++++++-------------- src/structs/lepton_encoder.rs | 6 +-- src/structs/model.rs | 62 +++++++++-------------- src/structs/probability_tables.rs | 2 +- 5 files changed, 74 insertions(+), 82 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 1ffbdf5a..8a21730c 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -81,9 +81,9 @@ pub const FREQ_MAX: [u16; 14] = [ ]; // used to get prediction branches basing on nonzero-number predictor `num_non_zeros_context` -pub const NON_ZERO_TO_BIN: [u8; 26] = [ +pub const NON_ZERO_TO_BIN: [RangedU8<0, 8>; 26] = into_array([ 0, 1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, -]; +]); // used to get prediction branches basing on current `num_non_zeros_left_7x7`, 0th element is not used pub const NON_ZERO_TO_BIN_7X7: [RangedU8<0, 8>; 50] = into_array([ diff --git a/src/structs/lepton_decoder.rs b/src/structs/lepton_decoder.rs index b630faca..6efdb9f1 100644 --- a/src/structs/lepton_decoder.rs +++ b/src/structs/lepton_decoder.rs @@ -9,7 +9,7 @@ use std::io::Read; use bytemuck::cast_mut; use default_boxed::DefaultBoxed; -use deranged::RangedU32; +use deranged::{RangedU32, RangedU8}; use wide::i32x8; use crate::consts::UNZIGZAG_49_TR; @@ -427,52 +427,60 @@ fn decode_one_edge( est_eob: u8, raster: &mut [i32; 64], ) -> Result<()> { - let mut num_non_zeros_edge = model_per_color + let num_non_zeros_edge = model_per_color .read_non_zero_edge_count::(bool_reader, est_eob, num_non_zeros_bin) .context()?; - let delta; - let mut zig15offset; - - if HORIZONTAL { - delta = 8; - zig15offset = 0; - } else { - delta = 1; - zig15offset = 7; + if num_non_zeros_edge == 0 { + return Ok(()); } - let mut coord_tr = delta; + if let Some(mut num_non_zeros_edge) = RangedU8::<1, 7>::new(num_non_zeros_edge) { + let delta; + let mut zig15offset; - for _lane in 0..7 { - if num_non_zeros_edge == 0 { - break; + if HORIZONTAL { + delta = 8; + zig15offset = 0; + } else { + delta = 1; + zig15offset = 7; } - let best_prior = - pt.calc_coefficient_context8_lak::(qt, coord_tr, pred); - - let coef = model_per_color.read_edge_coefficient( - bool_reader, - qt, - zig15offset, - num_non_zeros_edge, - best_prior, - )?; - - if coef != 0 { - num_non_zeros_edge -= 1; - here_mut.set_coefficient(coord_tr, coef); - raster[coord_tr] = - i32::from(coef) * i32::from(qt.get_quantization_table_transposed()[coord_tr]); - } + let mut coord_tr = delta; - coord_tr += delta; - zig15offset += 1; - } + for _lane in 0..7 { + let best_prior = + pt.calc_coefficient_context8_lak::(qt, coord_tr, pred); + + let coef = model_per_color.read_edge_coefficient( + bool_reader, + qt, + RangedU32::<0, 13>::new(zig15offset).unwrap(), + num_non_zeros_edge, + best_prior, + )?; - if num_non_zeros_edge != 0 { - return err_exit_code(ExitCode::StreamInconsistent, "StreamInconsistent"); + if coef != 0 { + here_mut.set_coefficient(coord_tr, coef); + raster[coord_tr] = + i32::from(coef) * i32::from(qt.get_quantization_table_transposed()[coord_tr]); + + if let Some(r) = num_non_zeros_edge.checked_sub(1) { + num_non_zeros_edge = r; + } else { + break; + } + } + + coord_tr += delta; + zig15offset += 1; + } + } else { + return err_exit_code( + ExitCode::StreamInconsistent, + "num_non_zeros_edge is too big", + ); } Ok(()) diff --git a/src/structs/lepton_encoder.rs b/src/structs/lepton_encoder.rs index 9893be23..e7244e23 100644 --- a/src/structs/lepton_encoder.rs +++ b/src/structs/lepton_encoder.rs @@ -9,7 +9,7 @@ use std::io::Write; use bytemuck::cast; use default_boxed::DefaultBoxed; -use deranged::RangedU32; +use deranged::{RangedU32, RangedU8}; use wide::i32x8; use crate::consts::UNZIGZAG_49_TR; @@ -542,8 +542,8 @@ fn encode_one_edge( bool_writer, qt, coef, - zig15offset, - num_non_zeros_edge, + RangedU32::new(zig15offset).unwrap(), + RangedU8::new(num_non_zeros_edge).unwrap(), best_prior, ) .context()?; diff --git a/src/structs/model.rs b/src/structs/model.rs index 68a6f4a3..d3e1173b 100644 --- a/src/structs/model.rs +++ b/src/structs/model.rs @@ -147,7 +147,7 @@ impl Model { pub struct ModelPerColor { // `num_non_zeros_context` cannot exceed 25, see `calc_non_zero_counts_context_7x7` num_non_zeros_counts7x7: - [[Branch; 1 << NON_ZERO_7X7_COUNT_BITS]; 1 + NON_ZERO_TO_BIN[25] as usize], + [[Branch; 1 << NON_ZERO_7X7_COUNT_BITS]; 1 + NON_ZERO_TO_BIN[25].get() as usize], counts: [[Counts7x7; 49]; NUM_NON_ZERO_7X7_BINS], @@ -254,11 +254,11 @@ impl ModelPerColor { pub fn write_non_zero_7x7_count( &mut self, bool_writer: &mut VPXBoolWriter, - num_non_zeros_7x7_context_bin: u8, + num_non_zeros_7x7_context_bin: RangedU8<0, 8>, num_non_zeros_7x7: u8, ) -> Result<()> { let num_non_zeros_prob = - &mut self.num_non_zeros_counts7x7[usize::from(num_non_zeros_7x7_context_bin)]; + &mut self.num_non_zeros_counts7x7[usize::from(num_non_zeros_7x7_context_bin.get())]; return bool_writer .put_grid( @@ -291,10 +291,10 @@ impl ModelPerColor { pub fn read_non_zero_7x7_count( &mut self, bool_reader: &mut VPXBoolReader, - num_non_zeros_7x7_context_bin: u8, + num_non_zeros_7x7_context_bin: RangedU8<0, 8>, ) -> Result { let num_non_zeros_prob = - &mut self.num_non_zeros_counts7x7[usize::from(num_non_zeros_7x7_context_bin)]; + &mut self.num_non_zeros_counts7x7[usize::from(num_non_zeros_7x7_context_bin.get())]; return Ok(bool_reader .get_grid(num_non_zeros_prob, ModelComponent::NonZero7x7Count) @@ -319,28 +319,17 @@ impl ModelPerColor { &mut self, bool_reader: &mut VPXBoolReader, qt: &QuantizationTables, - zig15offset: usize, - num_non_zeros_edge: u8, + zig15offset: RangedU32<0, 13>, + num_non_zeros_edge: RangedU8<1, 7>, best_prior: i32, ) -> Result { - let num_non_zeros_edge_bin = usize::from(num_non_zeros_edge) - 1; - - // bounds checks will test these anyway, so check here for better - // error messages and also gives the optimizer more freedom to move code around - assert!( - num_non_zeros_edge_bin < NUM_NON_ZERO_EDGE_BINS, - "num_non_zeros_edge_bin {0} too high", - num_non_zeros_edge_bin - ); - - assert!(zig15offset < 14, "zig15offset {0} too high", zig15offset); - // we cap the bit length since the prior prediction can be wonky let best_prior_abs = best_prior.unsigned_abs(); let best_prior_bit_len = cmp::min(MAX_EXPONENT - 1, u32_bit_length(best_prior_abs) as usize); - let length_branches = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset] + let length_branches = &mut self.counts_x[num_non_zeros_edge.get() as usize - 1] + [zig15offset.get() as usize] .exponent_counts[best_prior_bit_len]; let length = bool_reader @@ -364,7 +353,9 @@ impl ModelPerColor { coef = 1; if length > 1 { - let min_threshold: i32 = qt.get_min_noise_threshold(zig15offset).into(); + let min_threshold: i32 = qt + .get_min_noise_threshold(zig15offset.get() as usize) + .into(); let mut i: i32 = length - 2; if i >= min_threshold { @@ -393,7 +384,8 @@ impl ModelPerColor { } if i >= 0 { - let res_prob = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset] + let res_prob = &mut self.counts_x[num_non_zeros_edge.get() as usize - 1] + [zig15offset.get() as usize] .residual_noise_counts; coef <<= i + 1; @@ -417,21 +409,11 @@ impl ModelPerColor { bool_writer: &mut VPXBoolWriter, qt: &QuantizationTables, coef: i16, - zig15offset: usize, - num_non_zeros_edge: u8, + zig15offset: RangedU32<0, 13>, + num_non_zeros_edge: RangedU8<1, 7>, best_prior: i32, ) -> Result<()> { - let num_non_zeros_edge_bin = usize::from(num_non_zeros_edge) - 1; - - // bounds checks will test these anyway, so check here for better - // error messages and also gives the optimizer more freedom to move code around - assert!( - num_non_zeros_edge_bin < NUM_NON_ZERO_EDGE_BINS, - "num_non_zeros_edge_bin {0} too high", - num_non_zeros_edge_bin - ); - - assert!(zig15offset < 14, "zig15offset {0} too high", zig15offset); + let num_non_zeros_edge_bin = usize::from(num_non_zeros_edge.get()) - 1; // we cap the bit length since the prior prediction can be wonky let best_prior_abs = best_prior.unsigned_abs(); @@ -441,8 +423,8 @@ impl ModelPerColor { let abs_coef = coef.unsigned_abs(); let length = u16_bit_length(abs_coef) as usize; - let exp_array = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset].exponent_counts - [best_prior_bit_len]; + let exp_array = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset.get() as usize] + .exponent_counts[best_prior_bit_len]; if length > MAX_EXPONENT { return err_exit_code(ExitCode::CoefficientOutOfRange, "CoefficientOutOfRange"); @@ -467,7 +449,8 @@ impl ModelPerColor { )?; if length > 1 { - let min_threshold = i32::from(qt.get_min_noise_threshold(zig15offset)); + let min_threshold = + i32::from(qt.get_min_noise_threshold(zig15offset.get() as usize)); let mut i: i32 = length as i32 - 2; if i >= min_threshold { @@ -500,7 +483,8 @@ impl ModelPerColor { } if i >= 0 { - let res_prob = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset] + let res_prob = &mut self.counts_x[num_non_zeros_edge_bin] + [zig15offset.get() as usize] .residual_noise_counts; bool_writer diff --git a/src/structs/probability_tables.rs b/src/structs/probability_tables.rs index 3fcf31e7..e94e5eef 100644 --- a/src/structs/probability_tables.rs +++ b/src/structs/probability_tables.rs @@ -90,7 +90,7 @@ impl ProbabilityTables { pub fn calc_num_non_zeros_7x7_context_bin( &self, neighbor_data: &NeighborData, - ) -> u8 { + ) -> RangedU8<0, 8> { let mut num_non_zeros_above = 0; let mut num_non_zeros_left = 0; if ALL_PRESENT || self.above_present { From 19dfe4e6efb0f55fe739ea76fa33099ffc3934fe Mon Sep 17 00:00:00 2001 From: Kristof Date: Thu, 10 Apr 2025 13:59:13 +0200 Subject: [PATCH 03/12] added cargo --- Cargo.lock | 9 ++++++++- Cargo.toml | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 85095bc7..8befde68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,6 +130,12 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" + [[package]] name = "equivalent" version = "1.0.1" @@ -314,6 +320,7 @@ dependencies = [ "byteorder", "cpu-time", "default-boxed", + "deranged 0.4.0", "flate2", "git-version", "log", @@ -655,7 +662,7 @@ version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ - "deranged", + "deranged 0.3.11", "itoa", "libc", "num-conv", diff --git a/Cargo.toml b/Cargo.toml index 2682fe34..a44e34b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ unroll = "0.1" rayon-core = { version = "1", optional = true } git-version = "0.3" pico-args = "0.5" +deranged = "0.4" [target.'cfg(target_os = "windows")'.dependencies] cpu-time = "1.0" From c9103d0f08b196da2cbfe9dfadfd19147c60b76b Mon Sep 17 00:00:00 2001 From: Kristof Date: Thu, 10 Apr 2025 14:14:41 +0200 Subject: [PATCH 04/12] undo partial buffer change --- src/structs/partial_buffer.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/structs/partial_buffer.rs b/src/structs/partial_buffer.rs index e9773ad7..5192ce18 100644 --- a/src/structs/partial_buffer.rs +++ b/src/structs/partial_buffer.rs @@ -108,12 +108,12 @@ impl<'a> PartialBuffer<'a> { #[test] fn test_taking_simple() { - let mut extra: Vec = Vec::new(); + let mut extra = Vec::new(); let mut pb = PartialBuffer::new(&[1, 2, 3, 4], &mut extra); let taken = pb.take(4, 0).unwrap(); assert_eq!(taken, vec![1, 2, 3, 4]); - assert!(extra.is_empty()); + assert_eq!(&extra[..], []); } #[test] @@ -123,7 +123,7 @@ fn test_taking_simple_n() { let taken = pb.take_n::<4>(0).unwrap(); assert_eq!(taken, [1, 2, 3, 4]); - assert!(extra.is_empty()); + assert_eq!(&extra[..], []); } #[test] From 644b23074548cf21129c2d35d4cac4519132b870 Mon Sep 17 00:00:00 2001 From: Kristof Date: Thu, 10 Apr 2025 14:20:12 +0200 Subject: [PATCH 05/12] work --- src/structs/lepton_decoder.rs | 4 ++-- src/structs/lepton_encoder.rs | 4 ++-- src/structs/model.rs | 12 +++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/structs/lepton_decoder.rs b/src/structs/lepton_decoder.rs index 6efdb9f1..b92d622b 100644 --- a/src/structs/lepton_decoder.rs +++ b/src/structs/lepton_decoder.rs @@ -381,7 +381,7 @@ fn decode_edge( eob_x: u8, eob_y: u8, ) -> Result<(i32x8, i32x8)> { - let num_non_zeros_bin = (num_non_zeros_7x7 + 3) / 7; + let num_non_zeros_bin = RangedU8::new((num_non_zeros_7x7 + 3) / 7).unwrap(); // get predictors for edge coefficients of the current block let (curr_horiz_pred, curr_vert_pred) = @@ -423,7 +423,7 @@ fn decode_one_edge( here_mut: &mut AlignedBlock, qt: &QuantizationTables, pt: &ProbabilityTables, - num_non_zeros_bin: u8, + num_non_zeros_bin: RangedU8<0, 7>, est_eob: u8, raster: &mut [i32; 64], ) -> Result<()> { diff --git a/src/structs/lepton_encoder.rs b/src/structs/lepton_encoder.rs index e7244e23..26311b80 100644 --- a/src/structs/lepton_encoder.rs +++ b/src/structs/lepton_encoder.rs @@ -435,7 +435,7 @@ fn encode_edge( let (curr_horiz_pred, curr_vert_pred) = ProbabilityTables::predict_current_edges(neighbors_data, &raster); - let num_non_zeros_bin = (num_non_zeros_7x7 + 3) / 7; + let num_non_zeros_bin = RangedU8::new((num_non_zeros_7x7 + 3) / 7).unwrap(); encode_one_edge::( here_tr, @@ -482,7 +482,7 @@ fn encode_one_edge( pred: &[i32; 8], qt: &QuantizationTables, pt: &ProbabilityTables, - num_non_zeros_bin: u8, + num_non_zeros_bin: RangedU8<0, 7>, est_eob: u8, ) -> Result<()> { let mut num_non_zeros_edge; diff --git a/src/structs/model.rs b/src/structs/model.rs index d3e1173b..18388a48 100644 --- a/src/structs/model.rs +++ b/src/structs/model.rs @@ -273,7 +273,7 @@ impl ModelPerColor { &mut self, bool_writer: &mut VPXBoolWriter, est_eob: u8, - num_non_zeros_bin: u8, + num_non_zeros_bin: RangedU8<0, 7>, num_non_zeros_edge: u8, ) -> Result<()> { let prob_edge_eob = @@ -305,7 +305,7 @@ impl ModelPerColor { &mut self, bool_reader: &mut VPXBoolReader, est_eob: u8, - num_non_zeros_bin: u8, + num_non_zeros_bin: RangedU8<0, 7>, ) -> Result { let prob_edge_eob = self.get_non_zero_counts_edge_mut::(est_eob, num_non_zeros_bin); @@ -527,12 +527,14 @@ impl ModelPerColor { fn get_non_zero_counts_edge_mut( &mut self, est_eob: u8, - num_nonzeros_bin: u8, + num_nonzeros_bin: RangedU8<0, 7>, ) -> &mut [Branch; 8] { if HORIZONTAL { - return &mut self.num_non_zeros_counts8x1[est_eob as usize][num_nonzeros_bin as usize]; + return &mut self.num_non_zeros_counts8x1[est_eob as usize] + [num_nonzeros_bin.get() as usize]; } else { - return &mut self.num_non_zeros_counts1x8[est_eob as usize][num_nonzeros_bin as usize]; + return &mut self.num_non_zeros_counts1x8[est_eob as usize] + [num_nonzeros_bin.get() as usize]; } } } From 9a83b3064f98765bf34da2b28475857d3b4b543c Mon Sep 17 00:00:00 2001 From: Kristof Date: Thu, 10 Apr 2025 14:28:17 +0200 Subject: [PATCH 06/12] work --- src/consts.rs | 2 +- src/structs/lepton_encoder.rs | 48 ++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 6680956c..e620c4d0 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -25,7 +25,7 @@ pub enum JpegType { pub const COLOR_CHANNEL_NUM_BLOCK_TYPES: usize = 3; /// Convert a slice of u8 into an array of ConstRangedX. Useful for const initialization, eg -/// ```const CONTARRAY : [ConstRangedX<1,10>;5] = ConstRangedX::<1,10>::into_array([1,2,3,4,5]); +/// const CONTARRAY : [ConstRangedX<1,10>;5] = ConstRangedX::<1,10>::into_array([1,2,3,4,5]); /// will panic if any value is out of range const fn into_array( a: [u8; N], diff --git a/src/structs/lepton_encoder.rs b/src/structs/lepton_encoder.rs index 26311b80..42a50403 100644 --- a/src/structs/lepton_encoder.rs +++ b/src/structs/lepton_encoder.rs @@ -485,7 +485,7 @@ fn encode_one_edge( num_non_zeros_bin: RangedU8<0, 7>, est_eob: u8, ) -> Result<()> { - let mut num_non_zeros_edge; + let num_non_zeros_edge; if !HORIZONTAL { num_non_zeros_edge = count_non_zero(block.get_coefficient(1)) @@ -527,33 +527,35 @@ fn encode_one_edge( let mut coord_tr = delta; - for _lane in 0..7 { - if num_non_zeros_edge == 0 { - break; - } + if let Some(mut n) = RangedU8::<1, 7>::new(num_non_zeros_edge) { + for _lane in 0..7 { + let best_prior = + pt.calc_coefficient_context8_lak::(qt, coord_tr, pred); - let best_prior = - pt.calc_coefficient_context8_lak::(qt, coord_tr, pred); + let coef = block.get_coefficient(coord_tr); - let coef = block.get_coefficient(coord_tr); + model_per_color + .write_edge_coefficient( + bool_writer, + qt, + coef, + RangedU32::new(zig15offset).unwrap(), + n, + best_prior, + ) + .context()?; - model_per_color - .write_edge_coefficient( - bool_writer, - qt, - coef, - RangedU32::new(zig15offset).unwrap(), - RangedU8::new(num_non_zeros_edge).unwrap(), - best_prior, - ) - .context()?; + if coef != 0 { + if let Some(r) = n.checked_sub(1) { + n = r; + } else { + break; + } + } - if coef != 0 { - num_non_zeros_edge -= 1; + coord_tr += delta; + zig15offset += 1; } - - coord_tr += delta; - zig15offset += 1; } Ok(()) From dadb6e64e3d5ee3e73d377810ad6309f0f2aa525 Mon Sep 17 00:00:00 2001 From: Kristof Date: Wed, 28 May 2025 19:33:37 +0200 Subject: [PATCH 07/12] work --- lib/src/structs/model.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/structs/model.rs b/lib/src/structs/model.rs index 18388a48..04660c5d 100644 --- a/lib/src/structs/model.rs +++ b/lib/src/structs/model.rs @@ -34,7 +34,7 @@ const NUM_NON_ZERO_EDGE_BINS: usize = 7; type NumNonZerosCountsT = [[[Branch; 1 << NON_ZERO_EDGE_COUNT_BITS]; 8]; 8]; const RESIDUAL_THRESHOLD_COUNTS_D1: usize = 1 << (1 + RESIDUAL_NOISE_FLOOR); -// The array was used only on iBndices [2,7] of [0,7] +// The array was used only on indices [2,7] of [0,7] const RESIDUAL_THRESHOLD_COUNTS_D2: usize = 1 + RESIDUAL_NOISE_FLOOR - 2; const RESIDUAL_THRESHOLD_COUNTS_D3: usize = 1 << RESIDUAL_NOISE_FLOOR; From e980da891b0f85656d66c32258445c102e28575e Mon Sep 17 00:00:00 2001 From: Kristof Date: Wed, 28 May 2025 19:41:18 +0200 Subject: [PATCH 08/12] update lock --- Cargo.lock | 2 +- lib/Cargo.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 03ebe57e..62ea9590 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 780809cf..2ac207df 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -29,6 +29,7 @@ default-boxed = "0.2" wide = "0.7" log = "0.4" git-version = "0.3" +deranged = "0.4" rayon-core = { version = "1", optional = true } [target.'cfg(target_os = "windows")'.dependencies] From 69b1e7b9d9cd75ba02bc5688f973365b4d9cd0f0 Mon Sep 17 00:00:00 2001 From: mcrumpface Date: Wed, 6 Aug 2025 15:26:43 -0700 Subject: [PATCH 09/12] cargo --- Cargo.lock | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 80ce32fa..34fde09a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,6 +130,12 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" + [[package]] name = "either" version = "1.15.0" @@ -320,6 +326,7 @@ dependencies = [ "byteorder", "cpu-time", "default-boxed", + "deranged 0.4.0", "flate2", "git-version", "log", @@ -696,7 +703,7 @@ version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ - "deranged", + "deranged 0.3.11", "itoa", "libc", "num-conv", From fb18783248d41bf2a0f32ca3a4931e8fb3775132 Mon Sep 17 00:00:00 2001 From: Kristof Date: Sun, 24 Aug 2025 14:11:25 +0200 Subject: [PATCH 10/12] work --- lib/src/jpeg/block_based_image.rs | 4 +- lib/src/structs/lepton_decoder.rs | 51 +++++++------ lib/src/structs/lepton_encoder.rs | 53 +++++++------ lib/src/structs/model.rs | 103 +++++++++++--------------- lib/src/structs/neighbor_summary.rs | 6 +- lib/src/structs/probability_tables.rs | 11 ++- lib/src/structs/vpx_bool_writer.rs | 4 +- 7 files changed, 108 insertions(+), 124 deletions(-) diff --git a/lib/src/jpeg/block_based_image.rs b/lib/src/jpeg/block_based_image.rs index 98d47583..675ba270 100644 --- a/lib/src/jpeg/block_based_image.rs +++ b/lib/src/jpeg/block_based_image.rs @@ -279,7 +279,7 @@ impl AlignedBlock { } #[inline(always)] - pub fn get_count_of_non_zeros_7x7(&self) -> u8 { + pub fn get_count_of_non_zeros_7x7(&self) -> usize { /// counts a row of non-zero values in the 7x7 block #[inline(always)] fn count_non_zeros_7x7_row(v: i16x8) -> i16x8 { @@ -291,7 +291,7 @@ impl AlignedBlock { sum += count_non_zeros_7x7_row(self.as_i16x8(i)); } - return sum.reduce_add() as u8; + return sum.reduce_add() as usize; } #[inline(always)] diff --git a/lib/src/structs/lepton_decoder.rs b/lib/src/structs/lepton_decoder.rs index b92d622b..d1704602 100644 --- a/lib/src/structs/lepton_decoder.rs +++ b/lib/src/structs/lepton_decoder.rs @@ -9,7 +9,7 @@ use std::io::Read; use bytemuck::cast_mut; use default_boxed::DefaultBoxed; -use deranged::{RangedU32, RangedU8}; +use deranged::RangedUsize; use wide::i32x8; use crate::consts::UNZIGZAG_49_TR; @@ -243,8 +243,8 @@ pub fn read_coefficient_block( // read how many of these are non-zero, which is used both // to terminate the loop early and as a predictor for the model - let num_non_zeros_7x7 = - model_per_color.read_non_zero_7x7_count(bool_reader, num_non_zeros_7x7_context_bin)?; + let num_non_zeros_7x7 = model_per_color + .read_non_zero_7x7_count(bool_reader, num_non_zeros_7x7_context_bin.into())?; if num_non_zeros_7x7 > 49 { // most likely a stream or model synchronization error @@ -257,11 +257,10 @@ pub fn read_coefficient_block( // these are used as predictors for the number of non-zero edge coefficients // do math in 32 bits since this is faster on most platforms - let mut eob_x: u32 = 0; - let mut eob_y: u32 = 0; + let mut eob_x: usize = 0; + let mut eob_y: usize = 0; - if let Some(mut num_non_zeros_7x7_remaining) = RangedU32::<1, 49>::new(num_non_zeros_7x7 as u32) - { + if let Some(mut num_non_zeros_7x7_remaining) = RangedUsize::<1, 49>::new(num_non_zeros_7x7) { let best_priors = pt.calc_coefficient_context_7x7_aavg_block::( neighbor_data.left, neighbor_data.above, @@ -273,23 +272,23 @@ pub fn read_coefficient_block( ProbabilityTables::num_non_zeros_to_bin_7x7(num_non_zeros_7x7_remaining); // now loop through the coefficients in zigzag, terminating once we hit the number of non-zeros - let mut zig49 = RangedU32::<0, 48>::MIN; + let mut zig49 = RangedUsize::<0, 48>::MIN; loop { - let coord_tr = UNZIGZAG_49_TR[zig49.get() as usize]; - let best_prior_bit_length = u16_bit_length(best_priors[coord_tr.get() as usize]); + let coord_tr = UNZIGZAG_49_TR[zig49.get()]; + let best_prior_bit_length = u16_bit_length(best_priors[usize::from(coord_tr.get())]); let coef = model_per_color.read_coef( bool_reader, zig49, - num_non_zeros_bin, - RangedU32::<0, 11>::new(best_prior_bit_length.into()).unwrap(), + num_non_zeros_bin.into(), + RangedUsize::<0, 11>::new(best_prior_bit_length.into()).unwrap(), )?; if coef != 0 { // here we calculate the furthest x and y coordinates that have non-zero coefficients // which is later used as a predictor for the number of edge coefficients - let by = u32::from(coord_tr.get()) & 7; - let bx = u32::from(coord_tr.get()) >> 3; + let by = usize::from(coord_tr.get()) & 7; + let bx = usize::from(coord_tr.get()) >> 3; debug_assert!(bx > 0 && by > 0, "this does the DC and the lower 7x7 AC"); @@ -334,12 +333,12 @@ pub fn read_coefficient_block( pt, num_non_zeros_7x7, &mut raster, - eob_x as u8, - eob_y as u8, + RangedUsize::<0, 7>::new(eob_x).unwrap(), + RangedUsize::<0, 7>::new(eob_y).unwrap(), )?; // step 3, read the DC coefficient (0,0 of the block) - let q0 = qt.get_quantization_table()[0] as i32; + let q0 = i32::from(qt.get_quantization_table()[0]); let predicted_dc = pt.adv_predict_dc_pix::(&raster, q0, &neighbor_data, features); let coef = model.read_dc( @@ -359,7 +358,7 @@ pub fn read_coefficient_block( let neighbor_summary = NeighborSummary::new( predicted_dc.next_edge_pixels_h, predicted_dc.next_edge_pixels_v, - output.get_dc() as i32 * q0, + i32::from(output.get_dc()) * q0, num_non_zeros_7x7, horiz_pred, vert_pred, @@ -376,12 +375,12 @@ fn decode_edge( here_mut: &mut AlignedBlock, qt: &QuantizationTables, pt: &ProbabilityTables, - num_non_zeros_7x7: u8, + num_non_zeros_7x7: usize, raster: &mut [i32x8; 8], - eob_x: u8, - eob_y: u8, + eob_x: RangedUsize<0, 7>, + eob_y: RangedUsize<0, 7>, ) -> Result<(i32x8, i32x8)> { - let num_non_zeros_bin = RangedU8::new((num_non_zeros_7x7 + 3) / 7).unwrap(); + let num_non_zeros_bin = RangedUsize::new((num_non_zeros_7x7 + 3) / 7).unwrap(); // get predictors for edge coefficients of the current block let (curr_horiz_pred, curr_vert_pred) = @@ -423,8 +422,8 @@ fn decode_one_edge( here_mut: &mut AlignedBlock, qt: &QuantizationTables, pt: &ProbabilityTables, - num_non_zeros_bin: RangedU8<0, 7>, - est_eob: u8, + num_non_zeros_bin: RangedUsize<0, 7>, + est_eob: RangedUsize<0, 7>, raster: &mut [i32; 64], ) -> Result<()> { let num_non_zeros_edge = model_per_color @@ -435,7 +434,7 @@ fn decode_one_edge( return Ok(()); } - if let Some(mut num_non_zeros_edge) = RangedU8::<1, 7>::new(num_non_zeros_edge) { + if let Some(mut num_non_zeros_edge) = RangedUsize::<1, 7>::new(num_non_zeros_edge) { let delta; let mut zig15offset; @@ -456,7 +455,7 @@ fn decode_one_edge( let coef = model_per_color.read_edge_coefficient( bool_reader, qt, - RangedU32::<0, 13>::new(zig15offset).unwrap(), + RangedUsize::<0, 13>::new(zig15offset).unwrap(), num_non_zeros_edge, best_prior, )?; diff --git a/lib/src/structs/lepton_encoder.rs b/lib/src/structs/lepton_encoder.rs index 42a50403..3b9e84eb 100644 --- a/lib/src/structs/lepton_encoder.rs +++ b/lib/src/structs/lepton_encoder.rs @@ -9,7 +9,7 @@ use std::io::Write; use bytemuck::cast; use default_boxed::DefaultBoxed; -use deranged::{RangedU32, RangedU8}; +use deranged::RangedUsize; use wide::i32x8; use crate::consts::UNZIGZAG_49_TR; @@ -288,11 +288,10 @@ pub fn write_coefficient_block( // these are used as predictors for the number of non-zero edge coefficients // do math in 32 bits since this is faster on most modern platforms - let mut eob_x: u32 = 0; - let mut eob_y: u32 = 0; + let mut eob_x: usize = 0; + let mut eob_y: usize = 0; - if let Some(mut num_non_zeros_7x7_remaining) = RangedU32::<1, 49>::new(num_non_zeros_7x7 as u32) - { + if let Some(mut num_non_zeros_7x7_remaining) = RangedUsize::<1, 49>::new(num_non_zeros_7x7) { let best_priors = pt.calc_coefficient_context_7x7_aavg_block::( neighbors_data.left, neighbors_data.above, @@ -303,12 +302,12 @@ pub fn write_coefficient_block( ProbabilityTables::num_non_zeros_to_bin_7x7(num_non_zeros_7x7_remaining); // now loop through the coefficients in zigzag, terminating once we hit the number of non-zeros - let mut zig49 = RangedU32::<0, 48>::MIN; + let mut zig49 = RangedUsize::<0, 48>::MIN; loop { - let coord_tr = UNZIGZAG_49_TR[zig49.get() as usize]; - let best_prior_bit_length = u16_bit_length(best_priors[coord_tr.get() as usize]); + let coord_tr = UNZIGZAG_49_TR[zig49.get()]; + let best_prior_bit_length = u16_bit_length(best_priors[usize::from(coord_tr.get())]); - let coef = here_tr.get_coefficient(coord_tr.get() as usize); + let coef = here_tr.get_coefficient(coord_tr.get().into()); model_per_color .write_coef( @@ -316,15 +315,15 @@ pub fn write_coefficient_block( coef, zig49, num_non_zeros_remaining_bin, - RangedU32::<0, 11>::new(best_prior_bit_length.into()).unwrap(), + RangedUsize::<0, 11>::new(best_prior_bit_length.into()).unwrap(), ) .context()?; if coef != 0 { // here we calculate the furthest x and y coordinates that have non-zero coefficients // which is later used as a predictor for the number of edge coefficients - let by = u32::from(coord_tr.get()) & 7; - let bx = u32::from(coord_tr.get()) >> 3; + let by = usize::from(coord_tr.get()) & 7; + let bx = usize::from(coord_tr.get()) >> 3; debug_assert!(bx > 0 && by > 0, "this does the DC and the lower 7x7 AC"); @@ -361,13 +360,13 @@ pub fn write_coefficient_block( qt, pt, num_non_zeros_7x7, - eob_x as u8, - eob_y as u8, + RangedUsize::<0, 7>::new(eob_x).unwrap(), + RangedUsize::<0, 7>::new(eob_y).unwrap(), ) .context()?; // finally the DC coefficient (at 0,0) - let q0 = qt.get_quantization_table()[0] as i32; + let q0 = i32::from(qt.get_quantization_table()[0]); let predicted_val = pt.adv_predict_dc_pix::(&raster, q0, &neighbors_data, features); @@ -377,7 +376,7 @@ pub fn write_coefficient_block( predicted_val.predicted_dc, ); - if here_tr.get_dc() as i32 + if i32::from(here_tr.get_dc()) != ProbabilityTables::adv_predict_or_unpredict_dc( avg_predicted_dc as i16, true, @@ -401,7 +400,7 @@ pub fn write_coefficient_block( let neighbor_summary = NeighborSummary::new( predicted_val.next_edge_pixels_h, predicted_val.next_edge_pixels_v, - here_tr.get_dc() as i32 * q0, + i32::from(here_tr.get_dc()) * q0, num_non_zeros_7x7, horiz_pred, vert_pred, @@ -418,9 +417,9 @@ fn encode_edge( bool_writer: &mut VPXBoolWriter, qt: &QuantizationTables, pt: &ProbabilityTables, - num_non_zeros_7x7: u8, - eob_x: u8, - eob_y: u8, + num_non_zeros_7x7: usize, + eob_x: RangedUsize<0, 7>, + eob_y: RangedUsize<0, 7>, ) -> Result<([i32x8; 8], i32x8, i32x8)> { let q_tr = qt.get_quantization_table_transposed(); @@ -435,7 +434,7 @@ fn encode_edge( let (curr_horiz_pred, curr_vert_pred) = ProbabilityTables::predict_current_edges(neighbors_data, &raster); - let num_non_zeros_bin = RangedU8::new((num_non_zeros_7x7 + 3) / 7).unwrap(); + let num_non_zeros_bin = RangedUsize::new((num_non_zeros_7x7 + 3) / 7).unwrap(); encode_one_edge::( here_tr, @@ -467,7 +466,7 @@ fn encode_edge( Ok((raster, next_horiz_pred, next_vert_pred)) } -fn count_non_zero(v: i16) -> u8 { +fn count_non_zero(v: i16) -> usize { if v == 0 { 0 } else { @@ -482,8 +481,8 @@ fn encode_one_edge( pred: &[i32; 8], qt: &QuantizationTables, pt: &ProbabilityTables, - num_non_zeros_bin: RangedU8<0, 7>, - est_eob: u8, + num_non_zeros_bin: RangedUsize<0, 7>, + est_eob: RangedUsize<0, 7>, ) -> Result<()> { let num_non_zeros_edge; @@ -509,7 +508,7 @@ fn encode_one_edge( .write_non_zero_edge_count::( bool_writer, est_eob, - num_non_zeros_bin, + num_non_zeros_bin.into(), num_non_zeros_edge, ) .context()?; @@ -527,7 +526,7 @@ fn encode_one_edge( let mut coord_tr = delta; - if let Some(mut n) = RangedU8::<1, 7>::new(num_non_zeros_edge) { + if let Some(mut n) = RangedUsize::<1, 7>::new(num_non_zeros_edge) { for _lane in 0..7 { let best_prior = pt.calc_coefficient_context8_lak::(qt, coord_tr, pred); @@ -539,7 +538,7 @@ fn encode_one_edge( bool_writer, qt, coef, - RangedU32::new(zig15offset).unwrap(), + RangedUsize::new(zig15offset).unwrap(), n, best_prior, ) diff --git a/lib/src/structs/model.rs b/lib/src/structs/model.rs index 04660c5d..6c6e9f5f 100644 --- a/lib/src/structs/model.rs +++ b/lib/src/structs/model.rs @@ -8,7 +8,7 @@ use std::cmp; use std::io::{Read, Write}; use default_boxed::DefaultBoxed; -use deranged::{RangedU32, RangedU8}; +use deranged::RangedUsize; use crate::consts::*; use crate::helpers::{calc_sign_index, u16_bit_length, u32_bit_length}; @@ -188,9 +188,9 @@ impl ModelPerColor { pub fn read_coef( &mut self, bool_reader: &mut VPXBoolReader, - zig49: RangedU32<0, 48>, - num_non_zeros_bin: RangedU8<0, 8>, - best_prior_bit_len: RangedU32<0, 11>, + zig49: RangedUsize<0, 48>, + num_non_zeros_bin: RangedUsize<0, 8>, + best_prior_bit_len: RangedUsize<0, 11>, ) -> std::io::Result { let (exp, sign, bits) = self.get_coef_branches(num_non_zeros_bin, zig49, best_prior_bit_len); @@ -211,9 +211,9 @@ impl ModelPerColor { &mut self, bool_writer: &mut VPXBoolWriter, coef: i16, - zig49: RangedU32<0, 48>, - num_non_zeros_bin: RangedU8<0, 8>, - best_prior_bit_len: RangedU32<0, 11>, + zig49: RangedUsize<0, 48>, + num_non_zeros_bin: RangedUsize<0, 8>, + best_prior_bit_len: RangedUsize<0, 11>, ) -> Result<()> { let (exp, sign, bits) = self.get_coef_branches(num_non_zeros_bin, zig49, best_prior_bit_len); @@ -234,19 +234,18 @@ impl ModelPerColor { #[inline(always)] fn get_coef_branches( &mut self, - num_non_zeros_bin: RangedU8<0, 8>, - zig49: RangedU32<0, 48>, - best_prior_bit_len: RangedU32<0, 11>, + num_non_zeros_bin: RangedUsize<0, 8>, + zig49: RangedUsize<0, 48>, + best_prior_bit_len: RangedUsize<0, 11>, ) -> ( &mut [Branch; MAX_EXPONENT], &mut Branch, &mut [Branch; COEF_BITS], ) { - let exp = &mut self.counts[num_non_zeros_bin.get() as usize][zig49.get() as usize] - .exponent_counts[best_prior_bit_len.get() as usize]; + let exp = &mut self.counts[num_non_zeros_bin.get()][zig49.get()].exponent_counts + [best_prior_bit_len.get()]; let sign = &mut self.sign_counts[0][0]; - let bits = &mut self.counts[num_non_zeros_bin.get() as usize][zig49.get() as usize] - .residual_noise_counts; + let bits = &mut self.counts[num_non_zeros_bin.get()][zig49.get()].residual_noise_counts; (exp, sign, bits) } @@ -254,8 +253,8 @@ impl ModelPerColor { pub fn write_non_zero_7x7_count( &mut self, bool_writer: &mut VPXBoolWriter, - num_non_zeros_7x7_context_bin: RangedU8<0, 8>, - num_non_zeros_7x7: u8, + num_non_zeros_7x7_context_bin: RangedUsize<0, 8>, + num_non_zeros_7x7: usize, ) -> Result<()> { let num_non_zeros_prob = &mut self.num_non_zeros_counts7x7[usize::from(num_non_zeros_7x7_context_bin.get())]; @@ -272,9 +271,9 @@ impl ModelPerColor { pub fn write_non_zero_edge_count( &mut self, bool_writer: &mut VPXBoolWriter, - est_eob: u8, - num_non_zeros_bin: RangedU8<0, 7>, - num_non_zeros_edge: u8, + est_eob: RangedUsize<0, 7>, + num_non_zeros_bin: RangedUsize<0, 7>, + num_non_zeros_edge: usize, ) -> Result<()> { let prob_edge_eob = self.get_non_zero_counts_edge_mut::(est_eob, num_non_zeros_bin); @@ -291,36 +290,36 @@ impl ModelPerColor { pub fn read_non_zero_7x7_count( &mut self, bool_reader: &mut VPXBoolReader, - num_non_zeros_7x7_context_bin: RangedU8<0, 8>, - ) -> Result { + num_non_zeros_7x7_context_bin: RangedUsize<0, 8>, + ) -> Result { let num_non_zeros_prob = &mut self.num_non_zeros_counts7x7[usize::from(num_non_zeros_7x7_context_bin.get())]; return Ok(bool_reader .get_grid(num_non_zeros_prob, ModelComponent::NonZero7x7Count) - .context()? as u8); + .context()?); } pub fn read_non_zero_edge_count( &mut self, bool_reader: &mut VPXBoolReader, - est_eob: u8, - num_non_zeros_bin: RangedU8<0, 7>, - ) -> Result { + est_eob: RangedUsize<0, 7>, + num_non_zeros_bin: RangedUsize<0, 7>, + ) -> Result { let prob_edge_eob = self.get_non_zero_counts_edge_mut::(est_eob, num_non_zeros_bin); return Ok(bool_reader .get_grid(prob_edge_eob, ModelComponent::NonZeroEdgeCount) - .context()? as u8); + .context()?); } pub fn read_edge_coefficient( &mut self, bool_reader: &mut VPXBoolReader, qt: &QuantizationTables, - zig15offset: RangedU32<0, 13>, - num_non_zeros_edge: RangedU8<1, 7>, + zig15offset: RangedUsize<0, 13>, + num_non_zeros_edge: RangedUsize<1, 7>, best_prior: i32, ) -> Result { // we cap the bit length since the prior prediction can be wonky @@ -328,8 +327,7 @@ impl ModelPerColor { let best_prior_bit_len = cmp::min(MAX_EXPONENT - 1, u32_bit_length(best_prior_abs) as usize); - let length_branches = &mut self.counts_x[num_non_zeros_edge.get() as usize - 1] - [zig15offset.get() as usize] + let length_branches = &mut self.counts_x[num_non_zeros_edge.get() - 1][zig15offset.get()] .exponent_counts[best_prior_bit_len]; let length = bool_reader @@ -353,9 +351,7 @@ impl ModelPerColor { coef = 1; if length > 1 { - let min_threshold: i32 = qt - .get_min_noise_threshold(zig15offset.get() as usize) - .into(); + let min_threshold: i32 = qt.get_min_noise_threshold(zig15offset.get()).into(); let mut i: i32 = length - 2; if i >= min_threshold { @@ -384,9 +380,9 @@ impl ModelPerColor { } if i >= 0 { - let res_prob = &mut self.counts_x[num_non_zeros_edge.get() as usize - 1] - [zig15offset.get() as usize] - .residual_noise_counts; + let res_prob = &mut self.counts_x[num_non_zeros_edge.get() - 1] + [zig15offset.get()] + .residual_noise_counts; coef <<= i + 1; coef |= bool_reader.get_n_bits( @@ -409,8 +405,8 @@ impl ModelPerColor { bool_writer: &mut VPXBoolWriter, qt: &QuantizationTables, coef: i16, - zig15offset: RangedU32<0, 13>, - num_non_zeros_edge: RangedU8<1, 7>, + zig15offset: RangedUsize<0, 13>, + num_non_zeros_edge: RangedUsize<1, 7>, best_prior: i32, ) -> Result<()> { let num_non_zeros_edge_bin = usize::from(num_non_zeros_edge.get()) - 1; @@ -423,7 +419,7 @@ impl ModelPerColor { let abs_coef = coef.unsigned_abs(); let length = u16_bit_length(abs_coef) as usize; - let exp_array = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset.get() as usize] + let exp_array = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset.get()] .exponent_counts[best_prior_bit_len]; if length > MAX_EXPONENT { @@ -449,8 +445,7 @@ impl ModelPerColor { )?; if length > 1 { - let min_threshold = - i32::from(qt.get_min_noise_threshold(zig15offset.get() as usize)); + let min_threshold = i32::from(qt.get_min_noise_threshold(zig15offset.get())); let mut i: i32 = length as i32 - 2; if i >= min_threshold { @@ -483,8 +478,7 @@ impl ModelPerColor { } if i >= 0 { - let res_prob = &mut self.counts_x[num_non_zeros_edge_bin] - [zig15offset.get() as usize] + let res_prob = &mut self.counts_x[num_non_zeros_edge_bin][zig15offset.get()] .residual_noise_counts; bool_writer @@ -526,15 +520,13 @@ impl ModelPerColor { fn get_non_zero_counts_edge_mut( &mut self, - est_eob: u8, - num_nonzeros_bin: RangedU8<0, 7>, + est_eob: RangedUsize<0, 7>, + num_nonzeros_bin: RangedUsize<0, 7>, ) -> &mut [Branch; 8] { if HORIZONTAL { - return &mut self.num_non_zeros_counts8x1[est_eob as usize] - [num_nonzeros_bin.get() as usize]; + return &mut self.num_non_zeros_counts8x1[est_eob.get()][num_nonzeros_bin.get()]; } else { - return &mut self.num_non_zeros_counts1x8[est_eob as usize] - [num_nonzeros_bin.get() as usize]; + return &mut self.num_non_zeros_counts1x8[est_eob.get()][num_nonzeros_bin.get()]; } } } @@ -668,16 +660,16 @@ impl Model { ); let abs_coef = coef.unsigned_abs(); - let coef_bit_len = u16_bit_length(abs_coef); + let coef_bit_len = u16_bit_length(abs_coef) as usize; - if coef_bit_len > A as u8 { + if coef_bit_len > A { return err_exit_code( ExitCode::CoefficientOutOfRange, "coefficient > MAX_EXPONENT", ); } - bool_writer.put_unary_encoded(coef_bit_len as usize, magnitude_branches, mag_cmp)?; + bool_writer.put_unary_encoded(coef_bit_len, magnitude_branches, mag_cmp)?; if coef != 0 { bool_writer.put_bit(coef > 0, sign_branch, sign_cmp)?; } @@ -692,12 +684,7 @@ impl Model { "Beyond Biggest bit must be zero" ); - bool_writer.put_n_bits( - abs_coef as usize, - coef_bit_len as usize - 1, - bits_branch, - bits_cmp, - )?; + bool_writer.put_n_bits(abs_coef as usize, coef_bit_len - 1, bits_branch, bits_cmp)?; } Ok(()) diff --git a/lib/src/structs/neighbor_summary.rs b/lib/src/structs/neighbor_summary.rs index 8a5c464a..b23b1f57 100644 --- a/lib/src/structs/neighbor_summary.rs +++ b/lib/src/structs/neighbor_summary.rs @@ -16,7 +16,7 @@ pub struct NeighborSummary { edge_coefs_h: i32x8, edge_coefs_v: i32x8, - num_non_zeros: u8, + num_non_zeros: usize, } pub static NEIGHBOR_DATA_EMPTY: NeighborSummary = NeighborSummary { @@ -39,7 +39,7 @@ impl NeighborSummary { edge_pixels_h: i16x8, edge_pixels_v: i16x8, dc_deq: i32, - num_non_zeros_7x7: u8, + num_non_zeros_7x7: usize, horiz_pred: i32x8, vert_pred: i32x8, ) -> Self { @@ -52,7 +52,7 @@ impl NeighborSummary { } } - pub fn get_num_non_zeros(&self) -> u8 { + pub fn get_num_non_zeros(&self) -> usize { self.num_non_zeros } diff --git a/lib/src/structs/probability_tables.rs b/lib/src/structs/probability_tables.rs index e94e5eef..b1dc05c1 100644 --- a/lib/src/structs/probability_tables.rs +++ b/lib/src/structs/probability_tables.rs @@ -5,8 +5,7 @@ *--------------------------------------------------------------------------------------------*/ use bytemuck::cast; -use deranged::RangedU32; -use deranged::RangedU8; +use deranged::RangedUsize; use wide::{i16x8, i32x8, u16x8}; use crate::consts::*; @@ -83,14 +82,14 @@ impl ProbabilityTables { } #[inline(always)] - pub fn num_non_zeros_to_bin_7x7(num_non_zeros: RangedU32<1, 49>) -> RangedU8<0, 8> { - return NON_ZERO_TO_BIN_7X7[num_non_zeros.get() as usize]; + pub fn num_non_zeros_to_bin_7x7(num_non_zeros: RangedUsize<1, 49>) -> RangedUsize<0, 8> { + return NON_ZERO_TO_BIN_7X7[num_non_zeros.get()].into(); } pub fn calc_num_non_zeros_7x7_context_bin( &self, neighbor_data: &NeighborData, - ) -> RangedU8<0, 8> { + ) -> RangedUsize<0, 8> { let mut num_non_zeros_above = 0; let mut num_non_zeros_left = 0; if ALL_PRESENT || self.above_present { @@ -112,7 +111,7 @@ impl ProbabilityTables { num_non_zeros_context = 0; } - return NON_ZERO_TO_BIN[usize::from(num_non_zeros_context)]; + return NON_ZERO_TO_BIN[usize::from(num_non_zeros_context)].into(); } // calculates the average of the prior values from their corresponding value in the left, above and above/left block diff --git a/lib/src/structs/vpx_bool_writer.rs b/lib/src/structs/vpx_bool_writer.rs index 930e05c9..9a3f021f 100644 --- a/lib/src/structs/vpx_bool_writer.rs +++ b/lib/src/structs/vpx_bool_writer.rs @@ -173,7 +173,7 @@ impl VPXBoolWriter { #[inline(always)] pub fn put_grid( &mut self, - v: u8, + v: usize, branches: &mut [Branch; A], cmp: ModelComponent, ) -> Result<()> { @@ -429,7 +429,7 @@ fn test_roundtrip_vpxboolwriter_grid() { for i in 0..1024 { writer - .put_grid(i as u8 % 8, &mut branches.branches, ModelComponent::Dummy) + .put_grid(i % 8, &mut branches.branches, ModelComponent::Dummy) .unwrap(); } From 38ece87178ead781b91c784357bf91a09c4d1973 Mon Sep 17 00:00:00 2001 From: Kristof Date: Sun, 24 Aug 2025 14:11:53 +0200 Subject: [PATCH 11/12] work --- Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09cb58e1..635ff42b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "75d7cc94194b4dd0fa12845ef8c911101b7f37633cda14997a6e82099aa0b693" [[package]] name = "either" @@ -326,7 +326,7 @@ dependencies = [ "byteorder", "cpu-time", "default-boxed", - "deranged 0.4.0", + "deranged 0.5.2", "flate2", "git-version", "log", diff --git a/lib/Cargo.toml b/lib/Cargo.toml index a60eff0b..921cf8e4 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -28,7 +28,7 @@ default-boxed = "0.2" wide = "0.7" log = "0.4" git-version = "0.3" -deranged = "0.4" +deranged = "0.5.2" [target.'cfg(target_os = "windows")'.dependencies] cpu-time = "1.0" From 1de779ad8e361d00ee786ea29423dd68474b8f13 Mon Sep 17 00:00:00 2001 From: Kristof Date: Fri, 24 Oct 2025 08:49:29 +0200 Subject: [PATCH 12/12] fix formatting --- lib/src/structs/lepton_encoder.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/src/structs/lepton_encoder.rs b/lib/src/structs/lepton_encoder.rs index 5afffd93..cce864b5 100644 --- a/lib/src/structs/lepton_encoder.rs +++ b/lib/src/structs/lepton_encoder.rs @@ -467,11 +467,7 @@ fn encode_edge( } fn count_non_zero(v: i16) -> usize { - if v == 0 { - 0 - } else { - 1 - } + if v == 0 { 0 } else { 1 } } fn encode_one_edge(