-
Notifications
You must be signed in to change notification settings - Fork 623
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
Pixel access naming conventions #1853
Comments
We shouldn't forget fixing |
I'm supportive of an API overhaul to make these methods match API conventions. However, we should probably keep panicking versions of the accessors, given that they can be more ergonomic in many cases (think about array indexing vs. the |
I started working on this and had a few questions. What's changing?Current traits // pub trait GenericImageView {
- fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel;
+ fn pixel(&self, x: u32, y: u32) -> Option<&Self::Pixel>;
- unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> Self::Pixel;
+ unsafe fn pixel_unchecked(&self, x: u32, y: u32) -> &Self::Pixel; // pub trait GenericImage: GenericImageView {
- fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel; // deprecated
- fn put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel);
+ fn pixel_mut(&mut self, x: u32, y: u32) -> Option<&mut Self::Pixel>;
- unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel);
+ unsafe fn pixel_mut_unchecked(&mut self, x: u32, y: u32) -> &mut Self::Pixel;
- fn blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel); // deprecated I'm not sure if it's desirable to destructively remodel the traits or add the
Panicking access
Should that be delegated to buffer[(x, y)]
buffer.get_pixel(x, y) Users can migrate impl
|
fn put_pixel(&mut self, x: u32, y: u32, pixel: color::Rgba<u8>) { | |
match *self { | |
DynamicImage::ImageLuma8(ref mut p) => p.put_pixel(x, y, pixel.to_luma()), | |
DynamicImage::ImageLumaA8(ref mut p) => p.put_pixel(x, y, pixel.to_luma_alpha()), | |
DynamicImage::ImageRgb8(ref mut p) => p.put_pixel(x, y, pixel.to_rgb()), | |
DynamicImage::ImageRgba8(ref mut p) => p.put_pixel(x, y, pixel), | |
DynamicImage::ImageLuma16(ref mut p) => p.put_pixel(x, y, pixel.to_luma().into_color()), | |
DynamicImage::ImageLumaA16(ref mut p) => { | |
p.put_pixel(x, y, pixel.to_luma_alpha().into_color()) | |
} | |
DynamicImage::ImageRgb16(ref mut p) => p.put_pixel(x, y, pixel.to_rgb().into_color()), | |
DynamicImage::ImageRgba16(ref mut p) => p.put_pixel(x, y, pixel.into_color()), | |
DynamicImage::ImageRgb32F(ref mut p) => p.put_pixel(x, y, pixel.to_rgb().into_color()), | |
DynamicImage::ImageRgba32F(ref mut p) => p.put_pixel(x, y, pixel.into_color()), | |
} | |
} |
Does it make sense to move
put_pixel
to DynamicImage::put_pixel
and implement copy_from
and copy_within
in impl GenericImage for DynamicImage
in terms of DynamicImage::put_pixel
?
(Apologies for the length of this)
High-level Summary
Think about shortening the naming convention from
get_pixel
topixel
for accessing pixel data, add these functions to the related traits.I find
pixel_mut_i64
/pixel_mut_signed
preferable to the prospectivechecked_get_pixel_mut_i64
/checked_get_pixel_mut_signed
.Concern
#1851 adds functions for accessing pixel data using signed coordinates to
GenericImageView
. This is a common enough method for image processing algorithms that it might be sensible to offer more signed coordinate pixel access functions (e.g.,get_pixel_mut
), saving users from having to implement the boilerplate checks and type conversions repeatedly. Another benefit of offering these functions is more correctness in user code by providing a way to avoidas
casts and the errors they invite.Existing interfaces
Pre-
image 0.24
, #1500 addedImageBuffer::{get_pixel_checked, get_pixel_mut_checked}
as part ofImageBuffer
's impl instead of on theGenericImage
/GenericImageView
traits to avoid a breaking change in those traits (and their design is/was up in the air). The names were slightly messy to begin with sinceget_pixel
can panic and doesn't return an option like indexing getters tend to do.checked
doesn't really make sense as a prefix or suffix due to indexing-get
expectedly returning anOption
. Instd
, the only use ofchecked
seems to be as a prefix for checked math operations that can panic/overflow.get_pixel
feels redundant since it should probably be eitherget
orpixel
.unsafe_get_pixel
should beget_pixel_unchecked
,get_unchecked
, orpixel_unchecked
(#1340) depending on the chosen scheme.Discussion
Since #1851 is a breaking change, I think the naming should be reassessed for the current pixel access functions. I'm not sure what precedence exists other than the mixed integer operations, but I would expect a getter taking signed coordinates to indicate so in the function name (
get_signed
,get_i
, etc.). Coordinates could also beTryInto<u32>
, but I've only ever usedi64
personally for ease of implementation sinceu32
toi64
is lossless and you can avoid convertingi64
->u32
->usize
.I don't want to create unnecessary churn in the ecosystem, but if a breaking change is done I'd like to see these functions added to the traits if possible. I didn't feel a need to add the unsafe functions here just for a name change with no new functionality; there's
unsafe_put_pixel
today but nounsafe_get_pixel_mut
.Using this convention,
saturating_get_pixel
might better be called some combination ofnearest_available_pixel
orclosest_existing_pixel
(I thought there was a similarly named function in one of the decoder/encoder crates but I can't seem to find anything).Rust API Guidelines
The Rust API Guidelines offer recommendations on getter names:
(C-GETTER)
The text was updated successfully, but these errors were encountered: