diff options
| author | Dylan <boss@tehbox.org> | 2026-09-16 11:51:24 +1200 |
|---|---|---|
| committer | Dylan <boss@tehbox.org> | 2026-09-16 11:51:24 +1200 |
| commit | ebc1e7030558111134d18f87af3d108f08fb9488 (patch) | |
| tree | 5ab48f34d0219499d86386f994d75d8a88de2c35 /src | |
| parent | 048ebdcee5d48592b6d1b669e9db0a9ba030d859 (diff) | |
| download | tehimage-rs-master.tar.gz tehimage-rs-master.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/png.rs | 47 | ||||
| -rw-r--r-- | src/zlib.rs | 31 |
2 files changed, 41 insertions, 37 deletions
@@ -1,7 +1,6 @@ use std::{any::TypeId, collections::HashMap}; use byte_encode_derive::ByteEncode; -use zlib_rs::{InflateConfig, decompress_slice}; use crate::{byte_encode::ByteEncode, crc::update_crc, image::{RGB, ColorType, Image, ImageBase, PixelArr}, reader::FileReader, zlib::{BitBuffer, zlib_decode}}; @@ -14,24 +13,25 @@ pub struct PNGImage tEXt: Option<tEXt>, } -fn paeth_filter(a: u8, b: u8, c: u8) -> u8 { - let p = (a as i32 + b as i32 - c as i32) as u8; - let pa = p.abs_diff(a); - let pb = p.abs_diff(b); - let pc = p.abs_diff(c); +fn paeth_filter(a: &u8, b: &u8, c: &u8) -> u8 { + let p = (*a as i32 + *b as i32 - *c as i32) as u8; + let pa = p.abs_diff(*a); + let pb = p.abs_diff(*b); + let pc = p.abs_diff(*c); if pa <= pb && pa <= pc { - a + *a } else if pb <= pc { - b + *b } else { - c + *c } } +#[derive(Debug)] enum FilterMethod { None, @@ -52,12 +52,12 @@ impl FilterMethod _ => panic!("Filter {x} is invalid!\nOnly 5 filters exist") } } - fn apply(&self, a: u8, b: u8, c: u8, x: u8) -> u8 { + fn apply(&self, a: &u8, b: &u8, c: &u8, x: &u8) -> u8 { match self { - FilterMethod::None => x, - FilterMethod::Sub => x.wrapping_add(a), - FilterMethod::Up => x.wrapping_add(b), - FilterMethod::Average => x.wrapping_add((a + b)/2), + FilterMethod::None => *x, + FilterMethod::Sub => x.wrapping_add(*a), + FilterMethod::Up => x.wrapping_add(*b), + FilterMethod::Average => x.wrapping_add((*a + *b)/2), FilterMethod::Paeth => x.wrapping_add(paeth_filter(a, b, c)), } } @@ -295,12 +295,10 @@ impl<T: RGBu8> Image<T> for PNGImage let height: u32 = IHDR.height; println!("{bpp}, {width}, {height}"); - let compression_method: u8 = IDAT.data[0]; - let additional_flags: u8 = IDAT.data[1]; - - let mut decoded = vec![0u8; 1920*(1080*3 + 1)]; // zlib_decode(BitBuffer::new(&IDAT.data[2..])); - let (decompressed, rc) = decompress_slice(&mut decoded, &IDAT.data, InflateConfig::default()); - println!("{rc:?}"); + let _compression_method: u8 = IDAT.data[0]; + let _additional_flags: u8 = IDAT.data[1]; + + let decoded = zlib_decode(BitBuffer::new(&IDAT.data[2..])); let mut pixels = PixelArr::<T>::new(width, height); let mut rows: Vec<Vec<u8>> = Vec::new(); @@ -308,16 +306,15 @@ impl<T: RGBu8> Image<T> for PNGImage let mut i = 0; for y in 0..(height as usize) { - // println!("i: {i}"); let filter = FilterMethod::from_byte(decoded[i]); i += 1; let mut row: Vec<u8> = Vec::with_capacity(width as usize * 3); for x in 0..(width as usize * 3) { - let a: u8 = if x < 3 { 0 } else { row[x - 3] }; - let b: u8 = if y < 1 { 0 } else { rows[y - 1][x] }; - let c: u8 = if y < 1 || x < 3 { 0 } else { rows[y - 1][x - 3] }; - let x = decoded[i]; + let a: &u8 = if x < 3 { &0 } else { &row[x - 3] }; + let b: &u8 = if y < 1 { &0 } else { &rows[y - 1][x] }; + let c: &u8 = if y < 1 || x < 3 { &0 } else { &rows[y - 1][x - 3] }; + let x = &decoded[i]; i += 1; row.push(filter.apply(a, b, c, x)); } diff --git a/src/zlib.rs b/src/zlib.rs index 41816f3..f17c466 100644 --- a/src/zlib.rs +++ b/src/zlib.rs @@ -20,11 +20,11 @@ const DIST_EXTRA: [usize; 30] = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, const DYNAMIC_CODE_START: [usize; 3] = [3, 3, 11]; const DYNAMIC_CODE_EXTRA: [usize; 3] = [2, 3, 7]; -#[derive(Clone)] +#[derive(Clone, Debug)] struct HuffmanTree<const LENGTH: usize> { - pub len_counts: [u8; MAX_BITS + 1], - pub ordered_codes: [u16; LENGTH] + len_counts: [u8; MAX_BITS + 1], + ordered_codes: [u16; LENGTH] } impl<const LENGTH: usize> HuffmanTree<LENGTH> @@ -76,18 +76,20 @@ impl<const LENGTH: usize> HuffmanTree<LENGTH> fn decode<T: Bitstream>(&self, bitstream: &mut T) -> u16 { - let mut code: i16 = 0; + let mut code: u16 = 0; let mut first: u16 = 0; let mut index: usize = 0; - for len in 1..MAX_BITS + for len in 1..(MAX_BITS + 1) { - code |= bitstream.next_bit() as i16; - let count: i16 = self.len_counts[len] as i16; - // println!("{code} {count}"); - if code - count < first as i16 + code |= bitstream.next_bit() as u16; + let count: u16 = self.len_counts[len] as u16; + // println!("{code} {count} {len}"); + // let a = self.len_counts; + // println!("{a:?}"); + if count > code || code - count < first as u16 { - return self.ordered_codes[index + ((code - first as i16) as usize)]; + return self.ordered_codes[index + ((code - first) as usize)]; } index += count as usize; first += count as u16; @@ -218,7 +220,7 @@ pub fn zlib_decode<T: Bitstream>(mut instream: T) -> Vec<u8> final_chunk = instream.next_bit(); let compression_type = CompressionType::new(instream.next_bits(2) as u8); let t = output_buffer.len(); - println!("New chunk at pos: {t}, compression type: {compression_type:?}"); + // println!("New chunk at pos: {t}, compression type: {compression_type:?}"); if compression_type == CompressionType::Reserved { panic!("Reserved compression type should not be used"); @@ -300,10 +302,14 @@ pub fn zlib_decode<T: Bitstream>(mut instream: T) -> Vec<u8> let mut dist_tree_lens = [0u8; DIST_TREE_LEN]; dist_tree_lens[0..hdist].copy_from_slice(&code_dist_tree_lens[hlit..(hlit + hdist)]); + + // println!("{code_tree_lens:?}\n{dist_tree_lens:?}"); (HuffmanTree::new(code_tree_lens), HuffmanTree::new(dist_tree_lens)) }; + + // println!("{code_tree:?}\n{dist_tree:?}"); let mut code = 0u16; @@ -323,7 +329,8 @@ pub fn zlib_decode<T: Bitstream>(mut instream: T) -> Vec<u8> let dist = DIST_START[dist_code as usize] + instream.next_bits(DIST_EXTRA[dist_code as usize]) as usize; - let out_pos = output_buffer.len() - 1; + output_buffer.reserve(len); + let out_pos = output_buffer.len(); for i in 0..len { output_buffer.push(output_buffer[out_pos - dist + i]); |
