render: Add support for GIF decoding in DefineBitsJPEG tags

This commit is contained in:
Mike Welsh 2020-04-29 17:13:50 -07:00
parent 5d84d33710
commit b59140ee01
3 changed files with 21 additions and 1 deletions

1
Cargo.lock generated
View File

@ -1805,6 +1805,7 @@ dependencies = [
"gc-arena 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gc-arena-derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"generational-arena 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"gif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"jpeg-decoder 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
"libflate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -10,6 +10,7 @@ fnv = "1.0.3"
gc-arena = "0.2.0"
gc-arena-derive = "0.2.0"
generational-arena = "0.2.7"
gif = "0.10.3"
indexmap = "1.3.2"
libflate = "1.0.0"
log = "0.4"

View File

@ -176,7 +176,7 @@ pub fn decode_define_bits_jpeg(data: &[u8], alpha_data: Option<&[u8]>) -> Result
match format {
JpegTagFormat::Jpeg => decode_jpeg(data, alpha_data),
JpegTagFormat::Png => decode_png(data),
JpegTagFormat::Gif => Err("GIF data is currently unsupported".into()),
JpegTagFormat::Gif => decode_gif(data),
JpegTagFormat::Unknown => Err("Unknown bitmap data format".into()),
}
}
@ -432,6 +432,24 @@ pub fn decode_png(data: &[u8]) -> Result<Bitmap, Error> {
})
}
/// Decodes the bitmap data in DefineBitsLossless tag into RGBA.
/// DefineBitsLossless is Zlib encoded pixel data (similar to PNG), possibly
/// palletized.
pub fn decode_gif(data: &[u8]) -> Result<Bitmap, Error> {
use gif::SetParameter;
let mut decoder = gif::Decoder::new(data);
decoder.set(gif::ColorOutput::RGBA);
let mut reader = decoder.read_info()?;
let frame = reader.read_next_frame()?.ok_or("No frames in GIF")?;
Ok(Bitmap {
width: frame.width.into(),
height: frame.height.into(),
data: BitmapFormat::Rgba(frame.buffer.to_vec()),
})
}
/// Images in SWFs are stored with premultiplied alpha.
/// Converts RGBA premultiplied alpha to standard RBGA.
pub fn unmultiply_alpha_rgba(rgba: &mut [u8]) {