Add libqoi
helper crate that wraps qoi.h
This commit is contained in:
parent
50d268cd14
commit
81bd8abdbe
6 changed files with 95 additions and 1 deletions
|
@ -26,7 +26,7 @@ reference = [] # follows reference encoder implementation precisely, but may be
|
|||
bytemuck = "1.7"
|
||||
|
||||
[workspace]
|
||||
members = ["bench"]
|
||||
members = ["libqoi", "bench"]
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0"
|
||||
|
|
16
libqoi/Cargo.toml
Normal file
16
libqoi/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "libqoi"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
authors = ["Ivan Smirnov <rust@ivan.smirnov.ie>"]
|
||||
description = "Bindings to the original qoi.h (for test purposes only)"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
c_vec = "2.0"
|
||||
libc = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
2
libqoi/README.md
Normal file
2
libqoi/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
This crate provides direct bindings around the original `qoi.h`,
|
||||
and is only used for testing and benchmarking purposes.
|
18
libqoi/build.rs
Normal file
18
libqoi/build.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let out_src = out_dir.join("qoi.c");
|
||||
fs::write(&out_src, "#include \"qoi.h\"\n").unwrap();
|
||||
|
||||
cc::Build::new()
|
||||
.file(&out_src)
|
||||
.include("../ext/qoi")
|
||||
.define("QOI_NO_STDIO", None)
|
||||
.define("QOI_IMPLEMENTATION", None)
|
||||
.flag("-Wno-unsequenced")
|
||||
.opt_level(3)
|
||||
.compile("qoi");
|
||||
}
|
57
libqoi/src/lib.rs
Normal file
57
libqoi/src/lib.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use anyhow::{ensure, Result};
|
||||
use c_vec::CVec;
|
||||
use libc::{c_int, c_void};
|
||||
|
||||
mod ffi {
|
||||
use libc::{c_int, c_uchar, c_uint, c_void};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
#[repr(C)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct qoi_desc {
|
||||
pub width: c_uint,
|
||||
pub height: c_uint,
|
||||
pub channels: c_uchar,
|
||||
pub colorspace: c_uchar,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn qoi_encode(
|
||||
data: *const c_void, desc: *const qoi_desc, out_len: *mut c_int,
|
||||
) -> *mut c_void;
|
||||
pub fn qoi_decode(
|
||||
data: *const c_void, size: c_int, desc: *mut qoi_desc, channels: c_int,
|
||||
) -> *mut c_void;
|
||||
}
|
||||
}
|
||||
|
||||
pub use ffi::qoi_desc;
|
||||
|
||||
pub fn qoi_encode(data: &[u8], width: u32, height: u32, channels: u8) -> Result<CVec<u8>> {
|
||||
let desc =
|
||||
qoi_desc { width: width as _, height: height as _, channels: channels as _, colorspace: 0 };
|
||||
let mut out_len: c_int = 0;
|
||||
let out_ptr =
|
||||
unsafe { ffi::qoi_encode(data.as_ptr().cast(), &desc as *const _, &mut out_len as *mut _) };
|
||||
ensure!(!out_ptr.is_null(), "qoi.h: qoi_encode() returned null pointer");
|
||||
ensure!(out_len > 0, "qoi.h: qoi_encode() returned non-positive out_len");
|
||||
let vec = unsafe {
|
||||
CVec::new_with_dtor(out_ptr.cast::<u8>(), out_len as _, |p| libc::free(p.cast::<c_void>()))
|
||||
};
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
pub fn qoi_decode(data: &[u8], channels: u8) -> Result<(qoi_desc, CVec<u8>)> {
|
||||
let mut desc = qoi_desc::default();
|
||||
let out_ptr = unsafe {
|
||||
ffi::qoi_decode(data.as_ptr() as _, data.len() as _, &mut desc as *mut _, channels as _)
|
||||
};
|
||||
ensure!(!out_ptr.is_null(), "qoi.h: qoi_decode() returned null pointer");
|
||||
let out_len = (desc.width as usize)
|
||||
.saturating_mul(desc.height as usize)
|
||||
.saturating_mul(channels as usize);
|
||||
let vec = unsafe {
|
||||
CVec::new_with_dtor(out_ptr.cast::<u8>(), out_len, |p| libc::free(p.cast::<c_void>()))
|
||||
};
|
||||
Ok((desc, vec))
|
||||
}
|
1
libqoi/src/qoi.c
Normal file
1
libqoi/src/qoi.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "qoi.h"
|
Loading…
Reference in a new issue