Fixed input commands, png writing fixed.
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				build release package / build (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	build release package / build (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -207,7 +207,7 @@ dependencies = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "qoi" | ||||
| version = "0.9.0" | ||||
| version = "0.9.9" | ||||
| dependencies = [ | ||||
|  "array-init", | ||||
|  "clap", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| [package] | ||||
| name = "qoi" | ||||
| version = "0.9.0" | ||||
| version = "0.9.9" | ||||
| 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." | ||||
| @@ -10,7 +10,7 @@ repository = "https://git.valhrafnaz.gay/valhrafnaz/qoi-img" | ||||
| license-file = "LICENSE" | ||||
| keywords = ["image_compression", "encoding", "qoi", "cli", "library"] | ||||
| categories = ["command-line-utilities", "encoding", "graphics", "compression"] | ||||
| exlude = ["/qoi_test_images"] | ||||
| exclude = ["/qoi_test_images"] | ||||
| publish =  ["gitea"] | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										64
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -8,6 +8,9 @@ pub mod qoi_lib { | ||||
|     use std::fmt; | ||||
|     use std::fs::*; | ||||
|     use std::io::prelude::*; | ||||
|     use std::io::BufWriter; | ||||
|     use std::path::Path; | ||||
|     use png; | ||||
|      | ||||
|  | ||||
|     use array_init; | ||||
| @@ -40,7 +43,7 @@ pub mod qoi_lib { | ||||
|     } | ||||
|  | ||||
|     //boilerplate implementation of the log crate | ||||
|     struct SimpleLogger; | ||||
|     pub struct SimpleLogger; | ||||
|  | ||||
|     impl log::Log for SimpleLogger { | ||||
|         fn enabled(&self, metadata: &log::Metadata) -> bool { | ||||
| @@ -84,8 +87,8 @@ pub mod qoi_lib { | ||||
|     /// # | ||||
|     /// # } | ||||
|     /// ``` | ||||
|     pub fn init() -> Result<(), SetLoggerError> { | ||||
|         log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Debug)) | ||||
|     pub fn init(level: LevelFilter) -> Result<(), SetLoggerError> { | ||||
|         log::set_logger(&LOGGER).map(|()| log::set_max_level(level)) | ||||
|     } | ||||
|  | ||||
|     /// Custom image struct, which is used to store decoded data. Used by [encode_from_image] to encode the necessary data in bytes. Requires a Vector over [Pixel] values, `Vec<Pixel>`, | ||||
| @@ -204,7 +207,7 @@ pub mod qoi_lib { | ||||
|             } | ||||
|              | ||||
|         } | ||||
|         pub fn pixels_to_bytes(&self) -> Vec<u8> { | ||||
|         pub fn to_bytes(&self) -> Vec<u8> { | ||||
|             let mut buf: Vec<u8> = Vec::with_capacity(self.height as usize * self.width as usize * 4 as usize); | ||||
|             for pixel in &self.pixels { | ||||
|                 buf.push(pixel.r); | ||||
| @@ -214,6 +217,39 @@ pub mod qoi_lib { | ||||
|             } | ||||
|             return buf; | ||||
|         } | ||||
|         pub fn write_png(&self, path: &str) { | ||||
|             let mut file_path: String = String::new(); | ||||
|             file_path.push_str(path); | ||||
|             if !path.contains(".png") { | ||||
|                 file_path.push_str(".png"); | ||||
|             } | ||||
|             let path = Path::new(&file_path); | ||||
|             let file = match File::create(path) { | ||||
|                 Ok(f) => f, | ||||
|                 Err(e) => panic!("ERROR during writing output file: {e:?}") | ||||
|             }; | ||||
|             let buf: Vec<u8> = self.to_bytes(); | ||||
|             let ref mut w = BufWriter::new(file); | ||||
|             let mut encoder = png::Encoder::new(w, self.width, self.height); | ||||
|  | ||||
|             encoder.set_color(png::ColorType::Rgba); | ||||
|             encoder.set_depth(png::BitDepth::Eight); | ||||
|  | ||||
|             encoder.set_source_gamma(png::ScaledFloat::new(1.0 / 2.2));     // 1.0 / 2.2, unscaled, but rounded | ||||
|             let source_chromaticities = png::SourceChromaticities::new(     // Using unscaled instantiation here | ||||
|                 (0.31270, 0.32900), | ||||
|                 (0.64000, 0.33000), | ||||
|                 (0.30000, 0.60000), | ||||
|                 (0.15000, 0.06000) | ||||
|             ); | ||||
|             encoder.set_source_chromaticities(source_chromaticities); | ||||
|             let mut writer = encoder.write_header().unwrap(); | ||||
|             match writer.write_image_data(&buf) { | ||||
|                 Ok(_a) => (), | ||||
|                 Err(e) => panic!("Cannot write output file! {e:?}") | ||||
|             } | ||||
|             writer.finish().unwrap(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[derive(Clone, Copy, Debug, PartialEq)] | ||||
| @@ -577,10 +613,20 @@ pub mod qoi_lib { | ||||
|  | ||||
|         encoded_bytes | ||||
|     } | ||||
|  | ||||
|     /// Writes Image as byte vector to file with name given as string slice. | ||||
|     /// ```rust | ||||
|     /// use qoi::qoi_lib::* | ||||
|     ///  | ||||
|     /// let img = Image::new(); | ||||
|     /// let bytes: Vec<u8> = img.to_bytes(); | ||||
|     /// let name = "qoi-image"; | ||||
|     /// write_to_file(bytes, name); | ||||
|     /// ``` | ||||
|     pub fn write_to_file(bytes: Vec<u8>, filename: &str) -> std::io::Result<()> { | ||||
|         let mut file_path: String = String::from(filename); | ||||
|         file_path.push_str(".qoi"); | ||||
|         if !filename.contains(".qoi") { | ||||
|             file_path.push_str(".qoi"); | ||||
|         } | ||||
|  | ||||
|         let mut buffer = File::create(file_path)?; | ||||
|         let mut pos = 0; | ||||
| @@ -806,11 +852,11 @@ pub mod qoi_lib { | ||||
|         use super::*; | ||||
|         use std::io; | ||||
|         use std::io::{BufReader, Read}; | ||||
|         use std::path::*; | ||||
|  | ||||
|         #[test] | ||||
|         fn diff_test() { | ||||
|             init().expect("Logger initialisation failed!"); | ||||
|             let level: LevelFilter = LevelFilter::Debug; | ||||
|             init(level).expect("Logger initialisation failed!"); | ||||
|             let pix1: Pixel = Pixel::new(0, 0, 0, 255); | ||||
|             let pix2: Pixel = Pixel::new(255, 255, 255, 255); | ||||
|  | ||||
| @@ -899,7 +945,7 @@ pub mod qoi_lib { | ||||
|                 if !(file_path_str.contains(".png")) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 println!("{:}",file_path_str); | ||||
|                 debug!("{:}",file_path_str); | ||||
|                 let file = match File::open(&file_path) { | ||||
|                     Ok(f) => f, | ||||
|                     Err(e) => panic!("Cannot read file! \n {e:?}") | ||||
|   | ||||
							
								
								
									
										98
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
|  | ||||
| use clap::{Parser, Subcommand}; | ||||
| use clap::{Args,Parser, Subcommand}; | ||||
| use std::fs::File; | ||||
| use std::io::{BufReader, Read}; | ||||
| use std::time::SystemTime; | ||||
| @@ -7,6 +7,7 @@ use std::time::SystemTime; | ||||
| use colors_transform::{Color, Hsl, Rgb}; | ||||
| use png; | ||||
| use qoi::qoi_lib::*; | ||||
| use log::{error,info}; | ||||
|  | ||||
| fn encode_checkerboard() { | ||||
|     let mut pixels: Vec<Pixel> = Vec::with_capacity(64 * 64); | ||||
| @@ -59,7 +60,7 @@ fn encode_debug() { | ||||
|                     1 => img_data.push(rgb.get_green() as u8), | ||||
|                     2 => img_data.push(rgb.get_blue() as u8), | ||||
|                     3 => img_data.push(alpha as u8), | ||||
|                     _ => panic!("unrecoverable for-loop failure"), | ||||
|                     _ => error!("unrecoverable for-loop failure"), | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -73,11 +74,11 @@ fn encode_debug() { | ||||
|     let stop = match start.elapsed() { | ||||
|         Ok(elapsed) => elapsed.as_millis(), | ||||
|         Err(e) => { | ||||
|             println!("Error: {e:?}"); | ||||
|             error!("Error: {e:?}"); | ||||
|             return (); | ||||
|         } | ||||
|     }; | ||||
|     println!("Encode took: {} ms.", stop); | ||||
|     info!("Encode took: {} ms.", stop); | ||||
|     write_to_file(img_bytes, "test").expect("Error writing file!"); | ||||
| } | ||||
|  | ||||
| @@ -87,7 +88,7 @@ fn demo() { | ||||
|     let stop = match start.elapsed() { | ||||
|         Ok(elapsed) => elapsed.as_millis(), | ||||
|         Err(e) => { | ||||
|             println!("Error: {e:?}"); | ||||
|             error!("Error: {e:?}"); | ||||
|             return (); | ||||
|         } | ||||
|     }; | ||||
| @@ -129,7 +130,7 @@ fn encode(in_path: &str, out_path: &str) { | ||||
|     }; | ||||
|  | ||||
|     write_to_file(encode_from_image(img), out_path).expect("ERROR: Can't write file."); | ||||
|     println!("Encoding successful!"); | ||||
|     info!("Encoding successful!"); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -145,7 +146,7 @@ fn decode(path: &str) -> Result<Image, std::io::Error> { | ||||
|  | ||||
|     match qoi::qoi_lib::decode(bytes) { | ||||
|         Ok(img) => { | ||||
|             println!("Decoding successful!"); | ||||
|             info!("Decoding successful!"); | ||||
|             return Ok(img); | ||||
|         }, | ||||
|         Err(err) => panic!("ERROR: {err:?}"), | ||||
| @@ -177,13 +178,13 @@ fn bench(input: &str, output: Option<String>) { | ||||
|     } | ||||
|     let start = SystemTime::now(); | ||||
|     let mut out_path: String = out_path.to_owned(); | ||||
|     if !(out_path.contains(".qoi")) { | ||||
|     if !out_path.contains(".qoi") { | ||||
|         out_path.push_str(".qoi"); | ||||
|     } | ||||
|     match decode(&out_path) { | ||||
|         Ok(img) => { | ||||
|              | ||||
|             let out_buf = img.pixels_to_bytes(); | ||||
|             let out_buf = img.to_bytes(); | ||||
|             let _ = write_to_file(out_buf, out_path.strip_suffix(".qoi").unwrap()).expect("whoops!"); | ||||
|         }, | ||||
|         Err(e) => panic!("Error: {e:?}") | ||||
| @@ -208,6 +209,7 @@ fn bench(input: &str, output: Option<String>) { | ||||
| #[command(version, about, long_about = None)] | ||||
| #[command(next_line_help = true)]  | ||||
| struct Cli { | ||||
|     /// Specify log verbosity, respects multiple applications. | ||||
|     #[arg(short,long, action = clap::ArgAction::Count)] | ||||
|     verbose: Option<u8>, | ||||
|  | ||||
| @@ -217,51 +219,79 @@ struct Cli { | ||||
|  | ||||
| #[derive(Subcommand)] | ||||
| enum Commands { | ||||
|     Encode { | ||||
|         input: String, | ||||
|         output: Option<String> | ||||
|     }, | ||||
|     Decode { | ||||
|         input: String, | ||||
|         out_fmt: String, | ||||
|         output: Option<String> | ||||
|     }, | ||||
|     Bench { | ||||
|         input: String, | ||||
|         output: Option<String> | ||||
|     }, | ||||
|     /// Encode given [IMAGE] from { png } to qoi.  | ||||
|     Encode(EncodeArgs), | ||||
|     /// Decode given qoi to specified [FORMAT]. | ||||
|     Decode(DecodeArgs), | ||||
|     /// Benchmark en- and decoder by passing in [IMAGE] and optionally specifying [OUTPUT] file. | ||||
|     Bench(BenchArgs), | ||||
|     /// Demo the application. | ||||
|     Demo { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Args)] | ||||
| struct BenchArgs { | ||||
|     /// File to be encoded. | ||||
|     #[arg(short,long)] | ||||
|     input: String, | ||||
|     /// Optional output path. | ||||
|     #[arg(short,long)] | ||||
|     output: Option<String> | ||||
| } | ||||
|  | ||||
| #[derive(Args)] | ||||
| struct DecodeArgs { | ||||
|     /// Qoi file to be decoded | ||||
|     #[arg(short,long)] | ||||
|     input: String, | ||||
|     /// Format to transcode into | ||||
|     #[arg(short,long)] | ||||
|     format: String, | ||||
|     /// Optional file path | ||||
|     #[arg(short,long)] | ||||
|     output: Option<String> | ||||
| } | ||||
|  | ||||
| #[derive(Args)] | ||||
| struct EncodeArgs { | ||||
|     // File to be encoded | ||||
|     #[arg(short,long)] | ||||
|     input: String, | ||||
|     // Optional output path | ||||
|     #[arg(short,long)] | ||||
|     output: Option<String> | ||||
| } | ||||
|  | ||||
| fn main() { | ||||
|     let cli: Cli = Cli::parse(); | ||||
|      | ||||
|  | ||||
|     match &cli.command { | ||||
|         Commands::Bench { input, output } => { | ||||
|             bench(&input, output.clone()); | ||||
|         Commands::Bench(args) => { | ||||
|             bench(&args.input, args.output.clone()); | ||||
|         }, | ||||
|         Commands::Decode { input, out_fmt, output } => { | ||||
|             if out_fmt != "png" { | ||||
|         Commands::Decode(args)=> { | ||||
|             if args.format != "png" { | ||||
|                 panic!("Unsupported output format!") | ||||
|             } else { | ||||
|                 let img = match decode(&input) { | ||||
|                 let img = match decode(&args.input) { | ||||
|                     Ok(i) => i, | ||||
|                     Err(e) => panic!("Error: {e:?}") | ||||
|                 }; | ||||
|                 let out_path = match output { | ||||
|                 let out_path = match &args.output { | ||||
|                     Some(s) => s, | ||||
|                     None => input  | ||||
|                     None => &args.input  | ||||
|                 }; | ||||
|                 let _ = write_to_file(img.pixels_to_bytes(), &out_path).expect("Error writing file!"); | ||||
|                 img.write_png(&out_path); | ||||
|             } | ||||
|         }, | ||||
|         Commands::Encode { input, output } => { | ||||
|             let out_path = match output { | ||||
|         Commands::Encode(args) => { | ||||
|             let out_path = match &args.output { | ||||
|                 Some(s) => s, | ||||
|                 None => input | ||||
|                 None => &args.input | ||||
|             }; | ||||
|             encode(&input, &out_path); | ||||
|             encode(&args.input, &out_path); | ||||
|         }, | ||||
|         Commands::Demo {  } => demo() | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user