Skip to content

Commit

Permalink
Image: Bind loadFrom* and create* methods directly, update API
Browse files Browse the repository at this point in the history
  • Loading branch information
crumblingstatue committed Oct 18, 2024
1 parent eb85bfa commit 3c437ca
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 122 deletions.
65 changes: 17 additions & 48 deletions CSFML/src/Graphics/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,36 @@
#include <SFML/Graphics/Image.hpp>
#include <cstddef>

extern "C" sf::Image *sfImage_create(unsigned int width, unsigned int height) {
sf::Image *image = new sf::Image;
image->create(width, height);

return image;
extern "C" sf::Image *sfImage_new() {
return new sf::Image;
}

extern "C" sf::Image *sfImage_createFromColor(unsigned int width, unsigned int height, sfColor color) {
sf::Image *image = new sf::Image;
image->create(width, height, sf::Color(color.r, color.g, color.b, color.a));

return image;
extern "C" sf::Image *sfImage_cpy(const sf::Image *image) {
return new sf::Image(*image);
}

extern "C" sf::Image *sfImage_createFromPixels(unsigned int width, unsigned int height, const uint8_t *data) {
sf::Image *image = new sf::Image;
image->create(width, height, data);

return image;
extern "C" void sfImage_del(sf::Image *image) {
delete image;
}

extern "C" sf::Image *sfImage_createFromFile(const char *filename) {
sf::Image *image = new sf::Image;

if (!image->loadFromFile(filename)) {
delete image;
image = NULL;
}

return image;
extern "C" void sfImage_create_w_h_color(sf::Image *image, unsigned int width, unsigned int height, sfColor color) {
image->create(width, height, sf::Color(color.r, color.g, color.b, color.a));
}

extern "C" sf::Image *sfImage_createFromMemory(const void *data, size_t sizeInBytes) {
sf::Image *image = new sf::Image;

if (!image->loadFromMemory(data, sizeInBytes)) {
delete image;
image = NULL;
}

return image;
extern "C" void sfImage_create_w_h_pixels(sf::Image *image, unsigned int width, unsigned int height, const uint8_t *data) {
image->create(width, height, data);
}

extern "C" sf::Image *sfImage_createFromStream(sfInputStream *stream) {

sf::Image *image = new sf::Image;

if (!image->loadFromStream(*stream)) {
delete image;
image = NULL;
}

return image;
extern "C" bool sfImage_loadFromFile(sf::Image *image, const char *filename) {
return image->loadFromFile(filename);
}

extern "C" sf::Image *sfImage_copy(const sf::Image *image) {
return new sf::Image(*image);
extern "C" bool sfImage_loadFromMemory(sf::Image *image, const uint8_t *data, size_t sizeInBytes) {
return image->loadFromMemory(data, sizeInBytes);
}

extern "C" void sfImage_destroy(sf::Image *image) {
delete image;
extern "C" bool sfImage_loadFromStream(sf::Image *image, sfInputStream *stream) {
return image->loadFromStream(*stream);
}

extern "C" bool sfImage_saveToFile(const sf::Image *image, const char *filename) {
Expand All @@ -76,7 +45,7 @@ extern "C" void sfImage_createMaskFromColor(sf::Image *image, sfColor colorKey,
image->createMaskFromColor(sf::Color(colorKey.r, colorKey.g, colorKey.b, colorKey.a), alpha);
}

extern "C" void sfImage_copyImage(sf::Image *image, const sf::Image *source, unsigned int destX, unsigned int destY, sfIntRect sourceRect, bool applyAlpha) {
extern "C" void sfImage_copy(sf::Image *image, const sf::Image *source, unsigned int destX, unsigned int destY, sfIntRect sourceRect, bool applyAlpha) {
sf::IntRect sfmlRect(sourceRect.left, sourceRect.top, sourceRect.width, sourceRect.height);
image->copy(*source, destX, destY, sfmlRect, applyAlpha);
}
Expand Down
18 changes: 9 additions & 9 deletions src/ffi/graphics_bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,17 @@ pub fn sfFont_isSmooth(font: *const sfFont) -> bool;
pub fn sfFont_setSmooth(font: *mut sfFont, smooth: bool);
pub fn sfFont_getInfo(font: *const sfFont) -> sfFontInfo;
// Image.cpp
pub fn sfImage_create(width: c_uint, height: c_uint) -> *mut sfImage;
pub fn sfImage_createFromColor(width: c_uint, height: c_uint, color: sfColor) -> *mut sfImage;
pub fn sfImage_createFromPixels(width: c_uint, height: c_uint, data: *const u8) -> *mut sfImage;
pub fn sfImage_createFromFile(filename: *const c_char) -> *mut sfImage;
pub fn sfImage_createFromMemory(data: *const c_void, sizeInBytes: usize) -> *mut sfImage;
pub fn sfImage_createFromStream(stream: *mut sfInputStream) -> *mut sfImage;
pub fn sfImage_copy(image: *const sfImage) -> *mut sfImage;
pub fn sfImage_destroy(image: *mut sfImage);
pub fn sfImage_new() -> *mut sfImage;
pub fn sfImage_cpy(image: *const sfImage) -> *mut sfImage;
pub fn sfImage_del(image: *mut sfImage);
pub fn sfImage_create_w_h_color(image: *mut sfImage, width: c_uint, height: c_uint, color: sfColor);
pub fn sfImage_create_w_h_pixels(image: *mut sfImage, width: c_uint, height: c_uint, data: *const u8);
pub fn sfImage_loadFromFile(image: *mut sfImage, filename: *const c_char) -> bool;
pub fn sfImage_loadFromMemory(image: *mut sfImage, data: *const u8, sizeInBytes: usize) -> bool;
pub fn sfImage_loadFromStream(image: *mut sfImage, stream: *mut sfInputStream) -> bool;
pub fn sfImage_saveToFile(image: *const sfImage, filename: *const c_char) -> bool;
pub fn sfImage_createMaskFromColor(image: *mut sfImage, colorKey: sfColor, alpha: u8);
pub fn sfImage_copyImage(image: *mut sfImage, source: *const sfImage, destX: c_uint, destY: c_uint, sourceRect: sfIntRect, applyAlpha: bool);
pub fn sfImage_copy(image: *mut sfImage, source: *const sfImage, destX: c_uint, destY: c_uint, sourceRect: sfIntRect, applyAlpha: bool);
pub fn sfImage_setPixel(image: *mut sfImage, x: c_uint, y: c_uint, color: sfColor);
pub fn sfImage_getPixel(image: *const sfImage, x: c_uint, y: c_uint) -> sfColor;
pub fn sfImage_getPixelsPtr(image: *const sfImage) -> *const u8;
Expand Down
146 changes: 81 additions & 65 deletions src/graphics/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use {
ffi::graphics as ffi,
graphics::{Color, IntRect},
system::{InputStream, Vector2u},
IntoSfResult, SfBox, SfError, SfResult,
IntoSfResult, SfBox, SfResult,
},
std::{
error::Error,
Expand All @@ -21,86 +21,102 @@ decl_opaque! {

/// Creation and loading
impl Image {
/// Create an image
///
/// This image is filled with black pixels.
/// Create a new (empty) image.
pub fn new() -> SfResult<SfBox<Self>> {
SfBox::new(unsafe { ffi::sfImage_new() }).into_sf_result()
}
/// Create a new `Image` filled with a solid color.
///
/// # Arguments
/// * width - Width of the image
/// * height - Height of the image
pub fn new(width: u32, height: u32) -> SfResult<SfBox<Self>> {
let image = unsafe { ffi::sfImage_create(width, height) };
SfBox::new(image).ok_or(SfError::CallFailed)
/// See [`Self::recreate_solid`].
pub fn new_solid(width: u32, height: u32, color: Color) -> SfResult<SfBox<Self>> {
let mut new = Self::new()?;
new.recreate_solid(width, height, color);
Ok(new)
}

/// Create an image from a custom stream.
/// Create a new `Image` from the provided RGBA pixel data.
///
/// The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic.
/// Some format options are not supported, like progressive jpeg.
/// If this function fails, the image is left unchanged.
/// See [`Self::recreate_from_pixels`].
///
/// # Arguments
/// * stream - Your struct, implementing Read and Seek
pub fn from_stream<T: Read + Seek>(stream: &mut T) -> SfResult<SfBox<Self>> {
let mut input_stream = InputStream::new(stream);
let image = unsafe { ffi::sfImage_createFromStream(&mut *input_stream.stream) };
SfBox::new(image).ok_or(SfError::CallFailed)
/// # Safety
///
/// Also see [`Self::recreate_from_pixels`].
pub unsafe fn from_pixels(width: u32, height: u32, data: &[u8]) -> SfResult<SfBox<Self>> {
let mut new = Self::new()?;
unsafe {
new.recreate_from_pixels(width, height, data);
}
Ok(new)
}

/// Create an image from a file in memory
/// Create a new `Image` from an image file on the filesystem.
///
/// The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic.
/// Some format options are not supported, like progressive jpeg.
/// If this function fails, the image is left unchanged.
/// See [`Self::load_from_file`].
pub fn from_file(filename: &str) -> SfResult<SfBox<Self>> {
let mut new = Self::new()?;
new.load_from_file(filename)?;
Ok(new)
}
/// Create a new `Image` from image file data in memory.
///
/// # Arguments
/// * mem - Pointer to the file data in memory
pub fn from_memory(mem: &[u8]) -> SfResult<SfBox<Self>> {
let image = unsafe { ffi::sfImage_createFromMemory(mem.as_ptr().cast(), mem.len()) };
SfBox::new(image).ok_or(SfError::CallFailed)
/// See [`Self::load_from_memory`].
pub fn from_memory(data: &[u8]) -> SfResult<SfBox<Self>> {
let mut new = Self::new()?;
new.load_from_memory(data)?;
Ok(new)
}

/// Create an image and fill it with a unique color
/// Create a new `Image` from a stream.
///
/// # Arguments
/// * width - Width of the image
/// * height - Height of the image
/// * color - Fill color
pub fn from_color(width: u32, height: u32, color: Color) -> SfResult<SfBox<Self>> {
let image = unsafe { ffi::sfImage_createFromColor(width, height, color) };
SfBox::new(image).ok_or(SfError::CallFailed)
/// See [`Self::load_from_stream`].
pub fn from_stream<T: Read + Seek>(stream: &mut T) -> SfResult<SfBox<Self>> {
let mut new = Self::new()?;
new.load_from_stream(stream)?;
Ok(new)
}

/// Create an image from a file on disk
/// Recreate with the given size, filled with a solid color.
pub fn recreate_solid(&mut self, width: u32, height: u32, color: Color) {
unsafe {
ffi::sfImage_create_w_h_color(self, width, height, color);
}
}
/// Recreate from the provided RGBA pixel data.
///
/// # Safety
///
/// `data` is assumed to contain 32-bit RGBA pixels, and match the given size.
pub unsafe fn recreate_from_pixels(&mut self, width: u32, height: u32, data: &[u8]) {
unsafe {
ffi::sfImage_create_w_h_pixels(self, width, height, data.as_ptr());
}
}
/// Load from image file data on the filesystem.
///
/// The supported image formats are bmp, png, tga, jpg, gif,
/// psd, hdr and pic. Some format options are not supported,
/// like progressive jpeg.
/// If this function fails, the image is left unchanged.
///
/// # Arguments
/// * filename - Path of the image file to load
pub fn from_file(filename: &str) -> SfResult<SfBox<Self>> {
let c_filename = CString::new(filename).into_sf_result()?;
let image = unsafe { ffi::sfImage_createFromFile(c_filename.as_ptr()) };
SfBox::new(image).ok_or(SfError::CallFailed)
pub fn load_from_file(&mut self, path: &str) -> SfResult<()> {
let c_path = CString::new(path).into_sf_result()?;
unsafe { ffi::sfImage_loadFromFile(self, c_path.as_ptr()) }.into_sf_result()
}

/// Create an image from an vector of pixels
/// Load from image file data in memory.
///
/// # Arguments
/// * width - Width of the image
/// * height - Height of the image
/// * pixels - Vector of pixels to copy to the image
/// The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic.
/// Some format options are not supported, like progressive jpeg.
/// If this function fails, the image is left unchanged.
///
/// # Safety
/// # Arguments
/// * mem - Pointer to the file data in memory
pub fn load_from_memory(&mut self, data: &[u8]) -> SfResult<()> {
unsafe { ffi::sfImage_loadFromMemory(self, data.as_ptr(), data.len()) }.into_sf_result()
}
/// Load from image file data coming from a custom stream.
///
/// The pixel vector is assumed to contain 32-bits RGBA pixels,
/// and have the given width and height. If not, this is
/// an undefined behaviour.
pub unsafe fn from_pixels(width: u32, height: u32, pixels: &[u8]) -> SfResult<SfBox<Self>> {
let image = unsafe { ffi::sfImage_createFromPixels(width, height, pixels.as_ptr()) };
SfBox::new(image).ok_or(SfError::CallFailed)
/// The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic.
/// Some format options are not supported, like progressive jpeg.
/// If this function fails, the image is left unchanged.
pub fn load_from_stream<T: Read + Seek>(&mut self, stream: &mut T) -> SfResult<()> {
let mut input_stream = InputStream::new(stream);
unsafe { ffi::sfImage_loadFromStream(self, &mut *input_stream.stream) }.into_sf_result()?;
Ok(())
}
}

Expand Down Expand Up @@ -250,7 +266,7 @@ impl Image {
source_rect: IntRect,
apply_alpha: bool,
) {
unsafe { ffi::sfImage_copyImage(self, source, dest_x, dest_y, source_rect, apply_alpha) }
unsafe { ffi::sfImage_copy(self, source, dest_x, dest_y, source_rect, apply_alpha) }
}
}

Expand Down Expand Up @@ -285,7 +301,7 @@ impl ToOwned for Image {
type Owned = SfBox<Self>;

fn to_owned(&self) -> Self::Owned {
let ptr = unsafe { ffi::sfImage_copy(self) };
let ptr = unsafe { ffi::sfImage_cpy(self) };
match SfBox::new(ptr) {
Some(new) => new,
None => panic!("Failed to copy image"),
Expand All @@ -296,7 +312,7 @@ impl ToOwned for Image {
impl Drop for Image {
fn drop(&mut self) {
unsafe {
ffi::sfImage_destroy(self);
ffi::sfImage_del(self);
}
}
}
Expand Down

0 comments on commit 3c437ca

Please sign in to comment.