-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support u16/f32 pixmaps #63
Comments
Can you elaborate a bit? |
Also: this seems to be at odds with one of the non-goals on the readme. |
Well, PS: Readme is somewhat outdated. |
I guess one option is to make it E.g.: use num::{traits::ConstZero, Num};
use rand::prelude::*;
use smallvec::SmallVec;
struct Pixmap<T, F>
where
T: Clone + Num + ConstZero,
F: FnMut([f32; 4]) -> [T; 4],
{
pixels: Vec<T>,
mapper: F,
}
impl<T, F> Pixmap<T, F>
where
T: Clone + Num + ConstZero,
F: FnMut([f32; 4]) -> [T; 4],
{
pub fn new(width: u32, height: u32, mapper: F) -> Self {
Self {
pixels: vec![T::ZERO; (width * height) as _],
mapper,
}
}
}
fn main() {
let mapper_u8_naive = |rgba: [f32; 4]| {
rgba
.iter()
.map(|v| (v * 255.0) as u8)
.collect::<SmallVec<[u8; 4]>>()
.into_inner()
.unwrap()
};
let pixmap = Pixmap::new(320, 240, mapper_u8_naive);
let mut rng = rand::thread_rng();
// Map a value between 0..1 to 0..255 w. random noise dithering.
let mapper_u8_dither = |rgba: [f32; 4]| {
const ONE: f32 = u8::MAX as _;
const MIN: f32 = 0.0;
const MAX: f32 = u8::MAX as _;
const DITHER: f32 = 0.5;
rgba
.iter()
.map(|v| (ONE * v + DITHER * rng.gen::<f32>()).clamp(MIN, MAX) as u8)
.collect::<SmallVec<[u8; 4]>>()
.into_inner()
.unwrap()
};
let mut rng = rand::thread_rng();
// Map a value between 0..1 to 0..16383 and values above in the remaining range,
// clipping at 2.0 and w. random noise dithering.
let mapper_u16_headroom_dither = |rgba: [f32; 4]| {
const ONE: f32 = (u16::MAX / 2) as _;
const MIN: f32 = 0.0;
const MAX: f32 = u16::MAX as _;
const DITHER: f32 = 0.5;
rgba
.iter()
.map(|v| (ONE * v + DITHER * rng.gen::<f32>()).clamp(MIN, MAX) as u8)
.collect::<SmallVec<[u8; 4]>>()
.into_inner()
.unwrap()
};
} This allows a user to map to types that are not even PODs, e.g. For example, if the assumed working space was
|
The above could also be called |
Would a PR with the above approach have any chance of approval? 😁 |
Transferring function is definitely not an option. |
Hmm, but I presume the current hard-wired function is from (assumed) linear sRGB When |
Right now, Either way, this would be a pretty complicated change and I'm not expecting anyone to tackle it. |
The main reason I asked for support for higher bit depths is banding on gradients. This is especially relevant if the output of But banding could be prevented/hidden with dithering. I opened an issue in the new I think this could be relevant here too resp. be a 'workaround' until |
Good to have. This is technically already supported, but we have to provide a sane public API for it.
The text was updated successfully, but these errors were encountered: