fixed all bugs in de- and encoder, version bump to 0.9.0
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,4 @@ | ||||
| /target | ||||
| /qoi_test_images | ||||
| *.qoi | ||||
| *.png | ||||
|   | ||||
							
								
								
									
										227
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										227
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -8,6 +8,61 @@ version = "1.0.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" | ||||
|  | ||||
| [[package]] | ||||
| name = "adler2" | ||||
| version = "2.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" | ||||
|  | ||||
| [[package]] | ||||
| name = "anstream" | ||||
| version = "0.6.18" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" | ||||
| dependencies = [ | ||||
|  "anstyle", | ||||
|  "anstyle-parse", | ||||
|  "anstyle-query", | ||||
|  "anstyle-wincon", | ||||
|  "colorchoice", | ||||
|  "is_terminal_polyfill", | ||||
|  "utf8parse", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "anstyle" | ||||
| version = "1.0.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" | ||||
|  | ||||
| [[package]] | ||||
| name = "anstyle-parse" | ||||
| version = "0.2.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" | ||||
| dependencies = [ | ||||
|  "utf8parse", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "anstyle-query" | ||||
| version = "1.1.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" | ||||
| dependencies = [ | ||||
|  "windows-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "anstyle-wincon" | ||||
| version = "3.0.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" | ||||
| dependencies = [ | ||||
|  "anstyle", | ||||
|  "windows-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "array-init" | ||||
| version = "2.0.1" | ||||
| @@ -26,6 +81,39 @@ version = "1.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||||
|  | ||||
| [[package]] | ||||
| name = "clap" | ||||
| version = "4.5.21" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" | ||||
| dependencies = [ | ||||
|  "clap_builder", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "clap_builder" | ||||
| version = "4.5.21" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" | ||||
| dependencies = [ | ||||
|  "anstream", | ||||
|  "anstyle", | ||||
|  "clap_lex", | ||||
|  "strsim", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "clap_lex" | ||||
| version = "0.7.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" | ||||
|  | ||||
| [[package]] | ||||
| name = "colorchoice" | ||||
| version = "1.0.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" | ||||
|  | ||||
| [[package]] | ||||
| name = "colors-transform" | ||||
| version = "0.2.11" | ||||
| @@ -41,6 +129,15 @@ dependencies = [ | ||||
|  "cfg-if", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "fdeflate" | ||||
| version = "0.3.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" | ||||
| dependencies = [ | ||||
|  "simd-adler32", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "flate2" | ||||
| version = "1.0.24" | ||||
| @@ -48,17 +145,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" | ||||
| dependencies = [ | ||||
|  "crc32fast", | ||||
|  "miniz_oxide", | ||||
|  "miniz_oxide 0.5.4", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "log" | ||||
| version = "0.4.17" | ||||
| name = "is_terminal_polyfill" | ||||
| version = "1.70.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
| ] | ||||
| checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" | ||||
|  | ||||
| [[package]] | ||||
| name = "log" | ||||
| version = "0.4.22" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" | ||||
|  | ||||
| [[package]] | ||||
| name = "miniz_oxide" | ||||
| @@ -70,23 +170,126 @@ dependencies = [ | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "png" | ||||
| version = "0.17.6" | ||||
| name = "miniz_oxide" | ||||
| version = "0.8.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" | ||||
| checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" | ||||
| dependencies = [ | ||||
|  "adler2", | ||||
|  "simd-adler32", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "png" | ||||
| version = "0.17.14" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" | ||||
| dependencies = [ | ||||
|  "bitflags", | ||||
|  "crc32fast", | ||||
|  "fdeflate", | ||||
|  "flate2", | ||||
|  "miniz_oxide", | ||||
|  "miniz_oxide 0.8.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "qoi" | ||||
| version = "0.1.1" | ||||
| version = "0.9.0" | ||||
| dependencies = [ | ||||
|  "array-init", | ||||
|  "clap", | ||||
|  "colors-transform", | ||||
|  "log", | ||||
|  "png", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "simd-adler32" | ||||
| version = "0.3.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" | ||||
|  | ||||
| [[package]] | ||||
| name = "strsim" | ||||
| version = "0.11.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" | ||||
|  | ||||
| [[package]] | ||||
| name = "utf8parse" | ||||
| version = "0.2.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows-sys" | ||||
| version = "0.59.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" | ||||
| dependencies = [ | ||||
|  "windows-targets", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "windows-targets" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" | ||||
| dependencies = [ | ||||
|  "windows_aarch64_gnullvm", | ||||
|  "windows_aarch64_msvc", | ||||
|  "windows_i686_gnu", | ||||
|  "windows_i686_gnullvm", | ||||
|  "windows_i686_msvc", | ||||
|  "windows_x86_64_gnu", | ||||
|  "windows_x86_64_gnullvm", | ||||
|  "windows_x86_64_msvc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_aarch64_gnullvm" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_aarch64_msvc" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_i686_gnu" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_i686_gnullvm" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_i686_msvc" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnu" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnullvm" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" | ||||
|  | ||||
| [[package]] | ||||
| name = "windows_x86_64_msvc" | ||||
| version = "0.52.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| [package] | ||||
| name = "qoi" | ||||
| version = "0.1.1" | ||||
| version = "0.9.0" | ||||
| edition = "2021" | ||||
| authors = ["nihil carcosa <nihil@valhrafnaz.gay>"] | ||||
| description = "CLI tool and rust library for the de- and encoding of images to the QOI format." | ||||
| @@ -18,6 +18,7 @@ publish = false | ||||
|  | ||||
| [dependencies] | ||||
| array-init = "2.0.1" | ||||
| png = "0.17.6" | ||||
| log = "0.4.17" | ||||
| png = "0.17.14" | ||||
| log = "0.4.22" | ||||
| colors-transform = "0.2.11" | ||||
| clap = "4.5.21" | ||||
|   | ||||
							
								
								
									
										217
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | ||||
| //! # qoi_img | ||||
| //! `qoi_img` is a bad, from-scratch implementation of the decoder and encoder for the `.qoi` file format as described as on [qoiformat.org](https://qoiformat.org/qoi-specification.pdf). | ||||
| //! This crate should not be published as better crates are available, e.g. [rapid-qoi](https://crates.io/crates/rapid-qoi). | ||||
|  | ||||
| #![allow(dead_code, unused_variables)] | ||||
| pub mod qoi_lib { | ||||
|  | ||||
|     use log::{debug, info, Level, LevelFilter, Record, SetLoggerError}; | ||||
|     use std::fmt; | ||||
|     use std::fs::File; | ||||
|     use std::fs::*; | ||||
|     use std::io::prelude::*; | ||||
|      | ||||
|  | ||||
|     use array_init; | ||||
|  | ||||
| @@ -60,7 +60,7 @@ pub mod qoi_lib { | ||||
|     /// | ||||
|     /// ``` | ||||
|     /// # use std::error::Error; | ||||
|     /// # use crate::qoi_test::qoi_img::*; | ||||
|     /// # use crate::qoi::qoi_lib::*; | ||||
|     /// # fn main() -> Result<(), Box<ImgError>> { | ||||
|     /// init().expect("Failed to initialize logger"); | ||||
|     /// # | ||||
| @@ -73,7 +73,7 @@ pub mod qoi_lib { | ||||
|     /// | ||||
|     /// ``` | ||||
|     /// # use std::error::Error; | ||||
|     /// # use crate::qoi_test::qoi_img::*; | ||||
|     /// # use crate::qoi::qoi_lib::*; | ||||
|     /// # fn main() -> Result<(), ImgError> { | ||||
|     /// match init() { | ||||
|     /// Ok(()) => (), | ||||
| @@ -97,7 +97,7 @@ pub mod qoi_lib { | ||||
|     /// Create a new image via constructor [`Image::new()`]; | ||||
|     /// ```rust | ||||
|     /// # use std::error::Error; | ||||
|     /// # use crate::qoi_test::qoi_img::*; | ||||
|     /// # use crate::qoi::qoi_lib::*; | ||||
|     /// # fn main() -> Result<(), Box<ImgError>> { | ||||
|     /// | ||||
|     /// let pixels: Vec<u8> = vec![0;1024*1024*4]; | ||||
| @@ -129,7 +129,13 @@ pub mod qoi_lib { | ||||
|             channels: u8, | ||||
|             colorspace: u8, | ||||
|         ) -> Result<Image, ImgError> { | ||||
|             let pixels: Vec<Pixel> = match Image::pixels_from_bytes(data) { | ||||
|             let alpha: bool; | ||||
|             if channels == 4 { | ||||
|                 alpha = true; | ||||
|             } else { | ||||
|                 alpha = false; | ||||
|             } | ||||
|             let pixels: Vec<Pixel> = match Image::pixels_from_bytes(data, alpha) { | ||||
|                 Ok(out) => out, | ||||
|                 Err(error) => return Err(error), | ||||
|             }; | ||||
| @@ -164,21 +170,39 @@ pub mod qoi_lib { | ||||
|             img | ||||
|         } | ||||
|  | ||||
|         fn pixels_from_bytes(data: Vec<u8>) -> Result<Vec<Pixel>, ImgError> { | ||||
|         //Expects pixel data in order left to right, top to bottom, with values for rgba in sequential order | ||||
|         fn pixels_from_bytes(data: Vec<u8>, alpha: bool) -> Result<Vec<Pixel>, ImgError> { | ||||
|             let mut pixels: Vec<Pixel> = Vec::with_capacity(data.len() / 4); | ||||
|             if data.len() % 4 == 0 { | ||||
|                 for i in 0..data.len() / 4 { | ||||
|                     pixels.push(Pixel { | ||||
|                         r: data[i * 4], | ||||
|                         g: data[i * 4 + 1], | ||||
|                         b: data[i * 4 + 2], | ||||
|                         a: data[i * 4 + 3], | ||||
|                     }); | ||||
|             if alpha { | ||||
|                 if data.len() % 4 == 0 { | ||||
|                     for i in 0..data.len() / 4 { | ||||
|                         pixels.push(Pixel { | ||||
|                             r: data[i * 4], | ||||
|                             g: data[i * 4 + 1], | ||||
|                             b: data[i * 4 + 2], | ||||
|                             a: data[i * 4 + 3], | ||||
|                         }); | ||||
|                     } | ||||
|                     Ok(pixels) | ||||
|                 } else { | ||||
|                     Err(ImgError::DataError) | ||||
|                 } | ||||
|                 Ok(pixels) | ||||
|             } else { | ||||
|                 Err(ImgError::DataError) | ||||
|                 if data.len() % 4 == 0 { | ||||
|                     for i in 0..data.len() / 3 { | ||||
|                         pixels.push(Pixel { | ||||
|                             r: data[i * 3], | ||||
|                             g: data[i * 3 + 1], | ||||
|                             b: data[i * 3 + 2], | ||||
|                             a: 255, | ||||
|                         }); | ||||
|                     } | ||||
|                     Ok(pixels) | ||||
|                 } else { | ||||
|                     Err(ImgError::DataError) | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -378,6 +402,7 @@ pub mod qoi_lib { | ||||
|         (store % 64) as u8 | ||||
|     } | ||||
|  | ||||
|     //Definitely broken in some way | ||||
|     pub fn encode_from_image(img: Image) -> Vec<u8> { | ||||
|         let mut prev_pixel: Pixel = Pixel { | ||||
|             r: 0u8, | ||||
| @@ -399,7 +424,7 @@ pub mod qoi_lib { | ||||
|         } | ||||
|  | ||||
|         let mut encoded_bytes: Vec<u8> = Vec::new(); | ||||
|         let mut run: u8 = 0; | ||||
|         let mut run: u64 = 0; | ||||
|  | ||||
|         let head = Header { | ||||
|             magic: ['q', 'o', 'i', 'f'], | ||||
| @@ -414,7 +439,7 @@ pub mod qoi_lib { | ||||
|             encoded_bytes.push(i); | ||||
|         } | ||||
|  | ||||
|         let mut counter: u32 = 0; | ||||
|         let mut counter: u64 = 0; | ||||
|  | ||||
|         for pixel in img.pixels { | ||||
|             counter += 1; | ||||
| @@ -432,18 +457,21 @@ pub mod qoi_lib { | ||||
|                             encoded_bytes.push(QOI_OP_RUN | (62 - RUN_BIAS)); | ||||
|                             run -= 62; | ||||
|                         } else if run % 62 > 0 { | ||||
|                             encoded_bytes.push(QOI_OP_RUN | (run - RUN_BIAS)); | ||||
|                             let run_remainder: u8 = run.try_into().unwrap(); | ||||
|                             encoded_bytes.push(QOI_OP_RUN | (run_remainder - RUN_BIAS)); | ||||
|                             run = 0; | ||||
|                         } else { | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     encoded_bytes.push(QOI_OP_RUN | (run - RUN_BIAS)); | ||||
|                     let run8: u8 = run.try_into().unwrap(); | ||||
|                     encoded_bytes.push(QOI_OP_RUN | (run8 - RUN_BIAS)); | ||||
|                     run = 0; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|  | ||||
|             match chunk { | ||||
|                 (ChunkType::Index, Some((index, irr1, irr2))) => { | ||||
|                     encoded_bytes.push(QOI_OP_INDEX | index); | ||||
| @@ -509,14 +537,17 @@ pub mod qoi_lib { | ||||
|                         encoded_bytes.push(QOI_OP_RUN | (62 - RUN_BIAS)); | ||||
|                         run -= 62; | ||||
|                     } else if run % 62 > 0 { | ||||
|                         encoded_bytes.push(QOI_OP_RUN | (run - RUN_BIAS)); | ||||
|                         let run_remainder: u8 = run.try_into().unwrap(); | ||||
|                         encoded_bytes.push(QOI_OP_RUN | (run_remainder - RUN_BIAS)); | ||||
|                         run = 0; | ||||
|                     } else { | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 encoded_bytes.push(QOI_OP_RUN | (run - RUN_BIAS)); | ||||
|                 let run8: u8 = run.try_into().unwrap(); | ||||
|                 encoded_bytes.push(QOI_OP_RUN | (run8 - RUN_BIAS)); | ||||
|                 // run = 0; | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -760,10 +791,13 @@ pub mod qoi_lib { | ||||
|  | ||||
|     #[cfg(test)] | ||||
|     mod tests { | ||||
|  | ||||
|         use png::ColorType; | ||||
|  | ||||
|         use super::*; | ||||
|         use std::fs::File; | ||||
|         use std::io; | ||||
|         use std::io::{BufReader, Read}; | ||||
|         use std::path::*; | ||||
|  | ||||
|         #[test] | ||||
|         fn diff_test() { | ||||
| @@ -781,40 +815,131 @@ pub mod qoi_lib { | ||||
|         } | ||||
|  | ||||
|         #[test] | ||||
|         fn encode_test() -> io::Result<()> { | ||||
|             let f: File = File::open("test.qoi")?; | ||||
|             let mut reader = BufReader::new(f); | ||||
|             let mut bytes: Vec<u8> = Vec::new(); | ||||
|         fn qoi_to_qoi_test() -> io::Result<()> { | ||||
|             //Open path to test images | ||||
|             let path: &Path = Path::new("./qoi_test_images/"); | ||||
|             let dir: ReadDir = match path.read_dir() { | ||||
|                 Ok(d) => d, | ||||
|                 Err(e) => panic!("Error reading path {e:?}"), | ||||
|             }; | ||||
|             //Loop over files in directory, attempt to decode .qoi images and reencode  | ||||
|             for entry in dir { | ||||
|  | ||||
|             reader.read_to_end(&mut bytes)?; | ||||
|                 let file_path = match entry { | ||||
|                     Ok(d) => d.path(), | ||||
|                     Err(e) => panic!("Non-functional dir entry! \n {e:?}") | ||||
|                 }; | ||||
|                 let file_path_str = match file_path.to_str() { | ||||
|                     Some(s) => s, | ||||
|                     None => "" | ||||
|                 }; | ||||
|                 if !(file_path_str.contains(".qoi")) { | ||||
|                     continue; | ||||
|                 } | ||||
|                  | ||||
|                 let file = match File::open(&file_path) { | ||||
|                     Ok(f) => f, | ||||
|                     Err(e) => panic!("Error reading file with path {:?}", file_path_str), | ||||
|                 }; | ||||
|                 let mut reader = BufReader::new(file); | ||||
|                 let mut bytes: Vec<u8> = Vec::new(); | ||||
|  | ||||
|             let out_img: super::Image; | ||||
|                 reader.read_to_end(&mut bytes)?; | ||||
|  | ||||
|             match super::decode(bytes) { | ||||
|                 Ok(img) => out_img = img, | ||||
|                 Err(err) => panic!("wallah geht nicht :/ {:?}", err), | ||||
|                 let output_image: super::Image; | ||||
|                 match super::decode(bytes) { | ||||
|                     Ok(img) => output_image = img, | ||||
|                     Err(err) => panic!("Image decode failed for {:?}" , file_path.to_str()) | ||||
|                 } | ||||
|                 let mut name = match file_path.file_name() { | ||||
|                     Some(s) => match s.to_str() { | ||||
|                         Some(ss) => ss, | ||||
|                         None => panic!("File Name Error!") | ||||
|                     }, | ||||
|                     None => panic!("File Name Error!"), | ||||
|                 }; | ||||
|                 name = match name.strip_suffix(".qoi") { | ||||
|                     Some(n) => n, | ||||
|                     None => name, | ||||
|                 }; | ||||
|                 write_to_file(encode_from_image(output_image), name).expect("Writing image failed!"); | ||||
|             } | ||||
|             write_to_file(encode_from_image(out_img), "test_dec").expect("wallahi!"); | ||||
|              | ||||
|             Ok(()) | ||||
|         } | ||||
|  | ||||
|         #[test] | ||||
|         fn decode_test() -> io::Result<()> { | ||||
|             let f: File = File::open("testcard_rgba.qoi")?; | ||||
|             let mut reader = BufReader::new(f); | ||||
|             let mut bytes: Vec<u8> = Vec::new(); | ||||
|         fn png_to_qoi_test() -> io::Result<()> { | ||||
|             //Open path to test images | ||||
|             let path: &Path = Path::new("./qoi_test_images/"); | ||||
|             let dir: ReadDir = match path.read_dir() { | ||||
|                 Ok(d) => d, | ||||
|                 Err(e) => panic!("Error reading path {e:?}"), | ||||
|             }; | ||||
|             //Loop over files in directory, attempt to decode png and encode as qoi, compare to qoi | ||||
|             for entry in dir { | ||||
|  | ||||
|             reader.read_to_end(&mut bytes)?; | ||||
|                 let file_path = match entry { | ||||
|                     Ok(d) => d.path(), | ||||
|                     Err(e) => panic!("Non-functional dir entry! \n {e:?}") | ||||
|                 }; | ||||
|                 let file_path_str = match file_path.to_str() { | ||||
|                     Some(s) => s, | ||||
|                     None => "" | ||||
|                 }; | ||||
|                 if !(file_path_str.contains(".png")) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 println!("{:}",file_path_str); | ||||
|                 let file = match File::open(&file_path) { | ||||
|                     Ok(f) => f, | ||||
|                     Err(e) => panic!("Cannot read file! \n {e:?}") | ||||
|                 }; | ||||
|                 let decoder = png::Decoder::new(file); | ||||
|                 let mut reader = match decoder.read_info() { | ||||
|                     Ok(reader) => reader, | ||||
|                     Err(e) => panic!("ERROR: couldn't decode file: {e:}"), | ||||
|                 }; | ||||
|                 //read image metadata | ||||
|                 let width: u32 = reader.info().width; | ||||
|                 let height: u32 = reader.info().height; | ||||
|                 //for now: hardcoded to 4 | ||||
|                 let channels = match reader.info().color_type { | ||||
|                     ColorType::Rgb => 3, | ||||
|                     ColorType::Rgba => 4, | ||||
|                     _ => panic!("ERROR: Incompatible png file!") | ||||
|                 }; | ||||
|  | ||||
|             let out_img: super::Image; | ||||
|                 //create buffer matching the size of png-decoder output, writing size to output | ||||
|                 let mut buf = vec![0; reader.output_buffer_size()]; | ||||
|                 let info = match reader.next_frame(&mut buf) { | ||||
|                     Ok(i) => i, | ||||
|                     Err(e) => panic!("ERROR: {e:?}"), | ||||
|                 }; | ||||
|                 let bytes = &buf[..info.buffer_size()]; | ||||
|                 let byte_vec: Vec<u8> = bytes.to_vec(); | ||||
|  | ||||
|             match super::decode(bytes) { | ||||
|                 Ok(img) => out_img = img, | ||||
|                 Err(err) => panic!("Ja bruder war nicht so erfolgreich ahahahahahha {:?}", err), | ||||
|                 //create bitmap data from raw byte vector | ||||
|                 let img: Image = match Image::new(byte_vec, height, width, channels, 0) { | ||||
|                     Ok(image) => image, | ||||
|                     Err(err) => panic!("Problem generating image: {:?}", err), | ||||
|                 }; | ||||
|  | ||||
|                 let encoded_buffer = super::encode_from_image(img); | ||||
|                 let mut name =  match file_path.file_name() { | ||||
|                     None => panic!("whoops!"), | ||||
|                     Some(n) => match n.to_str() { | ||||
|                         None => panic!("im shiddin"), | ||||
|                         Some(s) => s,  | ||||
|                     }, | ||||
|                 }; | ||||
|                 name = match name.strip_suffix(".png") { | ||||
|                     Some(n) => n, | ||||
|                     None => name, | ||||
|                 }; | ||||
|                 write_to_file(encoded_buffer,name ).expect("Can't write resulting file!"); | ||||
|             } | ||||
|  | ||||
|             write_to_file(encode_from_image(out_img), "testcard_new").expect("Boowomb!"); | ||||
|  | ||||
|              | ||||
|             Ok(()) | ||||
|         } | ||||
|  | ||||
|   | ||||
							
								
								
									
										29
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -82,35 +82,6 @@ fn encode_debug() { | ||||
| } | ||||
|  | ||||
| fn demo() { | ||||
|     let decoder = png::Decoder::new(File::open("testcard_rgba.png").unwrap()); | ||||
|     let mut reader = match decoder.read_info() { | ||||
|         Ok(reader) => reader, | ||||
|         Err(e) => panic!("ERROR: couldn't read file: {e:}"), | ||||
|     }; | ||||
|     let mut buf = vec![0; reader.output_buffer_size()]; | ||||
|  | ||||
|     let info = match reader.next_frame(&mut buf) { | ||||
|         Ok(i) => i, | ||||
|         Err(e) => panic!("ERROR: {e:?}"), | ||||
|     }; | ||||
|  | ||||
|     let bytes = &buf[..info.buffer_size()]; | ||||
|     let byte_vec: Vec<u8> = bytes.to_vec(); | ||||
|  | ||||
|     let img: Image = match Image::new(byte_vec, 256, 256, 4, 0) { | ||||
|         Ok(image) => image, | ||||
|         Err(err) => panic!("Problem generating imag: {:?}", err), | ||||
|     }; | ||||
|     let start = SystemTime::now(); | ||||
|     write_to_file(encode_from_image(img), "img").expect("Error writing file!"); | ||||
|     let stop = match start.elapsed() { | ||||
|         Ok(elapsed) => elapsed.as_millis(), | ||||
|         Err(e) => { | ||||
|             println!("Error: {e:?}"); | ||||
|             return (); | ||||
|         } | ||||
|     }; | ||||
|     println!("Encode took: {} ms.", stop); | ||||
|     let start = SystemTime::now(); | ||||
|     encode_checkerboard(); | ||||
|     let stop = match start.elapsed() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user