use crate::{Reader, WriterPaletted, WriterRgb};
pub fn round_trip_rgb(width: u16, height: u16, pixels: &[u8]) {
let mut pcx = Vec::new();
let mut pcx_separate = Vec::new();
{
let mut writer = WriterRgb::new(&mut pcx, (width, height), (300, 300)).unwrap();
for y in 0..height as usize {
let row_size = width as usize * 3;
writer
.write_row(&pixels[y * row_size..(y + 1) * row_size])
.unwrap();
}
writer.finish().unwrap();
}
{
let mut writer = WriterRgb::new(&mut pcx_separate, (width, height), (300, 300)).unwrap();
let mut r: Vec<u8> = vec![0; width as usize];
let mut g: Vec<u8> = vec![0; width as usize];
let mut b: Vec<u8> = vec![0; width as usize];
for y in 0..height as usize {
for x in 0..width as usize {
let i = (y * width as usize + x) * 3;
r[x] = pixels[i + 0];
g[x] = pixels[i + 1];
b[x] = pixels[i + 2];
}
writer.write_row_from_separate(&r, &g, &b).unwrap();
}
writer.finish().unwrap();
}
assert!(pcx == pcx_separate);
{
let mut reader = Reader::from_mem(&pcx[..]).unwrap();
assert_eq!(reader.dimensions(), (width, height));
assert_eq!(reader.is_paletted(), false);
assert_eq!(reader.palette_length(), None);
let mut read_pixels: Vec<u8> = vec![0; (width as usize * height as usize) * 3];
reader.read_rgb_pixels(&mut read_pixels).unwrap();
assert!(pixels == read_pixels);
}
{
let mut reader = Reader::new(&pcx[..]).unwrap();
let mut r: Vec<u8> = vec![0; width as usize];
let mut g: Vec<u8> = vec![0; width as usize];
let mut b: Vec<u8> = vec![0; width as usize];
for y in 0..height as usize {
reader
.next_row_rgb_separate(&mut r, &mut g, &mut b)
.unwrap();
for x in 0..width as usize {
let i = (y * width as usize + x) * 3;
assert_eq!(r[x as usize], pixels[i + 0]);
assert_eq!(g[x as usize], pixels[i + 1]);
assert_eq!(b[x as usize], pixels[i + 2]);
}
}
}
}
#[cfg(test)]
fn round_trip_rgb_auto(width: u16, height: u16) {
let mut pixels = vec![0; (width as usize * height as usize) * 3];
for y in 0..height as usize {
for x in 0..width as usize {
let i = (y * width as usize + x) * 3;
pixels[i + 0] = (y % 256) as u8;
pixels[i + 1] = (x % 256) as u8;
pixels[i + 2] = 23;
}
}
round_trip_rgb(width, height, &pixels);
}
pub fn round_trip_paletted(width: u16, height: u16, palette: &[u8], pixels: &[u8]) {
let mut pcx = Vec::new();
{
let mut writer = WriterPaletted::new(&mut pcx, (width, height), (300, 300)).unwrap();
for y in 0..height as usize {
writer
.write_row(&pixels[width as usize * y..width as usize * (y + 1)])
.unwrap();
}
writer.write_palette(&palette).unwrap();
}
let mut reader = Reader::new(&pcx[..]).unwrap();
assert_eq!(reader.dimensions(), (width, height));
assert!(reader.is_paletted());
assert_eq!(reader.palette_length(), Some(256));
let mut row: Vec<u8> = vec![0; width as usize];
for y in 0..height as usize {
reader.next_row_paletted(&mut row).unwrap();
assert!(row == &pixels[width as usize * y..width as usize * (y + 1)]);
}
let mut palette_read = [0; 3 * 256];
reader.read_palette(&mut palette_read).unwrap();
assert_eq!(&palette[..], &palette_read[..palette.len()]);
}
#[cfg(test)]
fn round_trip_paletted_auto(width: u16, height: u16) {
let palette: Vec<u8> = (0..256 * 3).map(|v| (v % 0xFF) as u8).collect();
let mut pixels = vec![0u8; width as usize * height as usize];
for y in 0..height as usize {
for x in 0..width as usize {
pixels[width as usize * y + x] = (x + y) as u8;
}
}
round_trip_paletted(width, height, &palette, &pixels);
}
#[cfg(test)]
fn round_trip_all(width: u16, height: u16) {
round_trip_rgb_auto(width, height);
round_trip_paletted_auto(width, height);
}
#[test]
fn small_round_trip() {
for width in 1..40 {
for height in 1..40 {
round_trip_all(width, height);
}
}
}
#[test]
fn large_round_trip() {
round_trip_all(0xFFFF - 1, 1);
round_trip_all(1, 0xFFFF);
}
#[test]
fn fuzzer_test_case() {
let data: &[u8] = &[
10, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 8, 255, 255, 255, 255, 255, 255, 255, 39, 3, 3, 3, 3,
3, 189, 250, 189, 189, 189, 189, 173, 25, 189, 189, 189, 189, 189, 189, 189, 0, 0, 3, 3, 3,
3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 10, 0, 0, 1, 8, 255, 255,
255, 255, 255, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 253, 252, 252, 252, 252, 252, 218, 252,
3, 3, 0, 0, 3, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 253, 189, 253, 189, 189, 189, 189, 189, 189, 152, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 0, 0, 0, 3, 3, 3, 3, 3, 189, 189, 3, 3,
];
let mut pcx = Reader::from_mem(data).unwrap();
let size = pcx.width() as usize * pcx.height() as usize * 3;
let mut buffer = vec![0; size];
_ = pcx.read_rgb_pixels(&mut buffer);
}