1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use libc::c_void;
use std::ops;
use super::ffi;
use super::{Resource};
use super::ppb;
use ppb::ImageDataIf;
#[derive(Hash, Eq, PartialEq, Show)] pub struct ImageData(ffi::PP_Resource);
impl_resource_for!(ImageData, ResourceType::ImageDataRes);
#[derive(Eq, PartialEq, Hash, Clone, Copy)]
pub enum Format {
BGRA = ffi::PP_IMAGEDATAFORMAT_BGRA_PREMUL as int,
RGBA = ffi::PP_IMAGEDATAFORMAT_RGBA_PREMUL as int,
}
impl Format {
fn from_ffi(v: ffi::PP_ImageDataFormat) -> Format {
match v {
ffi::PP_IMAGEDATAFORMAT_BGRA_PREMUL => Format::BGRA,
ffi::PP_IMAGEDATAFORMAT_RGBA_PREMUL => Format::RGBA,
_ => panic!(),
}
}
pub fn to_ffi(&self) -> ffi::PP_ImageDataFormat {
match *self {
Format::BGRA => ffi::PP_IMAGEDATAFORMAT_BGRA_PREMUL,
Format::RGBA => ffi::PP_IMAGEDATAFORMAT_RGBA_PREMUL,
}
}
pub fn is_supported(&self) -> bool {
let ffi_val = *self as ffi::PP_ImageDataFormat;
(ppb::get_image_data().IsImageDataFormatSupported.unwrap())(ffi_val) != 0
}
}
#[derive(Clone, Copy)]
pub struct Description {
pub format: Format,
pub size: super::Size,
pub line_stride: u32,
}
impl Description {
pub fn from_ffi(desc: ffi::Struct_PP_ImageDataDesc) -> Description {
use core::mem::transmute;
Description {
format: Format::from_ffi(desc.format),
size: unsafe { transmute(desc.size) },
line_stride: desc.stride as u32,
}
}
}
pub struct MappedImage<'a> {
img: &'a ImageData,
pub desc: Description,
ptr: *mut c_void,
}
pub trait MappedSlice<'a> {
fn as_imm_slice(&self) -> &'a [u8];
}
impl<'a> MappedSlice<'a> for MappedImage<'a> {
fn as_imm_slice(&self) -> &'a [u8] {
use std::slice::from_raw_buf;
use std::mem::transmute;
let size = (self.desc.size.height * self.desc.line_stride) as usize;
unsafe { from_raw_buf(transmute(&self.ptr), size) }
}
}
#[unsafe_destructor]
impl<'a> ops::Drop for MappedImage<'a> {
fn drop(&mut self) {
ppb::get_image_data().unmap(&self.img.unwrap());
}
}
pub fn native_image_data_format() -> Format {
Format::from_ffi(ppb::get_image_data().native_image_data_format())
}
impl ImageData {
pub fn describe(&self) -> Option<Description> {
ppb::get_image_data()
.describe(self.unwrap())
.map(|desc| Description::from_ffi(desc) )
}
pub fn map<'a>(&'a self) -> MappedImage<'a> {
MappedImage {
img: self,
desc: self.describe().unwrap(),
ptr: ppb::get_image_data().map(&self.unwrap()),
}
}
}