diff options
author | Jack Moffitt <jack@metajack.im> | 2014-08-28 09:34:23 -0600 |
---|---|---|
committer | Jack Moffitt <jack@metajack.im> | 2014-09-08 20:21:42 -0600 |
commit | c6ab60dbfc6da7b4f800c9e40893c8b58413960c (patch) | |
tree | d1d74076cf7fa20e4f77ec7cb82cae98b67362cb /components/net/image/base.rs | |
parent | db2f642c32fc5bed445bb6f2e45b0f6f0b4342cf (diff) | |
download | servo-c6ab60dbfc6da7b4f800c9e40893c8b58413960c.tar.gz servo-c6ab60dbfc6da7b4f800c9e40893c8b58413960c.zip |
Cargoify servo
Diffstat (limited to 'components/net/image/base.rs')
-rw-r--r-- | components/net/image/base.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/components/net/image/base.rs b/components/net/image/base.rs new file mode 100644 index 00000000000..deda4ee8556 --- /dev/null +++ b/components/net/image/base.rs @@ -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 + } + } +} |