kornelski / rust-rgb

struct RGB for sharing pixels between crates
https://lib.rs/rgb
MIT License
97 stars 19 forks source link

Add Homogeneous/Heterogeneous trait derived from the `pixeli` crate #86

Closed ripytide closed 2 months ago

ripytide commented 2 months ago

I've ported and generalized the trait from pixeli to make them work with this crate.

This is quite type-heavy and macro-heavy code. But that seems to me like the only way to achieve supporting these kinds of operations (like map_components()) in a trait rather than an inherent method which should enable generic image processing functions to be written on top of these traits, like filter() all with compile-time known sizing which should prevent any allocations.

I've also managed to directly embed the relationship between the two traits HomogeneousPixel vs HeterogeneousPixel by making the second a super-trait of the first using associated type bounds:

pub trait HomogeneousPixel:
    HeterogeneousPixel<ColorComponent = Self::Component, AlphaComponent = Self::Component>

Let me know what you think.

kornelski commented 2 months ago

I think it's safe to assume that every type with alpha will have a non-alpha type too? In such case the type without alpha can be associated type, and fn without_alpha(&self) -> Self::WithoutAlpha<C>

ripytide commented 2 months ago

I'd say that's a fair assumption.

Currently the two traits for that are GainAlpha and LoseAlpha both with associated types.

The one potential issue for the GainAlpha trait is that there may be multiple potential types. For example Rgb -> Rgba or Argb. Currently I just use the variants with alpha at the end but that decision is a bit arbitrary.

kornelski commented 2 months ago

I've squashed the commits a bit.

ripytide commented 2 months ago

Thanks! I've got a few tweaks I'd like to make based on some of our discussion points, I'll make a follow up PR when I get some time.

kornelski commented 2 months ago

Something like .with_alpha(self, a) -> T where T: From<RGBA> could support other layouts, but I'm afraid that would cause type inference annoyances, so it's better to just pick alpha last.