diff options
author | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 |
commit | 1b6a04ca5504955c571d1c97504fb45ea0befee4 (patch) | |
tree | 7579f518b23313e8a9748a88ab6173d5e030b227 /vendor/jpeg-decoder/examples/decode.rs | |
parent | 5ecd8cf2cba827454317368b68571df0d13d7842 (diff) | |
download | fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.tar.xz fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.zip |
Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
Diffstat (limited to 'vendor/jpeg-decoder/examples/decode.rs')
-rw-r--r-- | vendor/jpeg-decoder/examples/decode.rs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/jpeg-decoder/examples/decode.rs b/vendor/jpeg-decoder/examples/decode.rs new file mode 100644 index 0000000..13934fe --- /dev/null +++ b/vendor/jpeg-decoder/examples/decode.rs @@ -0,0 +1,83 @@ +extern crate jpeg_decoder as jpeg; +extern crate png; + +use std::env; +use std::fs::File; +use std::io::{self, BufReader, Write}; +use std::process; + +fn usage() -> ! { + write!(io::stderr(), "usage: decode image.jpg image.png").unwrap(); + process::exit(1) +} + +fn main() { + let mut args = env::args().skip(1); + let input_path = args.next().unwrap_or_else(|| usage()); + let output_path = args.next().unwrap_or_else(|| usage()); + + let input_file = File::open(input_path).expect("The specified input file could not be opened"); + let mut decoder = jpeg::Decoder::new(BufReader::new(input_file)); + let mut data = decoder.decode().expect("Decoding failed. If other software can successfully decode the specified JPEG image, then it's likely that there is a bug in jpeg-decoder"); + let info = decoder.info().unwrap(); + + eprintln!("{:?}", info); + eprintln!("Exif: {}", decoder.exif_data().is_some()); + eprintln!("ICC: {}", decoder.icc_profile().is_some()); + + let output_file = File::create(output_path).unwrap(); + let mut encoder = png::Encoder::new(output_file, info.width as u32, info.height as u32); + + match info.pixel_format { + jpeg::PixelFormat::L16 => { + encoder.set_depth(png::BitDepth::Sixteen); + encoder.set_color(png::ColorType::Grayscale); + }, + jpeg::PixelFormat::RGB24 => { + encoder.set_depth(png::BitDepth::Eight); + encoder.set_color(png::ColorType::RGB); + }, + jpeg::PixelFormat::CMYK32 => { + data = cmyk_to_rgb(&mut data); + encoder.set_depth(png::BitDepth::Eight); + encoder.set_color(png::ColorType::RGB) + }, + jpeg::PixelFormat::L8 => { + encoder.set_depth(png::BitDepth::Eight); + encoder.set_color(png::ColorType::Grayscale); + }, + } + + encoder.write_header() + .expect("writing png header failed") + .write_image_data(&data) + .expect("png encoding failed"); +} + +fn cmyk_to_rgb(input: &[u8]) -> Vec<u8> { + let size = input.len() - input.len() / 4; + let mut output = Vec::with_capacity(size); + + for pixel in input.chunks(4) { + let c = pixel[0] as f32 / 255.0; + let m = pixel[1] as f32 / 255.0; + let y = pixel[2] as f32 / 255.0; + let k = pixel[3] as f32 / 255.0; + + // CMYK -> CMY + let c = c * (1.0 - k) + k; + let m = m * (1.0 - k) + k; + let y = y * (1.0 - k) + k; + + // CMY -> RGB + let r = (1.0 - c) * 255.0; + let g = (1.0 - m) * 255.0; + let b = (1.0 - y) * 255.0; + + output.push(r as u8); + output.push(g as u8); + output.push(b as u8); + } + + output +} |