1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 04:52:26 -05:00

fix error handling

This commit is contained in:
Hajime-san 2024-09-08 21:32:22 +09:00
parent dbac50db8f
commit f0895c6b7b
3 changed files with 75 additions and 56 deletions

View file

@ -16,9 +16,6 @@ use image::DynamicImage;
use image::ImageDecoder;
use image::ImageError;
use crate::error::image_error_message;
use crate::error::DOMExceptionInvalidStateError;
//
// About the animated image
// > Blob .4
@ -32,40 +29,43 @@ use crate::error::DOMExceptionInvalidStateError;
//
pub(crate) trait ImageDecoderFromReader<'a, R: BufRead + Seek> {
fn to_decoder(reader: R) -> Result<Self, AnyError>
fn to_decoder(
reader: R,
error_fn: fn(ImageError) -> AnyError,
) -> Result<Self, AnyError>
where
Self: Sized;
fn to_intermediate_image(self) -> Result<DynamicImage, AnyError>;
fn to_intermediate_image(
self,
error_fn: fn(ImageError) -> AnyError,
) -> Result<DynamicImage, AnyError>;
fn get_icc_profile(&mut self) -> Option<Vec<u8>>;
}
pub(crate) type ImageDecoderFromReaderType<'a> = BufReader<Cursor<&'a [u8]>>;
pub(crate) fn image_decoding_error(
error: ImageError,
) -> DOMExceptionInvalidStateError {
DOMExceptionInvalidStateError::new(&image_error_message(
"decoding",
&error.to_string(),
))
}
macro_rules! impl_image_decoder_from_reader {
($decoder:ty, $reader:ty) => {
impl<'a, R: BufRead + Seek> ImageDecoderFromReader<'a, R> for $decoder {
fn to_decoder(reader: R) -> Result<Self, AnyError>
fn to_decoder(
reader: R,
error_fn: fn(ImageError) -> AnyError,
) -> Result<Self, AnyError>
where
Self: Sized,
{
match <$decoder>::new(reader) {
Ok(decoder) => Ok(decoder),
Err(err) => return Err(image_decoding_error(err).into()),
Err(err) => return Err(error_fn(err)),
}
}
fn to_intermediate_image(self) -> Result<DynamicImage, AnyError> {
fn to_intermediate_image(
self,
error_fn: fn(ImageError) -> AnyError,
) -> Result<DynamicImage, AnyError> {
match DynamicImage::from_decoder(self) {
Ok(image) => Ok(image),
Err(err) => Err(image_decoding_error(err).into()),
Err(err) => Err(error_fn(err)),
}
}
fn get_icc_profile(&mut self) -> Option<Vec<u8>> {

View file

@ -89,7 +89,10 @@ where
/// Premultiply the alpha channel of the image.
pub(crate) fn premultiply_alpha(
image: DynamicImage,
unmatch: Option<fn(ColorType) -> Result<DynamicImage, AnyError>>,
unmatch_color_handler: fn(
ColorType,
DynamicImage,
) -> Result<DynamicImage, AnyError>,
) -> Result<DynamicImage, AnyError> {
let color = image.color();
match color {
@ -105,10 +108,7 @@ pub(crate) fn premultiply_alpha(
ColorType::Rgba16 => Ok(DynamicImage::ImageRgba16(
process_premultiply_alpha(&image.to_rgba16()),
)),
x => match unmatch {
Some(unmatch) => unmatch(x),
None => Ok(image),
},
x => unmatch_color_handler(x, image),
}
}
@ -217,7 +217,10 @@ where
/// Invert the premultiplied alpha channel of the image.
pub(crate) fn unpremultiply_alpha(
image: DynamicImage,
unmatch: Option<fn(ColorType) -> Result<DynamicImage, AnyError>>,
unmatch_color_handler: fn(
ColorType,
DynamicImage,
) -> Result<DynamicImage, AnyError>,
) -> Result<DynamicImage, AnyError> {
match image.color() {
ColorType::La8 => Ok(DynamicImage::ImageLumaA8(
@ -232,10 +235,7 @@ pub(crate) fn unpremultiply_alpha(
ColorType::Rgba16 => Ok(DynamicImage::ImageRgba16(
process_unpremultiply_alpha(&image.to_rgba16()),
)),
x => match unmatch {
Some(unmatch) => unmatch(x),
None => Ok(image),
},
x => unmatch_color_handler(x, image),
}
}
@ -387,7 +387,10 @@ where
/// Convert the color space of the image from sRGB to Display-P3.
pub(crate) fn srgb_to_display_p3(
image: DynamicImage,
unmatch: Option<fn(ColorType) -> Result<DynamicImage, AnyError>>,
unmatch_color_handler: fn(
ColorType,
DynamicImage,
) -> Result<DynamicImage, AnyError>,
) -> Result<DynamicImage, AnyError> {
match image.color() {
// The conversion of the lumincance color types to the display-p3 color space is meaningless.
@ -407,10 +410,7 @@ pub(crate) fn srgb_to_display_p3(
ColorType::Rgba16 => Ok(DynamicImage::ImageRgba16(
process_srgb_to_display_p3(&image.to_rgba16()),
)),
x => match unmatch {
Some(unmatch) => unmatch(x),
None => Ok(image),
},
x => unmatch_color_handler(x, image),
}
}
@ -551,7 +551,7 @@ where
pub(crate) fn to_srgb_from_icc_profile(
image: DynamicImage,
icc_profile: Option<Vec<u8>>,
unmatch: Option<fn(ColorType) -> Result<DynamicImage, AnyError>>,
unmatch_color_handler: fn(ColorType, DynamicImage) -> Result<DynamicImage, AnyError>,
) -> Result<DynamicImage, AnyError> {
match icc_profile {
// If there is no color profile information, return the image as is.
@ -586,10 +586,7 @@ pub(crate) fn to_srgb_from_icc_profile(
ColorType::Rgba16 => {
Ok(DynamicImage::ImageRgba16(process_icc_profile_conversion::<_,_,8>(&image,icc_profile,srgb_icc_profile)))
}
x => match unmatch {
Some(unmatch) => unmatch(x),
None => Ok(image),
},
x => unmatch_color_handler(x, image),
}
}
},

View file

@ -19,6 +19,7 @@ use image::imageops::overlay;
use image::imageops::FilterType;
use image::ColorType;
use image::DynamicImage;
use image::ImageError;
use image::RgbaImage;
use serde::Deserialize;
use serde::Serialize;
@ -111,55 +112,62 @@ fn decode_bitmap_data(
) -> Result<DecodeBitmapDataReturn, AnyError> {
let (image, width, height, icc_profile) = match image_bitmap_source {
ImageBitmapSource::Blob => {
fn image_decoding_error(error: ImageError) -> AnyError {
DOMExceptionInvalidStateError::new(&image_error_message(
"decoding",
&error.to_string(),
))
.into()
}
let (image, icc_profile) = match &*mime_type {
// Should we support the "image/apng" MIME type here?
"image/png" => {
let mut decoder: PngDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new(
buf,
)))?;
)), image_decoding_error)?;
let icc_profile = decoder.get_icc_profile();
(decoder.to_intermediate_image()?, icc_profile)
(decoder.to_intermediate_image(image_decoding_error)?, icc_profile)
}
"image/jpeg" => {
let mut decoder: JpegDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new(
buf,
)))?;
)), image_decoding_error)?;
let icc_profile = decoder.get_icc_profile();
(decoder.to_intermediate_image()?, icc_profile)
(decoder.to_intermediate_image(image_decoding_error)?, icc_profile)
}
"image/gif" => {
let mut decoder: GifDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new(
buf,
)))?;
)), image_decoding_error)?;
let icc_profile = decoder.get_icc_profile();
(decoder.to_intermediate_image()?, icc_profile)
(decoder.to_intermediate_image(image_decoding_error)?, icc_profile)
}
"image/bmp" => {
let mut decoder: BmpDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new(
buf,
)))?;
)), image_decoding_error)?;
let icc_profile = decoder.get_icc_profile();
(decoder.to_intermediate_image()?, icc_profile)
(decoder.to_intermediate_image(image_decoding_error)?, icc_profile)
}
"image/x-icon" => {
let mut decoder: IcoDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new(
buf,
)))?;
)), image_decoding_error)?;
let icc_profile = decoder.get_icc_profile();
(decoder.to_intermediate_image()?, icc_profile)
(decoder.to_intermediate_image(image_decoding_error)?, icc_profile)
}
"image/webp" => {
let mut decoder: WebPDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(BufReader::new(Cursor::new(
buf,
)))?;
)), image_decoding_error)?;
let icc_profile = decoder.get_icc_profile();
(decoder.to_intermediate_image()?, icc_profile)
(decoder.to_intermediate_image(image_decoding_error)?, icc_profile)
}
"" => {
return Err(
@ -243,25 +251,31 @@ fn apply_color_space_conversion(
ColorSpaceConversion::Default => {
match image_bitmap_source {
ImageBitmapSource::Blob => {
fn color_unmatch(x: ColorType) -> Result<DynamicImage, AnyError> {
fn unmatch_color_handler(
x: ColorType,
_: DynamicImage,
) -> Result<DynamicImage, AnyError> {
Err(type_error(image_error_message(
"apply colorspaceConversion: default",
&format!("The color type {:?} is not supported.", x),
)))
}
to_srgb_from_icc_profile(image, icc_profile, Some(color_unmatch))
to_srgb_from_icc_profile(image, icc_profile, unmatch_color_handler)
}
ImageBitmapSource::ImageData => match predefined_color_space {
// If the color space is sRGB, return the image as is.
PredefinedColorSpace::Srgb => Ok(image),
PredefinedColorSpace::DisplayP3 => {
fn unmatch(x: ColorType) -> Result<DynamicImage, AnyError> {
fn unmatch_color_handler(
x: ColorType,
_: DynamicImage,
) -> Result<DynamicImage, AnyError> {
Err(type_error(image_error_message(
"apply colorspace: display-p3",
&format!("The color type {:?} is not supported.", x),
)))
}
srgb_to_display_p3(image, Some(unmatch))
srgb_to_display_p3(image, unmatch_color_handler)
}
},
}
@ -278,6 +292,12 @@ fn apply_premultiply_alpha(
if !color.has_alpha() {
Ok(image)
} else {
fn unmatch_color_handler(
_: ColorType,
image: DynamicImage,
) -> Result<DynamicImage, AnyError> {
Ok(image)
}
match premultiply_alpha {
// 1.
PremultiplyAlpha::Default => Ok(image),
@ -285,7 +305,9 @@ fn apply_premultiply_alpha(
// https://html.spec.whatwg.org/multipage/canvas.html#convert-from-premultiplied
// 2.
PremultiplyAlpha::Premultiply => process_premultiply_alpha(image, None),
PremultiplyAlpha::Premultiply => {
process_premultiply_alpha(image, unmatch_color_handler)
}
// 3.
PremultiplyAlpha::None => {
// NOTE: It's not clear how to handle the case of ImageData.
@ -295,7 +317,7 @@ fn apply_premultiply_alpha(
return Ok(image);
}
unpremultiply_alpha(image, None)
unpremultiply_alpha(image, unmatch_color_handler)
}
}
}