mirror of
https://github.com/woelper/oculante
synced 2024-10-18 05:32:34 +00:00
cover all png variants
This commit is contained in:
parent
d9e5101c0e
commit
b9ace311ea
72
Cargo.lock
generated
72
Cargo.lock
generated
|
@ -275,6 +275,12 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded"
|
||||
|
||||
[[package]]
|
||||
name = "bitreader"
|
||||
version = "0.3.7"
|
||||
|
@ -394,7 +400,7 @@ version = "0.10.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"log",
|
||||
"nix 0.25.1",
|
||||
"slotmap",
|
||||
|
@ -473,7 +479,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"clap_lex",
|
||||
"indexmap",
|
||||
"strsim",
|
||||
|
@ -541,7 +547,7 @@ version = "0.24.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"core-foundation",
|
||||
|
@ -557,7 +563,7 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"block",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
|
@ -642,7 +648,7 @@ version = "0.22.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"foreign-types 0.3.2",
|
||||
|
@ -655,7 +661,7 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"foreign-types 0.3.2",
|
||||
"libc",
|
||||
|
@ -1062,7 +1068,7 @@ version = "0.2.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -1261,7 +1267,7 @@ version = "0.26.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"freetype-sys",
|
||||
"libc",
|
||||
]
|
||||
|
@ -1576,7 +1582,7 @@ version = "0.30.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b0385782048be65f0a9dd046c469d6a758a53fe1aa63a8111dea394d2ffa2f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cfg_aliases",
|
||||
"cgl",
|
||||
"core-foundation",
|
||||
|
@ -2572,7 +2578,7 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"jni-sys",
|
||||
"ndk-sys",
|
||||
"num_enum",
|
||||
|
@ -2636,7 +2642,7 @@ version = "0.24.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset 0.6.5",
|
||||
|
@ -2649,7 +2655,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset 0.6.5",
|
||||
|
@ -3164,6 +3170,7 @@ dependencies = [
|
|||
"webbrowser",
|
||||
"windres",
|
||||
"winres",
|
||||
"zune-png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3445,7 +3452,7 @@ version = "0.17.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
|
@ -3459,7 +3466,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if 1.0.0",
|
||||
"concurrent-queue",
|
||||
"libc",
|
||||
|
@ -3716,7 +3723,7 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3725,7 +3732,7 @@ version = "0.3.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3927,7 +3934,7 @@ version = "0.37.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
|
@ -3978,7 +3985,7 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162bdf42e261bee271b3957691018634488084ef577dddeb6420a9684cab2a6a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
"smallvec",
|
||||
"ttf-parser 0.18.1",
|
||||
|
@ -4246,7 +4253,7 @@ version = "0.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"calloop",
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
|
@ -5017,7 +5024,7 @@ version = "0.29.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"downcast-rs",
|
||||
"libc",
|
||||
"nix 0.24.3",
|
||||
|
@ -5056,7 +5063,7 @@ version = "0.29.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
|
@ -5398,7 +5405,7 @@ version = "0.27.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cocoa",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
|
@ -5547,6 +5554,15 @@ dependencies = [
|
|||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ca36c2e02af0d8d7ee977542bfe33ed1c516be73d3c1faa4420af46e96ceee"
|
||||
dependencies = [
|
||||
"bitflags 2.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-inflate"
|
||||
version = "0.2.54"
|
||||
|
@ -5555,3 +5571,15 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
|||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-png"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee5abc36f78f32bf5ffb5f070a69cb7beffa7cb393817d3a30f9fe7c1ea57655"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"log",
|
||||
"zune-core",
|
||||
"zune-inflate",
|
||||
]
|
||||
|
|
|
@ -59,7 +59,7 @@ usvg = "0.33.0"
|
|||
webbrowser = "0.8"
|
||||
tiff = "0.9"
|
||||
jxl-oxide = "0.3.0"
|
||||
|
||||
zune-png = "0.2"
|
||||
|
||||
[features]
|
||||
avif_native = ["avif-decode"]
|
||||
|
|
|
@ -1 +1 @@
|
|||
209ms
|
||||
213ms
|
|
@ -1 +1 @@
|
|||
247ms
|
||||
389ms
|
13
src/tests.rs
13
src/tests.rs
|
@ -40,10 +40,13 @@ fn net() {
|
|||
|
||||
#[test]
|
||||
fn bench_load_large() {
|
||||
#[cfg(debug_assertions)]
|
||||
panic!("This test needs release mode to pass.");
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
let _ = env_logger::try_init();
|
||||
let iters = 5;
|
||||
info!("Benching this with {iters} iterations...");
|
||||
|
||||
info!("Benching JPEG with {iters} iterations...");
|
||||
let mut total = 0;
|
||||
|
||||
for _i in 0..iters {
|
||||
|
@ -59,10 +62,9 @@ fn bench_load_large() {
|
|||
}
|
||||
info!("{} ms mean", total / iters);
|
||||
let mut f = File::create("benches/load_large_jpg.bench").unwrap();
|
||||
f.write_fmt(format_args!("{}ms", total / iters))
|
||||
.unwrap();
|
||||
f.write_fmt(format_args!("{}ms", total / iters)).unwrap();
|
||||
|
||||
info!("Benching this with {iters} iterations...");
|
||||
info!("Benching PNG with {iters} iterations...");
|
||||
let mut total = 0;
|
||||
|
||||
for _i in 0..iters {
|
||||
|
@ -75,8 +77,7 @@ fn bench_load_large() {
|
|||
}
|
||||
info!("{} ms mean", total / iters);
|
||||
let mut f = File::create("benches/load_large_png.bench").unwrap();
|
||||
f.write_fmt(format_args!("{}ms", total / iters))
|
||||
.unwrap();
|
||||
f.write_fmt(format_args!("{}ms", total / iters)).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
111
src/utils.rs
111
src/utils.rs
|
@ -5,7 +5,7 @@ use jxl_oxide::{JxlImage, PixelFormat, RenderResult};
|
|||
// use image::codecs::gif::GifDecoder;
|
||||
use exr::prelude as exrs;
|
||||
use exr::prelude::*;
|
||||
use image::{DynamicImage, EncodableLayout, GrayAlphaImage, RgbImage, RgbaImage};
|
||||
use image::{DynamicImage, EncodableLayout, GrayAlphaImage, GrayImage, RgbImage, RgbaImage};
|
||||
use log::{debug, error, info};
|
||||
use nalgebra::{clamp, Vector2};
|
||||
use notan::graphics::Texture;
|
||||
|
@ -23,6 +23,8 @@ use std::thread;
|
|||
use std::time::Duration;
|
||||
use tiff::decoder::Limits;
|
||||
use usvg::{TreeParsing, TreeTextToPath};
|
||||
use zune_png::zune_core::result::DecodingResult;
|
||||
use zune_png::PngDecoder;
|
||||
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use image::Rgba;
|
||||
|
@ -30,7 +32,6 @@ use image::{self};
|
|||
use libwebp_sys::{WebPDecodeRGBA, WebPGetInfo};
|
||||
use psd::Psd;
|
||||
use rgb::*;
|
||||
use std::io::Read;
|
||||
use std::sync::mpsc::{self, channel};
|
||||
use std::sync::mpsc::{Receiver, Sender};
|
||||
use strum::Display;
|
||||
|
@ -76,8 +77,6 @@ impl ExtendedImageInfo {
|
|||
let exifreader = exif::Reader::new();
|
||||
let exif = exifreader.read_from_container(&mut bufreader)?;
|
||||
for f in exif.fields() {
|
||||
// let s = format!("{} {} {}",
|
||||
// f.tag, f.ifd_num, f.display_value().with_unit(&exif));
|
||||
self.exif.insert(
|
||||
f.tag.to_string(),
|
||||
f.display_value().with_unit(&exif).to_string(),
|
||||
|
@ -92,7 +91,7 @@ impl ExtendedImageInfo {
|
|||
let mut green_histogram: HashMap<u8, usize> = Default::default();
|
||||
let mut blue_histogram: HashMap<u8, usize> = Default::default();
|
||||
|
||||
let mut num_pixels = 0;
|
||||
let num_pixels = img.width() as usize * img.height() as usize;
|
||||
let mut num_transparent_pixels = 0;
|
||||
for p in img.pixels() {
|
||||
if is_pixel_fully_transparent(p) {
|
||||
|
@ -106,26 +105,25 @@ impl ExtendedImageInfo {
|
|||
let mut p = *p;
|
||||
p.0[3] = 255;
|
||||
colors.insert(p);
|
||||
num_pixels += 1;
|
||||
}
|
||||
|
||||
let mut green_histogram: Vec<(i32, i32)> = green_histogram
|
||||
.par_iter()
|
||||
.map(|(k, v)| (*k as i32, *v as i32))
|
||||
.collect();
|
||||
green_histogram.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
green_histogram.par_sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
let mut red_histogram: Vec<(i32, i32)> = red_histogram
|
||||
.par_iter()
|
||||
.map(|(k, v)| (*k as i32, *v as i32))
|
||||
.collect();
|
||||
red_histogram.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
red_histogram.par_sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
let mut blue_histogram: Vec<(i32, i32)> = blue_histogram
|
||||
.par_iter()
|
||||
.map(|(k, v)| (*k as i32, *v as i32))
|
||||
.collect();
|
||||
blue_histogram.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
blue_histogram.par_sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
Self {
|
||||
num_pixels,
|
||||
|
@ -912,10 +910,7 @@ pub fn open_image(img_location: &Path) -> Result<Receiver<Frame>> {
|
|||
return Ok(receiver);
|
||||
}
|
||||
"psd" => {
|
||||
let mut file = File::open(img_location)?;
|
||||
let mut contents = vec![];
|
||||
file.read_to_end(&mut contents)?;
|
||||
|
||||
let contents = std::fs::read(img_location)?;
|
||||
let psd = Psd::from_bytes(&contents).map_err(|e| anyhow!("{:?}", e))?;
|
||||
let buf = image::ImageBuffer::from_raw(psd.width(), psd.height(), psd.rgba())
|
||||
.context("Can't create imagebuffer from PSD")?;
|
||||
|
@ -924,21 +919,91 @@ pub fn open_image(img_location: &Path) -> Result<Receiver<Frame>> {
|
|||
return Ok(receiver);
|
||||
}
|
||||
"webp" => {
|
||||
let mut file = File::open(img_location)?;
|
||||
let mut contents = vec![];
|
||||
file.read_to_end(&mut contents)?;
|
||||
let contents = std::fs::read(img_location)?;
|
||||
let buf = decode_webp(&contents).context("Can't decode webp")?;
|
||||
_ = sender.send(Frame::new_still(buf));
|
||||
return Ok(receiver);
|
||||
}
|
||||
"png" => {
|
||||
let file = File::open(img_location)?;
|
||||
let bufread = BufReader::new(file);
|
||||
let mut reader = image::io::Reader::new(bufread).with_guessed_format()?;
|
||||
reader.no_limits();
|
||||
_ = sender.send(Frame::new_still(reader.decode()?.into_rgba8()));
|
||||
return Ok(receiver);
|
||||
// col.add_still(reader.decode()?.into_rgba8());
|
||||
let contents = std::fs::read(&img_location)?;
|
||||
let mut decoder = PngDecoder::new(&contents);
|
||||
match decoder.decode().map_err(|e| anyhow!("{:?}", e))? {
|
||||
// 16 bpp data
|
||||
DecodingResult::U16(imgdata) => {
|
||||
//convert to 8bpp
|
||||
let imgdata_8bpp = imgdata
|
||||
.par_iter()
|
||||
.map(|x| *x as f32 / u16::MAX as f32)
|
||||
.map(|p| p.powf(2.2))
|
||||
.map(|p| tonemap_f32(p))
|
||||
// .map(|x| x as u8)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let (width, height) = decoder
|
||||
.get_dimensions()
|
||||
.context("Can't get png dimensions")?;
|
||||
let colorspace = decoder.get_colorspace().context("Can't get colorspace")?;
|
||||
|
||||
if colorspace.is_grayscale() {
|
||||
let buf: GrayImage =
|
||||
image::ImageBuffer::from_raw(width as u32, height as u32, imgdata_8bpp)
|
||||
.context("Can't interpret image as grayscale")?;
|
||||
let image_result = DynamicImage::ImageLuma8(buf);
|
||||
_ = sender.send(Frame::new_still(image_result.to_rgba8()));
|
||||
return Ok(receiver);
|
||||
}
|
||||
|
||||
if colorspace.has_alpha() {
|
||||
let float_image =
|
||||
RgbaImage::from_raw(width as u32, height as u32, imgdata_8bpp)
|
||||
.context("Can't decode rgba buffer")?;
|
||||
_ = sender.send(Frame::new_still(
|
||||
DynamicImage::ImageRgba8(float_image).to_rgba8(),
|
||||
));
|
||||
return Ok(receiver);
|
||||
} else {
|
||||
let float_image =
|
||||
RgbImage::from_raw(width as u32, height as u32, imgdata_8bpp)
|
||||
.context("Can't decode rgba buffer")?;
|
||||
_ = sender.send(Frame::new_still(
|
||||
DynamicImage::ImageRgb8(float_image).to_rgba8(),
|
||||
));
|
||||
return Ok(receiver);
|
||||
}
|
||||
}
|
||||
// 8bpp
|
||||
DecodingResult::U8(value) => {
|
||||
let (width, height) = decoder
|
||||
.get_dimensions()
|
||||
.context("Can't get png dimensions")?;
|
||||
|
||||
let colorspace = decoder.get_colorspace().context("Can't get colorspace")?;
|
||||
if colorspace.is_grayscale() {
|
||||
let buf: GrayImage =
|
||||
image::ImageBuffer::from_raw(width as u32, height as u32, value)
|
||||
.context("Can't interpret image as grayscale")?;
|
||||
let image_result = DynamicImage::ImageLuma8(buf);
|
||||
_ = sender.send(Frame::new_still(image_result.to_rgba8()));
|
||||
return Ok(receiver);
|
||||
}
|
||||
|
||||
if colorspace.has_alpha() {
|
||||
let buf: RgbaImage =
|
||||
image::ImageBuffer::from_raw(width as u32, height as u32, value)
|
||||
.context("Can't interpret image as rgba")?;
|
||||
_ = sender.send(Frame::new_still(buf));
|
||||
return Ok(receiver);
|
||||
} else {
|
||||
let buf: RgbImage =
|
||||
image::ImageBuffer::from_raw(width as u32, height as u32, value)
|
||||
.context("Can't interpret image as rgb")?;
|
||||
let image_result = DynamicImage::ImageRgb8(buf);
|
||||
_ = sender.send(Frame::new_still(image_result.to_rgba8()));
|
||||
return Ok(receiver);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
"gif" => {
|
||||
let file = File::open(img_location)?;
|
||||
|
|
BIN
tests/gray_8bpp.png
Normal file
BIN
tests/gray_8bpp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Loading…
Reference in a new issue