1#![cfg_attr(feature = "docs", doc(cfg(feature = "hdr")))]
9#![cfg(feature = "hdr")]
10use zune_core::bit_depth::BitDepth;
12use zune_core::bytestream::{ZByteReaderTrait, ZByteWriterTrait};
13use zune_core::colorspace::ColorSpace;
14use zune_core::options::EncoderOptions;
15pub use zune_hdr::*;
16
17use crate::codecs::{create_options_for_encoder, ImageFormat};
18use crate::errors::{ImageErrors, ImgEncodeErrors};
19use crate::image::Image;
20use crate::metadata::ImageMetadata;
21use crate::traits::{DecodeInto, DecoderTrait, EncoderTrait};
22
23impl<T> DecoderTrait for HdrDecoder<T>
24where
25 T: ZByteReaderTrait
26{
27 fn decode(&mut self) -> Result<Image, ImageErrors> {
28 let bytes = self.decode()?;
29 let (width, height) = self.dimensions().unwrap();
30 let colorspace = self.get_colorspace().unwrap();
31
32 Ok(Image::from_f32(&bytes, width, height, colorspace))
33 }
34
35 fn dimensions(&self) -> Option<(usize, usize)> {
36 self.dimensions()
37 }
38
39 fn out_colorspace(&self) -> ColorSpace {
40 self.get_colorspace().unwrap()
41 }
42
43 fn name(&self) -> &'static str {
44 "HDR decoder"
45 }
46
47 fn read_headers(&mut self) -> Result<Option<ImageMetadata>, ImageErrors> {
48 self.decode_headers()?;
49
50 let (width, height) = self.dimensions().unwrap();
51
52 let metadata = ImageMetadata {
53 width,
54 height,
55 colorspace: ColorSpace::RGB,
56 depth: BitDepth::Float32,
57 format: Some(ImageFormat::HDR),
58 ..Default::default()
59 };
60 Ok(Some(metadata))
61 }
62}
63
64impl From<HdrDecodeErrors> for ImageErrors {
65 fn from(value: HdrDecodeErrors) -> Self {
66 Self::ImageDecodeErrors(format!("hdr: {value:?}"))
67 }
68}
69
70#[derive(Default)]
71pub struct HdrEncoder {
72 options: Option<EncoderOptions>
73}
74
75impl HdrEncoder {
76 pub fn new() -> HdrEncoder {
77 Self::default()
78 }
79 pub fn new_with_options(options: EncoderOptions) -> HdrEncoder {
80 HdrEncoder {
81 options: Some(options)
82 }
83 }
84}
85
86impl EncoderTrait for HdrEncoder {
87 fn name(&self) -> &'static str {
88 "Hdr"
89 }
90
91 fn encode_inner<T: ZByteWriterTrait>(
92 &mut self, image: &Image, sink: T
93 ) -> Result<usize, ImageErrors> {
94 let options = create_options_for_encoder(self.options, image);
95
96 assert_eq!(image.depth(), BitDepth::Float32);
97
98 let data = &image.flatten_frames()[0];
99
100 let encoder_options = zune_hdr::HdrEncoder::new(data, options);
101
102 let data = encoder_options
103 .encode(sink)
104 .map_err(<HdrEncodeErrors as Into<ImgEncodeErrors>>::into)?;
105
106 Ok(data)
107 }
108 fn supported_colorspaces(&self) -> &'static [ColorSpace] {
109 &[ColorSpace::RGB]
110 }
111
112 fn format(&self) -> ImageFormat {
113 ImageFormat::HDR
114 }
115
116 fn supported_bit_depth(&self) -> &'static [BitDepth] {
117 &[BitDepth::Float32]
118 }
119
120 fn default_depth(&self, _: BitDepth) -> BitDepth {
121 BitDepth::Float32
122 }
123
124 fn default_colorspace(&self, _: ColorSpace) -> ColorSpace {
125 ColorSpace::RGB
126 }
127
128 fn set_options(&mut self, opts: EncoderOptions) {
129 self.options = Some(opts)
130 }
131}
132
133impl From<HdrEncodeErrors> for ImgEncodeErrors {
134 fn from(value: HdrEncodeErrors) -> Self {
135 ImgEncodeErrors::ImageEncodeErrors(format!("HDR: {:?}", value))
136 }
137}
138
139impl<T> DecodeInto for HdrDecoder<T>
140where
141 T: ZByteReaderTrait
142{
143 type BufferType = f32;
144
145 fn decode_into(&mut self, buffer: &mut [Self::BufferType]) -> Result<(), ImageErrors> {
146 self.decode_into(buffer)
147 .map_err(<HdrDecodeErrors as Into<ImageErrors>>::into)?;
148
149 Ok(())
150 }
151
152 fn decode_output_buffer_size(&mut self) -> Result<usize, ImageErrors> {
153 self.decode_headers()
154 .map_err(<HdrDecodeErrors as Into<ImageErrors>>::into)?;
155
156 Ok(self.output_buffer_size().unwrap())
158 }
159}