update
This commit is contained in:
parent
5cf99dda34
commit
1b17246d8d
2 changed files with 42 additions and 50 deletions
|
@ -1,22 +1,19 @@
|
||||||
//! XImage
|
|
||||||
//! ======
|
|
||||||
//!
|
|
||||||
//! Xlib provides some structures to perform operations on images. However, because there are
|
|
||||||
//! different in-memory representations, working with images is actually totally fucked. If you
|
|
||||||
//! want to maintain your sanity, do NOT pry into the raw data buffer of an Image. Instead, index
|
|
||||||
//! into the image using `PixBuffer::get_pixel` which already performs the conversion and returns a
|
|
||||||
//! tuple of RGB values.
|
|
||||||
//!
|
|
||||||
//! Peeking into the raw data buffer of an Image
|
|
||||||
//! --------------------------------------------
|
|
||||||
//!
|
|
||||||
//! Images consist of lines of longs in row-major form.
|
|
||||||
|
|
||||||
use x11::xlib;
|
use x11::xlib;
|
||||||
|
|
||||||
use crate::errors::{Error, Result};
|
use crate::errors::{Error, Result};
|
||||||
|
|
||||||
/// A handle to an XImage.
|
/// A handle to an XImage
|
||||||
|
///
|
||||||
|
/// Xlib provides some structures to perform operations on images. However, because there are
|
||||||
|
/// different in-memory representations, working with images is actually totally fucked. If you
|
||||||
|
/// want to maintain your sanity, do NOT pry into the raw data buffer of an Image. Instead, index
|
||||||
|
/// into the image using `PixBuffer::get_pixel` which already performs the conversion and returns a
|
||||||
|
/// tuple of RGB values.
|
||||||
|
///
|
||||||
|
/// Peeking into the raw data buffer of an Image
|
||||||
|
/// --------------------------------------------
|
||||||
|
///
|
||||||
|
/// Images consist of lines of longs in row-major form.
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
pub(super) inner: *mut xlib::XImage,
|
pub(super) inner: *mut xlib::XImage,
|
||||||
}
|
}
|
||||||
|
@ -29,20 +26,6 @@ pub enum ImageByteOrder {
|
||||||
MSBFirst,
|
MSBFirst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The buffer pointed to by an XImage.
|
|
||||||
pub struct PixBuffer<'a> {
|
|
||||||
/// The raw pointer to the buffer
|
|
||||||
pub buf: *mut u8,
|
|
||||||
|
|
||||||
/// The size of the buffer
|
|
||||||
pub size: usize,
|
|
||||||
|
|
||||||
/// Rgb masks
|
|
||||||
pub masks: (u64, u64, u64),
|
|
||||||
|
|
||||||
pub image: &'a Image,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
/// Get the size (in bytes) of the data buffer.
|
/// Get the size (in bytes) of the data buffer.
|
||||||
pub fn get_size(&self) -> usize {
|
pub fn get_size(&self) -> usize {
|
||||||
|
@ -64,7 +47,7 @@ impl Image {
|
||||||
unsafe { (*self.inner).depth as u32 }
|
unsafe { (*self.inner).depth as u32 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get byte order
|
/// Get byte order (LSB or MSB)
|
||||||
pub fn get_byte_order(&self) -> Result<ImageByteOrder> {
|
pub fn get_byte_order(&self) -> Result<ImageByteOrder> {
|
||||||
let byte_order = unsafe { (*self.inner).byte_order };
|
let byte_order = unsafe { (*self.inner).byte_order };
|
||||||
match byte_order {
|
match byte_order {
|
||||||
|
@ -81,7 +64,7 @@ impl Image {
|
||||||
(red_mask, blue_mask, green_mask)
|
(red_mask, blue_mask, green_mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produces a PixBuffer
|
/// Produces a PixBuffer.
|
||||||
pub fn buffer(&self) -> PixBuffer {
|
pub fn buffer(&self) -> PixBuffer {
|
||||||
let size = self.get_size();
|
let size = self.get_size();
|
||||||
let buf = unsafe { (*self.inner).data as *mut u8 };
|
let buf = unsafe { (*self.inner).data as *mut u8 };
|
||||||
|
@ -101,34 +84,43 @@ impl Drop for Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The buffer pointed to by an XImage.
|
||||||
|
pub struct PixBuffer<'a> {
|
||||||
|
/// The raw pointer to the buffer
|
||||||
|
pub buf: *mut u8,
|
||||||
|
|
||||||
|
/// The size of the buffer
|
||||||
|
pub size: usize,
|
||||||
|
|
||||||
|
/// Rgb masks
|
||||||
|
pub masks: (u64, u64, u64),
|
||||||
|
|
||||||
|
pub image: &'a Image,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> PixBuffer<'a> {
|
impl<'a> PixBuffer<'a> {
|
||||||
/// Gets the byte at the index of the data buffer.
|
/// Retrieve a direct reference to the internal buffer.
|
||||||
pub fn get_byte(&self, index: usize) -> Option<u8> {
|
pub fn get_buffer(&self) -> &[u8] {
|
||||||
if index > self.size {
|
unsafe { std::slice::from_raw_parts(self.buf, self.size) }
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(unsafe { *self.buf.offset(index as isize) as u8 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the rgb value of a particular pixel
|
/// Gets the rgb value of a particular pixel, after performing conversion
|
||||||
|
///
|
||||||
|
/// This uses XImage's get_pixel function to retrieve the pixel value, and then the various
|
||||||
|
/// red/green/blue masks to actually perform the conversions, and fails (returns `None`) if the
|
||||||
|
/// (x, y) coordinates given aren't actually in the image.
|
||||||
pub fn get_pixel(&self, x: u32, y: u32) -> Option<(u8, u8, u8)> {
|
pub fn get_pixel(&self, x: u32, y: u32) -> Option<(u8, u8, u8)> {
|
||||||
// let bytes_per_line = unsafe{(*self.image.inner).bytes_per_line} as u32;
|
|
||||||
// let bits_per_pixel=unsafe{(*self.image.inner).bits_per_pixel} as u32;
|
|
||||||
// let pixel_ptr = (y * bytes_per_line + x * bits_per_pixel) / 8;
|
|
||||||
// let pixel = unsafe{*((*self.image.inner).data.offset(pixel_ptr as isize) as *mut c_ulong)};
|
|
||||||
|
|
||||||
let get_pixel = unsafe { (*self.image.inner).funcs.get_pixel }.unwrap();
|
let get_pixel = unsafe { (*self.image.inner).funcs.get_pixel }.unwrap();
|
||||||
let pixel = unsafe { get_pixel(self.image.inner, x as i32, y as i32) };
|
let pixel = unsafe { get_pixel(self.image.inner, x as i32, y as i32) };
|
||||||
|
|
||||||
// warn!("pixel: {:?} {:#b}", pixel, pixel);
|
|
||||||
let red_mask = unsafe { (*self.image.inner).red_mask };
|
let red_mask = unsafe { (*self.image.inner).red_mask };
|
||||||
let green_mask = unsafe { (*self.image.inner).green_mask };
|
let green_mask = unsafe { (*self.image.inner).green_mask };
|
||||||
let blue_mask = unsafe { (*self.image.inner).blue_mask };
|
let blue_mask = unsafe { (*self.image.inner).blue_mask };
|
||||||
// warn!("masks: {:b} {:b} {:b}", red_mask, green_mask, blue_mask);
|
|
||||||
let red = ((pixel & unsafe { (*self.image.inner).red_mask }) >> 16) as u8;
|
let red = ((pixel & red_mask) >> 16) as u8;
|
||||||
let green = ((pixel & unsafe { (*self.image.inner).green_mask }) >> 8) as u8;
|
let green = ((pixel & green_mask) >> 8) as u8;
|
||||||
let blue = ((pixel & unsafe { (*self.image.inner).blue_mask }) >> 0) as u8;
|
let blue = ((pixel & blue_mask) >> 0) as u8;
|
||||||
// warn!("rgb: {:?}", (red, green, blue));
|
|
||||||
Some((red, green, blue))
|
Some((red, green, blue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,6 @@ pub use self::cursor::Cursor;
|
||||||
pub use self::display::{Display, GetDisplay};
|
pub use self::display::{Display, GetDisplay};
|
||||||
pub use self::drawable::Drawable;
|
pub use self::drawable::Drawable;
|
||||||
pub use self::event::{Event, EventKind};
|
pub use self::event::{Event, EventKind};
|
||||||
pub use self::image::{Image, ImageByteOrder};
|
pub use self::image::{Image, ImageByteOrder, PixBuffer};
|
||||||
pub use self::visual::Visual;
|
pub use self::visual::Visual;
|
||||||
pub use self::window::{EventMask, Window};
|
pub use self::window::{EventMask, Window};
|
||||||
|
|
Loading…
Reference in a new issue