1#![cfg(feature = "qoi")]
13#![cfg_attr(feature = "docs", doc(cfg(feature = "qoi")))]
14
15use zune_core::bit_depth::BitDepth;
16use zune_core::bytestream::{ZByteReaderTrait, ZByteWriterTrait};
17use zune_core::colorspace::ColorSpace;
18use zune_core::options::EncoderOptions;
19pub use zune_qoi::*;
20
21use crate::codecs::{create_options_for_encoder, ImageFormat};
22use crate::errors::{ImageErrors, ImgEncodeErrors};
23use crate::image::Image;
24use crate::metadata::ImageMetadata;
25use crate::traits::{DecodeInto, DecoderTrait, EncoderTrait};
26
27impl<T> DecoderTrait for QoiDecoder<T>
28where
29 T: ZByteReaderTrait
30{
31 fn decode(&mut self) -> Result<Image, ImageErrors> {
32 let pixels = self.decode()?;
33 let colorspace = self.colorspace().unwrap();
35 let (width, height) = self.dimensions().unwrap();
36
37 let depth = self.bit_depth();
38
39 let mut image = Image::from_u8(&pixels, width, height, colorspace);
40
41 image.metadata.format = Some(ImageFormat::QOI);
43
44 Ok(image)
45 }
46
47 fn dimensions(&self) -> Option<(usize, usize)> {
48 self.dimensions()
49 }
50
51 fn out_colorspace(&self) -> ColorSpace {
52 self.colorspace().unwrap()
53 }
54
55 fn name(&self) -> &'static str {
56 "QOI Decoder"
57 }
58
59 fn is_experimental(&self) -> bool {
60 true
61 }
62
63 fn read_headers(&mut self) -> Result<Option<ImageMetadata>, crate::errors::ImageErrors> {
64 self.decode_headers()
65 .map_err(<QoiErrors as Into<ImageErrors>>::into)?;
66
67 let (width, height) = self.dimensions().unwrap();
68 let depth = self.bit_depth();
69
70 let metadata = ImageMetadata {
71 format: Some(ImageFormat::QOI),
72 colorspace: self.colorspace().unwrap(),
73 depth: depth,
74 width: width,
75 height: height,
76 ..Default::default()
77 };
78
79 Ok(Some(metadata))
80 }
81}
82
83#[derive(Copy, Clone, Default)]
84pub struct QoiEncoder {
85 options: Option<EncoderOptions>
86}
87
88impl QoiEncoder {
89 pub fn new() -> QoiEncoder {
90 QoiEncoder::default()
91 }
92
93 pub fn new_with_options(options: EncoderOptions) -> QoiEncoder {
94 QoiEncoder {
95 options: Some(options)
96 }
97 }
98}
99
100impl EncoderTrait for QoiEncoder {
101 fn name(&self) -> &'static str {
102 "QOI Encoder"
103 }
104
105 fn encode_inner<T: ZByteWriterTrait>(
106 &mut self, image: &Image, sink: T
107 ) -> Result<usize, ImageErrors> {
108 let options = create_options_for_encoder(self.options, image);
109
110 let data = &image.to_u8()[0];
111
112 let mut qoi_encoder = zune_qoi::QoiEncoder::new(data, options);
113
114 let bytes_written = qoi_encoder
115 .encode(sink)
116 .map_err(<QoiEncodeErrors as Into<ImgEncodeErrors>>::into)?;
117
118 Ok(bytes_written)
119 }
120 fn supported_colorspaces(&self) -> &'static [ColorSpace] {
121 &[ColorSpace::RGBA, ColorSpace::RGB]
122 }
123
124 fn format(&self) -> ImageFormat {
125 ImageFormat::QOI
126 }
127
128 fn supported_bit_depth(&self) -> &'static [BitDepth] {
129 &[BitDepth::Eight]
130 }
131
132 fn default_depth(&self, _: BitDepth) -> BitDepth {
133 BitDepth::Eight
134 }
135
136 fn default_colorspace(&self, colorspace: ColorSpace) -> ColorSpace {
137 if colorspace.has_alpha() {
140 ColorSpace::RGBA
141 } else {
142 ColorSpace::RGB
144 }
145 }
146 fn set_options(&mut self, opts: EncoderOptions) {
147 self.options = Some(opts)
148 }
149}
150
151impl From<zune_qoi::QoiErrors> for ImageErrors {
152 fn from(error: zune_qoi::QoiErrors) -> Self {
153 let err = format!("qoi: {error:?}");
154
155 ImageErrors::ImageDecodeErrors(err)
156 }
157}
158
159impl From<zune_qoi::QoiEncodeErrors> for ImgEncodeErrors {
160 fn from(error: zune_qoi::QoiEncodeErrors) -> Self {
161 let err = format!("qoi: {error:?}");
162
163 ImgEncodeErrors::Generic(err)
164 }
165}
166
167impl<T> DecodeInto for QoiDecoder<T>
168where
169 T: ZByteReaderTrait
170{
171 type BufferType = u8;
172
173 fn decode_into(&mut self, buffer: &mut [Self::BufferType]) -> Result<(), ImageErrors> {
174 self.decode_into(buffer)?;
175
176 Ok(())
177 }
178
179 fn decode_output_buffer_size(&mut self) -> Result<usize, ImageErrors> {
180 self.decode_headers()?;
181
182 Ok(self.output_buffer_size().unwrap())
184 }
185}