glycin_common/
memory_format.rs

1use std::io::Read;
2
3use serde::{Deserialize, Serialize};
4use zerocopy::{FromBytes, IntoBytes};
5use zvariant::Type;
6
7pub trait MemoryFormatInfo: Sized {
8    fn n_bytes(self) -> MemoryFormatBytes;
9    fn n_channels(self) -> u8;
10}
11
12gufo_common::maybe_convertible_enum!(
13    #[repr(i32)]
14    #[derive(Deserialize, Serialize, Type, Debug, Clone, Copy, PartialEq, Eq)]
15    #[cfg_attr(feature = "gobject", derive(glib::Enum))]
16    #[cfg_attr(feature = "gobject", enum_type(name = "GlyMemoryFormat"))]
17    #[zvariant(signature = "u")]
18    /// Describes the formats the image data can have.
19    pub enum MemoryFormat {
20        B8g8r8a8Premultiplied = 0,
21        A8r8g8b8Premultiplied = 1,
22        R8g8b8a8Premultiplied = 2,
23        B8g8r8a8 = 3,
24        A8r8g8b8 = 4,
25        R8g8b8a8 = 5,
26        A8b8g8r8 = 6,
27        R8g8b8 = 7,
28        B8g8r8 = 8,
29        R16g16b16 = 9,
30        R16g16b16a16Premultiplied = 10,
31        R16g16b16a16 = 11,
32        R16g16b16Float = 12,
33        R16g16b16a16Float = 13,
34        R32g32b32Float = 14,
35        R32g32b32a32FloatPremultiplied = 15,
36        R32g32b32a32Float = 16,
37        G8a8Premultiplied = 17,
38        G8a8 = 18,
39        G8 = 19,
40        G16a16Premultiplied = 20,
41        G16a16 = 21,
42        G16 = 22,
43    }
44);
45
46impl MemoryFormatInfo for MemoryFormat {
47    fn n_bytes(self) -> MemoryFormatBytes {
48        match self {
49            MemoryFormat::B8g8r8a8Premultiplied => MemoryFormatBytes::B4,
50            MemoryFormat::A8r8g8b8Premultiplied => MemoryFormatBytes::B4,
51            MemoryFormat::R8g8b8a8Premultiplied => MemoryFormatBytes::B4,
52            MemoryFormat::B8g8r8a8 => MemoryFormatBytes::B4,
53            MemoryFormat::A8r8g8b8 => MemoryFormatBytes::B4,
54            MemoryFormat::R8g8b8a8 => MemoryFormatBytes::B4,
55            MemoryFormat::A8b8g8r8 => MemoryFormatBytes::B4,
56            MemoryFormat::R8g8b8 => MemoryFormatBytes::B3,
57            MemoryFormat::B8g8r8 => MemoryFormatBytes::B3,
58            MemoryFormat::R16g16b16 => MemoryFormatBytes::B6,
59            MemoryFormat::R16g16b16a16Premultiplied => MemoryFormatBytes::B8,
60            MemoryFormat::R16g16b16a16 => MemoryFormatBytes::B8,
61            MemoryFormat::R16g16b16Float => MemoryFormatBytes::B6,
62            MemoryFormat::R16g16b16a16Float => MemoryFormatBytes::B8,
63            MemoryFormat::R32g32b32Float => MemoryFormatBytes::B12,
64            MemoryFormat::R32g32b32a32FloatPremultiplied => MemoryFormatBytes::B16,
65            MemoryFormat::R32g32b32a32Float => MemoryFormatBytes::B16,
66            MemoryFormat::G8a8Premultiplied => MemoryFormatBytes::B2,
67            MemoryFormat::G8a8 => MemoryFormatBytes::B2,
68            MemoryFormat::G8 => MemoryFormatBytes::B1,
69            MemoryFormat::G16a16Premultiplied => MemoryFormatBytes::B4,
70            MemoryFormat::G16a16 => MemoryFormatBytes::B4,
71            MemoryFormat::G16 => MemoryFormatBytes::B2,
72        }
73    }
74
75    fn n_channels(self) -> u8 {
76        match self {
77            MemoryFormat::B8g8r8a8Premultiplied
78            | MemoryFormat::A8r8g8b8Premultiplied
79            | MemoryFormat::R8g8b8a8Premultiplied
80            | MemoryFormat::B8g8r8a8
81            | MemoryFormat::A8r8g8b8
82            | MemoryFormat::R8g8b8a8
83            | MemoryFormat::A8b8g8r8
84            | MemoryFormat::R16g16b16a16Premultiplied
85            | MemoryFormat::R16g16b16a16
86            | MemoryFormat::R16g16b16a16Float
87            | MemoryFormat::R32g32b32a32FloatPremultiplied
88            | MemoryFormat::R32g32b32a32Float => 4,
89            MemoryFormat::R8g8b8
90            | MemoryFormat::B8g8r8
91            | MemoryFormat::R16g16b16
92            | MemoryFormat::R16g16b16Float
93            | MemoryFormat::R32g32b32Float => 3,
94            MemoryFormat::G8a8Premultiplied
95            | MemoryFormat::G8a8
96            | MemoryFormat::G16a16Premultiplied
97            | MemoryFormat::G16a16 => 2,
98            MemoryFormat::G8 | MemoryFormat::G16 => 1,
99        }
100    }
101}
102
103impl MemoryFormat {
104    pub const fn channel_type(self) -> ChannelType {
105        match self {
106            MemoryFormat::B8g8r8a8Premultiplied
107            | MemoryFormat::A8r8g8b8Premultiplied
108            | MemoryFormat::R8g8b8a8Premultiplied
109            | MemoryFormat::B8g8r8a8
110            | MemoryFormat::A8r8g8b8
111            | MemoryFormat::R8g8b8a8
112            | MemoryFormat::A8b8g8r8
113            | MemoryFormat::R8g8b8
114            | MemoryFormat::B8g8r8
115            | MemoryFormat::G8a8Premultiplied
116            | MemoryFormat::G8a8
117            | MemoryFormat::G8 => ChannelType::U8,
118
119            MemoryFormat::R16g16b16
120            | MemoryFormat::R16g16b16a16Premultiplied
121            | MemoryFormat::R16g16b16a16
122            | MemoryFormat::G16a16Premultiplied
123            | MemoryFormat::G16a16
124            | MemoryFormat::G16 => ChannelType::U16,
125
126            MemoryFormat::R16g16b16Float | MemoryFormat::R16g16b16a16Float => ChannelType::F16,
127
128            MemoryFormat::R32g32b32Float
129            | MemoryFormat::R32g32b32a32FloatPremultiplied
130            | MemoryFormat::R32g32b32a32Float => ChannelType::F32,
131        }
132    }
133
134    pub const fn has_alpha(self) -> bool {
135        match self {
136            MemoryFormat::B8g8r8a8Premultiplied
137            | MemoryFormat::A8r8g8b8Premultiplied
138            | MemoryFormat::R8g8b8a8Premultiplied
139            | MemoryFormat::B8g8r8a8
140            | MemoryFormat::A8r8g8b8
141            | MemoryFormat::R8g8b8a8
142            | MemoryFormat::A8b8g8r8
143            | MemoryFormat::R16g16b16a16Premultiplied
144            | MemoryFormat::R32g32b32a32FloatPremultiplied
145            | MemoryFormat::R32g32b32a32Float
146            | MemoryFormat::G8a8Premultiplied
147            | MemoryFormat::G8a8
148            | MemoryFormat::R16g16b16a16
149            | MemoryFormat::R16g16b16a16Float
150            | MemoryFormat::G16a16Premultiplied
151            | MemoryFormat::G16a16 => true,
152
153            MemoryFormat::R8g8b8
154            | MemoryFormat::B8g8r8
155            | MemoryFormat::R16g16b16
156            | MemoryFormat::R16g16b16Float
157            | MemoryFormat::R32g32b32Float
158            | MemoryFormat::G8
159            | MemoryFormat::G16 => false,
160        }
161    }
162
163    pub const fn is_premultiplied(self) -> bool {
164        match self {
165            MemoryFormat::B8g8r8a8Premultiplied
166            | MemoryFormat::A8r8g8b8Premultiplied
167            | MemoryFormat::R8g8b8a8Premultiplied
168            | MemoryFormat::R16g16b16a16Premultiplied
169            | MemoryFormat::R32g32b32a32FloatPremultiplied
170            | MemoryFormat::G8a8Premultiplied
171            | MemoryFormat::G16a16Premultiplied => true,
172
173            MemoryFormat::B8g8r8a8
174            | MemoryFormat::A8r8g8b8
175            | MemoryFormat::R8g8b8a8
176            | MemoryFormat::A8b8g8r8
177            | MemoryFormat::R8g8b8
178            | MemoryFormat::B8g8r8
179            | MemoryFormat::R16g16b16
180            | MemoryFormat::R16g16b16a16
181            | MemoryFormat::R16g16b16Float
182            | MemoryFormat::R16g16b16a16Float
183            | MemoryFormat::R32g32b32Float
184            | MemoryFormat::R32g32b32a32Float
185            | MemoryFormat::G8a8
186            | MemoryFormat::G8
187            | MemoryFormat::G16a16
188            | MemoryFormat::G16 => false,
189        }
190    }
191
192    /// Defines from which channels to get the RGBA values
193    ///
194    /// The return value is in the order `[R, G, B, A]`.
195    pub const fn source_definition(self) -> [Source; 4] {
196        match self {
197            MemoryFormat::B8g8r8a8Premultiplied | MemoryFormat::B8g8r8a8 => {
198                [Source::C2, Source::C1, Source::C0, Source::C3]
199            }
200
201            MemoryFormat::A8r8g8b8Premultiplied | MemoryFormat::A8r8g8b8 => {
202                [Source::C1, Source::C2, Source::C3, Source::C0]
203            }
204
205            MemoryFormat::R8g8b8a8Premultiplied
206            | MemoryFormat::R8g8b8a8
207            | MemoryFormat::R16g16b16a16Premultiplied
208            | MemoryFormat::R16g16b16a16
209            | MemoryFormat::R16g16b16a16Float
210            | MemoryFormat::R32g32b32a32FloatPremultiplied
211            | MemoryFormat::R32g32b32a32Float => [Source::C0, Source::C1, Source::C2, Source::C3],
212
213            MemoryFormat::A8b8g8r8 => [Source::C1, Source::C2, Source::C3, Source::C0],
214
215            MemoryFormat::R8g8b8
216            | MemoryFormat::R16g16b16
217            | MemoryFormat::R16g16b16Float
218            | MemoryFormat::R32g32b32Float => [Source::C0, Source::C1, Source::C2, Source::Opaque],
219
220            MemoryFormat::B8g8r8 => [Source::C2, Source::C1, Source::C0, Source::Opaque],
221
222            MemoryFormat::G8a8Premultiplied
223            | MemoryFormat::G8a8
224            | MemoryFormat::G16a16Premultiplied
225            | MemoryFormat::G16a16 => [Source::C0, Source::C0, Source::C0, Source::C1],
226
227            MemoryFormat::G8 | MemoryFormat::G16 => {
228                [Source::C0, Source::C0, Source::C0, Source::Opaque]
229            }
230        }
231    }
232
233    pub const fn target_definition(self) -> &'static [Target] {
234        match self {
235            MemoryFormat::B8g8r8a8Premultiplied | MemoryFormat::B8g8r8a8 => {
236                &[Target::B, Target::G, Target::R, Target::A]
237            }
238            MemoryFormat::A8r8g8b8Premultiplied | MemoryFormat::A8r8g8b8 => {
239                &[Target::A, Target::R, Target::G, Target::B]
240            }
241            MemoryFormat::R8g8b8a8Premultiplied
242            | MemoryFormat::R8g8b8a8
243            | MemoryFormat::R16g16b16a16Premultiplied
244            | MemoryFormat::R16g16b16a16
245            | MemoryFormat::R16g16b16a16Float
246            | MemoryFormat::R32g32b32a32FloatPremultiplied
247            | MemoryFormat::R32g32b32a32Float => &[Target::R, Target::G, Target::B, Target::A],
248            MemoryFormat::A8b8g8r8 => &[Target::A, Target::B, Target::G, Target::R],
249            MemoryFormat::R8g8b8
250            | MemoryFormat::R16g16b16
251            | MemoryFormat::R16g16b16Float
252            | MemoryFormat::R32g32b32Float => &[Target::R, Target::G, Target::B],
253            MemoryFormat::B8g8r8 => &[Target::B, Target::G, Target::R],
254            MemoryFormat::G8a8Premultiplied
255            | MemoryFormat::G8a8
256            | MemoryFormat::G16a16Premultiplied
257            | MemoryFormat::G16a16 => &[Target::RgbAvg, Target::A],
258            MemoryFormat::G8 | MemoryFormat::G16 => &[Target::RgbAvg],
259        }
260    }
261
262    #[inline]
263    pub fn transform(src_format: Self, src: &[u8], target_format: Self, target: &mut [u8]) {
264        let channels_f32 = Self::to_f32(src_format, src);
265        Self::from_f32(channels_f32, target_format, target);
266    }
267
268    #[inline]
269    pub fn to_f32(src_format: Self, mut src: &[u8]) -> [f32; 4] {
270        match src_format.channel_type() {
271            ChannelType::U8 => {
272                Self::to_f32_internal::<u8>(FromBytes::ref_from_bytes(src).unwrap(), src_format)
273            }
274            ChannelType::U16 => {
275                Self::to_f32_internal::<u16>(FromBytes::ref_from_bytes(src).unwrap(), src_format)
276            }
277            ChannelType::F16 => {
278                let bytes = &mut [0; 2];
279                let mut f16_data = Vec::new();
280                while let Ok(()) = src.read_exact(bytes) {
281                    f16_data.push(half::f16::from_ne_bytes(*bytes));
282                }
283                Self::to_f32_internal::<half::f16>(&f16_data, src_format)
284            }
285            ChannelType::F32 => {
286                Self::to_f32_internal::<f32>(FromBytes::ref_from_bytes(src).unwrap(), src_format)
287            }
288        }
289    }
290
291    #[inline]
292    fn to_f32_internal<T: ChannelValue>(source_channels: &[T], source_format: Self) -> [f32; 4] {
293        let mut channels_f32 = [0.0_f32; 4];
294
295        let source_definition = source_format.source_definition();
296
297        for (n, channel) in channels_f32.iter_mut().enumerate() {
298            *channel = match source_definition[n] {
299                Source::C0 => (source_channels[0]).to_f32_normed(),
300                Source::C1 => (source_channels[1]).to_f32_normed(),
301                Source::C2 => (source_channels[2]).to_f32_normed(),
302                Source::C3 => (source_channels[3]).to_f32_normed(),
303                Source::Opaque => 1.,
304            };
305        }
306
307        if source_format.is_premultiplied() && channels_f32[3] > 0. {
308            channels_f32[0] /= channels_f32[3];
309            channels_f32[1] /= channels_f32[3];
310            channels_f32[2] /= channels_f32[3];
311        }
312
313        channels_f32
314    }
315
316    #[inline]
317    pub(crate) fn from_f32(channels_f32: [f32; 4], target_format: Self, target: &mut [u8]) {
318        match target_format.channel_type() {
319            ChannelType::U8 => Self::from_f32_internal::<u8>(channels_f32, target_format, target),
320            ChannelType::U16 => Self::from_f32_internal::<u16>(channels_f32, target_format, target),
321            ChannelType::F16 => {
322                Self::from_f32_internal::<half::f16>(channels_f32, target_format, target)
323            }
324            ChannelType::F32 => Self::from_f32_internal::<f32>(channels_f32, target_format, target),
325        }
326    }
327
328    #[inline]
329    fn from_f32_internal<T: ChannelValue>(
330        channels_f32: [f32; 4],
331        target_format: Self,
332        target: &mut [u8],
333    ) {
334        let target_channel_size = target_format.channel_type().size();
335
336        let premultiply = if target_format.is_premultiplied() {
337            channels_f32[3]
338        } else {
339            1.
340        };
341
342        for (n, def) in target_format.target_definition().iter().enumerate() {
343            let new_channel = match def {
344                Target::R => T::from_f32_normed(channels_f32[0] * premultiply),
345                Target::G => T::from_f32_normed(channels_f32[1] * premultiply),
346                Target::B => T::from_f32_normed(channels_f32[2] * premultiply),
347                Target::A => T::from_f32_normed(channels_f32[3]),
348                Target::RgbAvg => {
349                    T::from_f32_normed((channels_f32[0] + channels_f32[1] + channels_f32[2]) / 3.)
350                }
351            };
352
353            let bytes = new_channel.as_bytes_wrapper();
354
355            for i in 0..target_channel_size {
356                target[n * target_channel_size + i] = bytes[i];
357            }
358        }
359    }
360}
361
362#[derive(Debug, Clone, Copy)]
363pub enum ExtendedMemoryFormat {
364    Basic(MemoryFormat),
365    Y8Cb8Cr8,
366}
367
368impl MemoryFormatInfo for ExtendedMemoryFormat {
369    fn n_bytes(self) -> MemoryFormatBytes {
370        match self {
371            Self::Basic(basic) => basic.n_bytes(),
372            Self::Y8Cb8Cr8 => MemoryFormatBytes::B3,
373        }
374    }
375
376    fn n_channels(self) -> u8 {
377        match self {
378            Self::Basic(basic) => basic.n_channels(),
379            Self::Y8Cb8Cr8 => 3,
380        }
381    }
382}
383
384trait ChannelValue: Default + Copy {
385    fn from_f32_normed(value: f32) -> Self;
386    fn to_f32_normed(self) -> f32;
387    fn as_bytes_wrapper(&self) -> &[u8];
388}
389
390impl ChannelValue for u8 {
391    fn from_f32_normed(value: f32) -> Self {
392        (value * Self::MAX as f32).round() as Self
393    }
394
395    fn to_f32_normed(self) -> f32 {
396        (self as f32) / Self::MAX as f32
397    }
398
399    fn as_bytes_wrapper(&self) -> &[u8] {
400        self.as_bytes()
401    }
402}
403
404impl ChannelValue for u16 {
405    fn from_f32_normed(value: f32) -> Self {
406        (value * Self::MAX as f32).round() as Self
407    }
408
409    fn to_f32_normed(self) -> f32 {
410        (self as f32) / Self::MAX as f32
411    }
412
413    fn as_bytes_wrapper(&self) -> &[u8] {
414        self.as_bytes()
415    }
416}
417
418impl ChannelValue for half::f16 {
419    fn from_f32_normed(value: f32) -> Self {
420        Self::from_f32(value)
421    }
422
423    fn to_f32_normed(self) -> f32 {
424        self.into()
425    }
426
427    fn as_bytes_wrapper(&self) -> &[u8] {
428        self.as_bytes()
429    }
430}
431
432impl ChannelValue for f32 {
433    fn from_f32_normed(value: f32) -> Self {
434        value
435    }
436
437    fn to_f32_normed(self) -> f32 {
438        self
439    }
440
441    fn as_bytes_wrapper(&self) -> &[u8] {
442        self.as_bytes()
443    }
444}
445
446#[derive(Debug, Clone, Copy, PartialEq, Eq)]
447pub enum Target {
448    R,
449    G,
450    B,
451    A,
452    RgbAvg,
453}
454
455/// Defines a channel from which to take the value for a color/opacity
456///
457/// These are usually used in an array of sources of the order [R, G, B, A].
458#[derive(Debug, Clone, Copy, PartialEq, Eq)]
459pub enum Source {
460    C0,
461    C1,
462    C2,
463    C3,
464    Opaque,
465}
466
467#[derive(Debug, PartialEq, Eq)]
468pub enum ChannelType {
469    U8,
470    U16,
471    F16,
472    F32,
473}
474
475impl ChannelType {
476    pub fn size(self) -> usize {
477        match self {
478            Self::U8 => 1,
479            Self::U16 => 2,
480            Self::F16 => 2,
481            Self::F32 => 4,
482        }
483    }
484}
485
486impl From<MemoryFormat> for ExtendedMemoryFormat {
487    fn from(value: MemoryFormat) -> Self {
488        Self::Basic(value)
489    }
490}
491
492#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
493pub enum MemoryFormatBytes {
494    B1 = 1,
495    B2 = 2,
496    B3 = 3,
497    B4 = 4,
498    B6 = 6,
499    B8 = 8,
500    B12 = 12,
501    B16 = 16,
502}
503
504// TODO: Convert to From trait impls
505impl MemoryFormatBytes {
506    pub fn u8(self) -> u8 {
507        self as u8
508    }
509
510    pub fn u32(self) -> u32 {
511        self as u32
512    }
513
514    pub fn u64(self) -> u64 {
515        self as u64
516    }
517
518    pub fn usize(self) -> usize {
519        self as usize
520    }
521}
522
523#[cfg(test)]
524mod tests {
525    use super::*;
526
527    #[test]
528    fn simple() {
529        let target = &mut [0; 4];
530
531        MemoryFormat::transform(
532            MemoryFormat::R8g8b8,
533            &[255, 85, 127],
534            MemoryFormat::B8g8r8a8,
535            target,
536        );
537
538        assert_eq!(*target, [127, 85, 255, 255]);
539    }
540
541    #[test]
542    fn grayscale() {
543        let target = &mut [0; 1];
544
545        MemoryFormat::transform(
546            MemoryFormat::R8g8b8,
547            &[255, 0, 127],
548            MemoryFormat::G8,
549            target,
550        );
551
552        assert_eq!(*target, [127]);
553    }
554
555    #[test]
556    fn u16() {
557        let target = &mut [0; 6];
558
559        MemoryFormat::transform(
560            MemoryFormat::R8g8b8,
561            &[255, 0, 127],
562            MemoryFormat::R16g16b16,
563            target,
564        );
565
566        assert_eq!(*target, [255, 255, 0, 0, 127, 127]);
567    }
568}