Skip to content

Commit c55cd45

Browse files
committed
test extend_palette
1 parent f0fd9a2 commit c55cd45

1 file changed

Lines changed: 71 additions & 25 deletions

File tree

src/images.rs

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub fn convert_image(in_path: &Path, out_path: &Path, sys_pal: &Palette) -> Resu
1414
}
1515
let mut img_pal = make_palette(&img, sys_pal).context("detect colors used in the image")?;
1616
let mut out = File::create(out_path).context("create output path")?;
17+
// The magic number. "2"=image, "1"=v1.
1718
write_u8(&mut out, 0x21)?;
1819
let n_colors = img_pal.len();
1920
if n_colors <= 2 {
@@ -101,42 +102,47 @@ fn make_palette(img: &RgbaImage, sys_pal: &Palette) -> Result<Vec<Color>> {
101102
}
102103

103104
/// Add empty colors at the end of the palette to match the BPP size.
105+
///
106+
/// If the given image palette is fully contained within the system palette
107+
/// (after being cut to the expected swaps size), place the colors in the
108+
/// image palette in the same positions as they are in the system palette.
109+
/// This will make it possible to read such images without worrying about
110+
/// applying color swaps.
104111
fn extend_palette(img_pal: &mut Vec<Color>, sys_pal: &Palette, size: usize) {
105112
if img_pal.len() > size {
106113
return;
107114
}
108-
// If the given image palette is fully contained within the system palette,
109-
// place the colors in the image palette in the same positions as they are
110-
// in the system palette. This will make it possible to read such images
111-
// without worrying about applying color swaps.
112-
if size == sys_pal.len() && is_subpalette(img_pal, sys_pal) {
113-
let has_transp = img_pal.iter().any(Option::is_none);
114-
if !has_transp {
115-
img_pal.copy_from_slice(sys_pal);
116-
return;
117-
}
118115

119-
let mut new_pal: Vec<Color> = Vec::new();
120-
let mut found_transp = false;
121-
for c in sys_pal {
122-
if found_transp || img_pal.contains(c) {
123-
new_pal.push(*c);
124-
} else {
125-
new_pal.push(None);
126-
found_transp = true;
127-
}
128-
}
129-
img_pal.copy_from_slice(&new_pal[..]);
116+
let sys_pal_prefix = &sys_pal[..size];
117+
if !is_subpalette(img_pal, sys_pal_prefix) {
118+
img_pal.extend_from_slice(&sys_pal[img_pal.len()..size]);
130119
return;
131120
}
132-
let n = size - img_pal.len();
133-
for _ in 0..n {
134-
img_pal.push(sys_pal[0]);
121+
122+
// No transparency? Just use the system palette.
123+
let has_transp = img_pal.iter().any(Option::is_none);
124+
if !has_transp {
125+
img_pal.clear();
126+
img_pal.extend(sys_pal_prefix);
127+
return;
135128
}
129+
130+
// Has transparency? Then copy the system palette and poke one hole in it.
131+
let mut new_pal: Vec<Color> = Vec::new();
132+
let mut found_transp = false;
133+
for c in sys_pal_prefix {
134+
if found_transp || img_pal.contains(c) {
135+
new_pal.push(*c);
136+
} else {
137+
new_pal.push(None);
138+
found_transp = true;
139+
}
140+
}
141+
img_pal.copy_from_slice(&new_pal[..]);
136142
}
137143

138144
/// Check if the image palette is fully contained within the given system palette.
139-
fn is_subpalette(img_pal: &Vec<Color>, sys_pal: &Palette) -> bool {
145+
fn is_subpalette(img_pal: &[Color], sys_pal: &[Color]) -> bool {
140146
for c in img_pal {
141147
if c.is_some() && !sys_pal.contains(c) {
142148
return false;
@@ -231,4 +237,44 @@ mod tests {
231237
assert_eq!(pick_transparent(&[c1, c0, None], pal).unwrap(), 2);
232238
assert_eq!(pick_transparent(&[c0, c1, c2, c3, None], pal).unwrap(), 4);
233239
}
240+
241+
#[test]
242+
fn test_extend_palette() {
243+
let pal = SWEETIE16;
244+
let c0 = pal[0];
245+
let c1 = pal[1];
246+
let c2 = pal[2];
247+
let c3 = pal[3];
248+
let c4 = pal[4];
249+
250+
// Already the palette prefix, do nothing.
251+
let mut img_pal = vec![c0, c1];
252+
extend_palette(&mut img_pal, pal, 2);
253+
assert_eq!(img_pal, vec![c0, c1]);
254+
255+
// A prefix but in a wrong order. Fix the order.
256+
let mut img_pal = vec![c1, c0];
257+
extend_palette(&mut img_pal, pal, 2);
258+
assert_eq!(img_pal, vec![c0, c1]);
259+
260+
// Not a prefix and already full. Keep the given palette.
261+
let mut img_pal = vec![c2, c1];
262+
extend_palette(&mut img_pal, pal, 2);
263+
assert_eq!(img_pal, vec![c2, c1]);
264+
265+
// A prefix but too short. Fill the rest.
266+
let mut img_pal = vec![c0, c1];
267+
extend_palette(&mut img_pal, pal, 4);
268+
assert_eq!(img_pal, vec![c0, c1, c2, c3]);
269+
270+
// Within the palette prefix.
271+
let mut img_pal = vec![c2, c1];
272+
extend_palette(&mut img_pal, pal, 4);
273+
assert_eq!(img_pal, vec![c0, c1, c2, c3]);
274+
275+
// Not a prefix but too short. Don't touch the given, fill the rest.
276+
let mut img_pal = vec![c4, c2];
277+
extend_palette(&mut img_pal, pal, 4);
278+
assert_eq!(img_pal, vec![c4, c2, c2, c3]);
279+
}
234280
}

0 commit comments

Comments
 (0)