| 1 | //! How to write either a single or a list of layers.
|
| 2 |
|
| 3 | use crate::meta::header::{ImageAttributes, Header};
|
| 4 | use crate::meta::{Headers, compute_chunk_count};
|
| 5 | use crate::block::BlockIndex;
|
| 6 | use crate::image::{Layers, Layer};
|
| 7 | use crate::meta::attribute::{TileDescription};
|
| 8 | use crate::prelude::{SmallVec};
|
| 9 | use crate::image::write::channels::{WritableChannels, ChannelsWriter};
|
| 10 | use crate::image::recursive::{Recursive, NoneMore};
|
| 11 |
|
| 12 | /// Enables an image containing this list of layers to be written to a file.
|
| 13 | pub 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
|
| 26 | pub 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)]
|
| 34 | pub 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)]
|
| 40 | pub struct LayerWriter<ChannelsWriter> {
|
| 41 | channels: ChannelsWriter, // impl ChannelsWriter
|
| 42 | }
|
| 43 |
|
| 44 | // impl for smallvec
|
| 45 | impl<'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 |
|
| 56 | fn 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 |
|
| 63 | fn 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 |
|
| 75 | impl<'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 |
|
| 119 | impl<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 |
|
| 125 | impl<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 |
|
| 135 | impl<'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 |
|
| 142 | impl<'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 |
|
| 165 | type RecursiveLayersWriter<InnerLayersWriter, ChannelsWriter> = Recursive<InnerLayersWriter, (usize, LayerWriter<ChannelsWriter>)>;
|
| 166 |
|
| 167 | impl LayersWriter for NoneMore {
|
| 168 | fn extract_uncompressed_block(&self, _: &[Header], _: BlockIndex) -> Vec<u8> {
|
| 169 | panic!("recursive length mismatch bug" );
|
| 170 | }
|
| 171 | }
|
| 172 |
|
| 173 | impl<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 | |