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
use std::io::{Read, Write};
use super::{Chunk, DecoderError, DecoderResult, EncoderResult};
use crate::{consts, decoder::Parser, encoder::Enc};
#[derive(Debug, Clone, PartialEq)]
#[allow(variant_size_differences)]
#[must_use]
pub enum Transparency {
Palette(Vec<u8>),
RgbKey(u16, u16, u16),
GrayKey(u16),
}
impl Transparency {
pub(crate) fn len(&self) -> usize {
self.as_slice().len()
}
pub(crate) fn as_slice(&self) -> &[u8] {
use Transparency::*;
match self {
Palette(p) => p.as_slice(),
_ => unreachable!(),
}
}
pub(crate) fn parse<R: Read>(
parse: &mut Parser<R>,
) -> DecoderResult<Chunk> {
if parse.has_palette() {
let apal = parse.raw()?;
Ok(Chunk::Transparency(Transparency::Palette(apal)))
} else {
match parse.len() {
2 => {
Ok(Chunk::Transparency(Transparency::GrayKey(parse.u16()?)))
}
6 => Ok(Chunk::Transparency(Transparency::RgbKey(
parse.u16()?,
parse.u16()?,
parse.u16()?,
))),
_ => Err(DecoderError::ChunkLength(consts::TRANSPARENCY)),
}
}
}
pub(crate) fn write<W: Write>(
&self,
enc: &mut Enc<W>,
) -> EncoderResult<()> {
use Transparency::*;
match self {
Palette(plte) => {
enc.prepare(plte.len(), consts::TRANSPARENCY)?;
for alpha in plte.iter().cloned() {
enc.u8(alpha)?;
}
}
RgbKey(red, green, blue) => {
enc.prepare(6, consts::TRANSPARENCY)?;
enc.u16(*red)?;
enc.u16(*green)?;
enc.u16(*blue)?;
}
GrayKey(key) => {
enc.prepare(2, consts::TRANSPARENCY)?;
enc.u16(*key)?
}
}
enc.write_crc()
}
}