gistools/parsers/image/
decoder.rs1#[cfg(feature = "std")]
2use super::ImageData;
3#[cfg(feature = "std")]
4use crate::parsers::Buffer;
5#[cfg(feature = "std")]
6use image::ImageReader;
7#[cfg(feature = "std")]
8use std::io::Cursor;
9
10#[derive(Debug, Default, Clone)]
12pub struct DecodeOptions {
13 pub x: Option<u32>,
15 pub y: Option<u32>,
17 pub width: Option<u32>,
19 pub height: Option<u32>,
21 pub modulo: Option<u32>,
23}
24
25#[cfg(feature = "std")]
34pub fn image_decoder(
35 buffer: &Buffer,
36 options: Option<DecodeOptions>,
37) -> Result<ImageData, image::ImageError> {
38 use image::GenericImageView;
39
40 let img = ImageReader::new(Cursor::new(buffer.buf())).with_guessed_format()?.decode()?;
41
42 let (img_width, img_height) = img.dimensions();
43 let opts = options.unwrap_or_default();
44
45 let modulo = opts.modulo.unwrap_or(1);
46 let diff = img_width % modulo;
47
48 let (x, y, width, height) = if diff != 0 {
49 let shift = diff / 2;
50 (shift, shift, img_width - diff, img_width - diff)
51 } else {
52 (
53 opts.x.unwrap_or(0),
54 opts.y.unwrap_or(0),
55 opts.width.unwrap_or(img_width),
56 opts.height.unwrap_or(img_height),
57 )
58 };
59
60 let sub_image = img.view(x, y, width, height).to_image();
61
62 Ok(ImageData {
63 width: width as usize,
64 height: height as usize,
65 data: sub_image.into_raw().into(),
66 })
67}
68
69#[cfg(feature = "std")]
78pub fn image_decoder_buffer(buffer: &Buffer, options: Option<DecodeOptions>) -> Buffer {
79 image_decoder(buffer, options).unwrap().data
80}