Skip to content

Commit 2986d5a

Browse files
committed
Merge remote-tracking branch 'origin/master' into HEAD
2 parents 3aa8a4f + b3c025f commit 2986d5a

File tree

5 files changed

+42
-25
lines changed

5 files changed

+42
-25
lines changed

src/decoder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -803,8 +803,8 @@ impl<R: Read> Decoder<R> {
803803
(block_y * component.block_size.width as usize + block_x) * 64;
804804
&mut mcu_row_coefficients[i][block_offset..block_offset + 64]
805805
} else {
806-
&mut dummy_block[..]
807-
};
806+
&mut dummy_block[..64]
807+
}.try_into().unwrap();
808808

809809
if scan.successive_approximation_high == 0 {
810810
decode_block(
@@ -900,7 +900,7 @@ impl<R: Read> Decoder<R> {
900900

901901
fn decode_block<R: Read>(
902902
reader: &mut R,
903-
coefficients: &mut [i16],
903+
coefficients: &mut [i16; 64],
904904
huffman: &mut HuffmanDecoder,
905905
dc_table: Option<&HuffmanTable>,
906906
ac_table: Option<&HuffmanTable>,
@@ -988,7 +988,7 @@ fn decode_block<R: Read>(
988988

989989
fn decode_block_successive_approximation<R: Read>(
990990
reader: &mut R,
991-
coefficients: &mut [i16],
991+
coefficients: &mut [i16; 64],
992992
huffman: &mut HuffmanDecoder,
993993
ac_table: Option<&HuffmanTable>,
994994
spectral_selection: Range<u8>,
@@ -1074,7 +1074,7 @@ fn decode_block_successive_approximation<R: Read>(
10741074

10751075
fn refine_non_zeroes<R: Read>(
10761076
reader: &mut R,
1077-
coefficients: &mut [i16],
1077+
coefficients: &mut [i16; 64],
10781078
huffman: &mut HuffmanDecoder,
10791079
range: Range<u8>,
10801080
zrl: u8,

src/idct.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ fn test_choose_idct_size() {
204204

205205
pub(crate) fn dequantize_and_idct_block(
206206
scale: usize,
207-
coefficients: &[i16],
207+
coefficients: &[i16; 64],
208208
quantization_table: &[u16; 64],
209209
output_linestride: usize,
210210
output: &mut [u8],
@@ -239,7 +239,7 @@ pub(crate) fn dequantize_and_idct_block(
239239
}
240240

241241
pub fn dequantize_and_idct_block_8x8(
242-
coefficients: &[i16],
242+
coefficients: &[i16; 64],
243243
quantization_table: &[u16; 64],
244244
output_linestride: usize,
245245
output: &mut [u8],
@@ -258,7 +258,7 @@ pub fn dequantize_and_idct_block_8x8(
258258

259259
// This is based on stb_image's 'stbi__idct_block'.
260260
fn dequantize_and_idct_block_8x8_inner<'a, I>(
261-
coefficients: &[i16],
261+
coefficients: &[i16; 64],
262262
quantization_table: &[u16; 64],
263263
output: I,
264264
) where
@@ -272,9 +272,6 @@ fn dequantize_and_idct_block_8x8_inner<'a, I>(
272272
output.len()
273273
);
274274

275-
// optimizer hint to eliminate bounds checks within loops
276-
assert!(coefficients.len() == 64);
277-
278275
let mut temp = [Wrapping(0); 64];
279276

280277
// columns
@@ -338,6 +335,9 @@ fn dequantize_and_idct_block_8x8_inner<'a, I>(
338335
// to encode as 0..255 by adding 128, so we'll add that before the shift
339336
const X_SCALE: i32 = 65536 + (128 << 17);
340337

338+
// eliminate downstream bounds checks
339+
let output_chunk = &mut output_chunk[..8];
340+
341341
// TODO When the minimum rust version supports it
342342
// let [s0, rest @ ..] = chunk;
343343
let (s0, rest) = chunk.split_first().unwrap();
@@ -454,7 +454,7 @@ fn dequantize(c: i16, q: u16) -> Wrapping<i32> {
454454
// 4x4 and 2x2 IDCT based on Rakesh Dugad and Narendra Ahuja: "A Fast Scheme for Image Size Change in the Compressed Domain" (2001).
455455
// http://sylvana.net/jpegcrop/jidctred/
456456
fn dequantize_and_idct_block_4x4(
457-
coefficients: &[i16],
457+
coefficients: &[i16; 64],
458458
quantization_table: &[u16; 64],
459459
output_linestride: usize,
460460
output: &mut [u8],
@@ -516,7 +516,7 @@ fn dequantize_and_idct_block_4x4(
516516
}
517517

518518
fn dequantize_and_idct_block_2x2(
519-
coefficients: &[i16],
519+
coefficients: &[i16; 64],
520520
quantization_table: &[u16; 64],
521521
output_linestride: usize,
522522
output: &mut [u8],
@@ -552,15 +552,14 @@ fn dequantize_and_idct_block_2x2(
552552
}
553553

554554
fn dequantize_and_idct_block_1x1(
555-
coefficients: &[i16],
555+
coefficients: &[i16; 64],
556556
quantization_table: &[u16; 64],
557557
_output_linestride: usize,
558558
output: &mut [u8],
559559
) {
560560
debug_assert_eq!(coefficients.len(), 64);
561561

562-
let s0 = (Wrapping(coefficients[0] as i32 * quantization_table[0] as i32) + Wrapping(128 * 8))
563-
/ Wrapping(8);
562+
let s0 = (Wrapping(coefficients[0] as i32 * quantization_table[0] as i32) + Wrapping(128 * 8)) / Wrapping(8);
564563
output[0] = stbi_clamp(s0);
565564
}
566565

src/worker/immediate.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use alloc::vec;
22
use alloc::vec::Vec;
33
use core::mem;
4+
use core::convert::TryInto;
45
use decoder::MAX_COMPONENTS;
56
use error::Result;
67
use idct::dequantize_and_idct_block;
@@ -46,7 +47,7 @@ impl ImmediateWorker {
4647
let x = (i % component.block_size.width as usize) * component.dct_scale;
4748
let y = (i / component.block_size.width as usize) * component.dct_scale;
4849

49-
let coefficients = &data[i * 64..(i + 1) * 64];
50+
let coefficients = data[i * 64..(i + 1) * 64].try_into().unwrap();
5051
let output = &mut self.results[index][self.offsets[index] + y * line_stride + x..];
5152

5253
dequantize_and_idct_block(component.dct_scale, coefficients, quantization_table, line_stride, output);

src/worker/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
mod immediate;
2-
#[cfg(feature = "std")]
32
mod multithreaded;
43

5-
#[cfg(all(feature = "std", not(any(target_arch = "asmjs", target_arch = "wasm32"))))]
4+
#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
65
pub use self::multithreaded::MultiThreadedWorker as PlatformWorker;
7-
#[cfg(any(not(feature = "std"), target_arch = "asmjs", target_arch = "wasm32"))]
6+
#[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))]
87
pub use self::immediate::ImmediateWorker as PlatformWorker;
98

109
use alloc::sync::Arc;

src/worker/multithreaded.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
77
use decoder::MAX_COMPONENTS;
88
use error::Result;
9-
use std::{mem, sync::mpsc::{self, Sender}};
10-
use std::thread;
9+
use std::{mem, io, sync::mpsc::{self, Sender}};
1110
use super::{RowData, Worker};
1211
use super::immediate::ImmediateWorker;
1312

@@ -57,10 +56,9 @@ impl Worker for MultiThreadedWorker {
5756
}
5857

5958
fn spawn_worker_thread(component: usize) -> Result<Sender<WorkerMsg>> {
60-
let thread_builder = thread::Builder::new().name(format!("worker thread for component {}", component));
6159
let (tx, rx) = mpsc::channel();
6260

63-
thread_builder.spawn(move || {
61+
spawn(component, move || {
6462
let mut worker = ImmediateWorker::new_immediate();
6563

6664
while let Ok(message) = rx.recv() {
@@ -84,4 +82,24 @@ fn spawn_worker_thread(component: usize) -> Result<Sender<WorkerMsg>> {
8482
})?;
8583

8684
Ok(tx)
87-
}
85+
}
86+
87+
#[cfg(feature = "rayon")]
88+
fn spawn<F>(_component: usize, func: F) -> io::Result<()>
89+
where
90+
F: FnOnce() + Send + 'static,
91+
{
92+
rayon::spawn(func);
93+
Ok(())
94+
}
95+
96+
#[cfg(not(feature = "rayon"))]
97+
fn spawn<F>(component: usize, func: F) -> io::Result<()>
98+
where
99+
F: FnOnce() + Send + 'static,
100+
{
101+
let thread_builder =
102+
std::thread::Builder::new().name(format!("worker thread for component {}", component));
103+
thread_builder.spawn(func)?;
104+
Ok(())
105+
}

0 commit comments

Comments
 (0)