1use core::slice::IterMut;
10
11pub trait PixelBuffer<'a> {
13    type Pixel: Copy;
15    fn from_line(line_buffer: &'a mut [u8]) -> Self;
18    fn put_pixel(&mut self, pixel: Self::Pixel);
23    #[inline]
29    fn put_pixels(&mut self, pixel: Self::Pixel, count: usize) {
30        for _ in 0..count {
31            self.put_pixel(pixel);
32        }
33    }
34    #[inline]
36    fn pixel_stride() -> usize {
37        core::mem::size_of::<Self::Pixel>()
38    }
39}
40
41pub trait Palette {
43    type Pixel: Copy;
45    #[inline]
58    fn get_pixel(index: u8) -> Self::Pixel {
59        Self::get_pixel_grb8(index_to_grb(index))
60    }
61    fn get_pixel_gray(index: u8) -> Self::Pixel;
65    fn get_pixel_grb8(g3r3b2: u8) -> Self::Pixel;
67    fn get_pixel_gray8(value: u8) -> Self::Pixel;
69}
70
71pub struct PixelBufA24<'a> {
74    iter: IterMut<'a, [u8;3]>
75}
76
77pub struct PixelBufA32<'a> {
80    iter: IterMut<'a, [u8;4]>
81}
82
83pub struct PixelBufP32<'a> {
85    iter: IterMut<'a, u32>
86}
87
88pub struct PixelBufP16<'a> {
90    iter: IterMut<'a, u16>
91}
92
93pub struct PixelBufP8<'a> {
95    iter: IterMut<'a, u8>
96}
97
98pub struct SpectrumPalRGB24;
100
101pub struct SpectrumPalRGBA32;
103
104pub struct SpectrumPalARGB32;
106
107pub struct SpectrumPalA8R8G8B8;
109
110pub struct SpectrumPalR8G8B8A8;
112
113pub struct SpectrumPalR5G6B5;
115
116pub struct SpectrumPalR3G3B2;
118
119pub struct GrayscalePalRGB24;
121
122pub struct GrayscalePalRGBA32;
124
125pub struct GrayscalePalARGB32;
127
128pub struct GrayscalePalA8R8G8B8;
130
131pub struct GrayscalePalR8G8B8A8;
133
134pub struct GrayscalePalR5G6B5;
136
137pub struct GrayscalePalR3G3B2;
139
140#[allow(clippy::unusual_byte_groupings)]
141#[inline]
142fn index_to_grb(index: u8) -> u8 {
143    #[allow(clippy::inconsistent_digit_grouping)]
144    match index & 15 {
145         0 => 0b000_000_00,
146         1 => 0b000_000_10,
147         2 => 0b000_101_00,
148         3 => 0b000_101_10,
149         4 => 0b101_000_00,
150         5 => 0b101_000_10,
151         6 => 0b101_101_00,
152         7 => 0b101_101_10,
153         8 => 0b000_000_00,
154         9 => 0b000_000_11,
155        10 => 0b000_111_00,
156        11 => 0b000_111_11,
157        12 => 0b111_000_00,
158        13 => 0b111_000_11,
159        14 => 0b111_111_00,
160        15 => 0b111_111_11,
161        _ => unsafe { core::hint::unreachable_unchecked() }
162    }
163}
164
165macro_rules! impl_pixel_buffer {
166    ($pixel_buf:ty, $pixel:ty) => {
167        impl<'a> PixelBuffer<'a> for $pixel_buf {
168            type Pixel = $pixel;
169
170            fn from_line(line_buffer: &'a mut [u8]) -> Self {
171                let (_, pixels, _) = unsafe { line_buffer.align_to_mut::<Self::Pixel>() };
172                let iter = pixels.iter_mut();
173                Self { iter }
174            }
175
176            #[inline]
177            fn put_pixel(&mut self, pixel: Self::Pixel) {
178                if let Some(dest) = self.iter.next() {
179                    *dest = pixel;
180                }
181            }
182
183            #[inline]
184            fn put_pixels(&mut self, pixel: Self::Pixel, count: usize) {
185                for dest in self.iter.by_ref().take(count) {
186                    *dest = pixel;
187                }
188            }
189        }
190    };
191}
192
193impl_pixel_buffer!(PixelBufA24<'a>, [u8;3]);
194impl_pixel_buffer!(PixelBufA32<'a>, [u8;4]);
195impl_pixel_buffer!(PixelBufP32<'a>, u32);
196impl_pixel_buffer!(PixelBufP16<'a>, u16);
197impl_pixel_buffer!(PixelBufP8<'a>,  u8);
198
199macro_rules! impl_palette {
200    ($palette:ty, $pixel:ty) => {
201        impl Palette for $palette {
202            type Pixel = $pixel;
203
204            #[inline(always)]
205            fn get_pixel_grb8(g3r3b2: u8) -> Self::Pixel {
206                Self::pixel_grb(g3r3b2)
207            }
208            #[inline(always)]
209            fn get_pixel_gray(index: u8) -> Self::Pixel {
210                Self::pixel_gray_grb(index_to_grb(index))
211            }
212            #[inline(always)]
213            fn get_pixel_gray8(value: u8) -> Self::Pixel {
214                Self::pixel_gray_intensity(value)
215            }
216        }        
217    };
218}
219
220macro_rules! impl_pixel_grb_const {
221    ($palette:ty, $pixel:ty, $grayscale:ident) => {
222        impl $palette {
223            #[inline(always)]
224            fn pixel_grb(g3r3b2: u8) -> $pixel {
225                Self::COLORS_GRB[g3r3b2 as usize]
226            }
227            #[inline(always)]
228            fn pixel_gray_grb(i: u8) -> $pixel {
229                Self::pixel_gray_intensity($grayscale[i as usize])
230            }
231        }
232    };
233}
234
235macro_rules! impl_pixel_grb_gray {
236    ($palette:ty, $pixel:ty, $grayscale:ident) => {
237        impl $palette {
238            #[inline(always)]
239            fn pixel_grb(g3r3b2: u8) -> $pixel {
240                Self::pixel_gray_grb(g3r3b2)
241            }
242            #[inline(always)]
243            fn pixel_gray_grb(i: u8) -> $pixel {
244                Self::pixel_gray_intensity($grayscale[i as usize])
245            }
246        }
247    };
248}
249
250const ALPHA_MAX: u8 = u8::max_value();
251
252const fn grb_2r(grb: u8) -> u8 {
253    ((grb >> 3) & 3) | (grb & 0b11100) | ((grb & 0b11100) << 3)
254}
255
256const fn grb_2g(grb: u8) -> u8 {
257    ((grb >> 6) & 3) | ((grb >> 3) & 0b11100) | (grb & 0b11100000)
258}
259
260const fn grb_2b(grb: u8) -> u8 {
261    (grb & 3) | ((grb << 3) & 0b11000) | (((grb << 2) | (grb << 1)) & 0b100) |
262    ((grb << 6) & 0b11000000) | (((grb << 5) | (grb << 4)) & 0b100000)
263}
264
265#[inline(always)]
266const fn pack_8888(a: u8, b: u8, c: u8, d: u8) -> u32 {
267    ((a as u32) << 24) | ((b as u32) << 16) | ((c as u32) << 8) | (d as u32)
268}
269
270#[inline(always)]
271const fn pack_565(a: u8, b: u8, c: u8) -> u16 {
272    (((a as u16) >> 3) << 11) | (((b as u16) >> 2) << 5) | ((c as u16) >> 3)
273}
274
275#[inline(always)]
276const fn pack_332(a: u8, b: u8, c: u8) -> u8 {
277    ((a >> 5) << 5) | ((b >> 5) << 2) | (c >> 6)
278}
279
280const fn grayscale(r: u8, g: u8, b: u8) -> u8 {
281    ((13933 * r as u32 + 46871 * g as u32 + 4732 * b as u32) >> 16) as u8
282}
283
284macro_rules! impl_palette_plus_formats {
285    ([$($grb:expr),*]) => {
286        const GRAYSCALE: [u8; 256] = [$(grayscale(grb_2r($grb), grb_2g($grb), grb_2b($grb))),*];
287
288        impl SpectrumPalRGB24 {
289            const COLORS_GRB: [[u8;3]; 256] = [
290                $([grb_2r($grb), grb_2g($grb), grb_2b($grb)]),*
291            ];
292            #[inline(always)]
293            fn pixel_gray_intensity(v: u8) -> [u8;3] { [v, v, v] }
294        }
295        impl_pixel_grb_const!(SpectrumPalRGB24, [u8;3], GRAYSCALE);
296
297        impl SpectrumPalRGBA32 {
298            const COLORS_GRB: [[u8;4]; 256] = [
299                $([grb_2r($grb), grb_2g($grb), grb_2b($grb), ALPHA_MAX]),*
300            ];
301            #[inline(always)]
302            fn pixel_gray_intensity(v: u8) -> [u8;4] { [v, v, v, ALPHA_MAX] }
303        }
304        impl_pixel_grb_const!(SpectrumPalRGBA32, [u8;4], GRAYSCALE);
305
306        impl SpectrumPalARGB32 {
307            const COLORS_GRB: [[u8;4]; 256] = [
308                $([ALPHA_MAX, grb_2r($grb), grb_2g($grb), grb_2b($grb)]),*
309            ];
310            #[inline(always)]
311            fn pixel_gray_intensity(v: u8) -> [u8;4] { [ALPHA_MAX, v, v, v] }
312        }
313        impl_pixel_grb_const!(SpectrumPalARGB32, [u8;4], GRAYSCALE);
314
315        impl SpectrumPalA8R8G8B8 {
316            const COLORS_GRB: [u32; 256] = [
317                $(pack_8888(ALPHA_MAX, grb_2r($grb), grb_2g($grb), grb_2b($grb))),*
318            ];
319            #[inline(always)]
320            fn pixel_gray_intensity(v: u8) -> u32 { pack_8888(ALPHA_MAX, v, v, v) }
321        }
322        impl_pixel_grb_const!(SpectrumPalA8R8G8B8, u32, GRAYSCALE);
323
324        impl SpectrumPalR8G8B8A8 {
325            const COLORS_GRB: [u32; 256] = [
326                $(pack_8888(grb_2r($grb), grb_2g($grb), grb_2b($grb), ALPHA_MAX)),*
327            ];
328            #[inline(always)]
329            fn pixel_gray_intensity(v: u8) -> u32 { pack_8888(v, v, v, ALPHA_MAX) }
330        }
331        impl_pixel_grb_const!(SpectrumPalR8G8B8A8, u32, GRAYSCALE);
332
333        impl SpectrumPalR5G6B5 {
334            const COLORS_GRB: [u16; 256] = [
335                $(pack_565(grb_2r($grb), grb_2g($grb), grb_2b($grb))),*
336            ];
337            #[inline(always)]
338            fn pixel_gray_intensity(v: u8) -> u16 { pack_565(v, v, v) }
339        }
340        impl_pixel_grb_const!(SpectrumPalR5G6B5, u16, GRAYSCALE);
341
342        impl SpectrumPalR3G3B2 {
343            const COLORS_GRB: [u8; 256] = [
344                $(pack_332(grb_2r($grb), grb_2g($grb), grb_2b($grb))),*
345            ];
346            #[inline(always)]
347            fn pixel_gray_intensity(v: u8) -> u8 { pack_332(v, v, v) }
348        }
349        impl_pixel_grb_const!(SpectrumPalR3G3B2, u8, GRAYSCALE);
350
351        impl GrayscalePalRGB24 {
352            #[inline(always)]
353            fn pixel_gray_intensity(v: u8) -> [u8;3] { [v, v, v] }
354        }
355        impl_pixel_grb_gray!(GrayscalePalRGB24, [u8;3], GRAYSCALE);
356
357        impl GrayscalePalRGBA32 {
358            #[inline(always)]
359            fn pixel_gray_intensity(v: u8) -> [u8;4] { [v, v, v, ALPHA_MAX] }
360        }
361        impl_pixel_grb_gray!(GrayscalePalRGBA32, [u8;4], GRAYSCALE);
362
363        impl GrayscalePalARGB32 {
364            #[inline(always)]
365            fn pixel_gray_intensity(v: u8) -> [u8;4] { [ALPHA_MAX, v, v, v] }
366        }
367        impl_pixel_grb_gray!(GrayscalePalARGB32, [u8;4], GRAYSCALE);
368
369        impl GrayscalePalA8R8G8B8 {
370            #[inline(always)]
371            fn pixel_gray_intensity(v: u8) -> u32 { pack_8888(ALPHA_MAX, v, v, v) }
372        }
373        impl_pixel_grb_gray!(GrayscalePalA8R8G8B8, u32, GRAYSCALE);
374
375        impl GrayscalePalR8G8B8A8 {
376            #[inline(always)]
377            fn pixel_gray_intensity(v: u8) -> u32 { pack_8888(v, v, v, ALPHA_MAX) }
378        }
379        impl_pixel_grb_gray!(GrayscalePalR8G8B8A8, u32, GRAYSCALE);
380
381        impl GrayscalePalR5G6B5 {
382            #[inline(always)]
383            fn pixel_gray_intensity(v: u8) -> u16 { pack_565(v, v, v) }
384        }
385        impl_pixel_grb_gray!(GrayscalePalR5G6B5, u16, GRAYSCALE);
386
387        impl GrayscalePalR3G3B2 {
388            #[inline(always)]
389            fn pixel_gray_intensity(v: u8) -> u8 { pack_332(v, v, v) }
390        }
391        impl_pixel_grb_gray!(GrayscalePalR3G3B2, u8, GRAYSCALE);
392    };
393}
394
395impl_palette_plus_formats!([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]);
416impl_palette!(SpectrumPalRGB24,     [u8;3]);
417impl_palette!(SpectrumPalRGBA32,    [u8;4]);
418impl_palette!(SpectrumPalARGB32,    [u8;4]);
419impl_palette!(SpectrumPalA8R8G8B8,  u32);
420impl_palette!(SpectrumPalR8G8B8A8,  u32);
421impl_palette!(SpectrumPalR5G6B5,    u16);
422impl_palette!(SpectrumPalR3G3B2,    u8);
423impl_palette!(GrayscalePalRGB24,    [u8;3]);
424impl_palette!(GrayscalePalRGBA32,   [u8;4]);
425impl_palette!(GrayscalePalARGB32,   [u8;4]);
426impl_palette!(GrayscalePalA8R8G8B8, u32);
427impl_palette!(GrayscalePalR8G8B8A8, u32);
428impl_palette!(GrayscalePalR5G6B5,   u16);
429impl_palette!(GrayscalePalR3G3B2,   u8);
430
431#[cfg(test)]
432mod tests {
433    use super::*;
434
435    #[test]
436    fn pixel_palette_works() {
437        for i in (0..=255).step_by(16) {
438            assert_eq!(SpectrumPalRGB24::get_pixel(i + 0),  [         0,          0,          0]);
439            assert_eq!(SpectrumPalRGB24::get_pixel(i + 1),  [         0,          0, 0b10110110]);
440            assert_eq!(SpectrumPalRGB24::get_pixel(i + 2),  [0b10110110,          0,          0]);
441            assert_eq!(SpectrumPalRGB24::get_pixel(i + 3),  [0b10110110,          0, 0b10110110]);
442            assert_eq!(SpectrumPalRGB24::get_pixel(i + 4),  [         0, 0b10110110,          0]);
443            assert_eq!(SpectrumPalRGB24::get_pixel(i + 5),  [         0, 0b10110110, 0b10110110]);
444            assert_eq!(SpectrumPalRGB24::get_pixel(i + 6),  [0b10110110, 0b10110110,          0]);
445            assert_eq!(SpectrumPalRGB24::get_pixel(i + 7),  [0b10110110, 0b10110110, 0b10110110]);
446            assert_eq!(SpectrumPalRGB24::get_pixel(i + 8),  [         0,          0,          0]);
447            assert_eq!(SpectrumPalRGB24::get_pixel(i + 9),  [         0,          0, 0b11111111]);
448            assert_eq!(SpectrumPalRGB24::get_pixel(i + 10), [0b11111111,          0,          0]);
449            assert_eq!(SpectrumPalRGB24::get_pixel(i + 11), [0b11111111,          0, 0b11111111]);
450            assert_eq!(SpectrumPalRGB24::get_pixel(i + 12), [         0, 0b11111111,          0]);
451            assert_eq!(SpectrumPalRGB24::get_pixel(i + 13), [         0, 0b11111111, 0b11111111]);
452            assert_eq!(SpectrumPalRGB24::get_pixel(i + 14), [0b11111111, 0b11111111,          0]);
453            assert_eq!(SpectrumPalRGB24::get_pixel(i + 15), [0b11111111, 0b11111111, 0b11111111]);
454
455            assert_eq!(GrayscalePalRGB24::get_pixel(i + 0),  [  0,  0,  0]);
456            assert_eq!(GrayscalePalRGB24::get_pixel(i + 1),  [ 13, 13, 13]);
457            assert_eq!(GrayscalePalRGB24::get_pixel(i + 2),  [ 38, 38, 38]);
458            assert_eq!(GrayscalePalRGB24::get_pixel(i + 3),  [ 51, 51, 51]);
459            assert_eq!(GrayscalePalRGB24::get_pixel(i + 4),  [130,130,130]);
460            assert_eq!(GrayscalePalRGB24::get_pixel(i + 5),  [143,143,143]);
461            assert_eq!(GrayscalePalRGB24::get_pixel(i + 6),  [168,168,168]);
462            assert_eq!(GrayscalePalRGB24::get_pixel(i + 7),  [182,182,182]);
463            assert_eq!(GrayscalePalRGB24::get_pixel(i + 8),  [  0,  0,  0]);
464            assert_eq!(GrayscalePalRGB24::get_pixel(i + 9),  [ 18, 18, 18]);
465            assert_eq!(GrayscalePalRGB24::get_pixel(i + 10), [ 54, 54, 54]);
466            assert_eq!(GrayscalePalRGB24::get_pixel(i + 11), [ 72, 72, 72]);
467            assert_eq!(GrayscalePalRGB24::get_pixel(i + 12), [182,182,182]);
468            assert_eq!(GrayscalePalRGB24::get_pixel(i + 13), [200,200,200]);
469            assert_eq!(GrayscalePalRGB24::get_pixel(i + 14), [236,236,236]);
470            assert_eq!(GrayscalePalRGB24::get_pixel(i + 15), [255,255,255]);
471        }
472    }
473
474    #[test]
475    fn pixel_palette_grb_works() {
476        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(0), [0, 0, 0]);
477        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(0b000_001_00), [0b00100100, 0, 0]);
478        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(0b001_010_00), [0b01001001, 0b00100100, 0]);
479        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(1), [0, 0, 0b01101101]);
480        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(0b000_101_01), [0b10110110, 0, 0b01101101]);
481        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(0b110_111_01), [0b11111111, 0b11011011, 0b01101101]);
482        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(2), [0, 0, 0b10110110]);
483        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(0b011_011_10), [0b01101101, 0b01101101, 0b10110110]);
484        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(3), [0, 0, 0b11111111]);
485        assert_eq!(SpectrumPalRGB24::get_pixel_grb8(255), [255, 255, 255]);
486        assert_eq!(SpectrumPalRGBA32::get_pixel_grb8(0), [0, 0, 0, 255]);
487        assert_eq!(SpectrumPalRGBA32::get_pixel_grb8(0b111_011_01), [0b01101101, 0b11111111, 0b01101101, 255]);
488        assert_eq!(SpectrumPalRGBA32::get_pixel_grb8(255), [255, 255, 255, 255]);
489        assert_eq!(SpectrumPalARGB32::get_pixel_grb8(0), [255, 0, 0, 0]);
490        assert_eq!(SpectrumPalARGB32::get_pixel_grb8(0b111_011_01), [255, 0b01101101, 0b11111111, 0b01101101]);
491        assert_eq!(SpectrumPalARGB32::get_pixel_grb8(255), [255, 255, 255, 255]);
492        assert_eq!(SpectrumPalR8G8B8A8::get_pixel_grb8(0), 255);
493        assert_eq!(SpectrumPalR8G8B8A8::get_pixel_grb8(0b111_011_01), 0b01101101_11111111_01101101_11111111);
494        assert_eq!(SpectrumPalR8G8B8A8::get_pixel_grb8(255), 0xffff_ffff);
495        assert_eq!(SpectrumPalA8R8G8B8::get_pixel_grb8(0), 0xff00_0000);
496        assert_eq!(SpectrumPalA8R8G8B8::get_pixel_grb8(0b111_011_01), 0b11111111_01101101_11111111_01101101);
497        assert_eq!(SpectrumPalA8R8G8B8::get_pixel_grb8(255), 0xffff_ffff);
498        assert_eq!(SpectrumPalR5G6B5::get_pixel_grb8(0), 0);
499        assert_eq!(SpectrumPalR5G6B5::get_pixel_grb8(0b111_011_01), 0b01101_111111_01101);
500        assert_eq!(SpectrumPalR5G6B5::get_pixel_grb8(255), 0xffff);
501        assert_eq!(SpectrumPalR3G3B2::get_pixel_grb8(0), 0);
502        assert_eq!(SpectrumPalR3G3B2::get_pixel_grb8(0b111_011_01), 0b011_111_01);
503        assert_eq!(SpectrumPalR3G3B2::get_pixel_grb8(255), 0xff);
504    }
505
506    #[test]
507    fn pixel_palette_gray_works() {
508        let grayscale_u16 = |v| (((v as u16) >> 3) << 11)|(((v as u16) >> 2) << 5)|((v as u16) >> 3);
509        let grayscale_u8 = |v| ((v >> 5) << 5)|((v >> 5) << 2)|(v >> 6);
510        for i in 0..=255u8 {
511            let v = GRAYSCALE[i as usize];
512            assert_eq!(SpectrumPalRGB24::get_pixel_gray8(i), [i, i, i]);
513            assert_eq!(GrayscalePalRGB24::get_pixel_gray8(i), [i, i, i]);
514            assert_eq!(GrayscalePalRGB24::get_pixel_grb8(i), [v, v, v]);
515            assert_eq!(SpectrumPalRGBA32::get_pixel_gray8(i), [i, i, i, 255]);
516            assert_eq!(GrayscalePalRGBA32::get_pixel_gray8(i), [i, i, i, 255]);
517            assert_eq!(GrayscalePalRGBA32::get_pixel_grb8(i), [v, v, v, 255]);
518            assert_eq!(SpectrumPalARGB32::get_pixel_gray8(i), [255, i, i, i]);
519            assert_eq!(GrayscalePalARGB32::get_pixel_gray8(i), [255, i, i, i]);
520            assert_eq!(GrayscalePalARGB32::get_pixel_grb8(i), [255, v, v, v]);
521            assert_eq!(SpectrumPalA8R8G8B8::get_pixel_gray8(i), u32::from_be_bytes([255, i, i, i]));
522            assert_eq!(GrayscalePalA8R8G8B8::get_pixel_gray8(i), u32::from_be_bytes([255, i, i, i]));
523            assert_eq!(GrayscalePalA8R8G8B8::get_pixel_grb8(i), u32::from_be_bytes([255, v, v, v]));
524            assert_eq!(SpectrumPalR8G8B8A8::get_pixel_gray8(i), u32::from_be_bytes([i, i, i, 255]));
525            assert_eq!(GrayscalePalR8G8B8A8::get_pixel_gray8(i), u32::from_be_bytes([i, i, i, 255]));
526            assert_eq!(GrayscalePalR8G8B8A8::get_pixel_grb8(i), u32::from_be_bytes([v, v, v, 255]));
527            assert_eq!(SpectrumPalR5G6B5::get_pixel_gray8(i), grayscale_u16(i));
528            assert_eq!(GrayscalePalR5G6B5::get_pixel_gray8(i), grayscale_u16(i));
529            assert_eq!(GrayscalePalR5G6B5::get_pixel_grb8(i), grayscale_u16(v));
530            assert_eq!(SpectrumPalR3G3B2::get_pixel_gray8(i), grayscale_u8(i));
531            assert_eq!(GrayscalePalR3G3B2::get_pixel_gray8(i), grayscale_u8(i));
532            assert_eq!(GrayscalePalR3G3B2::get_pixel_grb8(i), grayscale_u8(v));
533        }
534    }
535}