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

remove boilerplate

- https://github.com/denoland/deno/pull/25517#discussion_r1855114381
This commit is contained in:
Hajime-san 2024-11-26 12:24:45 +09:00
parent 24306b3ed6
commit 332fc416e8
3 changed files with 47 additions and 130 deletions

View file

@ -1,87 +0,0 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::io::BufRead;
use std::io::BufReader;
use std::io::Cursor;
use std::io::Seek;
use image::codecs::bmp::BmpDecoder;
use image::codecs::gif::GifDecoder;
use image::codecs::ico::IcoDecoder;
use image::codecs::jpeg::JpegDecoder;
use image::codecs::png::PngDecoder;
use image::codecs::webp::WebPDecoder;
use image::DynamicImage;
use image::ImageError;
use crate::CanvasError;
//
// About the animated image
// > Blob .4
// > ... If this is an animated image, imageBitmap's bitmap data must only be taken from
// > the default image of the animation (the one that the format defines is to be used when animation is
// > not supported or is disabled), or, if there is no such image, the first frame of the animation.
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html
//
// see also browser implementations: (The implementation of Gecko and WebKit is hard to read.)
// https://source.chromium.org/chromium/chromium/src/+/bdbc054a6cabbef991904b5df9066259505cc686:third_party/blink/renderer/platform/image-decoders/image_decoder.h;l=175-189
//
/// A trait for converting a reader into an image decoder.
/// This trait is used to abstract over the different image decoders and
/// provide thin helpers to handle errors for the runtime.
pub(crate) trait ImageDecoderFromReader<'a, R: BufRead + Seek> {
/// Create a new image decoder from a reader.
fn to_decoder(
reader: R,
error_fn: fn(ImageError) -> CanvasError,
) -> Result<Self, CanvasError>
where
Self: Sized;
/// Convert the image decoder into an intermediate image(DynamicImage).
fn to_intermediate_image(
self,
error_fn: fn(ImageError) -> CanvasError,
) -> Result<DynamicImage, CanvasError>;
}
pub(crate) type ImageDecoderFromReaderType<'a> = BufReader<Cursor<&'a [u8]>>;
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,
error_fn: fn(ImageError) -> CanvasError,
) -> Result<Self, CanvasError>
where
Self: Sized,
{
match <$decoder>::new(reader) {
Ok(decoder) => Ok(decoder),
Err(err) => return Err(error_fn(err)),
}
}
fn to_intermediate_image(
self,
error_fn: fn(ImageError) -> CanvasError,
) -> Result<DynamicImage, CanvasError> {
match DynamicImage::from_decoder(self) {
Ok(image) => Ok(image),
Err(err) => Err(error_fn(err)),
}
}
}
};
}
// If PngDecoder decodes an animated image, it returns the default image if one is set, or the first frame if not.
impl_image_decoder_from_reader!(PngDecoder<R>, ImageDecoderFromReaderType);
impl_image_decoder_from_reader!(JpegDecoder<R>, ImageDecoderFromReaderType);
// The GifDecoder decodes the first frame.
impl_image_decoder_from_reader!(GifDecoder<R>, ImageDecoderFromReaderType);
impl_image_decoder_from_reader!(BmpDecoder<R>, ImageDecoderFromReaderType);
impl_image_decoder_from_reader!(IcoDecoder<R>, ImageDecoderFromReaderType);
// The WebPDecoder decodes the first frame.
impl_image_decoder_from_reader!(WebPDecoder<R>, ImageDecoderFromReaderType);

View file

@ -2,7 +2,6 @@
use std::path::PathBuf;
mod image_decoder;
mod image_ops;
mod op_create_image_bitmap;
use image::ColorType;
@ -28,6 +27,13 @@ pub enum CanvasError {
Image(#[from] image::ImageError),
}
impl CanvasError {
/// Convert an [`image::ImageError`] to an [`CanvasError::InvalidImage`].
fn image_error_to_invalid_image(error: image::ImageError) -> Self {
Self::InvalidImage(error.to_string())
}
}
deno_core::extension!(
deno_canvas,
deps = [deno_webidl, deno_web, deno_webgpu],

View file

@ -17,11 +17,8 @@ use image::imageops::FilterType;
use image::metadata::Orientation;
use image::DynamicImage;
use image::ImageDecoder;
use image::ImageError;
use image::RgbaImage;
use crate::image_decoder::ImageDecoderFromReader;
use crate::image_decoder::ImageDecoderFromReaderType;
use crate::image_ops::premultiply_alpha as process_premultiply_alpha;
use crate::image_ops::to_srgb_from_icc_profile;
use crate::image_ops::unpremultiply_alpha;
@ -84,90 +81,91 @@ fn decode_bitmap_data(
let (image, width, height, orientation, icc_profile) =
match image_bitmap_source {
ImageBitmapSource::Blob => {
fn image_decoding_error(error: ImageError) -> CanvasError {
CanvasError::InvalidImage(error.to_string())
}
//
// About the animated image
// > Blob .4
// > ... If this is an animated image, imageBitmap's bitmap data must only be taken from
// > the default image of the animation (the one that the format defines is to be used when animation is
// > not supported or is disabled), or, if there is no such image, the first frame of the animation.
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html
//
// see also browser implementations: (The implementation of Gecko and WebKit is hard to read.)
// https://source.chromium.org/chromium/chromium/src/+/bdbc054a6cabbef991904b5df9066259505cc686:third_party/blink/renderer/platform/image-decoders/image_decoder.h;l=175-189
//
let (image, orientation, icc_profile) = match mime_type {
MimeType::Png => {
let mut decoder: PngDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(
BufReader::new(Cursor::new(buf)),
image_decoding_error,
)?;
// If PngDecoder decodes an animated image, it returns the default image if one is set, or the first frame if not.
let mut decoder = PngDecoder::new(BufReader::new(Cursor::new(buf)))
.map_err(CanvasError::image_error_to_invalid_image)?;
let orientation = decoder.orientation()?;
let icc_profile = decoder.icc_profile()?;
(
decoder.to_intermediate_image(image_decoding_error)?,
DynamicImage::from_decoder(decoder)
.map_err(CanvasError::image_error_to_invalid_image)?,
orientation,
icc_profile,
)
}
MimeType::Jpeg => {
let mut decoder: JpegDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(
BufReader::new(Cursor::new(buf)),
image_decoding_error,
)?;
let mut decoder =
JpegDecoder::new(BufReader::new(Cursor::new(buf)))
.map_err(CanvasError::image_error_to_invalid_image)?;
let orientation = decoder.orientation()?;
let icc_profile = decoder.icc_profile()?;
(
decoder.to_intermediate_image(image_decoding_error)?,
DynamicImage::from_decoder(decoder)
.map_err(CanvasError::image_error_to_invalid_image)?,
orientation,
icc_profile,
)
}
MimeType::Gif => {
let mut decoder: GifDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(
BufReader::new(Cursor::new(buf)),
image_decoding_error,
)?;
// The GifDecoder decodes the first frame.
let mut decoder = GifDecoder::new(BufReader::new(Cursor::new(buf)))
.map_err(CanvasError::image_error_to_invalid_image)?;
let orientation = decoder.orientation()?;
let icc_profile = decoder.icc_profile()?;
(
decoder.to_intermediate_image(image_decoding_error)?,
DynamicImage::from_decoder(decoder)
.map_err(CanvasError::image_error_to_invalid_image)?,
orientation,
icc_profile,
)
}
MimeType::Bmp => {
let mut decoder: BmpDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(
BufReader::new(Cursor::new(buf)),
image_decoding_error,
)?;
let mut decoder = BmpDecoder::new(BufReader::new(Cursor::new(buf)))
.map_err(CanvasError::image_error_to_invalid_image)?;
let orientation = decoder.orientation()?;
let icc_profile = decoder.icc_profile()?;
(
decoder.to_intermediate_image(image_decoding_error)?,
DynamicImage::from_decoder(decoder)
.map_err(CanvasError::image_error_to_invalid_image)?,
orientation,
icc_profile,
)
}
MimeType::Ico => {
let mut decoder: IcoDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(
BufReader::new(Cursor::new(buf)),
image_decoding_error,
)?;
let mut decoder = IcoDecoder::new(BufReader::new(Cursor::new(buf)))
.map_err(CanvasError::image_error_to_invalid_image)?;
let orientation = decoder.orientation()?;
let icc_profile = decoder.icc_profile()?;
(
decoder.to_intermediate_image(image_decoding_error)?,
DynamicImage::from_decoder(decoder)
.map_err(CanvasError::image_error_to_invalid_image)?,
orientation,
icc_profile,
)
}
MimeType::Webp => {
let mut decoder: WebPDecoder<ImageDecoderFromReaderType> =
ImageDecoderFromReader::to_decoder(
BufReader::new(Cursor::new(buf)),
image_decoding_error,
)?;
// The WebPDecoder decodes the first frame.
let mut decoder =
WebPDecoder::new(BufReader::new(Cursor::new(buf)))
.map_err(CanvasError::image_error_to_invalid_image)?;
let orientation = decoder.orientation()?;
let icc_profile = decoder.icc_profile()?;
(
decoder.to_intermediate_image(image_decoding_error)?,
DynamicImage::from_decoder(decoder)
.map_err(CanvasError::image_error_to_invalid_image)?,
orientation,
icc_profile,
)