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 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(super) inner: *mut xlib::XImage,
|
||||
}
|
||||
|
@ -29,20 +26,6 @@ pub enum ImageByteOrder {
|
|||
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 {
|
||||
/// Get the size (in bytes) of the data buffer.
|
||||
pub fn get_size(&self) -> usize {
|
||||
|
@ -64,7 +47,7 @@ impl Image {
|
|||
unsafe { (*self.inner).depth as u32 }
|
||||
}
|
||||
|
||||
/// Get byte order
|
||||
/// Get byte order (LSB or MSB)
|
||||
pub fn get_byte_order(&self) -> Result<ImageByteOrder> {
|
||||
let byte_order = unsafe { (*self.inner).byte_order };
|
||||
match byte_order {
|
||||
|
@ -81,7 +64,7 @@ impl Image {
|
|||
(red_mask, blue_mask, green_mask)
|
||||
}
|
||||
|
||||
/// Produces a PixBuffer
|
||||
/// Produces a PixBuffer.
|
||||
pub fn buffer(&self) -> PixBuffer {
|
||||
let size = self.get_size();
|
||||
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> {
|
||||
/// Gets the byte at the index of the data buffer.
|
||||
pub fn get_byte(&self, index: usize) -> Option<u8> {
|
||||
if index > self.size {
|
||||
return None;
|
||||
}
|
||||
Some(unsafe { *self.buf.offset(index as isize) as u8 })
|
||||
/// Retrieve a direct reference to the internal buffer.
|
||||
pub fn get_buffer(&self) -> &[u8] {
|
||||
unsafe { std::slice::from_raw_parts(self.buf, self.size) }
|
||||
}
|
||||
|
||||
/// 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)> {
|
||||
// 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 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 green_mask = unsafe { (*self.image.inner).green_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 green = ((pixel & unsafe { (*self.image.inner).green_mask }) >> 8) as u8;
|
||||
let blue = ((pixel & unsafe { (*self.image.inner).blue_mask }) >> 0) as u8;
|
||||
// warn!("rgb: {:?}", (red, green, blue));
|
||||
|
||||
let red = ((pixel & red_mask) >> 16) as u8;
|
||||
let green = ((pixel & green_mask) >> 8) as u8;
|
||||
let blue = ((pixel & blue_mask) >> 0) as u8;
|
||||
|
||||
Some((red, green, blue))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,6 @@ pub use self::cursor::Cursor;
|
|||
pub use self::display::{Display, GetDisplay};
|
||||
pub use self::drawable::Drawable;
|
||||
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::window::{EventMask, Window};
|
||||
|
|
Loading…
Reference in a new issue