1use crate::image::recursive::*;
5use crate::block::samples::*;
6use crate::image::*;
7use crate::math::*;
8use crate::meta::header::*;
9use crate::error::*;
10use crate::block::UncompressedBlock;
11use crate::image::read::layers::{ChannelsReader, ReadChannels};
12use crate::block::chunk::TileCoordinates;
13
14use std::marker::PhantomData;
15use crate::io::Read;
16
17
18pub trait ReadSpecificChannel: Sized + CheckDuplicates {
22
23 type RecursivePixelReader: RecursivePixelReader;
26
27 fn create_recursive_reader(&self, channels: &ChannelList) -> Result<Self::RecursivePixelReader>;
29
30 fn required<Sample>(self, channel_name: impl Into<Text>) -> ReadRequiredChannel<Self, Sample> {
34 let channel_name = channel_name.into();
35 assert!(self.already_contains(&channel_name).not(), "a channel with the name `{}` is already defined", channel_name);
36 ReadRequiredChannel { channel_name, previous_channels: self, px: Default::default() }
37 }
38
39 fn optional<Sample>(self, channel_name: impl Into<Text>, default_sample: Sample)
45 -> ReadOptionalChannel<Self, Sample>
46 {
47 let channel_name = channel_name.into();
48 assert!(self.already_contains(&channel_name).not(), "a channel with the name `{}` is already defined", channel_name);
49 ReadOptionalChannel { channel_name, previous_channels: self, default_sample }
50 }
51
52 fn collect_pixels<Pixel, PixelStorage, CreatePixels, SetPixel>(
58 self, create_pixels: CreatePixels, set_pixel: SetPixel
59 ) -> CollectPixels<Self, Pixel, PixelStorage, CreatePixels, SetPixel>
60 where
61 <Self::RecursivePixelReader as RecursivePixelReader>::RecursivePixel: IntoTuple<Pixel>,
62 <Self::RecursivePixelReader as RecursivePixelReader>::RecursiveChannelDescriptions: IntoNonRecursive,
63 CreatePixels: Fn(
64 Vec2<usize>,
65 &<<Self::RecursivePixelReader as RecursivePixelReader>::RecursiveChannelDescriptions as IntoNonRecursive>::NonRecursive
66 ) -> PixelStorage,
67 SetPixel: Fn(&mut PixelStorage, Vec2<usize>, Pixel),
68 {
69 CollectPixels { read_channels: self, set_pixel, create_pixels, px: Default::default() }
70 }
71}
72
73pub trait RecursivePixelReader {
75
76 type RecursiveChannelDescriptions;
79
80 fn get_descriptions(&self) -> Self::RecursiveChannelDescriptions;
82
83 type RecursivePixel: Copy + Default + 'static;
85
86 fn read_pixels<'s, FullPixel>(
88 &self, bytes: &'s[u8], pixels: &mut [FullPixel],
89 get_pixel: impl Fn(&mut FullPixel) -> &mut Self::RecursivePixel
90 );
91}
92
93#[derive(Clone, Debug)]
97pub struct ReadOptionalChannel<ReadChannels, Sample> {
98 previous_channels: ReadChannels,
99 channel_name: Text,
100 default_sample: Sample,
101}
102
103#[derive(Clone, Debug)]
107pub struct ReadRequiredChannel<ReadChannels, Sample> {
108 previous_channels: ReadChannels,
109 channel_name: Text,
110 px: PhantomData<Sample>,
111}
112
113#[derive(Copy, Clone, Debug)]
115pub struct CollectPixels<ReadChannels, Pixel, PixelStorage, CreatePixels, SetPixel> {
116 read_channels: ReadChannels,
117 create_pixels: CreatePixels,
118 set_pixel: SetPixel,
119 px: PhantomData<(Pixel, PixelStorage)>,
120}
121
122impl<Inner: CheckDuplicates, Sample> CheckDuplicates for ReadRequiredChannel<Inner, Sample> {
123 fn already_contains(&self, name: &Text) -> bool {
124 &self.channel_name == name || self.previous_channels.already_contains(name)
125 }
126}
127
128impl<Inner: CheckDuplicates, Sample> CheckDuplicates for ReadOptionalChannel<Inner, Sample> {
129 fn already_contains(&self, name: &Text) -> bool {
130 &self.channel_name == name || self.previous_channels.already_contains(name)
131 }
132}
133
134impl<'s, InnerChannels, Pixel, PixelStorage, CreatePixels, SetPixel: 's>
135ReadChannels<'s> for CollectPixels<InnerChannels, Pixel, PixelStorage, CreatePixels, SetPixel>
136 where
137 InnerChannels: ReadSpecificChannel,
138 <InnerChannels::RecursivePixelReader as RecursivePixelReader>::RecursivePixel: IntoTuple<Pixel>,
139 <InnerChannels::RecursivePixelReader as RecursivePixelReader>::RecursiveChannelDescriptions: IntoNonRecursive,
140 CreatePixels: Fn(Vec2<usize>, &<<InnerChannels::RecursivePixelReader as RecursivePixelReader>::RecursiveChannelDescriptions as IntoNonRecursive>::NonRecursive) -> PixelStorage,
141 SetPixel: Fn(&mut PixelStorage, Vec2<usize>, Pixel),
142{
143 type Reader = SpecificChannelsReader<
144 PixelStorage, &'s SetPixel,
145 InnerChannels::RecursivePixelReader,
146 Pixel,
147 >;
148
149 fn create_channels_reader(&'s self, header: &Header) -> Result<Self::Reader> {
150 if header.deep { return Err(Error::invalid("`SpecificChannels` does not support deep data yet")) }
151
152 let pixel_reader = self.read_channels.create_recursive_reader(&header.channels)?;
153 let channel_descriptions = pixel_reader.get_descriptions().into_non_recursive();let create = &self.create_pixels;
156 let pixel_storage = create(header.layer_size, &channel_descriptions);
157
158 Ok(SpecificChannelsReader {
159 set_pixel: &self.set_pixel,
160 pixel_storage,
161 pixel_reader,
162 px: Default::default()
163 })
164 }
165}
166
167#[derive(Copy, Clone, Debug)]
169pub struct SpecificChannelsReader<PixelStorage, SetPixel, PixelReader, Pixel> {
170 set_pixel: SetPixel,
171 pixel_storage: PixelStorage,
172 pixel_reader: PixelReader,
173 px: PhantomData<Pixel>
174}
175
176impl<PixelStorage, SetPixel, PxReader, Pixel>
177ChannelsReader for SpecificChannelsReader<PixelStorage, SetPixel, PxReader, Pixel>
178 where PxReader: RecursivePixelReader,
179 PxReader::RecursivePixel: IntoTuple<Pixel>,
180 PxReader::RecursiveChannelDescriptions: IntoNonRecursive,
181 SetPixel: Fn(&mut PixelStorage, Vec2<usize>, Pixel),
182{
183 type Channels = SpecificChannels<PixelStorage, <PxReader::RecursiveChannelDescriptions as IntoNonRecursive>::NonRecursive>;
184
185 fn filter_block(&self, tile: TileCoordinates) -> bool { tile.is_largest_resolution_level() } fn read_block(&mut self, header: &Header, block: UncompressedBlock) -> UnitResult {
188 let mut pixels = vec![PxReader::RecursivePixel::default(); block.index.pixel_size.width()]; let byte_lines = block.data.chunks_exact(header.channels.bytes_per_pixel * block.index.pixel_size.width());
191 debug_assert_eq!(byte_lines.len(), block.index.pixel_size.height(), "invalid block lines split");
192
193 for (y_offset, line_bytes) in byte_lines.enumerate() { self.pixel_reader.read_pixels(line_bytes, &mut pixels, |px| px);
196
197 for (x_offset, pixel) in pixels.iter().enumerate() {
198 let set_pixel = &self.set_pixel;
199 set_pixel(&mut self.pixel_storage, block.index.pixel_position + Vec2(x_offset, y_offset), pixel.into_tuple());
200 }
201 }
202
203 Ok(())
204 }
205
206 fn into_channels(self) -> Self::Channels {
207 SpecificChannels { channels: self.pixel_reader.get_descriptions().into_non_recursive(), pixels: self.pixel_storage }
208 }
209}
210
211
212pub type ReadZeroChannels = NoneMore;
215
216impl ReadSpecificChannel for NoneMore {
217 type RecursivePixelReader = NoneMore;
218 fn create_recursive_reader(&self, _: &ChannelList) -> Result<Self::RecursivePixelReader> { Ok(NoneMore) }
219}
220
221impl<DefaultSample, ReadChannels> ReadSpecificChannel for ReadOptionalChannel<ReadChannels, DefaultSample>
222 where ReadChannels: ReadSpecificChannel, DefaultSample: FromNativeSample + 'static,
223{
224 type RecursivePixelReader = Recursive<ReadChannels::RecursivePixelReader, OptionalSampleReader<DefaultSample>>;
225
226 fn create_recursive_reader(&self, channels: &ChannelList) -> Result<Self::RecursivePixelReader> {
227 debug_assert!(self.previous_channels.already_contains(&self.channel_name).not(), "duplicate channel name: {}", self.channel_name);
228
229 let inner_samples_reader = self.previous_channels.create_recursive_reader(channels)?;
230 let reader = channels.channels_with_byte_offset()
231 .find(|(_, channel)| channel.name == self.channel_name)
232 .map(|(channel_byte_offset, channel)| SampleReader {
233 channel_byte_offset, channel: channel.clone(),
234 px: Default::default()
235 });
236
237 Ok(Recursive::new(inner_samples_reader, OptionalSampleReader {
238 reader, default_sample: self.default_sample,
239 }))
240 }
241}
242
243impl<Sample, ReadChannels> ReadSpecificChannel for ReadRequiredChannel<ReadChannels, Sample>
244 where ReadChannels: ReadSpecificChannel, Sample: FromNativeSample + 'static
245{
246 type RecursivePixelReader = Recursive<ReadChannels::RecursivePixelReader, SampleReader<Sample>>;
247
248 fn create_recursive_reader(&self, channels: &ChannelList) -> Result<Self::RecursivePixelReader> {
249 let previous_samples_reader = self.previous_channels.create_recursive_reader(channels)?;
250 let (channel_byte_offset, channel) = channels.channels_with_byte_offset()
251 .find(|(_, channel)| channel.name == self.channel_name)
252 .ok_or_else(|| Error::invalid(format!(
253 "layer does not contain all of your specified channels (`{}` is missing)",
254 self.channel_name
255 )))?;
256
257 Ok(Recursive::new(previous_samples_reader, SampleReader { channel_byte_offset, channel: channel.clone(), px: Default::default() }))
258 }
259}
260
261#[derive(Clone, Debug)]
263pub struct SampleReader<Sample> {
264
265 channel_byte_offset: usize,
267
268 channel: ChannelDescription,
269 px: PhantomData<Sample>
270}
271
272#[derive(Clone, Debug)]
275pub struct OptionalSampleReader<DefaultSample> {
276 reader: Option<SampleReader<DefaultSample>>,
277 default_sample: DefaultSample,
278}
279
280impl<Sample: FromNativeSample> SampleReader<Sample> {
281 fn read_own_samples<'s, FullPixel>(
282 &self, bytes: &'s[u8], pixels: &mut [FullPixel],
283 get_sample: impl Fn(&mut FullPixel) -> &mut Sample
284 ){
285 let start_index = pixels.len() * self.channel_byte_offset;
286 let byte_count = pixels.len() * self.channel.sample_type.bytes_per_sample();
287 let mut own_bytes_reader = &mut &bytes[start_index .. start_index + byte_count]; let mut samples_out = pixels.iter_mut().map(|pixel| get_sample(pixel));
289
290 match self.channel.sample_type {
292 SampleType::F16 => read_and_convert_all_samples_batched(
293 &mut own_bytes_reader, &mut samples_out,
294 Sample::from_f16s
295 ),
296
297 SampleType::F32 => read_and_convert_all_samples_batched(
298 &mut own_bytes_reader, &mut samples_out,
299 Sample::from_f32s
300 ),
301
302 SampleType::U32 => read_and_convert_all_samples_batched(
303 &mut own_bytes_reader, &mut samples_out,
304 Sample::from_u32s
305 ),
306 }
307
308 debug_assert!(samples_out.next().is_none(), "not all samples have been converted");
309 debug_assert!(own_bytes_reader.is_empty(), "bytes left after reading all samples");
310 }
311}
312
313
314fn read_and_convert_all_samples_batched<'t, From, To>(
320 mut in_bytes: impl Read,
321 out_samples: &mut impl ExactSizeIterator<Item=&'t mut To>,
322 convert_batch: fn(&[From], &mut [To])
323) where From: Data + Default + Copy, To: 't + Default + Copy
324{
325 #[allow(non_upper_case_globals)]
327 const batch_size: usize = 16;
328
329 let total_sample_count = out_samples.len();
330 let batch_count = total_sample_count / batch_size;
331 let remaining_samples_count = total_sample_count % batch_size;
332
333 let len_error_msg = "sample count was miscalculated";
334 let byte_error_msg = "error when reading from in-memory slice";
335
336 let output_n_samples = &mut move |samples: &[To]| {
338 for converted_sample in samples {
339 *out_samples.next().expect(len_error_msg) = *converted_sample;
340 }
341 };
342
343 let read_n_samples = &mut move |samples: &mut [From]| {
348 Data::read_slice_ne(&mut in_bytes, samples).expect(byte_error_msg);
349 };
350
351 let mut source_samples_batch: [From; batch_size] = Default::default();
353 let mut desired_samples_batch: [To; batch_size] = Default::default();
354
355 for _ in 0 .. batch_count {
357 read_n_samples(&mut source_samples_batch);
358 convert_batch(source_samples_batch.as_slice(), desired_samples_batch.as_mut_slice());
359 output_n_samples(&desired_samples_batch);
360 }
361
362 if remaining_samples_count != 0 {
364 let source_samples_batch = &mut source_samples_batch[..remaining_samples_count];
365 let desired_samples_batch = &mut desired_samples_batch[..remaining_samples_count];
366
367 read_n_samples(source_samples_batch);
368 convert_batch(source_samples_batch, desired_samples_batch);
369 output_n_samples(desired_samples_batch);
370 }
371}
372
373#[cfg(test)]
374mod test {
375 use super::*;
376
377 #[test]
378 fn equals_naive_f32(){
379 for total_array_size in [3, 7, 30, 41, 120, 10_423] {
380 let input_f32s = (0..total_array_size).map(|_| rand::random::<f32>()).collect::<Vec<f32>>();
381 let in_f32s_bytes = input_f32s.iter().cloned().flat_map(f32::to_ne_bytes).collect::<Vec<u8>>();
382
383 let mut out_f16_samples_batched = vec![
384 f16::from_f32(rand::random::<f32>());
385 total_array_size
386 ];
387
388 read_and_convert_all_samples_batched(
389 &mut in_f32s_bytes.as_slice(),
390 &mut out_f16_samples_batched.iter_mut(),
391 f16::from_f32s
392 );
393
394 let out_f16_samples_naive = input_f32s.iter()
395 .cloned().map(f16::from_f32);
396
397 assert!(out_f16_samples_naive.eq(out_f16_samples_batched));
398 }
399 }
400}
401
402
403impl RecursivePixelReader for NoneMore {
404 type RecursiveChannelDescriptions = NoneMore;
405 fn get_descriptions(&self) -> Self::RecursiveChannelDescriptions { NoneMore }
406
407 type RecursivePixel = NoneMore;
408
409 fn read_pixels<'s, FullPixel>(
410 &self, _: &'s[u8], _: &mut [FullPixel],
411 _: impl Fn(&mut FullPixel) -> &mut NoneMore
412 ){}
413}
414
415impl<Sample, InnerReader: RecursivePixelReader>
416 RecursivePixelReader
417 for Recursive<InnerReader, SampleReader<Sample>>
418 where Sample: FromNativeSample + 'static
419{
420 type RecursiveChannelDescriptions = Recursive<InnerReader::RecursiveChannelDescriptions, ChannelDescription>;
421 fn get_descriptions(&self) -> Self::RecursiveChannelDescriptions { Recursive::new(self.inner.get_descriptions(), self.value.channel.clone()) }
422
423 type RecursivePixel = Recursive<InnerReader::RecursivePixel, Sample>;
424
425 fn read_pixels<'s, FullPixel>(
426 &self, bytes: &'s[u8], pixels: &mut [FullPixel],
427 get_pixel: impl Fn(&mut FullPixel) -> &mut Self::RecursivePixel
428 ) {
429 self.value.read_own_samples(bytes, pixels, |px| &mut get_pixel(px).value);
430 self.inner.read_pixels(bytes, pixels, |px| &mut get_pixel(px).inner);
431 }
432}
433
434impl<Sample, InnerReader: RecursivePixelReader>
435RecursivePixelReader
436for Recursive<InnerReader, OptionalSampleReader<Sample>>
437 where Sample: FromNativeSample + 'static
438{
439 type RecursiveChannelDescriptions = Recursive<InnerReader::RecursiveChannelDescriptions, Option<ChannelDescription>>;
440 fn get_descriptions(&self) -> Self::RecursiveChannelDescriptions { Recursive::new(
441 self.inner.get_descriptions(), self.value.reader.as_ref().map(|reader| reader.channel.clone())
442 ) }
443
444 type RecursivePixel = Recursive<InnerReader::RecursivePixel, Sample>;
445
446 fn read_pixels<'s, FullPixel>(
447 &self, bytes: &'s[u8], pixels: &mut [FullPixel],
448 get_pixel: impl Fn(&mut FullPixel) -> &mut Self::RecursivePixel
449 ) {
450 if let Some(reader) = &self.value.reader {
451 reader.read_own_samples(bytes, pixels, |px| &mut get_pixel(px).value);
452 }
453 else {
454 for pixel in pixels.iter_mut() {
456 get_pixel(pixel).value = self.value.default_sample;
457 }
458 }
459
460 self.inner.read_pixels(bytes, pixels, |px| &mut get_pixel(px).inner);
461 }
462}
463
464