diff --git a/README.md b/README.md index b06c45933e..2dfdec5152 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ All image processing functions provided operate on types that implement the `Gen | AVIF | Only 8-bit | Lossy | | PNM | PBM, PGM, PPM, standard PAM | Yes | | DDS | DXT1, DXT3, DXT5 | No | -| TGA | Yes | RGB(8), RGBA(8), BGR(8), BGRA(8), Gray(8), GrayA(8) | +| TGA | Yes | RGB(8), RGBA(8), Gray(8), GrayA(8) | | farbfeld | Yes | Yes | ### The [`ImageDecoder`](https://docs.rs/image/*/image/trait.ImageDecoder.html) and [`ImageDecoderExt`](https://docs.rs/image/*/image/trait.ImageDecoderExt.html) Traits diff --git a/src/buffer.rs b/src/buffer.rs index 353f399bc9..93c052d6c8 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -6,7 +6,7 @@ use std::ops::{Deref, DerefMut, Index, IndexMut, Range}; use std::path::Path; use std::slice::{ChunksExact, ChunksExactMut}; -use crate::color::{FromColor, Luma, LumaA, Rgb, Rgba, Bgr, Bgra}; +use crate::color::{FromColor, Luma, LumaA, Rgb, Rgba}; use crate::flat::{FlatSamples, SampleLayout}; use crate::dynimage::{save_buffer, save_buffer_with_format}; use crate::error::ImageResult; @@ -1296,10 +1296,6 @@ pub type RgbaImage = ImageBuffer, Vec>; pub type GrayImage = ImageBuffer, Vec>; /// Sendable grayscale + alpha channel image buffer pub type GrayAlphaImage = ImageBuffer, Vec>; -/// Sendable Bgr image buffer -pub(crate) type BgrImage = ImageBuffer, Vec>; -/// Sendable Bgr + alpha channel image buffer -pub(crate) type BgraImage = ImageBuffer, Vec>; /// Sendable 16-bit Rgb image buffer pub(crate) type Rgb16Image = ImageBuffer, Vec>; /// Sendable 16-bit Rgb + alpha channel image buffer diff --git a/src/codecs/avif/decoder.rs b/src/codecs/avif/decoder.rs index 72941474ce..85e93b07dc 100644 --- a/src/codecs/avif/decoder.rs +++ b/src/codecs/avif/decoder.rs @@ -80,7 +80,7 @@ impl<'a, R: 'a + Read> ImageDecoder<'a> for AvifDecoder { } fn color_type(&self) -> ColorType { - ColorType::Bgra8 + ColorType::Rgba8 } fn into_reader(self) -> ImageResult { @@ -158,6 +158,11 @@ impl<'a, R: 'a + Read> ImageDecoder<'a> for AvifDecoder { } } + // Convert Bgra to Rgba + for chunk in buf.chunks_exact_mut(4) { + chunk.swap(0, 2); + } + Ok(()) } } diff --git a/src/codecs/avif/encoder.rs b/src/codecs/avif/encoder.rs index 75d0a5fb18..fad7fb60d2 100644 --- a/src/codecs/avif/encoder.rs +++ b/src/codecs/avif/encoder.rs @@ -10,7 +10,7 @@ use std::cmp::min; use crate::{ColorType, ImageBuffer, ImageFormat, Pixel}; use crate::{ImageError, ImageResult}; use crate::buffer::ConvertBuffer; -use crate::color::{FromColor, Luma, LumaA, Bgr, Bgra, Rgb, Rgba}; +use crate::color::{FromColor, Luma, LumaA, Rgb, Rgba}; use crate::error::{EncodingError, ParameterError, ParameterErrorKind, UnsupportedError, UnsupportedErrorKind}; use bytemuck::{Pod, PodCastError, try_cast_slice, try_cast_slice_mut}; @@ -190,14 +190,6 @@ impl AvifEncoder { let image = try_from_raw::>(data, width, height)?; Ok(convert_into(&mut self.fallback, image)) } - ColorType::Bgr8 => { - let image = try_from_raw::>(data, width, height)?; - Ok(convert_into(&mut self.fallback, image)) - } - ColorType::Bgra8 => { - let image = try_from_raw::>(data, width, height)?; - Ok(convert_into(&mut self.fallback, image)) - } // we need to really convert data.. ColorType::L16 => { let buffer = cast_buffer(data)?; diff --git a/src/codecs/jpeg/encoder.rs b/src/codecs/jpeg/encoder.rs index 592e9a5f66..11325f978b 100644 --- a/src/codecs/jpeg/encoder.rs +++ b/src/codecs/jpeg/encoder.rs @@ -5,7 +5,7 @@ use std::io::{self, Write}; use num_iter::range_step; -use crate::{Bgr, Bgra, ColorType, GenericImageView, ImageBuffer, Luma, LumaA, Pixel, Rgb, Rgba}; +use crate::{ColorType, GenericImageView, ImageBuffer, Luma, LumaA, Pixel, Rgb, Rgba}; use crate::error::{ImageError, ImageResult, ParameterError, ParameterErrorKind, UnsupportedError, UnsupportedErrorKind}; use crate::image::{ImageEncoder, ImageFormat}; use crate::utils::clamp; @@ -449,14 +449,6 @@ impl<'a, W: Write> JpegEncoder<'a, W> { let image: ImageBuffer, _> = ImageBuffer::from_raw(width, height, image).unwrap(); self.encode_image(&image) }, - ColorType::Bgr8 => { - let image: ImageBuffer, _> = ImageBuffer::from_raw(width, height, image).unwrap(); - self.encode_image(&image) - }, - ColorType::Bgra8 => { - let image: ImageBuffer, _> = ImageBuffer::from_raw(width, height, image).unwrap(); - self.encode_image(&image) - }, _ => { Err(ImageError::Unsupported( UnsupportedError::from_format_and_kind( @@ -857,7 +849,7 @@ mod tests { #[cfg(feature = "benchmarks")] use test::{Bencher}; - use crate::{Bgra, ImageBuffer, ImageEncoder, ImageError}; + use crate::{ImageBuffer, ImageEncoder, ImageError}; use crate::color::ColorType; use crate::error::ParameterErrorKind::DimensionMismatch; use crate::image::ImageDecoder; @@ -976,22 +968,6 @@ mod tests { } } - #[test] - fn test_bgra16() { - // Test encoding an RGBA 16-bit image. - // Jpeg is RGB 8-bit, so the conversion should be done on the fly - let mut encoded = Vec::new(); - let max = std::u16::MAX; - let image: ImageBuffer, _> = ImageBuffer::from_raw( - 1, 1, vec![0, max / 2, max, max]).unwrap(); - let mut encoder = JpegEncoder::new_with_quality(&mut encoded, 100); - encoder.encode_image(&image).unwrap(); - let decoded = decode(&encoded); - assert!(decoded[0] > 200, "bad red channel in {:?}", &decoded); - assert!(100 < decoded[1] && decoded[1] < 150, "bad green channel in {:?}", &decoded); - assert!(decoded[2] < 50, "bad blue channel in {:?}", &decoded); - } - #[test] fn test_build_jfif_header() { let mut buf = vec![]; diff --git a/src/codecs/tga/encoder.rs b/src/codecs/tga/encoder.rs index 37ee81068b..981881ecdd 100644 --- a/src/codecs/tga/encoder.rs +++ b/src/codecs/tga/encoder.rs @@ -188,22 +188,6 @@ mod tests { assert_eq!(decoded.as_slice(), image); } - #[test] - fn round_trip_single_pixel_bgr() { - let image = [0, 1, 2]; - let decoded = round_trip_image(&image, 1, 1, ColorType::Bgr8); - assert_eq!(decoded.len(), image.len()); - assert_eq!(decoded.as_slice(), [2, 1, 0]); - } - - #[test] - fn round_trip_single_pixel_bgra() { - let image = [0, 1, 2, 3]; - let decoded = round_trip_image(&image, 1, 1, ColorType::Bgra8); - assert_eq!(decoded.len(), image.len()); - assert_eq!(decoded.as_slice(), [2, 1, 0, 3]); - } - #[test] fn round_trip_gray() { let image = [0, 1, 2]; diff --git a/src/codecs/tga/header.rs b/src/codecs/tga/header.rs index c74aa10850..7bf9fc6de2 100644 --- a/src/codecs/tga/header.rs +++ b/src/codecs/tga/header.rs @@ -95,8 +95,8 @@ impl Header { if width > 0 && height > 0 { let (num_alpha_bits, other_channel_bits, image_type) = match color_type { - ColorType::Rgba8 | ColorType::Bgra8 => (8, 24, ImageType::RawTrueColor), - ColorType::Rgb8 | ColorType::Bgr8 => (0, 24, ImageType::RawTrueColor), + ColorType::Rgba8 => (8, 24, ImageType::RawTrueColor), + ColorType::Rgb8 => (0, 24, ImageType::RawTrueColor), ColorType::La8 => (8, 8, ImageType::RawGrayScale), ColorType::L8 => (0, 8, ImageType::RawGrayScale), _ => { diff --git a/src/color.rs b/src/color.rs index 0166c082aa..057cdd7531 100644 --- a/src/color.rs +++ b/src/color.rs @@ -25,11 +25,6 @@ pub enum ColorType { /// Pixel is 16-bit RGBA Rgba16, - /// Pixel contains 8-bit B, G and R channels - Bgr8, - /// Pixel is 8-bit BGR with an alpha channel - Bgra8, - #[doc(hidden)] __NonExhaustive(crate::utils::NonExhaustiveMarker), } @@ -40,8 +35,8 @@ impl ColorType { match self { ColorType::L8 => 1, ColorType::L16 | ColorType::La8 => 2, - ColorType::Rgb8 | ColorType::Bgr8 => 3, - ColorType::Rgba8 | ColorType::Bgra8 | ColorType::La16 => 4, + ColorType::Rgb8 => 3, + ColorType::Rgba8 | ColorType::La16 => 4, ColorType::Rgb16 => 6, ColorType::Rgba16 => 8, ColorType::__NonExhaustive(marker) => match marker._private {}, @@ -52,8 +47,8 @@ impl ColorType { pub fn has_alpha(self) -> bool { use ColorType::*; match self { - L8 | L16 | Rgb8 | Bgr8 | Rgb16 => false, - La8 | Rgba8 | Bgra8 | La16 | Rgba16 => true, + L8 | L16 | Rgb8 | Rgb16 => false, + La8 | Rgba8 | La16 | Rgba16 => true, __NonExhaustive(marker) => match marker._private {}, } } @@ -63,7 +58,7 @@ impl ColorType { use ColorType::*; match self { L8 | L16 | La8 | La16 => false, - Rgb8 | Bgr8 | Rgb16 | Rgba8 | Bgra8 | Rgba16 => true, + Rgb8 | Rgb16 | Rgba8 | Rgba16 => true, __NonExhaustive(marker) => match marker._private {}, } } @@ -193,8 +188,6 @@ impl From for ExtendedColorType { ColorType::La16 => ExtendedColorType::La16, ColorType::Rgb16 => ExtendedColorType::Rgb16, ColorType::Rgba16 => ExtendedColorType::Rgba16, - ColorType::Bgr8 => ExtendedColorType::Bgr8, - ColorType::Bgra8 => ExtendedColorType::Bgra8, ColorType::__NonExhaustive(marker) => match marker._private {}, } } @@ -265,24 +258,12 @@ impl Pixel for $ident { pix } - fn to_bgr(&self) -> Bgr { - let mut pix = Bgr([Zero::zero(), Zero::zero(), Zero::zero()]); - pix.from_color(self); - pix - } - fn to_rgba(&self) -> Rgba { let mut pix = Rgba([Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero()]); pix.from_color(self); pix } - fn to_bgra(&self) -> Bgra { - let mut pix = Bgra([Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero()]); - pix.from_color(self); - pix - } - fn to_luma(&self) -> Luma { let mut pix = Luma([Zero::zero()]); pix.from_color(self); @@ -374,10 +355,8 @@ impl From<[T; $channels]> for $ident { define_colors! { Rgb, 3, 0, "RGB", ColorType::Rgb8, ColorType::Rgb16, #[doc = "RGB colors"]; - Bgr, 3, 0, "BGR", ColorType::Bgr8, ColorType::Bgr8, #[doc = "BGR colors"]; Luma, 1, 0, "Y", ColorType::L8, ColorType::L16, #[doc = "Grayscale colors"]; Rgba, 4, 1, "RGBA", ColorType::Rgba8, ColorType::Rgba16, #[doc = "RGB colors + alpha channel"]; - Bgra, 4, 1, "BGRA", ColorType::Bgra8, ColorType::Bgra8, #[doc = "BGR colors + alpha channel"]; LumaA, 2, 1, "YA", ColorType::La8, ColorType::La16, #[doc = "Grayscale colors + alpha channel"]; } @@ -425,14 +404,6 @@ fn rgb_to_luma(rgb: &[T]) -> T { NumCast::from(l).unwrap() } -#[inline] -fn bgr_to_luma(bgr: &[T]) -> T { - let l = SRGB_LUMA[0] * bgr[2].to_f32().unwrap() - + SRGB_LUMA[1] * bgr[1].to_f32().unwrap() - + SRGB_LUMA[2] * bgr[0].to_f32().unwrap(); - NumCast::from(l).unwrap() -} - #[inline] fn downcast_channel(c16: u16) -> u8 { NumCast::from(c16.to_u64().unwrap() >> 8).unwrap() @@ -454,14 +425,6 @@ impl FromColor> for Luma { } } -impl FromColor> for Luma { - fn from_color(&mut self, other: &Bgra) { - let gray = self.channels_mut(); - let bgra = other.channels(); - gray[0] = bgr_to_luma(bgra); - } -} - impl FromColor> for Luma { fn from_color(&mut self, other: &Rgb) { let gray = self.channels_mut(); @@ -470,14 +433,6 @@ impl FromColor> for Luma { } } -impl FromColor> for Luma { - fn from_color(&mut self, other: &Bgr) { - let gray = self.channels_mut(); - let bgr = other.channels(); - gray[0] = bgr_to_luma(bgr); - } -} - impl FromColor> for Luma { fn from_color(&mut self, other: &LumaA) { self.channels_mut()[0] = other.channels()[0] @@ -548,23 +503,6 @@ impl FromColor> for Luma { } } -impl FromColor> for Luma { - fn from_color(&mut self, other: &Bgr) { - let bgr = other.channels(); - let gray = self.channels_mut(); - gray[0] = upcast_channel(bgr_to_luma(bgr)); - } -} - -impl FromColor> for Luma { - fn from_color(&mut self, other: &Bgra) { - let bgra = other.channels(); - let gray = self.channels_mut(); - gray[0] = upcast_channel(bgr_to_luma(bgra)); - } -} - - // `FromColor` for LumaA impl FromColor> for LumaA { @@ -576,15 +514,6 @@ impl FromColor> for LumaA { } } -impl FromColor> for LumaA { - fn from_color(&mut self, other: &Bgra) { - let gray_a = self.channels_mut(); - let bgra = other.channels(); - gray_a[0] = bgr_to_luma(bgra); - gray_a[1] = bgra[3]; - } -} - impl FromColor> for LumaA { fn from_color(&mut self, other: &Rgb) { let gray_a = self.channels_mut(); @@ -594,15 +523,6 @@ impl FromColor> for LumaA { } } -impl FromColor> for LumaA { - fn from_color(&mut self, other: &Bgr) { - let gray_a = self.channels_mut(); - let bgr = other.channels(); - gray_a[0] = bgr_to_luma(bgr); - gray_a[1] = T::max_value(); - } -} - impl FromColor> for LumaA { fn from_color(&mut self, other: &Luma) { let gray_a = self.channels_mut(); @@ -658,25 +578,6 @@ impl FromColor> for LumaA { } } -impl FromColor> for LumaA { - fn from_color(&mut self, other: &Bgr) { - let bgr = other.channels(); - let gray_a = self.channels_mut(); - gray_a[0] = upcast_channel(bgr_to_luma(bgr)); - gray_a[1] = u16::max_value(); - } -} - -impl FromColor> for LumaA { - fn from_color(&mut self, other: &Bgra) { - let bgra = other.channels(); - let gray_a = self.channels_mut(); - gray_a[0] = upcast_channel(bgr_to_luma(bgra)); - gray_a[1] = upcast_channel(bgra[3]); - } -} - - // `FromColor` for RGBA impl FromColor> for Rgba { @@ -690,27 +591,6 @@ impl FromColor> for Rgba { } } -impl FromColor> for Rgba { - fn from_color(&mut self, other: &Bgr) { - let rgba = self.channels_mut(); - let bgr = other.channels(); - rgba[0] = bgr[2]; - rgba[1] = bgr[1]; - rgba[2] = bgr[0]; - rgba[3] = T::max_value(); - } -} - -impl FromColor> for Rgba { - fn from_color(&mut self, other: &Bgra) { - let rgba = self.channels_mut(); - let bgra = other.channels(); - rgba[0] = bgra[2]; - rgba[1] = bgra[1]; - rgba[2] = bgra[0]; - rgba[3] = bgra[3]; - } -} impl FromColor> for Rgba { fn from_color(&mut self, other: &LumaA) { @@ -792,85 +672,6 @@ impl FromColor> for Rgba { } } -impl FromColor> for Rgba { - fn from_color(&mut self, other: &Bgr) { - let bgr = other.channels(); - let rgba = self.channels_mut(); - rgba[0] = upcast_channel(bgr[2]); - rgba[1] = upcast_channel(bgr[1]); - rgba[2] = upcast_channel(bgr[0]); - rgba[3] = u16::max_value(); - } -} - -impl FromColor> for Rgba { - fn from_color(&mut self, other: &Bgra) { - let bgra = other.channels(); - let rgba = self.channels_mut(); - rgba[0] = upcast_channel(bgra[2]); - rgba[1] = upcast_channel(bgra[1]); - rgba[2] = upcast_channel(bgra[0]); - rgba[3] = upcast_channel(bgra[3]); - } -} - -// `FromColor` for BGRA - -impl FromColor> for Bgra { - fn from_color(&mut self, other: &Rgb) { - let bgra = self.channels_mut(); - let rgb = other.channels(); - bgra[0] = rgb[2]; - bgra[1] = rgb[1]; - bgra[2] = rgb[0]; - bgra[3] = T::max_value(); - } -} - -impl FromColor> for Bgra { - fn from_color(&mut self, other: &Bgr) { - let bgra = self.channels_mut(); - let bgr = other.channels(); - bgra[0] = bgr[0]; - bgra[1] = bgr[1]; - bgra[2] = bgr[2]; - bgra[3] = T::max_value(); - } -} - -impl FromColor> for Bgra { - fn from_color(&mut self, other: &Rgba) { - let bgra = self.channels_mut(); - let rgba = other.channels(); - bgra[2] = rgba[0]; - bgra[1] = rgba[1]; - bgra[0] = rgba[2]; - bgra[3] = rgba[3]; - } -} - -impl FromColor> for Bgra { - fn from_color(&mut self, other: &LumaA) { - let bgra = self.channels_mut(); - let gray = other.channels(); - bgra[0] = gray[0]; - bgra[1] = gray[0]; - bgra[2] = gray[0]; - bgra[3] = gray[1]; - } -} - -impl FromColor> for Bgra { - fn from_color(&mut self, gray: &Luma) { - let bgra = self.channels_mut(); - let gray = gray.channels()[0]; - bgra[0] = gray; - bgra[1] = gray; - bgra[2] = gray; - bgra[3] = T::max_value(); - } -} - // `FromColor` for RGB @@ -884,26 +685,6 @@ impl FromColor> for Rgb { } } -impl FromColor> for Rgb { - fn from_color(&mut self, other: &Bgra) { - let rgb = self.channels_mut(); - let bgra = other.channels(); - rgb[0] = bgra[2]; - rgb[1] = bgra[1]; - rgb[2] = bgra[0]; - } -} - -impl FromColor> for Rgb { - fn from_color(&mut self, other: &Bgr) { - let rgb = self.channels_mut(); - let bgr = other.channels(); - rgb[0] = bgr[2]; - rgb[1] = bgr[1]; - rgb[2] = bgr[0]; - } -} - impl FromColor> for Rgb { fn from_color(&mut self, other: &LumaA) { let rgb = self.channels_mut(); @@ -972,80 +753,6 @@ impl FromColor> for Rgb { } } -impl FromColor> for Rgb { - fn from_color(&mut self, other: &Bgr) { - let bgr = other.channels(); - let rgb = self.channels_mut(); - rgb[0] = upcast_channel(bgr[2]); - rgb[1] = upcast_channel(bgr[1]); - rgb[2] = upcast_channel(bgr[0]); - } -} - -impl FromColor> for Rgb { - fn from_color(&mut self, other: &Bgra) { - let bgra = other.channels(); - let rgb = self.channels_mut(); - rgb[0] = upcast_channel(bgra[2]); - rgb[1] = upcast_channel(bgra[1]); - rgb[2] = upcast_channel(bgra[0]); - } -} - - -/// `FromColor` for BGR - -impl FromColor> for Bgr { - fn from_color(&mut self, other: &Rgba) { - let bgr = self.channels_mut(); - let rgba = other.channels(); - bgr[0] = rgba[2]; - bgr[1] = rgba[1]; - bgr[2] = rgba[0]; - } -} - -impl FromColor> for Bgr { - fn from_color(&mut self, other: &Rgb) { - let bgr = self.channels_mut(); - let rgb = other.channels(); - bgr[0] = rgb[2]; - bgr[1] = rgb[1]; - bgr[2] = rgb[0]; - } -} - - -impl FromColor> for Bgr { - fn from_color(&mut self, other: &Bgra) { - let bgr = self.channels_mut(); - let bgra = other.channels(); - bgr[0] = bgra[0]; - bgr[1] = bgra[1]; - bgr[2] = bgra[2]; - } -} - -impl FromColor> for Bgr { - fn from_color(&mut self, other: &LumaA) { - let bgr = self.channels_mut(); - let gray = other.channels()[0]; - bgr[0] = gray; - bgr[1] = gray; - bgr[2] = gray; - } -} - -impl FromColor> for Bgr { - fn from_color(&mut self, gray: &Luma) { - let bgr = self.channels_mut(); - let gray = gray.channels()[0]; - bgr[0] = gray; - bgr[1] = gray; - bgr[2] = gray; - } -} - macro_rules! downcast_bit_depth_early { ($src:ident, $intermediate:ident, $dst:ident) => { impl FromColor<$src> for $dst { @@ -1072,17 +779,6 @@ downcast_bit_depth_early!(Rgba, Rgba, Rgb); downcast_bit_depth_early!(Luma, Luma, Rgba); downcast_bit_depth_early!(LumaA, LumaA, Rgba); downcast_bit_depth_early!(Rgb, Rgb, Rgba); -// Bgr -downcast_bit_depth_early!(Luma, Luma, Bgr); -downcast_bit_depth_early!(LumaA, LumaA, Bgr); -downcast_bit_depth_early!(Rgb, Rgb, Bgr); -downcast_bit_depth_early!(Rgba, Rgba, Bgr); -// Bgra -downcast_bit_depth_early!(Luma, Luma, Bgra); -downcast_bit_depth_early!(LumaA, LumaA, Bgra); -downcast_bit_depth_early!(Rgb, Rgb, Bgra); -downcast_bit_depth_early!(Rgba, Rgba, Bgra); - /// Blends a color inter another one pub(crate) trait Blend { @@ -1185,76 +881,12 @@ impl Blend for Rgba { } } - - -impl Blend for Bgra { - fn blend(&mut self, other: &Bgra) { - // http://stackoverflow.com/questions/7438263/alpha-compositing-algorithm-blend-modes#answer-11163848 - - // First, as we don't know what type our pixel is, we have to convert to floats between 0.0 and 1.0 - let max_t = T::max_value(); - let max_t = max_t.to_f32().unwrap(); - let (bg_r, bg_g, bg_b, bg_a) = (self.0[2], self.0[1], self.0[0], self.0[3]); - let (fg_r, fg_g, fg_b, fg_a) = (other.0[2], other.0[1], other.0[0], other.0[3]); - let (bg_r, bg_g, bg_b, bg_a) = ( - bg_r.to_f32().unwrap() / max_t, - bg_g.to_f32().unwrap() / max_t, - bg_b.to_f32().unwrap() / max_t, - bg_a.to_f32().unwrap() / max_t, - ); - let (fg_r, fg_g, fg_b, fg_a) = ( - fg_r.to_f32().unwrap() / max_t, - fg_g.to_f32().unwrap() / max_t, - fg_b.to_f32().unwrap() / max_t, - fg_a.to_f32().unwrap() / max_t, - ); - - // Work out what the final alpha level will be - let alpha_final = bg_a + fg_a - bg_a * fg_a; - if alpha_final == 0.0 { - return; - }; - - // We premultiply our channels by their alpha, as this makes it easier to calculate - let (bg_r_a, bg_g_a, bg_b_a) = (bg_r * bg_a, bg_g * bg_a, bg_b * bg_a); - let (fg_r_a, fg_g_a, fg_b_a) = (fg_r * fg_a, fg_g * fg_a, fg_b * fg_a); - - // Standard formula for src-over alpha compositing - let (out_r_a, out_g_a, out_b_a) = ( - fg_r_a + bg_r_a * (1.0 - fg_a), - fg_g_a + bg_g_a * (1.0 - fg_a), - fg_b_a + bg_b_a * (1.0 - fg_a), - ); - - // Unmultiply the channels by our resultant alpha channel - let (out_r, out_g, out_b) = ( - out_r_a / alpha_final, - out_g_a / alpha_final, - out_b_a / alpha_final, - ); - - // Cast back to our initial type on return - *self = Bgra([ - NumCast::from(max_t * out_b).unwrap(), - NumCast::from(max_t * out_g).unwrap(), - NumCast::from(max_t * out_r).unwrap(), - NumCast::from(max_t * alpha_final).unwrap(), - ]) - } -} - impl Blend for Rgb { fn blend(&mut self, other: &Rgb) { *self = *other } } -impl Blend for Bgr { - fn blend(&mut self, other: &Bgr) { - *self = *other - } -} - /// Invert a color pub(crate) trait Invert { @@ -1293,17 +925,6 @@ impl Invert for Rgba { } -impl Invert for Bgra { - fn invert(&mut self) { - let bgra = self.0; - - let max = T::max_value(); - - *self = Bgra([max - bgra[2], max - bgra[1], max - bgra[0], bgra[3]]) - } -} - - impl Invert for Rgb { fn invert(&mut self) { let rgb = self.0; @@ -1318,23 +939,9 @@ impl Invert for Rgb { } } -impl Invert for Bgr { - fn invert(&mut self) { - let bgr = self.0; - - let max = T::max_value(); - - let r1 = max - bgr[2]; - let g1 = max - bgr[1]; - let b1 = max - bgr[0]; - - *self = Bgr([b1, g1, r1]) - } -} - #[cfg(test)] mod tests { - use super::{Bgr, Bgra, Luma, LumaA, Pixel, Rgb, Rgba}; + use super::{Luma, LumaA, Pixel, Rgb, Rgba}; #[test] fn test_apply_with_alpha_rgba() { @@ -1343,13 +950,6 @@ mod tests { assert_eq!(rgba, Rgba([0, 0, 0, 0xFF])); } - #[test] - fn test_apply_with_alpha_bgra() { - let mut bgra = Bgra([0, 0, 0, 0]); - bgra.apply_with_alpha(|s| s, |_| 0xFF); - assert_eq!(bgra, Bgra([0, 0, 0, 0xFF])); - } - #[test] fn test_apply_with_alpha_rgb() { let mut rgb = Rgb([0, 0, 0]); @@ -1357,14 +957,6 @@ mod tests { assert_eq!(rgb, Rgb([0, 0, 0])); } - #[test] - fn test_apply_with_alpha_bgr() { - let mut bgr = Bgr([0, 0, 0]); - bgr.apply_with_alpha(|s| s, |_| panic!("bug")); - assert_eq!(bgr, Bgr([0, 0, 0])); - } - - #[test] fn test_map_with_alpha_rgba() { let rgba = Rgba([0, 0, 0, 0]).map_with_alpha(|s| s, |_| 0xFF); @@ -1377,19 +969,6 @@ mod tests { assert_eq!(rgb, Rgb([0, 0, 0])); } - #[test] - fn test_map_with_alpha_bgr() { - let bgr = Bgr([0, 0, 0]).map_with_alpha(|s| s, |_| panic!("bug")); - assert_eq!(bgr, Bgr([0, 0, 0])); - } - - - #[test] - fn test_map_with_alpha_bgra() { - let bgra = Bgra([0, 0, 0, 0]).map_with_alpha(|s| s, |_| 0xFF); - assert_eq!(bgra, Bgra([0, 0, 0, 0xFF])); - } - #[test] fn test_blend_luma_alpha() { let ref mut a = LumaA([255 as u8, 255]); @@ -1447,13 +1026,6 @@ mod tests { assert_eq!(rgba, Rgba([1, 1, 1, 0])); } - #[test] - fn test_apply_without_alpha_bgra() { - let mut bgra = Bgra([0, 0, 0, 0]); - bgra.apply_without_alpha(|s| s + 1); - assert_eq!(bgra, Bgra([1, 1, 1, 0])); - } - #[test] fn test_apply_without_alpha_rgb() { let mut rgb = Rgb([0, 0, 0]); @@ -1461,13 +1033,6 @@ mod tests { assert_eq!(rgb, Rgb([1, 1, 1])); } - #[test] - fn test_apply_without_alpha_bgr() { - let mut bgr = Bgr([0, 0, 0]); - bgr.apply_without_alpha(|s| s + 1); - assert_eq!(bgr, Bgr([1, 1, 1])); - } - #[test] fn test_map_without_alpha_rgba() { let rgba = Rgba([0, 0, 0, 0]).map_without_alpha(|s| s + 1); @@ -1480,18 +1045,6 @@ mod tests { assert_eq!(rgb, Rgb([1, 1, 1])); } - #[test] - fn test_map_without_alpha_bgr() { - let bgr = Bgr([0, 0, 0]).map_without_alpha(|s| s + 1); - assert_eq!(bgr, Bgr([1, 1, 1])); - } - - #[test] - fn test_map_without_alpha_bgra() { - let bgra = Bgra([0, 0, 0, 0]).map_without_alpha(|s| s + 1); - assert_eq!(bgra, Bgra([1, 1, 1, 0])); - } - macro_rules! test_lossless_conversion { ($a:ty, $b:ty, $c:ty) => { let a: $a = [<$a as Pixel>::Subpixel::max_value() >> 2; <$a as Pixel>::CHANNEL_COUNT as usize].into(); @@ -1505,8 +1058,6 @@ mod tests { fn test_lossless_conversions() { use super::IntoColor; - test_lossless_conversion!(Bgr, Rgba, Bgr); - test_lossless_conversion!(Bgra, Rgba, Bgra); test_lossless_conversion!(Luma, Luma, Luma); test_lossless_conversion!(LumaA, LumaA, LumaA); test_lossless_conversion!(Rgb, Rgb, Rgb); diff --git a/src/dynimage.rs b/src/dynimage.rs index 380b8f437a..b585b24f4e 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -23,7 +23,7 @@ use crate::codecs::tga; use crate::codecs::avif; use crate::buffer_::{ - BgrImage, BgraImage, ConvertBuffer, GrayAlphaImage, GrayAlpha16Image, + ConvertBuffer, GrayAlphaImage, GrayAlpha16Image, GrayImage, Gray16Image, ImageBuffer, RgbImage, Rgb16Image, RgbaImage, Rgba16Image, }; @@ -53,12 +53,6 @@ pub enum DynamicImage { /// Each pixel in this image is 8-bit Rgb with alpha ImageRgba8(RgbaImage), - /// Each pixel in this image is 8-bit Bgr - ImageBgr8(BgrImage), - - /// Each pixel in this image is 8-bit Bgr with alpha - ImageBgra8(BgraImage), - /// Each pixel in this image is 16-bit Luma ImageLuma16(Gray16Image), @@ -79,8 +73,6 @@ macro_rules! dynamic_map( DynamicImage::ImageLumaA8(ref $image) => DynamicImage::ImageLumaA8($action), DynamicImage::ImageRgb8(ref $image) => DynamicImage::ImageRgb8($action), DynamicImage::ImageRgba8(ref $image) => DynamicImage::ImageRgba8($action), - DynamicImage::ImageBgr8(ref $image) => DynamicImage::ImageBgr8($action), - DynamicImage::ImageBgra8(ref $image) => DynamicImage::ImageBgra8($action), DynamicImage::ImageLuma16(ref $image) => DynamicImage::ImageLuma16($action), DynamicImage::ImageLumaA16(ref $image) => DynamicImage::ImageLumaA16($action), DynamicImage::ImageRgb16(ref $image) => DynamicImage::ImageRgb16($action), @@ -94,8 +86,6 @@ macro_rules! dynamic_map( DynamicImage::ImageLumaA8(ref mut $image) => DynamicImage::ImageLumaA8($action), DynamicImage::ImageRgb8(ref mut $image) => DynamicImage::ImageRgb8($action), DynamicImage::ImageRgba8(ref mut $image) => DynamicImage::ImageRgba8($action), - DynamicImage::ImageBgr8(ref mut $image) => DynamicImage::ImageBgr8($action), - DynamicImage::ImageBgra8(ref mut $image) => DynamicImage::ImageBgra8($action), DynamicImage::ImageLuma16(ref mut $image) => DynamicImage::ImageLuma16($action), DynamicImage::ImageLumaA16(ref mut $image) => DynamicImage::ImageLumaA16($action), DynamicImage::ImageRgb16(ref mut $image) => DynamicImage::ImageRgb16($action), @@ -109,8 +99,6 @@ macro_rules! dynamic_map( DynamicImage::ImageLumaA8(ref $image) => $action, DynamicImage::ImageRgb8(ref $image) => $action, DynamicImage::ImageRgba8(ref $image) => $action, - DynamicImage::ImageBgr8(ref $image) => $action, - DynamicImage::ImageBgra8(ref $image) => $action, DynamicImage::ImageLuma16(ref $image) => $action, DynamicImage::ImageLumaA16(ref $image) => $action, DynamicImage::ImageRgb16(ref $image) => $action, @@ -124,8 +112,6 @@ macro_rules! dynamic_map( DynamicImage::ImageLumaA8(ref mut $image) => $action, DynamicImage::ImageRgb8(ref mut $image) => $action, DynamicImage::ImageRgba8(ref mut $image) => $action, - DynamicImage::ImageBgr8(ref mut $image) => $action, - DynamicImage::ImageBgra8(ref mut $image) => $action, DynamicImage::ImageLuma16(ref mut $image) => $action, DynamicImage::ImageLumaA16(ref mut $image) => $action, DynamicImage::ImageRgb16(ref mut $image) => $action, @@ -156,16 +142,6 @@ impl DynamicImage { DynamicImage::ImageRgba8(ImageBuffer::new(w, h)) } - /// Creates a dynamic image backed by a buffer of BGRA pixels. - pub fn new_bgra8(w: u32, h: u32) -> DynamicImage { - DynamicImage::ImageBgra8(ImageBuffer::new(w, h)) - } - - /// Creates a dynamic image backed by a buffer of BGR pixels. - pub fn new_bgr8(w: u32, h: u32) -> DynamicImage { - DynamicImage::ImageBgr8(ImageBuffer::new(w, h)) - } - /// Creates a dynamic image backed by a buffer of grey pixels. pub fn new_luma16(w: u32, h: u32) -> DynamicImage { DynamicImage::ImageLuma16(ImageBuffer::new(w, h)) @@ -238,36 +214,6 @@ impl DynamicImage { }) } - /// Returns a copy of this image as an BGR image. - #[deprecated = "replaced by `to_bgr8`"] - pub fn to_bgr(&self) -> BgrImage { - dynamic_map!(*self, ref p -> { - p.convert() - }) - } - - /// Returns a copy of this image as an BGR image. - pub fn to_bgr8(&self) -> BgrImage { - dynamic_map!(*self, ref p -> { - p.convert() - }) - } - - /// Returns a copy of this image as an BGRA image. - #[deprecated = "replaced by `to_bgra8`"] - pub fn to_bgra(&self) -> BgraImage { - dynamic_map!(*self, ref p -> { - p.convert() - }) - } - - /// Returns a copy of this image as an BGRA image. - pub fn to_bgra8(&self) -> BgraImage { - dynamic_map!(*self, ref p -> { - p.convert() - }) - } - /// Returns a copy of this image as a Luma image. #[deprecated = "replaced by `to_luma8`"] pub fn to_luma(&self) -> GrayImage { @@ -380,56 +326,6 @@ impl DynamicImage { } } - /// Consume the image and returns a BGR image. - /// - /// If the image was already the correct format, it is returned as is. - /// Otherwise, a copy is created. - #[deprecated = "replaced by `into_bgra8`"] - pub fn into_bgr(self) -> BgrImage { - match self { - DynamicImage::ImageBgr8(x) => x, - x => x.to_bgr8(), - } - } - - /// Consume the image and returns a BGR image. - /// - /// If the image was already the correct format, it is returned as is. - /// Otherwise, a copy is created. - pub fn into_bgr8(self) -> BgrImage { - match self { - DynamicImage::ImageBgr8(x) => x, - x => x.to_bgr8(), - } - } - - // NOTE: DynamicImage::ImageBgr16 variant does not currently exist, so there is no `into_bgr16` - - /// Consume the image and returns a BGRA image. - /// - /// If the image was already the correct format, it is returned as is. - /// Otherwise, a copy is created. - #[deprecated = "replaced by `into_bgra8`"] - pub fn into_bgra(self) -> BgraImage { - match self { - DynamicImage::ImageBgra8(x) => x, - x => x.to_bgra8(), - } - } - - /// Consume the image and returns a BGRA image. - /// - /// If the image was already the correct format, it is returned as is. - /// Otherwise, a copy is created. - pub fn into_bgra8(self) -> BgraImage { - match self { - DynamicImage::ImageBgra8(x) => x, - x => x.to_bgra8(), - } - } - - // NOTE: DynamicImage::ImageBgra16 variant does not currently exist, so there is no `into_bgra16` - /// Consume the image and returns a Luma image. /// /// If the image was already the correct format, it is returned as is. @@ -527,22 +423,6 @@ impl DynamicImage { } } - /// Return a reference to an 8bit BGR image - pub fn as_bgr8(&self) -> Option<&BgrImage> { - match *self { - DynamicImage::ImageBgr8(ref p) => Some(p), - _ => None, - } - } - - /// Return a mutable reference to an 8bit BGR image - pub fn as_mut_bgr8(&mut self) -> Option<&mut BgrImage> { - match *self { - DynamicImage::ImageBgr8(ref mut p) => Some(p), - _ => None, - } - } - /// Return a reference to an 8bit RGBA image pub fn as_rgba8(&self) -> Option<&RgbaImage> { match *self { @@ -559,22 +439,6 @@ impl DynamicImage { } } - /// Return a reference to an 8bit BGRA image - pub fn as_bgra8(&self) -> Option<&BgraImage> { - match *self { - DynamicImage::ImageBgra8(ref p) => Some(p), - _ => None, - } - } - - /// Return a mutable reference to an 8bit RGBA image - pub fn as_mut_bgra8(&mut self) -> Option<&mut BgraImage> { - match *self { - DynamicImage::ImageBgra8(ref mut p) => Some(p), - _ => None, - } - } - /// Return a reference to an 8bit Grayscale image pub fn as_luma8(&self) -> Option<&GrayImage> { match *self { @@ -678,8 +542,6 @@ impl DynamicImage { DynamicImage::ImageLumaA8(ref p) => Some(p.as_flat_samples()), DynamicImage::ImageRgb8(ref p) => Some(p.as_flat_samples()), DynamicImage::ImageRgba8(ref p) => Some(p.as_flat_samples()), - DynamicImage::ImageBgr8(ref p) => Some(p.as_flat_samples()), - DynamicImage::ImageBgra8(ref p) => Some(p.as_flat_samples()), _ => None, } } @@ -719,8 +581,6 @@ impl DynamicImage { DynamicImage::ImageLumaA8(_) => color::ColorType::La8, DynamicImage::ImageRgb8(_) => color::ColorType::Rgb8, DynamicImage::ImageRgba8(_) => color::ColorType::Rgba8, - DynamicImage::ImageBgra8(_) => color::ColorType::Bgra8, - DynamicImage::ImageBgr8(_) => color::ColorType::Bgr8, DynamicImage::ImageLuma16(_) => color::ColorType::L16, DynamicImage::ImageLumaA16(_) => color::ColorType::La16, DynamicImage::ImageRgb16(_) => color::ColorType::Rgb16, @@ -735,8 +595,6 @@ impl DynamicImage { DynamicImage::ImageLumaA8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)), DynamicImage::ImageRgb8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)), DynamicImage::ImageRgba8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)), - DynamicImage::ImageBgr8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)), - DynamicImage::ImageBgra8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)), DynamicImage::ImageLuma16(ref p) => DynamicImage::ImageLuma16(p.clone()), DynamicImage::ImageLumaA16(ref p) => DynamicImage::ImageLuma16(imageops::grayscale(p)), DynamicImage::ImageRgb16(ref p) => DynamicImage::ImageLuma16(imageops::grayscale(p)), @@ -920,20 +778,6 @@ impl DynamicImage { #[cfg(feature = "png")] image::ImageOutputFormat::Png => { let p = png::PngEncoder::new(w); - let converted; - match *self { - DynamicImage::ImageBgra8(_) => { - converted = self.to_rgba().into_raw(); - bytes = &converted; - color = color::ColorType::Rgba8; - } - DynamicImage::ImageBgr8(_) => { - converted = self.to_rgb().into_raw(); - bytes = &converted; - color = color::ColorType::Rgb8; - } - _ => {} - } p.encode(&bytes, width, height, color)?; Ok(()) } @@ -941,20 +785,6 @@ impl DynamicImage { #[cfg(feature = "pnm")] image::ImageOutputFormat::Pnm(subtype) => { let mut p = pnm::PnmEncoder::new(w).with_subtype(subtype); - let converted; - match *self { - DynamicImage::ImageBgra8(_) => { - converted = self.to_rgba().into_raw(); - bytes = &converted; - color = color::ColorType::Rgba8; - } - DynamicImage::ImageBgr8(_) => { - converted = self.to_rgb().into_raw(); - bytes = &converted; - color = color::ColorType::Rgb8; - } - _ => {} - } p.encode(bytes, width, height, color)?; Ok(()) } @@ -1071,8 +901,6 @@ impl GenericImage for DynamicImage { 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::ImageBgr8(ref mut p) => p.put_pixel(x, y, pixel.to_bgr()), - DynamicImage::ImageBgra8(ref mut p) => p.put_pixel(x, y, pixel.to_bgra()), 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()), @@ -1086,8 +914,6 @@ impl GenericImage for DynamicImage { DynamicImage::ImageLumaA8(ref mut p) => p.blend_pixel(x, y, pixel.to_luma_alpha()), DynamicImage::ImageRgb8(ref mut p) => p.blend_pixel(x, y, pixel.to_rgb()), DynamicImage::ImageRgba8(ref mut p) => p.blend_pixel(x, y, pixel), - DynamicImage::ImageBgr8(ref mut p) => p.blend_pixel(x, y, pixel.to_bgr()), - DynamicImage::ImageBgra8(ref mut p) => p.blend_pixel(x, y, pixel.to_bgra()), DynamicImage::ImageLuma16(ref mut p) => p.blend_pixel(x, y, pixel.to_luma().into_color()), DynamicImage::ImageLumaA16(ref mut p) => p.blend_pixel(x, y, pixel.to_luma_alpha().into_color()), DynamicImage::ImageRgb16(ref mut p) => p.blend_pixel(x, y, pixel.to_rgb().into_color()), @@ -1121,16 +947,6 @@ fn decoder_to_image<'a, I: ImageDecoder<'a>>(decoder: I) -> ImageResult { - let buf = image::decoder_to_vec(decoder)?; - ImageBuffer::from_raw(w, h, buf).map(DynamicImage::ImageBgr8) - } - - color::ColorType::Bgra8 => { - let buf = image::decoder_to_vec(decoder)?; - ImageBuffer::from_raw(w, h, buf).map(DynamicImage::ImageBgra8) - } - color::ColorType::L8 => { let buf = image::decoder_to_vec(decoder)?; ImageBuffer::from_raw(w, h, buf).map(DynamicImage::ImageLuma8) @@ -1181,8 +997,6 @@ fn image_to_bytes(image: &DynamicImage) -> Vec { DynamicImage::ImageLumaA8(ref a) => a.as_raw().clone(), DynamicImage::ImageRgb8(ref a) => a.as_raw().clone(), DynamicImage::ImageRgba8(ref a) => a.as_raw().clone(), - DynamicImage::ImageBgr8(ref a) => a.as_raw().clone(), - DynamicImage::ImageBgra8(ref a) => a.as_raw().clone(), DynamicImage::ImageLuma16(ref a) => a.as_bytes().to_vec(), DynamicImage::ImageLumaA16(ref a) => a.as_bytes().to_vec(), DynamicImage::ImageRgb16(ref a) => a.as_bytes().to_vec(), @@ -1196,8 +1010,6 @@ fn image_into_bytes(image: DynamicImage) -> Vec { DynamicImage::ImageLumaA8(a) => a.into_raw(), DynamicImage::ImageRgb8(a) => a.into_raw(), DynamicImage::ImageRgba8(a) => a.into_raw(), - DynamicImage::ImageBgr8(a) => a.into_raw(), - DynamicImage::ImageBgra8(a) => a.into_raw(), DynamicImage::ImageLuma16(_) => image.to_bytes(), DynamicImage::ImageLumaA16(_) => image.to_bytes(), DynamicImage::ImageRgb16(_) => image.to_bytes(), @@ -1212,8 +1024,6 @@ fn image_as_bytes(image: &DynamicImage) -> &[u8] { DynamicImage::ImageLumaA8(a) => &*a, DynamicImage::ImageRgb8(a) => &*a, DynamicImage::ImageRgba8(a) => &*a, - DynamicImage::ImageBgr8(a) => &*a, - DynamicImage::ImageBgra8(a) => &*a, DynamicImage::ImageLuma16(a) => cast_slice(&*a), DynamicImage::ImageLumaA16(a) => cast_slice(&*a), DynamicImage::ImageRgb16(a) => cast_slice(&*a), diff --git a/src/lib.rs b/src/lib.rs index 0ea2e1138e..aa395c6f6a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,7 +104,7 @@ use std::io::Write; pub use crate::color::{ColorType, ExtendedColorType}; -pub use crate::color::{Luma, LumaA, Rgb, Rgba, Bgr, Bgra}; +pub use crate::color::{Luma, LumaA, Rgb, Rgba}; pub use crate::error::{ImageError, ImageResult}; diff --git a/src/traits.rs b/src/traits.rs index e095cbb0cd..e7572bd266 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -5,7 +5,7 @@ use num_traits::{Bounded, Num, NumCast}; use std::ops::{AddAssign}; -use crate::color::{ColorType, Luma, LumaA, Rgb, Rgba, Bgr, Bgra}; +use crate::color::{ColorType, Luma, LumaA, Rgb, Rgba}; /// Types which are safe to treat as an immutable byte slice in a pixel layout /// for image encoding. @@ -186,12 +186,6 @@ pub trait Pixel: Copy + Clone { /// Convert this pixel to luma with an alpha channel fn to_luma_alpha(&self) -> LumaA; - /// Convert this pixel to BGR - fn to_bgr(&self) -> Bgr; - - /// Convert this pixel to BGR with an alpha channel - fn to_bgra(&self) -> Bgra; - /// Apply the function ```f``` to each channel of this pixel. fn map(&self, f: F) -> Self where