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