Merge pull request #26 from HsuJv/dev

init webrdp & webssh
This commit is contained in:
Jovi Hsu 2022-10-10 13:15:24 +08:00 committed by GitHub
commit 8fd1cce0fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 569 additions and 35 deletions

View File

@ -6,12 +6,16 @@ dependencies = ["websockify", "wasm-release"]
[tasks.wasm-debug]
script = '''
cd ${VNC} && cargo make install-debug
cd ${VNC} && cargo make install-debug && cd ..
cd ${RDP} && cargo make install-debug && cd ..
cd ${SSH} && cargo make install-debug && cd ..
'''
[tasks.wasm-release]
script = '''
cd ${VNC} && cargo make install-release
cd ${VNC} && cargo make install-release && cd ..
cd ${RDP} && cargo make install-release && cd ..
cd ${SSH} && cargo make install-release && cd ..
'''
@ -24,10 +28,12 @@ cd ${WEBSOCKIFY} && cargo build --release && cp ./target/release/${WEBSOCKIFY} $
[tasks.install-dir]
script = '''
mkdir -p $INSTALL_PATH
cp asserts/* $INSTALL_PATH
cp assets/* $INSTALL_PATH
'''
[env]
INSTALL_PATH= "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/build"
WEBSOCKIFY="axum-websockify"
VNC="webvnc"
VNC="webvnc"
RDP="webrdp"
SSH="webssh"

11
webrdp/.appveyor.yml Normal file
View File

@ -0,0 +1,11 @@
install:
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --locked

6
webrdp/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/target
**/*.rs.bk
Cargo.lock
bin/
pkg/
wasm-pack.log

69
webrdp/.travis.yml Normal file
View File

@ -0,0 +1,69 @@
language: rust
sudo: false
cache: cargo
matrix:
include:
# Builds with wasm-pack.
- rust: beta
env: RUST_BACKTRACE=1
addons:
firefox: latest
chrome: stable
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
script:
- cargo generate --git . --name testing
# Having a broken Cargo.toml (in that it has curlies in fields) anywhere
# in any of our parent dirs is problematic.
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- wasm-pack build
- wasm-pack test --chrome --firefox --headless
# Builds on nightly.
- rust: nightly
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
- cargo check --no-default-features --features "console_error_panic_hook wee_alloc"
- cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc"
# Builds on beta.
- rust: beta
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
# Note: no enabling the `wee_alloc` feature here because it requires
# nightly for now.

32
webrdp/Cargo.toml Normal file
View File

@ -0,0 +1,32 @@
[package]
name = "webrdp"
version = "0.1.0"
authors = ["Jovi Hsu <jv.hsu@outlook.com>"]
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
wasm-bindgen = "0.2.63"
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.6", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
wee_alloc = { version = "0.4.5", optional = true }
[dev-dependencies]
wasm-bindgen-test = "0.3.13"
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"

25
webrdp/Makefile.toml Normal file
View File

@ -0,0 +1,25 @@
[tasks.build-debug]
command = "wasm-pack"
args = ["build", "--target", "web", "--out-name", "webrdp", "--out-dir", "./pkg", "--dev"]
[tasks.build-release]
command = "wasm-pack"
args = ["build", "--target", "web", "--out-name", "webrdp", "--out-dir", "./pkg"]
[tasks.install-debug]
dependencies=["build-debug", "install_wasm", "install_html"]
[tasks.install-release]
dependencies=["build-release", "install_wasm", "install_html"]
[tasks.install_wasm]
script = '''
mkdir -p $INSTALL_PATH
cp ./pkg/webrdp.js $INSTALL_PATH
cp ./pkg/webrdp_bg.wasm $INSTALL_PATH
'''
[tasks.install_html]
script = '''
cp assets/* $INSTALL_PATH
'''

95
webrdp/assets/rdp.html Normal file
View File

@ -0,0 +1,95 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Web Gateway</title>
<style type="text/css">
.horizontal-centre {
position: relative;
text-align: center;
}
.vertical-centre {
position: relative;
vertical-align: middle;
}
html,
body {
height: 100%;
margin: 0;
}
</style>
<style>
@import url("clipboard.css");
</style>
<script src="jquery-3.6.1.min.js" type="text/javascript"></script>
<script type="module" defer>
import init from "/webrdp.js";
await init();
</script>
</head>
<body>
<div id="vnc_status" style="position: relative; height: auto;" class="horizontal-centre vertical-centre"></div>
<div id="canvas" class="horizontal-centre vertical-centre">
<canvas id="vnc-canvas" tabIndex=1></canvas>
<button type="button" id="ctrlaltdel" style="display: inline; position:absolute; right: 10px; top: 10px;">Send
CtrlAltDel</button>
</div>
<div class="clipboardback">
<div class="clipboard">
<button id="clipboardbtn">clipboard</button>
<div id="clipboardbox" class="horizontal-centre vertical-centre">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div><textarea id="clipboardtxt" rows="30"></textarea></div>
<div><button id="clipboardsend">Send</button></div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript" defer>
$("#clipboardbtn").attr("open1", 0);
$("#clipboardbtn").click(
function (e) {
e.stopPropagation();
if (($("#clipboardbtn")).attr("open1") == 0) {
open();
} else {
close();
}
}
);
$(".clipboardback").click(function () {
close();
})
$(".clipboard").click(function () {
event.stopPropagation();
})
function open() {
$("#clipboardbtn").attr("open1", 1);
$("#clipboardbtn").html(">")
$(".clipboard").toggleClass("clipboard-open");
$(".clipboardback").toggleClass("clipboardback-open");
$(".clipboardback").css("pointer-events", "auto");
}
function close() {
$("#clipboardbtn").attr("open1", 0);
$("#clipboardbtn").html("clipboard")
$(".clipboard").toggleClass("clipboard-open");
$(".clipboardback").toggleClass("clipboardback-open");
$(".clipboardback").css("pointer-events", "none");
}
function setClipBoard(s) {
$("#clipboardtxt").val(s);
}
function getClipBoard() {
return $("#clipboardtxt").val();
}
</script>

24
webrdp/src/lib.rs Normal file
View File

@ -0,0 +1,24 @@
mod utils;
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
fn start_websocket() -> Result<(), JsValue> {
Ok(())
}
#[wasm_bindgen(start)]
pub fn run_app() -> Result<(), JsValue> {
utils::set_panic_hook();
start_websocket()
}

10
webrdp/src/utils.rs Normal file
View File

@ -0,0 +1,10 @@
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}

13
webrdp/tests/web.rs Normal file
View File

@ -0,0 +1,13 @@
//! Test suite for the Web and headless browsers.
#![cfg(target_arch = "wasm32")]
extern crate wasm_bindgen_test;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn pass() {
assert_eq!(1 + 1, 2);
}

11
webssh/.appveyor.yml Normal file
View File

@ -0,0 +1,11 @@
install:
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --locked

6
webssh/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/target
**/*.rs.bk
Cargo.lock
bin/
pkg/
wasm-pack.log

69
webssh/.travis.yml Normal file
View File

@ -0,0 +1,69 @@
language: rust
sudo: false
cache: cargo
matrix:
include:
# Builds with wasm-pack.
- rust: beta
env: RUST_BACKTRACE=1
addons:
firefox: latest
chrome: stable
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
script:
- cargo generate --git . --name testing
# Having a broken Cargo.toml (in that it has curlies in fields) anywhere
# in any of our parent dirs is problematic.
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- wasm-pack build
- wasm-pack test --chrome --firefox --headless
# Builds on nightly.
- rust: nightly
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
- cargo check --no-default-features --features "console_error_panic_hook wee_alloc"
- cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc"
# Builds on beta.
- rust: beta
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
# Note: no enabling the `wee_alloc` feature here because it requires
# nightly for now.

32
webssh/Cargo.toml Normal file
View File

@ -0,0 +1,32 @@
[package]
name = "webssh"
version = "0.1.0"
authors = ["Jovi Hsu <jv.hsu@outlook.com>"]
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
wasm-bindgen = "0.2.63"
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.6", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
wee_alloc = { version = "0.4.5", optional = true }
[dev-dependencies]
wasm-bindgen-test = "0.3.13"
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"

25
webssh/Makefile.toml Normal file
View File

@ -0,0 +1,25 @@
[tasks.build-debug]
command = "wasm-pack"
args = ["build", "--target", "web", "--out-name", "webssh", "--out-dir", "./pkg", "--dev"]
[tasks.build-release]
command = "wasm-pack"
args = ["build", "--target", "web", "--out-name", "webssh", "--out-dir", "./pkg"]
[tasks.install-debug]
dependencies=["build-debug", "install_wasm", "install_html"]
[tasks.install-release]
dependencies=["build-release", "install_wasm", "install_html"]
[tasks.install_wasm]
script = '''
mkdir -p $INSTALL_PATH
cp ./pkg/webssh.js $INSTALL_PATH
cp ./pkg/webssh_bg.wasm $INSTALL_PATH
'''
[tasks.install_html]
script = '''
cp assets/* $INSTALL_PATH
'''

32
webssh/assets/ssh.html Normal file
View File

@ -0,0 +1,32 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Web Gateway</title>
<style type="text/css">
.horizontal-centre {
position: relative;
text-align: center;
}
.vertical-centre {
position: relative;
vertical-align: middle;
}
html,
body {
height: 100%;
margin: 0;
}
</style>
<script src="jquery-3.6.1.min.js" type="text/javascript"></script>
<script type="module" defer>
import init from "/webssh.js";
await init();
</script>
</head>
<body>
</body>

24
webssh/src/lib.rs Normal file
View File

@ -0,0 +1,24 @@
mod utils;
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
fn start_websocket() -> Result<(), JsValue> {
Ok(())
}
#[wasm_bindgen(start)]
pub fn run_app() -> Result<(), JsValue> {
utils::set_panic_hook();
start_websocket()
}

10
webssh/src/utils.rs Normal file
View File

@ -0,0 +1,10 @@
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}

13
webssh/tests/web.rs Normal file
View File

@ -0,0 +1,13 @@
//! Test suite for the Web and headless browsers.
#![cfg(target_arch = "wasm32")]
extern crate wasm_bindgen_test;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn pass() {
assert_eq!(1 + 1, 2);
}

View File

@ -21,5 +21,5 @@ script = '''
[tasks.install_html]
script = '''
cp asserts/* $INSTALL_PATH
cp assets/* $INSTALL_PATH
'''

View File

@ -2,7 +2,7 @@ use std::rc::Rc;
use crate::{
console_log, log,
vnc::{ImageData, MouseEventType, Vnc},
vnc::{ImageData, ImageType, MouseEventType, Vnc},
};
use wasm_bindgen::prelude::*;
use wasm_bindgen::{Clamped, JsCast};
@ -162,7 +162,7 @@ impl Canvas {
fn draw(&self, ri: &ImageData) {
match ri.type_ {
1 => {
ImageType::Copy => {
//copy
let sx = (ri.data[0] as u16) << 8 | ri.data[1] as u16;
let sy = (ri.data[2] as u16) << 8 | ri.data[3] as u16;
@ -181,7 +181,13 @@ impl Canvas {
ri.height as f64,
);
}
_ => {
ImageType::Fill => {
// fill
let (r, g, b) = (ri.data[2], ri.data[1], ri.data[0]);
let style = format!("rgb({},{},{})", r, g, b);
self.ctx.set_fill_style(&JsValue::from_str(&style));
}
ImageType::Raw => {
let data = web_sys::ImageData::new_with_u8_clamped_array_and_sh(
Clamped(&ri.data),
ri.width as u32,

View File

@ -13,7 +13,7 @@ pub enum MouseEventType {
use std::{rc::Rc, sync::Mutex};
pub struct ImageData {
pub type_: u32,
pub type_: ImageType,
pub x: u16,
pub y: u16,
pub width: u16,
@ -21,6 +21,13 @@ pub struct ImageData {
pub data: Vec<u8>,
}
#[allow(dead_code)]
pub enum ImageType {
Raw,
Copy,
Fill,
}
pub enum VncOutput {
WsBuf(Vec<u8>),
Err(String),

View File

@ -37,6 +37,18 @@ pub enum VncEncoding {
DesktopSizePseudo = -223,
}
impl From<u32> for VncEncoding {
fn from(num: u32) -> Self {
unsafe { std::mem::transmute(num) }
}
}
impl From<VncEncoding> for u32 {
fn from(e: VncEncoding) -> Self {
e as u32
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VncState {
Init,
@ -80,12 +92,12 @@ impl Vnc {
Self {
state: VncState::Init,
supported_encodings: vec![
// VncEncoding::Raw,
VncEncoding::ZRLE,
VncEncoding::Raw,
VncEncoding::CopyRect,
// VncEncoding::RRE,
// VncEncoding::Hextile,
// VncEncoding::TRLE,
VncEncoding::ZRLE,
// VncEncoding::CursorPseudo,
// VncEncoding::DesktopSizePseudo,
],
@ -396,7 +408,7 @@ impl Vnc {
VncState::Authing => self.handle_auth_result(),
VncState::ServerInit => self.handle_server_init(),
VncState::Connected => self.handle_server_message(),
_ => unimplemented!(),
VncState::Disconnected => (),
}
}
@ -533,9 +545,8 @@ impl Vnc {
let y = self.read_u16();
let width = self.read_u16();
let height = self.read_u16();
let encoding_type = self.read_u32();
let encoding_enum = unsafe { std::mem::transmute(encoding_type) };
match encoding_enum {
let encoding_type = self.read_u32().into();
match encoding_type {
VncEncoding::Raw => self.handle_raw_encoding(x, y, width, height),
VncEncoding::CopyRect => self.handle_copy_rect_encoding(x, y, width, height),
VncEncoding::RRE => self.handle_rre_encoding(x, y, width, height),
@ -550,21 +561,18 @@ impl Vnc {
}
}
} else {
match self.padding_rect.as_ref().unwrap().encoding_type {
16 => {
if self.require == 4 {
self.require = self.read_u32() as usize;
return;
}
if let VncEncoding::ZRLE = self.padding_rect.as_ref().unwrap().encoding_type {
if self.require == 4 {
self.require = self.read_u32() as usize;
return;
}
_ => (),
}
// we now have an entire rectangle
let rect = self.padding_rect.take().unwrap();
let mut image_data: Vec<u8> = Vec::with_capacity(self.require);
self.read_exact_vec(&mut image_data, self.require);
match rect.encoding_type {
0 => {
VncEncoding::Raw => {
// raw
let mut y = 0;
let mut x = 0;
@ -579,7 +587,7 @@ impl Vnc {
y += 1;
}
self.outs.push(VncOutput::RenderImage(ImageData {
type_: rect.encoding_type,
type_: ImageType::Raw,
x: rect.x,
y: rect.y,
width: rect.width,
@ -587,10 +595,10 @@ impl Vnc {
data: image_data,
}));
}
1 => {
VncEncoding::CopyRect => {
// copy rectangle
self.outs.push(VncOutput::RenderImage(ImageData {
type_: rect.encoding_type,
type_: ImageType::Copy,
x: rect.x,
y: rect.y,
width: rect.width,
@ -598,7 +606,7 @@ impl Vnc {
data: image_data,
}));
}
16 => {
VncEncoding::ZRLE => {
// ZRLE
match self.zlib_decoder.decode(&self.pf, &rect, &image_data) {
Ok(images) => {
@ -607,11 +615,11 @@ impl Vnc {
}
}
Err(e) => {
self.outs.push(VncOutput::Err(format!("{:?}", e)));
self.disconnect_with_err(&format!("{:?}", e));
}
}
}
_ => unimplemented!("Unknow encoding {}", rect.encoding_type),
_ => unimplemented!("Unknow encoding {}", rect.encoding_type as u32),
}
self.num_rect_left -= 1;
if 0 == self.num_rect_left {
@ -697,7 +705,7 @@ impl Vnc {
y,
width,
height,
encoding_type: 0,
encoding_type: VncEncoding::Raw,
});
}
@ -709,7 +717,7 @@ impl Vnc {
y,
width,
height,
encoding_type: 1,
encoding_type: VncEncoding::CopyRect,
});
}
@ -737,7 +745,7 @@ impl Vnc {
y,
width,
height,
encoding_type: 16,
encoding_type: VncEncoding::ZRLE,
})
}
@ -848,5 +856,5 @@ pub struct VncRect {
pub y: u16,
pub width: u16,
pub height: u16,
pub encoding_type: u32,
pub encoding_type: VncEncoding,
}

View File

@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE.
*/
use super::vnc_impl::*;
use super::ImageData;
use super::{ImageData, ImageType};
use byteorder::ReadBytesExt;
use std::io::{Read, Result};
@ -330,7 +330,7 @@ impl Decoder {
width,
x: rect.x + x,
y: rect.y + y,
type_: 0,
type_: ImageType::Raw,
});
x += width;
}