1use std::borrow::Borrow;
2
3use crate::{MemoryFormat, MemoryFormatInfo};
4
5#[cfg(feature = "gobject")]
7#[glib::flags(name = "GlyMemoryFormatSelection")]
8pub enum MemoryFormatSelection {
9 B8g8r8a8Premultiplied = (1 << 0),
10 A8r8g8b8Premultiplied = (1 << 1),
11 R8g8b8a8Premultiplied = (1 << 2),
12 B8g8r8a8 = (1 << 3),
13 A8r8g8b8 = (1 << 4),
14 R8g8b8a8 = (1 << 5),
15 A8b8g8r8 = (1 << 6),
16 R8g8b8 = (1 << 7),
17 B8g8r8 = (1 << 8),
18 R16g16b16 = (1 << 9),
19 R16g16b16a16Premultiplied = (1 << 10),
20 R16g16b16a16 = (1 << 11),
21 R16g16b16Float = (1 << 12),
22 R16g16b16a16Float = (1 << 13),
23 R32g32b32Float = (1 << 14),
24 R32g32b32a32FloatPremultiplied = (1 << 15),
25 R32g32b32a32Float = (1 << 16),
26 G8a8Premultiplied = (1 << 17),
27 G8a8 = (1 << 18),
28 G8 = (1 << 19),
29 G16a16Premultiplied = (1 << 20),
30 G16a16 = (1 << 21),
31 G16 = (1 << 22),
32}
33
34#[cfg(not(feature = "gobject"))]
35bitflags::bitflags! {
36 #[derive(Debug, Clone, Copy)]
38 pub struct MemoryFormatSelection: u32 {
39 const B8g8r8a8Premultiplied = (1 << 0);
40 const A8r8g8b8Premultiplied = (1 << 1);
41 const R8g8b8a8Premultiplied = (1 << 2);
42 const B8g8r8a8 = (1 << 3);
43 const A8r8g8b8 = (1 << 4);
44 const R8g8b8a8 = (1 << 5);
45 const A8b8g8r8 = (1 << 6);
46 const R8g8b8 = (1 << 7);
47 const B8g8r8 = (1 << 8);
48 const R16g16b16 = (1 << 9);
49 const R16g16b16a16Premultiplied = (1 << 10);
50 const R16g16b16a16 = (1 << 11);
51 const R16g16b16Float = (1 << 12);
52 const R16g16b16a16Float = (1 << 13);
53 const R32g32b32Float = (1 << 14);
54 const R32g32b32a32FloatPremultiplied = (1 << 15);
55 const R32g32b32a32Float = (1 << 16);
56 const G8a8Premultiplied = (1 << 17);
57 const G8a8 = (1 << 18);
58 const G8 = (1 << 19);
59 const G16a16Premultiplied = (1 << 20);
60 const G16a16 = (1 << 21);
61 const G16 = (1 << 22);
62 }
63}
64
65impl Default for MemoryFormatSelection {
66 fn default() -> Self {
67 Self::all()
68 }
69}
70
71impl MemoryFormatSelection {
72 const X: [(MemoryFormatSelection, MemoryFormat); 23] = [
73 (
74 MemoryFormatSelection::B8g8r8a8Premultiplied,
75 MemoryFormat::B8g8r8a8Premultiplied,
76 ),
77 (
78 MemoryFormatSelection::A8r8g8b8Premultiplied,
79 MemoryFormat::A8r8g8b8Premultiplied,
80 ),
81 (
82 MemoryFormatSelection::R8g8b8a8Premultiplied,
83 MemoryFormat::R8g8b8a8Premultiplied,
84 ),
85 (MemoryFormatSelection::B8g8r8a8, MemoryFormat::B8g8r8a8),
86 (MemoryFormatSelection::A8r8g8b8, MemoryFormat::A8r8g8b8),
87 (MemoryFormatSelection::R8g8b8a8, MemoryFormat::R8g8b8a8),
88 (MemoryFormatSelection::A8b8g8r8, MemoryFormat::A8b8g8r8),
89 (MemoryFormatSelection::R8g8b8, MemoryFormat::R8g8b8),
90 (MemoryFormatSelection::B8g8r8, MemoryFormat::B8g8r8),
91 (MemoryFormatSelection::R16g16b16, MemoryFormat::R16g16b16),
92 (
93 MemoryFormatSelection::R16g16b16a16Premultiplied,
94 MemoryFormat::R16g16b16a16Premultiplied,
95 ),
96 (
97 MemoryFormatSelection::R16g16b16a16,
98 MemoryFormat::R16g16b16a16,
99 ),
100 (
101 MemoryFormatSelection::R16g16b16Float,
102 MemoryFormat::R16g16b16Float,
103 ),
104 (
105 MemoryFormatSelection::R16g16b16a16Float,
106 MemoryFormat::R16g16b16a16Float,
107 ),
108 (
109 MemoryFormatSelection::R32g32b32Float,
110 MemoryFormat::R32g32b32Float,
111 ),
112 (
113 MemoryFormatSelection::R32g32b32a32FloatPremultiplied,
114 MemoryFormat::R32g32b32a32FloatPremultiplied,
115 ),
116 (
117 MemoryFormatSelection::R32g32b32a32Float,
118 MemoryFormat::R32g32b32a32Float,
119 ),
120 (
121 MemoryFormatSelection::G8a8Premultiplied,
122 MemoryFormat::G8a8Premultiplied,
123 ),
124 (MemoryFormatSelection::G8a8, MemoryFormat::G8a8),
125 (MemoryFormatSelection::G8, MemoryFormat::G8),
126 (
127 MemoryFormatSelection::G16a16Premultiplied,
128 MemoryFormat::G16a16Premultiplied,
129 ),
130 (MemoryFormatSelection::G16a16, MemoryFormat::G16a16),
131 (MemoryFormatSelection::G16, MemoryFormat::G16),
132 ];
133
134 pub fn memory_formats(self) -> Vec<MemoryFormat> {
136 let mut vec = Vec::new();
137 for (selection, format) in Self::X {
138 if self.contains(selection) {
139 vec.push(format);
140 }
141 }
142
143 vec
144 }
145 pub fn from_memory_format(memory_format: MemoryFormat) -> Self {
146 for (selection, format) in Self::X {
147 if format == memory_format {
148 return selection;
149 }
150 }
151
152 Self::empty()
153 }
154
155 pub fn from_memory_formats(
156 memory_formats: impl IntoIterator<Item = impl Borrow<MemoryFormat>>,
157 ) -> Self {
158 let mut x = Self::empty();
159 for format in memory_formats {
160 x |= Self::from_memory_format(*format.borrow());
161 }
162 x
163 }
164
165 pub fn best_format_for(self, src: MemoryFormat) -> Option<MemoryFormat> {
202 let formats: Vec<MemoryFormat> = self.memory_formats();
203
204 if formats.contains(&src) {
206 return Some(src);
207 }
208
209 let mut formats_categorized = formats
210 .into_iter()
211 .map(|x| {
212 (
213 (
215 x.has_alpha() == src.has_alpha(),
216 x.n_channels() >= src.n_channels(),
217 x.channel_type() == src.channel_type(),
218 x.channel_type().size() >= src.channel_type().size(),
219 -(x.n_channels() as i16),
221 -(x.channel_type().size() as i16),
223 ),
224 x,
225 )
226 })
227 .collect::<Vec<_>>();
228
229 formats_categorized.sort_by_key(|x| x.0);
230
231 formats_categorized.last().map(|x| x.1)
233 }
234}