-
Notifications
You must be signed in to change notification settings - Fork 90
Add the ability to scale down images during decode (IDCT scaling) #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3123fc5
cb87665
85adaf5
d28ea6f
168ee6b
12920df
67dc09e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,8 +100,8 @@ impl<R: Read> Decoder<R> { | |
}; | ||
|
||
Some(ImageInfo { | ||
width: frame.image_size.width, | ||
height: frame.image_size.height, | ||
width: frame.output_size.width, | ||
height: frame.output_size.height, | ||
pixel_format: pixel_format, | ||
}) | ||
}, | ||
|
@@ -116,6 +116,23 @@ impl<R: Read> Decoder<R> { | |
self.decode_internal(true).map(|_| ()) | ||
} | ||
|
||
/// Configure the decoder to scale the image during decoding. | ||
/// | ||
/// This efficiently scales the image by the smallest supported scale | ||
/// factor that produces an image larger than or equal to the requested | ||
/// size in at least one axis. The currently implemented scale factors | ||
/// are 1/8, 1/4, 1/2 and 1. | ||
/// | ||
/// To generate a thumbnail of an exact size, pass the desired size and | ||
/// then scale to the final size using a traditional resampling algorithm. | ||
pub fn scale(&mut self, requested_width: u16, requested_height: u16) -> Result<(u16, u16)> { | ||
self.read_info()?; | ||
let frame = self.frame.as_mut().unwrap(); | ||
let idct_size = crate::idct::choose_idct_size(frame.image_size, Dimensions{ width: requested_width, height: requested_height }); | ||
frame.update_idct_size(idct_size); | ||
Ok((frame.output_size.width, frame.output_size.height)) | ||
} | ||
|
||
/// Decodes the image and returns the decoded pixels if successful. | ||
pub fn decode(&mut self) -> Result<Vec<u8>> { | ||
self.decode_internal(false) | ||
|
@@ -329,7 +346,7 @@ impl<R: Read> Decoder<R> { | |
} | ||
|
||
let frame = self.frame.as_ref().unwrap(); | ||
compute_image(&frame.components, &planes, frame.image_size, self.is_jfif, self.color_transform) | ||
compute_image(&frame.components, &planes, frame.output_size, self.is_jfif, self.color_transform) | ||
} | ||
|
||
fn read_marker(&mut self) -> Result<Marker> { | ||
|
@@ -435,7 +452,7 @@ impl<R: Read> Decoder<R> { | |
let x = (block_num % blocks_per_row) as u16; | ||
let y = (block_num / blocks_per_row) as u16; | ||
|
||
if x * 8 >= component.size.width || y * 8 >= component.size.height { | ||
if x * component.dct_scale as u16 >= component.size.width || y * component.dct_scale as u16 >= component.size.height { | ||
continue; | ||
} | ||
|
||
|
@@ -764,12 +781,15 @@ fn compute_image(components: &[Component], | |
return Ok(data[0].clone()) | ||
} | ||
|
||
let mut buffer = vec![0u8; component.size.width as usize * component.size.height as usize]; | ||
let line_stride = component.block_size.width as usize * 8; | ||
let width = component.size.width as usize; | ||
let height = component.size.height as usize; | ||
|
||
let mut buffer = vec![0u8; width * height]; | ||
let line_stride = width * component.dct_scale; | ||
|
||
for y in 0 .. component.size.height as usize { | ||
for x in 0 .. component.size.width as usize { | ||
buffer[y * component.size.width as usize + x] = data[0][y * line_stride + x]; | ||
for y in 0 .. width { | ||
for x in 0 .. height { | ||
buffer[y * width + x] = data[0][y * line_stride + x]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #125 seems to have been introduced by this line There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like I swapped Also, this presumably means there are no single-channel JPEG images in the test suite? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow, I missed that ! I fixed that too in #126 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test suite could clearly be more extensive ! |
||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was inadvertently changed from
component.block_size.width
tocomponent.size.width
, causing #125