mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
servo: Merge #8503 - Adding method to detect if image formats should be supported by servo (from craftytrickster:8406/limit-suppported-format); r=mbrubeck
https://github.com/servo/servo/issues/8406 Please let me know if I need to make any changes. Source-Repo: https://github.com/servo/servo Source-Revision: f17f89059a3681b7bd2da0a04259353ca21c8122 --HG-- rename : servo/tests/unit/gfx/lib.rs => servo/tests/unit/net_traits/lib.rs
This commit is contained in:
parent
e0b4ad2928
commit
f84e0e094b
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use ipc_channel::ipc::IpcSharedMemory;
|
||||
use piston_image::{self, DynamicImage, GenericImage};
|
||||
use piston_image::{self, DynamicImage, GenericImage, ImageFormat};
|
||||
use stb_image::image as stb_image2;
|
||||
use util::vec::byte_swap;
|
||||
|
||||
@ -31,61 +31,80 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
||||
return None;
|
||||
}
|
||||
|
||||
if is_jpeg(buffer) {
|
||||
// For JPEG images, we use stb_image because piston_image does not yet support progressive
|
||||
// JPEG.
|
||||
let image_fmt_result = detect_image_format(buffer);
|
||||
match image_fmt_result {
|
||||
Err(msg) => {
|
||||
debug!("{}", msg);
|
||||
None
|
||||
}
|
||||
Ok(ImageFormat::JPEG) => {
|
||||
// For JPEG images, we use stb_image because piston_image does not yet support progressive
|
||||
// JPEG.
|
||||
|
||||
// Can't remember why we do this. Maybe it's what cairo wants
|
||||
static FORCE_DEPTH: usize = 4;
|
||||
// Can't remember why we do this. Maybe it's what cairo wants
|
||||
static FORCE_DEPTH: usize = 4;
|
||||
|
||||
match stb_image2::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
||||
stb_image2::LoadResult::ImageU8(mut image) => {
|
||||
assert!(image.depth == 4);
|
||||
// handle gif separately because the alpha-channel has to be premultiplied
|
||||
if is_gif(buffer) {
|
||||
byte_swap_and_premultiply(&mut image.data);
|
||||
} else {
|
||||
byte_swap(&mut image.data);
|
||||
match stb_image2::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
||||
stb_image2::LoadResult::ImageU8(mut image) => {
|
||||
assert!(image.depth == 4);
|
||||
// handle gif separately because the alpha-channel has to be premultiplied
|
||||
if is_gif(buffer) {
|
||||
byte_swap_and_premultiply(&mut image.data);
|
||||
} else {
|
||||
byte_swap(&mut image.data);
|
||||
}
|
||||
Some(Image {
|
||||
width: image.width as u32,
|
||||
height: image.height as u32,
|
||||
format: PixelFormat::RGBA8,
|
||||
bytes: IpcSharedMemory::from_bytes(&image.data[..]),
|
||||
})
|
||||
}
|
||||
stb_image2::LoadResult::ImageF32(_image) => {
|
||||
debug!("HDR images not implemented");
|
||||
None
|
||||
}
|
||||
stb_image2::LoadResult::Error(e) => {
|
||||
debug!("stb_image failed: {}", e);
|
||||
None
|
||||
}
|
||||
Some(Image {
|
||||
width: image.width as u32,
|
||||
height: image.height as u32,
|
||||
format: PixelFormat::RGBA8,
|
||||
bytes: IpcSharedMemory::from_bytes(&image.data[..]),
|
||||
})
|
||||
}
|
||||
stb_image2::LoadResult::ImageF32(_image) => {
|
||||
debug!("HDR images not implemented");
|
||||
None
|
||||
}
|
||||
stb_image2::LoadResult::Error(e) => {
|
||||
debug!("stb_image failed: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match piston_image::load_from_memory(buffer) {
|
||||
Ok(image) => {
|
||||
let mut rgba = match image {
|
||||
DynamicImage::ImageRgba8(rgba) => rgba,
|
||||
image => image.to_rgba()
|
||||
};
|
||||
byte_swap_and_premultiply(&mut *rgba);
|
||||
Some(Image {
|
||||
width: rgba.width(),
|
||||
height: rgba.height(),
|
||||
format: PixelFormat::RGBA8,
|
||||
bytes: IpcSharedMemory::from_bytes(&*rgba),
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Image decoding error: {:?}", e);
|
||||
None
|
||||
_ => {
|
||||
match piston_image::load_from_memory(buffer) {
|
||||
Ok(image) => {
|
||||
let mut rgba = match image {
|
||||
DynamicImage::ImageRgba8(rgba) => rgba,
|
||||
image => image.to_rgba()
|
||||
};
|
||||
byte_swap_and_premultiply(&mut *rgba);
|
||||
Some(Image {
|
||||
width: rgba.width(),
|
||||
height: rgba.height(),
|
||||
format: PixelFormat::RGBA8,
|
||||
bytes: IpcSharedMemory::from_bytes(&*rgba),
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Image decoding error: {:?}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
|
||||
pub fn detect_image_format(buffer: &[u8]) -> Result<ImageFormat, &str> {
|
||||
if is_gif(buffer) { Ok(ImageFormat::GIF) }
|
||||
else if is_jpeg(buffer) { Ok(ImageFormat::JPEG) }
|
||||
else if is_png(buffer) { Ok(ImageFormat::PNG) }
|
||||
else if is_bmp(buffer) { Ok(ImageFormat::BMP) }
|
||||
else if is_ico(buffer) { Ok(ImageFormat::ICO) }
|
||||
else { Err("Image Format Not Supported") }
|
||||
}
|
||||
|
||||
fn is_gif(buffer: &[u8]) -> bool {
|
||||
match buffer {
|
||||
[b'G', b'I', b'F', b'8', n, b'a', ..] if n == b'7' || n == b'9' => true,
|
||||
@ -96,3 +115,15 @@ fn is_gif(buffer: &[u8]) -> bool {
|
||||
fn is_jpeg(buffer: &[u8]) -> bool {
|
||||
buffer.starts_with(&[0xff, 0xd8, 0xff])
|
||||
}
|
||||
|
||||
fn is_png(buffer: &[u8]) -> bool {
|
||||
buffer.starts_with(&[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
|
||||
}
|
||||
|
||||
fn is_bmp(buffer: &[u8]) -> bool {
|
||||
buffer.starts_with(&[0x42, 0x4D])
|
||||
}
|
||||
|
||||
fn is_ico(buffer: &[u8]) -> bool {
|
||||
buffer.starts_with(&[0x00, 0x00, 0x01, 0x00])
|
||||
}
|
||||
|
8
servo/components/servo/Cargo.lock
generated
8
servo/components/servo/Cargo.lock
generated
@ -24,6 +24,7 @@ dependencies = [
|
||||
"net 0.0.1",
|
||||
"net_tests 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"net_traits_tests 0.0.1",
|
||||
"offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
|
||||
"profile 0.0.1",
|
||||
"profile_traits 0.0.1",
|
||||
@ -1231,6 +1232,13 @@ dependencies = [
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net_traits_tests"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"net_traits 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.27"
|
||||
|
@ -26,6 +26,9 @@ path = "../../tests/unit/gfx"
|
||||
[dev-dependencies.net_tests]
|
||||
path = "../../tests/unit/net"
|
||||
|
||||
[dev-dependencies.net_traits_tests]
|
||||
path = "../../tests/unit/net_traits"
|
||||
|
||||
[dev-dependencies.script_tests]
|
||||
path = "../../tests/unit/script"
|
||||
|
||||
|
12
servo/tests/unit/net_traits/Cargo.toml
Normal file
12
servo/tests/unit/net_traits/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "net_traits_tests"
|
||||
version = "0.0.1"
|
||||
authors = ["The Servo Project Developers"]
|
||||
|
||||
[lib]
|
||||
name = "net_traits_tests"
|
||||
path = "lib.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies.net_traits]
|
||||
path = "../../../components/net_traits"
|
24
servo/tests/unit/net_traits/image.rs
Normal file
24
servo/tests/unit/net_traits/image.rs
Normal file
@ -0,0 +1,24 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use net_traits::image::base::detect_image_format;
|
||||
|
||||
#[test]
|
||||
fn test_supported_images() {
|
||||
let gif1 = [b'G', b'I', b'F', b'8', b'7', b'a'];
|
||||
let gif2 = [b'G', b'I', b'F', b'8', b'9', b'a'];
|
||||
let jpeg = [0xff, 0xd8, 0xff];
|
||||
let png = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
|
||||
let bmp = [0x42, 0x4D];
|
||||
let ico = [0x00, 0x00, 0x01, 0x00];
|
||||
let junk_format = [0x01, 0x02, 0x03, 0x04, 0x05];
|
||||
|
||||
assert!(detect_image_format(&gif1).is_ok());
|
||||
assert!(detect_image_format(&gif2).is_ok());
|
||||
assert!(detect_image_format(&jpeg).is_ok());
|
||||
assert!(detect_image_format(&png).is_ok());
|
||||
assert!(detect_image_format(&bmp).is_ok());
|
||||
assert!(detect_image_format(&ico).is_ok());
|
||||
assert!(detect_image_format(&junk_format).is_err());
|
||||
}
|
7
servo/tests/unit/net_traits/lib.rs
Normal file
7
servo/tests/unit/net_traits/lib.rs
Normal file
@ -0,0 +1,7 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
extern crate net_traits;
|
||||
|
||||
#[cfg(test)] mod image;
|
Loading…
Reference in New Issue
Block a user