diff options
Diffstat (limited to 'vendor/image/src/codecs/ico/encoder.rs')
-rw-r--r-- | vendor/image/src/codecs/ico/encoder.rs | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/vendor/image/src/codecs/ico/encoder.rs b/vendor/image/src/codecs/ico/encoder.rs deleted file mode 100644 index dd5961b..0000000 --- a/vendor/image/src/codecs/ico/encoder.rs +++ /dev/null @@ -1,194 +0,0 @@ -use byteorder::{LittleEndian, WriteBytesExt}; -use std::borrow::Cow; -use std::io::{self, Write}; - -use crate::color::ColorType; -use crate::error::{ImageError, ImageResult, ParameterError, ParameterErrorKind}; -use crate::image::ImageEncoder; - -use crate::codecs::png::PngEncoder; - -// Enum value indicating an ICO image (as opposed to a CUR image): -const ICO_IMAGE_TYPE: u16 = 1; -// The length of an ICO file ICONDIR structure, in bytes: -const ICO_ICONDIR_SIZE: u32 = 6; -// The length of an ICO file DIRENTRY structure, in bytes: -const ICO_DIRENTRY_SIZE: u32 = 16; - -/// ICO encoder -pub struct IcoEncoder<W: Write> { - w: W, -} - -/// An ICO image entry -pub struct IcoFrame<'a> { - // Pre-encoded PNG or BMP - encoded_image: Cow<'a, [u8]>, - // Stored as `0 => 256, n => n` - width: u8, - // Stored as `0 => 256, n => n` - height: u8, - color_type: ColorType, -} - -impl<'a> IcoFrame<'a> { - /// Construct a new `IcoFrame` using a pre-encoded PNG or BMP - /// - /// The `width` and `height` must be between 1 and 256 (inclusive). - pub fn with_encoded( - encoded_image: impl Into<Cow<'a, [u8]>>, - width: u32, - height: u32, - color_type: ColorType, - ) -> ImageResult<Self> { - let encoded_image = encoded_image.into(); - - if !(1..=256).contains(&width) { - return Err(ImageError::Parameter(ParameterError::from_kind( - ParameterErrorKind::Generic(format!( - "the image width must be `1..=256`, instead width {} was provided", - width, - )), - ))); - } - - if !(1..=256).contains(&height) { - return Err(ImageError::Parameter(ParameterError::from_kind( - ParameterErrorKind::Generic(format!( - "the image height must be `1..=256`, instead height {} was provided", - height, - )), - ))); - } - - Ok(Self { - encoded_image, - width: width as u8, - height: height as u8, - color_type, - }) - } - - /// Construct a new `IcoFrame` by encoding `buf` as a PNG - /// - /// The `width` and `height` must be between 1 and 256 (inclusive) - pub fn as_png(buf: &[u8], width: u32, height: u32, color_type: ColorType) -> ImageResult<Self> { - let mut image_data: Vec<u8> = Vec::new(); - PngEncoder::new(&mut image_data).write_image(buf, width, height, color_type)?; - - let frame = Self::with_encoded(image_data, width, height, color_type)?; - Ok(frame) - } -} - -impl<W: Write> IcoEncoder<W> { - /// Create a new encoder that writes its output to ```w```. - pub fn new(w: W) -> IcoEncoder<W> { - IcoEncoder { w } - } - - /// Encodes the image ```image``` that has dimensions ```width``` and - /// ```height``` and ```ColorType``` ```c```. The dimensions of the image - /// must be between 1 and 256 (inclusive) or an error will be returned. - /// - /// Expects data to be big endian. - #[deprecated = "Use `IcoEncoder::write_image` instead. Beware that `write_image` has a different endianness convention"] - pub fn encode(self, data: &[u8], width: u32, height: u32, color: ColorType) -> ImageResult<()> { - let mut image_data: Vec<u8> = Vec::new(); - #[allow(deprecated)] - PngEncoder::new(&mut image_data).encode(data, width, height, color)?; - - let image = IcoFrame::with_encoded(&image_data, width, height, color)?; - self.encode_images(&[image]) - } - - /// Takes some [`IcoFrame`]s and encodes them into an ICO. - /// - /// `images` is a list of images, usually ordered by dimension, which - /// must be between 1 and 65535 (inclusive) in length. - pub fn encode_images(mut self, images: &[IcoFrame<'_>]) -> ImageResult<()> { - if !(1..=usize::from(u16::MAX)).contains(&images.len()) { - return Err(ImageError::Parameter(ParameterError::from_kind( - ParameterErrorKind::Generic(format!( - "the number of images must be `1..=u16::MAX`, instead {} images were provided", - images.len(), - )), - ))); - } - let num_images = images.len() as u16; - - let mut offset = ICO_ICONDIR_SIZE + (ICO_DIRENTRY_SIZE * (images.len() as u32)); - write_icondir(&mut self.w, num_images)?; - for image in images { - write_direntry( - &mut self.w, - image.width, - image.height, - image.color_type, - offset, - image.encoded_image.len() as u32, - )?; - - offset += image.encoded_image.len() as u32; - } - for image in images { - self.w.write_all(&image.encoded_image)?; - } - Ok(()) - } -} - -impl<W: Write> ImageEncoder for IcoEncoder<W> { - /// Write an ICO image with the specified width, height, and color type. - /// - /// For color types with 16-bit per channel or larger, the contents of `buf` should be in - /// native endian. - /// - /// WARNING: In image 0.23.14 and earlier this method erroneously expected buf to be in big endian. - fn write_image( - self, - buf: &[u8], - width: u32, - height: u32, - color_type: ColorType, - ) -> ImageResult<()> { - let image = IcoFrame::as_png(buf, width, height, color_type)?; - self.encode_images(&[image]) - } -} - -fn write_icondir<W: Write>(w: &mut W, num_images: u16) -> io::Result<()> { - // Reserved field (must be zero): - w.write_u16::<LittleEndian>(0)?; - // Image type (ICO or CUR): - w.write_u16::<LittleEndian>(ICO_IMAGE_TYPE)?; - // Number of images in the file: - w.write_u16::<LittleEndian>(num_images)?; - Ok(()) -} - -fn write_direntry<W: Write>( - w: &mut W, - width: u8, - height: u8, - color: ColorType, - data_start: u32, - data_size: u32, -) -> io::Result<()> { - // Image dimensions: - w.write_u8(width)?; - w.write_u8(height)?; - // Number of colors in palette (or zero for no palette): - w.write_u8(0)?; - // Reserved field (must be zero): - w.write_u8(0)?; - // Color planes: - w.write_u16::<LittleEndian>(0)?; - // Bits per pixel: - w.write_u16::<LittleEndian>(color.bits_per_pixel())?; - // Image data size, in bytes: - w.write_u32::<LittleEndian>(data_size)?; - // Image data offset, in bytes: - w.write_u32::<LittleEndian>(data_start)?; - Ok(()) -} |