#![allow(unused, reason = "WIP")]
#[cfg(doc)]
use crate::ImageError::FmtError;
#[cfg(feature = "alloc")]
use crate::text::String;
use crate::{
FmtWrite, ImageError,
ImageError::{InvalidImageSize, InvalidPixel},
ImageResult as Result, Mem,
};
#[cold] #[rustfmt::skip]
const fn invalid_pixel<T>() -> crate::Result<T, ImageError> { Err(InvalidPixel) }
#[doc = crate::_tags!(image namespace)]
#[doc = crate::_doc_location!("media/visual/image")]
#[derive(Debug)]
pub struct Pnm;
impl Pnm {
#[cfg(feature = "alloc")]
#[cfg_attr(nightly_doc, doc(cfg(feature = "alloc")))]
pub fn p1_encode_bytes(bitmap: &[u8], width: usize, height: usize) -> Result<String> {
if bitmap.len() != width * height {
return Err(InvalidImageSize(Some((width, height))));
}
let mut result = String::new();
writeln!(result, "P1\n{width} {height}")?;
for row in 0..height {
let first_pixel = bitmap[row * width];
result.push(match first_pixel {
0 => '0',
1 => '1',
_ => return invalid_pixel(),
});
for col in 1..width {
let pixel = bitmap[row * width + col];
result.push(' '); match pixel {
0 => result.push('0'),
1 => result.push('1'),
_ => return invalid_pixel(),
}
}
result.push('\n'); }
Ok(result)
}
#[cfg(feature = "alloc")]
#[cfg_attr(nightly_doc, doc(cfg(feature = "alloc")))]
pub fn p1_encode_bits(bitmap: &[u8], width: usize, height: usize) -> Result<String> {
if bitmap.len() != Mem::bytes_from_bits(width * height) {
return Err(InvalidImageSize(Some((width, height))));
}
let mut result = String::new();
writeln!(result, "P1\n{width} {height}")?;
for row in 0..height {
let first_col = 0;
let byte_index = (row * width + first_col) / 8;
let bit = 1 << (7 - (first_col % 8));
let first_pixel = (bitmap[byte_index] & bit) != 0;
result.push(if first_pixel { '1' } else { '0' });
for col in 1..width {
let byte_index = (row * width + col) / 8;
let bit = 1 << (7 - (col % 8));
let pixel = (bitmap[byte_index] & bit) != 0;
result.push(' '); result.push(if pixel { '1' } else { '0' });
}
result.push('\n'); }
Ok(result)
}
}
#[cfg(all(test, feature = "alloc"))]
mod tests_alloc {
use super::*;
use crate::_dep::_alloc::vec;
#[test]
fn p1_encode_bytes() {
let bitmap = vec![
1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, ];
let (w, h) = (8, 2);
let expected_output = "P1\n8 2\n1 0 1 0 1 0 1 0\n0 1 0 1 0 1 0 1\n";
let result = Pnm::p1_encode_bytes(&bitmap, w, h).expect("PNM P1 encoded");
assert_eq!(result, expected_output);
}
#[test]
fn p1_encode_bytes_invalid_size() {
let bitmap = vec![1, 0, 1, 0]; let (w, h) = (3, 3);
let result = Pnm::p1_encode_bytes(&bitmap, w, h);
assert_eq!(result, Err(InvalidImageSize(Some((3, 3)))));
}
#[test]
fn p1_encode_bytes_invalid_pixel() {
let bitmap = vec![1, 0, 2, 0]; let (w, h) = (2, 2);
let result = Pnm::p1_encode_bytes(&bitmap, w, h);
assert_eq!(result, Err(InvalidPixel));
}
#[test]
fn p1_encode_bits() {
let bitmap = vec![0b10101010, 0b01010101]; let (w, h) = (8, 2);
let expected_output = "P1\n8 2\n1 0 1 0 1 0 1 0\n0 1 0 1 0 1 0 1\n";
let result = Pnm::p1_encode_bits(&bitmap, w, h).expect("PNM P1 encoded");
assert_eq!(result, expected_output);
}
#[test]
fn p1_encode_bits_invalid_size() {
let bitmap = vec![0b10101010]; let (w, h) = (8, 2);
let result = Pnm::p1_encode_bits(&bitmap, w, h);
assert_eq!(result, Err(InvalidImageSize(Some((8, 2)))));
}
}