1//! How to write either a single or a list of layers.
2
3use 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
12/// Enables an image containing this list of layers to be written to a file.
13pub trait WritableLayers<'slf> {
14
15 /// Generate the file meta data for this list of layers
16 fn infer_headers(&self, image_attributes: &ImageAttributes) -> Headers;
17
18 /// The type of temporary writer
19 type Writer: LayersWriter;
20
21 /// Create a temporary writer for this list of layers
22 fn create_writer(&'slf self, headers: &[Header]) -> Self::Writer;
23}
24
25/// A temporary writer for a list of channels
26pub trait LayersWriter: Sync {
27
28 /// Deliver a block of pixels from a single layer to be stored in the file
29 fn extract_uncompressed_block(&self, headers: &[Header], block: BlockIndex) -> Vec<u8>;
30}
31
32/// A temporary writer for an arbitrary list of layers
33#[derive(Debug, Clone, Eq, PartialEq)]
34pub struct AllLayersWriter<ChannelsWriter> {
35 layers: SmallVec<[LayerWriter<ChannelsWriter>; 2]>
36}
37
38/// A temporary writer for a single layer
39#[derive(Debug, Clone, Eq, PartialEq)]
40pub struct LayerWriter<ChannelsWriter> {
41 channels: ChannelsWriter, // impl ChannelsWriter
42}
43
44// impl for smallvec
45impl<'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| layer.infer_headers(image_attributes).remove(index:0)).collect() // TODO no array-vs-first
61}
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: sliceimpl Iterator>.iter().zip(headers.chunks_exact(chunk_size:1)) // TODO no array-vs-first
69 .map(|(layer: &Layer, header: &[Header])| layer.create_writer(headers: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, // TODO deep data
103 deep_data_version: None,
104 max_samples_per_pixel: None,
105 };
106
107 smallvec![ header ]// TODO no array-vs-first
108 }
109
110 type Writer = LayerWriter</*'l,*/ 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")); // TODO no array-vs-first
114
115 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(headers:std::slice::from_ref(&headers[block.layer]), block) // TODO no array-vs-first
122 }
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(header:headers.first().expect(msg:"invalid inferred header"), block) // TODO no array-vs-first
128 }
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: SmallVec<[Header; 3]> = self.inner.infer_headers(image_attributes);
147 headers.push(self.value.infer_headers(image_attributes).remove(index:0)); // TODO no unwrap
148 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: &Header, inner_headers: &[Header]) = headers.split_last()
155 .expect(msg:"header has not been inferred correctly");
156
157 let layer_index: usize = inner_headers.len();
158 RecursiveLayersWriter {
159 inner: self.inner.create_writer(inner_headers),
160 value: (layer_index, self.value.create_writer(headers:std::slice::from_ref(own_header))) // TODO no slice
161 }
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: &usize, layer: &LayerWriter) = &self.value;
178 if *layer_index == block.layer {
179 let header: &Header = headers.get(*layer_index).expect(msg:"layer index bug");
180 layer.extract_uncompressed_block(headers:std::slice::from_ref(header), block) // TODO no slice?
181 }
182 else {
183 self.inner.extract_uncompressed_block(headers, block)
184 }
185 }
186}
187
188
189