mirror of
https://github.com/servo/servo.git
synced 2025-07-29 02:00:23 +01:00
Cargoify servo
This commit is contained in:
parent
db2f642c32
commit
c6ab60dbfc
1761 changed files with 8423 additions and 2294 deletions
67
components/net/image/base.rs
Normal file
67
components/net/image/base.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* 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 std::iter::range_step;
|
||||
use stb_image = stb_image::image;
|
||||
use png;
|
||||
|
||||
// FIXME: Images must not be copied every frame. Instead we should atomically
|
||||
// reference count them.
|
||||
pub type Image = png::Image;
|
||||
|
||||
|
||||
static TEST_IMAGE: &'static [u8] = include_bin!("test.jpeg");
|
||||
|
||||
pub fn test_image_bin() -> Vec<u8> {
|
||||
TEST_IMAGE.iter().map(|&x| x).collect()
|
||||
}
|
||||
|
||||
// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
|
||||
fn byte_swap(data: &mut [u8]) {
|
||||
let length = data.len();
|
||||
for i in range_step(0, length, 4) {
|
||||
let r = data[i + 2];
|
||||
data[i + 2] = data[i + 0];
|
||||
data[i + 0] = r;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
||||
if buffer.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
if png::is_png(buffer) {
|
||||
match png::load_png_from_memory(buffer) {
|
||||
Ok(mut png_image) => {
|
||||
match png_image.pixels {
|
||||
png::RGB8(ref mut data) | png::RGBA8(ref mut data) => {
|
||||
byte_swap(data.as_mut_slice());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Some(png_image)
|
||||
}
|
||||
Err(_err) => None,
|
||||
}
|
||||
} else {
|
||||
// For non-png images, we use stb_image
|
||||
// Can't remember why we do this. Maybe it's what cairo wants
|
||||
static FORCE_DEPTH: uint = 4;
|
||||
|
||||
match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
||||
stb_image::ImageU8(mut image) => {
|
||||
assert!(image.depth == 4);
|
||||
byte_swap(image.data.as_mut_slice());
|
||||
Some(png::Image {
|
||||
width: image.width as u32,
|
||||
height: image.height as u32,
|
||||
pixels: png::RGBA8(image.data)
|
||||
})
|
||||
}
|
||||
stb_image::ImageF32(_image) => fail!("HDR images not implemented"),
|
||||
stb_image::Error(_) => None
|
||||
}
|
||||
}
|
||||
}
|
109
components/net/image/holder.rs
Normal file
109
components/net/image/holder.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* 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 image::base::Image;
|
||||
use image_cache_task::{ImageReady, ImageNotReady, ImageFailed};
|
||||
use local_image_cache::LocalImageCache;
|
||||
|
||||
use geom::size::Size2D;
|
||||
use std::mem;
|
||||
use sync::{Arc, Mutex};
|
||||
use url::Url;
|
||||
|
||||
// FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from
|
||||
// the network stack. This should probably be factored out into an interface and use dependency
|
||||
// injection.
|
||||
|
||||
/// A struct to store image data. The image will be loaded once the first time it is requested,
|
||||
/// and an Arc will be stored. Clones of this Arc are given out on demand.
|
||||
#[deriving(Clone)]
|
||||
pub struct ImageHolder {
|
||||
url: Url,
|
||||
image: Option<Arc<Box<Image>>>,
|
||||
cached_size: Size2D<int>,
|
||||
local_image_cache: Arc<Mutex<LocalImageCache>>,
|
||||
}
|
||||
|
||||
impl ImageHolder {
|
||||
pub fn new(url: Url, local_image_cache: Arc<Mutex<LocalImageCache>>) -> ImageHolder {
|
||||
debug!("ImageHolder::new() {}", url.serialize());
|
||||
let holder = ImageHolder {
|
||||
url: url,
|
||||
image: None,
|
||||
cached_size: Size2D(0,0),
|
||||
local_image_cache: local_image_cache.clone(),
|
||||
};
|
||||
|
||||
// Tell the image cache we're going to be interested in this url
|
||||
// FIXME: These two messages must be sent to prep an image for use
|
||||
// but they are intended to be spread out in time. Ideally prefetch
|
||||
// should be done as early as possible and decode only once we
|
||||
// are sure that the image will be used.
|
||||
{
|
||||
let val = holder.local_image_cache.lock();
|
||||
let mut local_image_cache = val;
|
||||
local_image_cache.prefetch(&holder.url);
|
||||
local_image_cache.decode(&holder.url);
|
||||
}
|
||||
|
||||
holder
|
||||
}
|
||||
|
||||
/// This version doesn't perform any computation, but may be stale w.r.t. newly-available image
|
||||
/// data that determines size.
|
||||
///
|
||||
/// The intent is that the impure version is used during layout when dimensions are used for
|
||||
/// computing layout.
|
||||
pub fn size(&self) -> Size2D<int> {
|
||||
self.cached_size
|
||||
}
|
||||
|
||||
/// Query and update the current image size.
|
||||
pub fn get_size(&mut self) -> Option<Size2D<int>> {
|
||||
debug!("get_size() {}", self.url.serialize());
|
||||
self.get_image().map(|img| {
|
||||
self.cached_size = Size2D(img.width as int,
|
||||
img.height as int);
|
||||
self.cached_size.clone()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_image_if_present(&self) -> Option<Arc<Box<Image>>> {
|
||||
debug!("get_image_if_present() {}", self.url.serialize());
|
||||
self.image.clone()
|
||||
}
|
||||
|
||||
pub fn get_image(&mut self) -> Option<Arc<Box<Image>>> {
|
||||
debug!("get_image() {}", self.url.serialize());
|
||||
|
||||
// If this is the first time we've called this function, load
|
||||
// the image and store it for the future
|
||||
if self.image.is_none() {
|
||||
let port = {
|
||||
let val = self.local_image_cache.lock();
|
||||
let mut local_image_cache = val;
|
||||
local_image_cache.get_image(&self.url)
|
||||
};
|
||||
match port.recv() {
|
||||
ImageReady(image) => {
|
||||
self.image = Some(image);
|
||||
}
|
||||
ImageNotReady => {
|
||||
debug!("image not ready for {:s}", self.url.serialize());
|
||||
}
|
||||
ImageFailed => {
|
||||
debug!("image decoding failed for {:s}", self.url.serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clone isn't pure so we have to swap out the mutable image option
|
||||
let image = mem::replace(&mut self.image, None);
|
||||
let result = image.clone();
|
||||
mem::replace(&mut self.image, image);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
BIN
components/net/image/test.jpeg
Normal file
BIN
components/net/image/test.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
Loading…
Add table
Add a link
Reference in a new issue