exr/image/write/
layers.rs1use crate::meta::header::{ImageAttributes, Header};
4use crate::meta::{Headers, compute_chunk_count};
5use crate::block::BlockIndex;
6use crate::image::{Layers, Layer};
7use crate::meta::attribute::{TileDescription};
8use crate::prelude::{SmallVec};
9use crate::image::write::channels::{WritableChannels, ChannelsWriter};
10use crate::image::recursive::{Recursive, NoneMore};
11
12pub trait WritableLayers<'slf> {
14
15 fn infer_headers(&self, image_attributes: &ImageAttributes) -> Headers;
17
18 type Writer: LayersWriter;
20
21 fn create_writer(&'slf self, headers: &[Header]) -> Self::Writer;
23}
24
25pub trait LayersWriter: Sync {
27
28 fn extract_uncompressed_block(&self, headers: &[Header], block: BlockIndex) -> Vec<u8>;
30}
31
32#[derive(Debug, Clone, Eq, PartialEq)]
34pub struct AllLayersWriter<ChannelsWriter> {
35 layers: SmallVec<[LayerWriter<ChannelsWriter>; 2]>
36}
37
38#[derive(Debug, Clone, Eq, PartialEq)]
40pub struct LayerWriter<ChannelsWriter> {
41 channels: ChannelsWriter, }
43
44impl<'slf, Channels: 'slf> WritableLayers<'slf> for Layers<Channels> where Channels: WritableChannels<'slf> {
46 fn infer_headers(&self, image_attributes: &ImageAttributes) -> Headers {
47 slice_infer_headers(self.as_slice(), image_attributes)
48 }
49
50 type Writer = AllLayersWriter<Channels::Writer>;
51 fn create_writer(&'slf self, headers: &[Header]) -> Self::Writer {
52 slice_create_writer(self.as_slice(), headers)
53 }
54}
55
56fn slice_infer_headers<'slf, Channels:'slf + WritableChannels<'slf>>(
57 slice: &[Layer<Channels>], image_attributes: &ImageAttributes
58) -> Headers
59{
60 slice.iter().map(|layer| layer.infer_headers(image_attributes).remove(0)).collect() }
62
63fn slice_create_writer<'slf, Channels:'slf + WritableChannels<'slf>>(
64 slice: &'slf [Layer<Channels>], headers: &[Header]
65) -> AllLayersWriter<Channels::Writer>
66{
67 AllLayersWriter {
68 layers: slice.iter().zip(headers.chunks_exact(1)) .map(|(layer, header)| layer.create_writer(header))
70 .collect()
71 }
72}
73
74
75impl<'slf, Channels: WritableChannels<'slf>> WritableLayers<'slf> for Layer<Channels> {
76 fn infer_headers(&self, image_attributes: &ImageAttributes) -> Headers {
77 let blocks = match self.encoding.blocks {
78 crate::image::Blocks::ScanLines => crate::meta::BlockDescription::ScanLines,
79 crate::image::Blocks::Tiles(tile_size) => {
80 let (level_mode, rounding_mode) = self.channel_data.infer_level_modes();
81 crate::meta::BlockDescription::Tiles(TileDescription { level_mode, rounding_mode, tile_size, })
82 },
83 };
84
85 let chunk_count = compute_chunk_count(
86 self.encoding.compression, self.size, blocks
87 );
88
89 let header = Header {
90 channels: self.channel_data.infer_channel_list(),
91 compression: self.encoding.compression,
92
93 blocks,
94 chunk_count,
95
96 line_order: self.encoding.line_order,
97 layer_size: self.size,
98 shared_attributes: image_attributes.clone(),
99 own_attributes: self.attributes.clone(),
100
101
102 deep: false, deep_data_version: None,
104 max_samples_per_pixel: None,
105 };
106
107 smallvec![ header ]}
109
110 type Writer = LayerWriter<Channels::Writer>;
111 fn create_writer(&'slf self, headers: &[Header]) -> Self::Writer {
112 let channels = self.channel_data
113 .create_writer(headers.first().expect("inferred header error")); LayerWriter { channels }
116 }
117}
118
119impl<C> LayersWriter for AllLayersWriter<C> where C: ChannelsWriter {
120 fn extract_uncompressed_block(&self, headers: &[Header], block: BlockIndex) -> Vec<u8> {
121 self.layers[block.layer].extract_uncompressed_block(std::slice::from_ref(&headers[block.layer]), block) }
123}
124
125impl<C> LayersWriter for LayerWriter<C> where C: ChannelsWriter {
126 fn extract_uncompressed_block(&self, headers: &[Header], block: BlockIndex) -> Vec<u8> {
127 self.channels.extract_uncompressed_block(headers.first().expect("invalid inferred header"), block) }
129}
130
131
132
133
134
135impl<'slf> WritableLayers<'slf> for NoneMore {
136 fn infer_headers(&self, _: &ImageAttributes) -> Headers { SmallVec::new() }
137
138 type Writer = NoneMore;
139 fn create_writer(&'slf self, _: &[Header]) -> Self::Writer { NoneMore }
140}
141
142impl<'slf, InnerLayers, Channels> WritableLayers<'slf> for Recursive<InnerLayers, Layer<Channels>>
143 where InnerLayers: WritableLayers<'slf>, Channels: WritableChannels<'slf>
144{
145 fn infer_headers(&self, image_attributes: &ImageAttributes) -> Headers {
146 let mut headers = self.inner.infer_headers(image_attributes);
147 headers.push(self.value.infer_headers(image_attributes).remove(0)); headers
149 }
150
151 type Writer = RecursiveLayersWriter<InnerLayers::Writer, Channels::Writer>;
152
153 fn create_writer(&'slf self, headers: &[Header]) -> Self::Writer {
154 let (own_header, inner_headers) = headers.split_last()
155 .expect("header has not been inferred correctly");
156
157 let layer_index = inner_headers.len();
158 RecursiveLayersWriter {
159 inner: self.inner.create_writer(inner_headers),
160 value: (layer_index, self.value.create_writer(std::slice::from_ref(own_header))) }
162 }
163}
164
165type RecursiveLayersWriter<InnerLayersWriter, ChannelsWriter> = Recursive<InnerLayersWriter, (usize, LayerWriter<ChannelsWriter>)>;
166
167impl LayersWriter for NoneMore {
168 fn extract_uncompressed_block(&self, _: &[Header], _: BlockIndex) -> Vec<u8> {
169 panic!("recursive length mismatch bug");
170 }
171}
172
173impl<InnerLayersWriter, Channels> LayersWriter for RecursiveLayersWriter<InnerLayersWriter, Channels>
174 where InnerLayersWriter: LayersWriter, Channels: ChannelsWriter
175{
176 fn extract_uncompressed_block(&self, headers: &[Header], block: BlockIndex) -> Vec<u8> {
177 let (layer_index, layer) = &self.value;
178 if *layer_index == block.layer {
179 let header = headers.get(*layer_index).expect("layer index bug");
180 layer.extract_uncompressed_block(std::slice::from_ref(header), block) }
182 else {
183 self.inner.extract_uncompressed_block(headers, block)
184 }
185 }
186}
187
188