Skip to content

Commit 88c2572

Browse files
authored
Merge pull request #2444 from Its-Just-Nans/add-color-type-conversion
add color type conversion
2 parents db6cdfe + 1bec8e1 commit 88c2572

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

src/color.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use std::ops::{Index, IndexMut};
22

33
use num_traits::{NumCast, ToPrimitive, Zero};
44

5-
use crate::traits::{Enlargeable, Pixel, Primitive};
5+
use crate::{
6+
error::TryFromExtendedColorError,
7+
traits::{Enlargeable, Pixel, Primitive},
8+
};
69

710
/// An enumeration over supported color types and bit depths
811
#[derive(Copy, PartialEq, Eq, Debug, Clone, Hash)]
@@ -230,13 +233,53 @@ impl ExtendedColorType {
230233
}
231234
}
232235

236+
/// Returns the ColorType that is equivalent to this ExtendedColorType.
237+
///
238+
/// # Example
239+
///
240+
/// ```
241+
/// use image::{ColorType, ExtendedColorType};
242+
///
243+
/// assert_eq!(Some(ColorType::L8), ExtendedColorType::L8.color_type());
244+
/// assert_eq!(None, ExtendedColorType::L1.color_type());
245+
/// ```
246+
///
247+
/// The method is equivalent to converting via the `TryFrom`/`TryInto` traits except for the
248+
/// error path. Choose the more ergonomic option in your usage.
249+
///
250+
/// ```
251+
/// use image::{ColorType, ExtendedColorType, ImageError};
252+
///
253+
/// fn handle_errors() -> Result<(), ImageError> {
254+
/// let color: ColorType = ExtendedColorType::L8.try_into()?;
255+
/// assert_eq!(color, ColorType::L8);
256+
/// # Ok(())
257+
/// }
258+
/// ```
259+
pub fn color_type(&self) -> Option<ColorType> {
260+
match *self {
261+
ExtendedColorType::L8 => Some(ColorType::L8),
262+
ExtendedColorType::La8 => Some(ColorType::La8),
263+
ExtendedColorType::Rgb8 => Some(ColorType::Rgb8),
264+
ExtendedColorType::Rgba8 => Some(ColorType::Rgba8),
265+
ExtendedColorType::L16 => Some(ColorType::L16),
266+
ExtendedColorType::La16 => Some(ColorType::La16),
267+
ExtendedColorType::Rgb16 => Some(ColorType::Rgb16),
268+
ExtendedColorType::Rgba16 => Some(ColorType::Rgba16),
269+
ExtendedColorType::Rgb32F => Some(ColorType::Rgb32F),
270+
ExtendedColorType::Rgba32F => Some(ColorType::Rgba32F),
271+
_ => None,
272+
}
273+
}
274+
233275
/// Returns the number of bytes required to hold a width x height image of this color type.
234276
pub(crate) fn buffer_size(self, width: u32, height: u32) -> u64 {
235277
let bpp = self.bits_per_pixel() as u64;
236278
let row_pitch = (width as u64 * bpp).div_ceil(8);
237279
row_pitch.saturating_mul(height as u64)
238280
}
239281
}
282+
240283
impl From<ColorType> for ExtendedColorType {
241284
fn from(c: ColorType) -> Self {
242285
match c {
@@ -254,6 +297,16 @@ impl From<ColorType> for ExtendedColorType {
254297
}
255298
}
256299

300+
impl TryFrom<ExtendedColorType> for ColorType {
301+
type Error = TryFromExtendedColorError;
302+
303+
fn try_from(value: ExtendedColorType) -> Result<ColorType, Self::Error> {
304+
value
305+
.color_type()
306+
.ok_or(TryFromExtendedColorError { was: value })
307+
}
308+
}
309+
257310
macro_rules! define_colors {
258311
{$(
259312
$(#[$doc:meta])*

src/error.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,42 @@ impl fmt::Display for ImageFormatHint {
509509
}
510510
}
511511

512+
/// Converting [`ExtendedColorType`] to [`ColorType`] failed.
513+
///
514+
/// This type is convertible to [`ImageError`] as [`ImageError::Unsupported`].
515+
#[derive(Clone)]
516+
#[allow(missing_copy_implementations)]
517+
pub struct TryFromExtendedColorError {
518+
pub(crate) was: ExtendedColorType,
519+
}
520+
521+
impl fmt::Debug for TryFromExtendedColorError {
522+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
523+
write!(f, "{}", self)
524+
}
525+
}
526+
527+
impl fmt::Display for TryFromExtendedColorError {
528+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
529+
write!(
530+
f,
531+
"The pixel layout {:?} is not supported as a buffer ColorType",
532+
self.was
533+
)
534+
}
535+
}
536+
537+
impl Error for TryFromExtendedColorError {}
538+
539+
impl From<TryFromExtendedColorError> for ImageError {
540+
fn from(err: TryFromExtendedColorError) -> ImageError {
541+
ImageError::Unsupported(UnsupportedError::from_format_and_kind(
542+
ImageFormatHint::Unknown,
543+
UnsupportedErrorKind::Color(err.was),
544+
))
545+
}
546+
}
547+
512548
#[cfg(test)]
513549
mod tests {
514550
use super::*;

0 commit comments

Comments
 (0)