Auto merge of #7933 - mbrubeck:piston-image, r=glennw

Replace libpng and stb_image with PistonDevelopers/image

Fixes #3368. r? @glennw 

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7933)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-10-12 15:06:31 -06:00
commit 0f597d3890
24 changed files with 270 additions and 193 deletions

View file

@ -52,10 +52,6 @@ git = "https://github.com/servo/rust-azure"
[dependencies.layers]
git = "https://github.com/servo/rust-layers"
[dependencies.png]
git = "https://github.com/servo/rust-png"
features = [ "serde-serialization" ]
[dependencies.clipboard]
git = "https://github.com/aweinstock314/rust-clipboard"
@ -72,6 +68,7 @@ features = [ "serde_serialization" ]
[dependencies]
app_units = "0.1"
image = "0.3.14"
log = "0.3"
num = "0.1.24"
time = "0.1.17"

View file

@ -16,7 +16,8 @@ use gfx::paint_task::{ChromeToPaintMsg, PaintRequest};
use gfx_traits::color;
use gleam::gl;
use gleam::gl::types::{GLint, GLsizei};
use ipc_channel::ipc;
use image::{DynamicImage, ImageFormat, RgbImage};
use ipc_channel::ipc::{self, IpcSharedMemory};
use ipc_channel::router::ROUTER;
use layers::geometry::{DevicePixel, LayerPixel};
use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet};
@ -27,18 +28,18 @@ use layers::scene::Scene;
use layout_traits::LayoutControlChan;
use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerKind};
use msg::compositor_msg::{LayerProperties, ScrollPolicy};
use msg::constellation_msg::AnimationState;
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{AnimationState, Image, PixelFormat};
use msg::constellation_msg::{ConstellationChan, Key, KeyModifiers, KeyState, LoadData};
use msg::constellation_msg::{NavigationDirection, PipelineId, WindowSizeData};
use pipeline::CompositionPipeline;
use png;
use profile_traits::mem::{self, ReportKind, Reporter, ReporterRequest};
use profile_traits::time::{self, ProfilerCategory, profile};
use script_traits::{ConstellationControlMsg, LayoutControlMsg};
use scrolling::ScrollingTimerProxy;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::mem as std_mem;
use std::rc::Rc;
use std::slice::bytes::copy_memory;
@ -1521,7 +1522,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
/// for some reason. If CompositeTarget is Window or Png no image data is returned;
/// in the latter case the image is written directly to a file. If CompositeTarget
/// is WindowAndPng Ok(Some(png::Image)) is returned.
pub fn composite_specific_target(&mut self, target: CompositeTarget) -> Result<Option<png::Image>, ()> {
pub fn composite_specific_target(&mut self, target: CompositeTarget) -> Result<Option<Image>, ()> {
if !self.context.is_some() {
return Err(())
@ -1573,13 +1574,19 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let rv = match target {
CompositeTarget::Window => None,
CompositeTarget::WindowAndPng => {
Some(self.draw_png(framebuffer_ids, texture_ids, width, height))
let img = self.draw_img(framebuffer_ids, texture_ids, width, height);
Some(Image {
width: img.width(),
height: img.height(),
format: PixelFormat::RGB8,
bytes: IpcSharedMemory::from_bytes(&*img),
})
}
CompositeTarget::PngFile => {
let mut img = self.draw_png(framebuffer_ids, texture_ids, width, height);
let img = self.draw_img(framebuffer_ids, texture_ids, width, height);
let path = opts::get().output_file.as_ref().unwrap();
let res = png::store_png(&mut img, &path);
assert!(res.is_ok(), format!("Error writing png: {}", res.unwrap_err()));
let mut file = File::create(path).unwrap();
DynamicImage::ImageRgb8(img).save(&mut file, ImageFormat::PNG).unwrap();
None
}
};
@ -1596,12 +1603,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
Ok(rv)
}
fn draw_png(&self,
fn draw_img(&self,
framebuffer_ids: Vec<gl::GLuint>,
texture_ids: Vec<gl::GLuint>,
width: usize,
height: usize)
-> png::Image {
-> RgbImage {
let mut pixels = gl::read_pixels(0, 0,
width as gl::GLsizei,
height as gl::GLsizei,
@ -1622,11 +1629,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
copy_memory(&src_slice[..stride],
&mut pixels[dst_start .. dst_start + stride]);
}
png::Image {
width: width as u32,
height: height as u32,
pixels: png::PixelsByColorType::RGB8(pixels),
}
RgbImage::from_raw(width as u32, height as u32, pixels).unwrap()
}
fn composite_if_necessary(&mut self, reason: CompositingReason) {

View file

@ -13,8 +13,7 @@ use layers::platform::surface::{NativeDisplay, NativeSurface};
use msg::compositor_msg::{Epoch, FrameTreeId, LayerId, LayerProperties};
use msg::compositor_msg::{PaintListener, ScriptToCompositorMsg};
use msg::constellation_msg::{AnimationState, ConstellationChan, PipelineId};
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use png;
use msg::constellation_msg::{Image, Key, KeyModifiers, KeyState};
use profile_traits::mem;
use profile_traits::time;
use std::fmt::{Debug, Error, Formatter};
@ -193,7 +192,7 @@ pub enum Msg {
/// Changes the cursor.
SetCursor(Cursor),
/// Composite to a PNG file and return the Image over a passed channel.
CreatePng(IpcSender<Option<png::Image>>),
CreatePng(IpcSender<Option<Image>>),
/// Informs the compositor that the paint task for the given pipeline has exited.
PaintTaskExited(PipelineId),
/// Alerts the compositor that the viewport has been constrained in some manner

View file

@ -33,6 +33,7 @@ extern crate euclid;
extern crate gfx;
extern crate gfx_traits;
extern crate gleam;
extern crate image;
extern crate ipc_channel;
extern crate layers;
extern crate layout_traits;
@ -40,7 +41,6 @@ extern crate msg;
extern crate net_traits;
extern crate num;
extern crate offscreen_gl_context;
extern crate png;
extern crate script_traits;
extern crate style_traits;
extern crate time;

View file

@ -22,10 +22,6 @@ git = "https://github.com/servo/rust-azure"
[dependencies.layers]
git = "https://github.com/servo/rust-layers"
[dependencies.png]
git = "https://github.com/servo/rust-png"
features = [ "serde-serialization" ]
[dependencies.hyper]
version = "0.6"
features = [ "serde-serialization" ]

View file

@ -11,10 +11,9 @@ use euclid::scale_factor::ScaleFactor;
use euclid::size::{Size2D, TypedSize2D};
use hyper::header::Headers;
use hyper::method::Method;
use ipc_channel::ipc::IpcSender;
use ipc_channel::ipc::{IpcSender, IpcSharedMemory};
use layers::geometry::DevicePixel;
use offscreen_gl_context::GLContextAttributes;
use png::Image;
use std::cell::Cell;
use std::collections::HashMap;
use std::fmt;
@ -372,7 +371,24 @@ pub enum WebDriverCommandMsg {
LoadUrl(PipelineId, LoadData, IpcSender<LoadStatus>),
Refresh(PipelineId, IpcSender<LoadStatus>),
ScriptCommand(PipelineId, WebDriverScriptCommand),
TakeScreenshot(PipelineId, IpcSender<Option<Image>>)
TakeScreenshot(PipelineId, IpcSender<Option<Image>>),
}
#[derive(Deserialize, Eq, PartialEq, Serialize, HeapSizeOf)]
pub enum PixelFormat {
K8, // Luminance channel only
KA8, // Luminance + alpha
RGB8, // RGB, 8 bits per channel
RGBA8, // RGB + alpha, 8 bits per channel
}
#[derive(Deserialize, Serialize, HeapSizeOf)]
pub struct Image {
pub width: u32,
pub height: u32,
pub format: PixelFormat,
#[ignore_heap_size_of = "Defined in ipc-channel"]
pub bytes: IpcSharedMemory,
}
/// Similar to net::resource_task::LoadData

View file

@ -2,7 +2,7 @@
* 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/. */
#![feature(custom_derive, plugin)]
#![feature(custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros, plugins)]
extern crate app_units;
@ -19,7 +19,6 @@ extern crate io_surface;
extern crate ipc_channel;
extern crate layers;
extern crate offscreen_gl_context;
extern crate png;
extern crate rustc_serialize;
extern crate serde;
extern crate style_traits;

View file

@ -19,10 +19,6 @@ path = "../devtools_traits"
[dependencies.plugins]
path = "../plugins"
[dependencies.png]
git = "https://github.com/servo/rust-png"
features = [ "serde-serialization" ]
[dependencies.hyper]
version = "0.6"
features = [ "serde-serialization" ]

View file

@ -21,7 +21,6 @@ extern crate hyper;
extern crate ipc_channel;
extern crate net_traits;
extern crate openssl;
extern crate png;
extern crate rustc_serialize;
extern crate time;
extern crate url;

View file

@ -7,10 +7,6 @@ authors = ["The Servo Project Developers"]
name = "net_traits"
path = "lib.rs"
[dependencies.png]
git = "https://github.com/servo/rust-png"
features = [ "serde-serialization" ]
[dependencies.util]
path = "../util"
@ -37,6 +33,7 @@ path = "../plugins"
[dependencies]
log = "0.3"
euclid = "0.2"
image = "0.3.14"
regex = "0.1.33"
regex_macros = "0.1.19"
serde = "0.6"

View file

@ -3,32 +3,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use ipc_channel::ipc::IpcSharedMemory;
use png;
use piston_image::{self, DynamicImage, GenericImage};
use stb_image::image as stb_image2;
use std::mem;
use util::mem::HeapSizeOf;
use util::vec::byte_swap;
pub use msg::constellation_msg::{Image, PixelFormat};
// FIXME: Images must not be copied every frame. Instead we should atomically
// reference count them.
#[derive(Deserialize, Serialize, HeapSizeOf)]
pub enum PixelFormat {
K8, // Luminance channel only
KA8, // Luminance + alpha
RGB8, // RGB, 8 bits per channel
RGBA8, // RGB + alpha, 8 bits per channel
}
#[derive(Deserialize, Serialize, HeapSizeOf)]
pub struct Image {
pub width: u32,
pub height: u32,
pub format: PixelFormat,
#[ignore_heap_size_of = "Defined in ipc-channel"]
pub bytes: IpcSharedMemory,
}
// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
fn byte_swap_and_premultiply(data: &mut [u8]) {
let length = data.len();
@ -48,41 +31,10 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
return None;
}
if png::is_png(buffer) {
match png::load_png_from_memory(buffer) {
Ok(mut png_image) => {
let (bytes, format) = match png_image.pixels {
png::PixelsByColorType::K8(ref mut data) => {
(data, PixelFormat::K8)
}
png::PixelsByColorType::KA8(ref mut data) => {
(data, PixelFormat::KA8)
}
png::PixelsByColorType::RGB8(ref mut data) => {
byte_swap(data);
(data, PixelFormat::RGB8)
}
png::PixelsByColorType::RGBA8(ref mut data) => {
byte_swap_and_premultiply(data);
(data, PixelFormat::RGBA8)
}
};
if is_jpeg(buffer) {
// For JPEG images, we use stb_image because piston_image does not yet support progressive
// JPEG.
let bytes = mem::replace(bytes, Vec::new());
let bytes = IpcSharedMemory::from_bytes(&bytes[..]);
let image = Image {
width: png_image.width,
height: png_image.height,
format: format,
bytes: bytes,
};
Some(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: usize = 4;
@ -111,6 +63,26 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
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
}
}
}
}
@ -120,3 +92,7 @@ fn is_gif(buffer: &[u8]) -> bool {
_ => false
}
}
fn is_jpeg(buffer: &[u8]) -> bool {
buffer.starts_with(&[0xff, 0xd8, 0xff])
}

View file

@ -2,8 +2,8 @@
* 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 ipc_channel::ipc::{self, IpcSender};
use msg::constellation_msg::Image;
use std::sync::Arc;
use url::Url;
use util::mem::HeapSizeOf;

View file

@ -18,8 +18,8 @@ extern crate log;
extern crate euclid;
extern crate hyper;
extern crate ipc_channel;
extern crate image as piston_image;
extern crate msg;
extern crate png;
extern crate regex;
extern crate serde;
extern crate stb_image;

View file

@ -15,6 +15,7 @@ dependencies = [
"gfx_tests 0.0.1",
"gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1",
"image 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"layout 0.0.1",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@ -22,7 +23,6 @@ dependencies = [
"net 0.0.1",
"net_tests 0.0.1",
"net_traits 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"profile 0.0.1",
"profile_traits 0.0.1",
"script 0.0.1",
@ -239,6 +239,11 @@ dependencies = [
"objc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "color_quant"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "compositing"
version = "0.0.1"
@ -255,6 +260,7 @@ dependencies = [
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
@ -264,7 +270,6 @@ dependencies = [
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
"plugins 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"profile_traits 0.0.1",
"script_traits 0.0.1",
"style_traits 0.0.1",
@ -494,6 +499,14 @@ dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "enum_primitive"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "env_logger"
version = "0.3.1"
@ -660,6 +673,15 @@ dependencies = [
"azure 0.1.0 (git+https://github.com/servo/rust-azure)",
]
[[package]]
name = "gif"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lzw 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gl_common"
version = "0.0.4"
@ -699,6 +721,11 @@ dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "glutin"
version = "0.3.6"
@ -873,6 +900,19 @@ dependencies = [
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "image"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gif 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "io-surface"
version = "0.1.0"
@ -1049,6 +1089,11 @@ dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lzw"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mac"
version = "0.0.2"
@ -1126,7 +1171,6 @@ dependencies = [
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
"plugins 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1149,7 +1193,6 @@ dependencies = [
"net_traits 0.0.1",
"openssl 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"regex_macros 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1181,11 +1224,11 @@ version = "0.0.1"
dependencies = [
"euclid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"regex_macros 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1344,22 +1387,13 @@ dependencies = [
[[package]]
name = "png"
version = "0.1.0"
source = "git+https://github.com/servo/rust-png#b8c2bf074719e5a39b9e4423989f5f06fa79317d"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"png-sys 1.6.16 (git+https://github.com/servo/rust-png)",
"serde 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "png-sys"
version = "1.6.16"
source = "git+https://github.com/servo/rust-png#b8c2bf074719e5a39b9e4423989f5f06fa79317d"
dependencies = [
"libz-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1962,11 +1996,11 @@ name = "webdriver_server"
version = "0.0.1"
dependencies = [
"hyper 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
"png 0.1.0 (git+https://github.com/servo/rust-png)",
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -16,6 +16,9 @@ test = false
doc = false
bench = false
[dev-dependencies]
image = "0.3.14"
[dev-dependencies.gfx_tests]
path = "../../tests/unit/gfx"
@ -36,10 +39,6 @@ name = "reftest"
path = "../../tests/reftest.rs"
harness = false
[dependencies.png]
git = "https://github.com/servo/rust-png"
features = [ "serde-serialization" ]
[features]
default = ["glutin_app", "window", "webdriver"]
window = ["glutin_app/window"]

View file

@ -19,10 +19,6 @@ path = "../util"
[dependencies.webdriver]
git = "https://github.com/jgraham/webdriver-rust.git"
[dependencies.png]
git = "https://github.com/servo/rust-png"
features = [ "serde-serialization" ]
[dependencies.ipc-channel]
git = "https://github.com/pcwalton/ipc-channel"
@ -31,6 +27,7 @@ version = "0.2"
features = [ "serde_serialization" ]
[dependencies]
image = "0.3.14"
log = "0.3"
hyper = "0.6"
rustc-serialize = "0.3.4"

View file

@ -11,9 +11,9 @@
#[macro_use]
extern crate log;
extern crate hyper;
extern crate image;
extern crate ipc_channel;
extern crate msg;
extern crate png;
extern crate regex;
extern crate rustc_serialize;
extern crate url;
@ -22,10 +22,11 @@ extern crate uuid;
extern crate webdriver;
use hyper::method::Method::{self, Post};
use image::{DynamicImage, ImageFormat, RgbImage};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{ConstellationChan, FrameId, LoadData, PipelineId};
use msg::constellation_msg::{NavigationDirection, WebDriverCommandMsg};
use msg::constellation_msg::{NavigationDirection, PixelFormat, WebDriverCommandMsg};
use msg::webdriver_msg::{LoadStatus, WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverScriptCommand};
use regex::Captures;
use rustc_serialize::base64::{CharacterSet, Config, Newline, ToBase64};
@ -615,24 +616,26 @@ impl Handler {
sleep_ms(interval)
}
let mut img = match img {
let img = match img {
Some(img) => img,
None => return Err(WebDriverError::new(ErrorStatus::Timeout,
"Taking screenshot timed out")),
};
let img_vec = match png::to_vec(&mut img) {
Ok(x) => x,
Err(_) => return Err(WebDriverError::new(ErrorStatus::UnknownError,
"Taking screenshot failed"))
};
// The compositor always sends RGB pixels.
assert!(img.format == PixelFormat::RGB8, "Unexpected screenshot pixel format");
let rgb = RgbImage::from_raw(img.width, img.height, img.bytes.to_vec()).unwrap();
let mut png_data = Vec::new();
DynamicImage::ImageRgb8(rgb).save(&mut png_data, ImageFormat::PNG).unwrap();
let config = Config {
char_set: CharacterSet::Standard,
newline: Newline::LF,
pad: true,
line_length: None
};
let encoded = img_vec.to_base64(config);
let encoded = png_data.to_base64(config);
Ok(WebDriverResponse::Generic(ValueResponse::new(encoded.to_json())))
}