#![cfg_attr(feature = "cargo-clippy", allow(needless_borrow))]
#![allow(non_upper_case_globals)]
use crate::ChunkRef;
use crate::rustimpl::*;
use crate::huffman;
use std::ptr;
use std::mem;
use std::slice;
use std::fmt;
use std::os::raw::*;
use std::ffi::CStr;
use std::path::*;
use crate::rustimpl;
macro_rules! lode_error {
($e:expr) => {
if let Err(e) = $e {
e
} else {
Error(0)
}
}
}
macro_rules! lode_try {
($e:expr) => {{
match $e {
Err(e) => return e,
Ok(o) => o,
}
}}
}
macro_rules! lode_try_state {
($state:expr, $e:expr) => {{
match $e {
Err(err) => {
$state = err;
return err;
},
Ok(ok) => {
$state = Error(0);
ok
}
}
}}
}
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(pub c_uint);
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ColorType {
GREY = 0,
RGB = 2,
PALETTE = 3,
GREY_ALPHA = 4,
RGBA = 6,
BGRA = 6|64,
BGR = 2|64,
BGRX = 3|64,
}
#[repr(C)]
#[derive(Debug)]
pub struct ColorMode {
pub colortype: ColorType,
pub(crate) bitdepth: c_uint,
pub(crate) palette: *mut RGBA,
pub(crate) palettesize: usize,
pub(crate) key_defined: c_uint,
pub(crate) key_r: c_uint,
pub(crate) key_g: c_uint,
pub(crate) key_b: c_uint,
}
pub type custom_compress_callback = Option<unsafe extern "C" fn(arg1: &mut *mut c_uchar, arg2: &mut usize, arg3: *const c_uchar, arg4: usize, arg5: *const CompressSettings) -> c_uint>;
pub type custom_decompress_callback = Option<unsafe extern "C" fn(arg1: *mut *mut c_uchar, arg2: *mut usize, arg3: *const c_uchar, arg4: usize, arg5: *const DecompressSettings) -> c_uint>;
#[repr(C)]
#[derive(Clone, Debug)]
pub struct DecompressSettings {
pub(crate) ignore_adler32: c_uint,
pub(crate) custom_zlib: custom_decompress_callback,
pub(crate) custom_inflate: custom_decompress_callback,
pub(crate) custom_context: *const c_void,
}
#[repr(C)]
#[derive(Clone)]
pub struct CompressSettings {
pub btype: c_uint,
pub use_lz77: c_uint,
pub windowsize: c_uint,
pub minmatch: c_uint,
pub nicematch: c_uint,
pub lazymatching: c_uint,
pub custom_zlib: custom_compress_callback,
pub custom_deflate: custom_compress_callback,
pub custom_context: *const c_void,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct Time {
pub year: c_uint,
pub month: c_uint,
pub day: c_uint,
pub hour: c_uint,
pub minute: c_uint,
pub second: c_uint,
}
#[repr(C)]
#[derive(Debug)]
pub struct Info {
pub compression_method: c_uint,
pub filter_method: c_uint,
pub interlace_method: c_uint,
pub color: ColorMode,
pub background_defined: c_uint,
pub background_r: c_uint,
pub background_g: c_uint,
pub background_b: c_uint,
pub(crate) text_num: usize,
pub(crate) text_keys: *mut *mut c_char,
pub(crate) text_strings: *mut *mut c_char,
pub(crate) itext_num: usize,
pub(crate) itext_keys: *mut *mut c_char,
pub(crate) itext_langtags: *mut *mut c_char,
pub(crate) itext_transkeys: *mut *mut c_char,
pub(crate) itext_strings: *mut *mut c_char,
pub time_defined: c_uint,
pub time: Time,
pub phys_defined: c_uint,
pub phys_x: c_uint,
pub phys_y: c_uint,
pub phys_unit: c_uint,
pub unknown_chunks_data: [*mut c_uchar; 3],
pub unknown_chunks_size: [usize; 3],
}
#[repr(C)]
#[derive(Clone, Debug)]
pub struct DecoderSettings {
pub zlibsettings: DecompressSettings,
pub ignore_crc: c_uint,
pub color_convert: c_uint,
pub read_text_chunks: c_uint,
pub remember_unknown_chunks: c_uint,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum FilterStrategy {
ZERO = 0,
MINSUM,
ENTROPY,
BRUTE_FORCE,
PREDEFINED,
}
#[repr(C)]
#[derive(Clone, Debug)]
pub struct EncoderSettings {
pub zlibsettings: CompressSettings,
pub auto_convert: c_uint,
pub filter_palette_zero: c_uint,
pub filter_strategy: FilterStrategy,
pub(crate) predefined_filters: *const u8,
pub force_palette: c_uint,
pub add_id: c_uint,
pub text_compression: c_uint,
}
#[repr(C)]
#[derive(Clone, Debug)]
pub struct State {
pub decoder: DecoderSettings,
pub encoder: EncoderSettings,
pub info_raw: ColorMode,
pub info_png: Info,
pub error: Error,
}
#[repr(C)]
pub struct ColorProfile {
pub colored: c_uint,
pub key: c_uint,
pub key_r: u16,
pub key_g: u16,
pub key_b: u16,
pub alpha: c_uint,
pub numcolors: c_uint,
pub palette: [crate::RGBA; 256],
pub bits: c_uint,
}
impl fmt::Debug for ColorProfile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ColorProfile")
.field("colored", &self.colored)
.field("key", &self.key)
.field("key_r", &self.key_r)
.field("key_g", &self.key_g)
.field("key_b", &self.key_b)
.field("alpha", &self.alpha)
.field("numcolors", &self.numcolors)
.field("bits", &self.bits)
.finish()
}
}
impl fmt::Debug for CompressSettings {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("CompressSettings")
}
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_malloc(size: usize) -> *mut c_void {
rustimpl::lodepng_malloc(size)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_realloc(ptr: *mut c_void, size: usize) -> *mut c_void {
rustimpl::lodepng_realloc(ptr, size)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_free(ptr: *mut c_void) {
rustimpl::lodepng_free(ptr)
}
#[no_mangle]
#[allow(deprecated)]
pub unsafe extern "C" fn lodepng_state_init(state: *mut State) {
ptr::write(state, State::new())
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_state_cleanup(state: &mut State) {
let mut hack = mem::zeroed();
ptr::swap(&mut hack, state);
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_state_copy(dest: *mut State, source: &State) -> Error {
ptr::write(dest, source.clone());
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_error_text(code: Error) -> *const u8 {
code.c_description().as_ptr()
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode32(out: &mut *mut u8, outsize: &mut usize, image: *const u8, w: c_uint, h: c_uint) -> Error {
to_vec(out, outsize, rustimpl::lodepng_encode_memory(slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, ColorType::RGBA, 8))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode24(out: &mut *mut u8, outsize: &mut usize, image: *const u8, w: c_uint, h: c_uint) -> Error {
to_vec(out, outsize, rustimpl::lodepng_encode_memory(slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, ColorType::RGB, 8))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode_file(filename: *const c_char, image: *const u8, w: c_uint, h: c_uint, colortype: ColorType, bitdepth: c_uint) -> Error {
lode_error!(rustimpl::lodepng_encode_file(&c_path(filename), slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, colortype, bitdepth))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode32_file(filename: *const c_char, image: *const u8, w: c_uint, h: c_uint) -> Error {
lode_error!(rustimpl::lodepng_encode_file(&c_path(filename), slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, ColorType::RGBA, 8))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode24_file(filename: *const c_char, image: *const u8, w: c_uint, h: c_uint) -> Error {
lode_error!(rustimpl::lodepng_encode_file(&c_path(filename), slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, ColorType::RGB, 8))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_get_bpp_lct(colortype: ColorType, bitdepth: c_uint) -> c_uint {
rustimpl::lodepng_get_bpp_lct(colortype, bitdepth)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_get_bpp(info: &ColorMode) -> c_uint {
info.bpp()
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_get_channels(info: &ColorMode) -> c_uint {
c_uint::from(info.channels())
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_is_greyscale_type(info: &ColorMode) -> c_uint {
info.is_greyscale_type() as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_is_alpha_type(info: &ColorMode) -> c_uint {
info.is_alpha_type() as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_is_palette_type(info: &ColorMode) -> c_uint {
info.is_palette_type() as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_has_palette_alpha(info: &ColorMode) -> c_uint {
info.has_palette_alpha() as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_can_have_alpha(info: &ColorMode) -> c_uint {
info.can_have_alpha() as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_get_raw_size(w: c_uint, h: c_uint, color: &ColorMode) -> usize {
color.raw_size(w, h)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_get_raw_size_lct(w: c_uint, h: c_uint, colortype: ColorType, bitdepth: c_uint) -> usize {
rustimpl::lodepng_get_raw_size_lct(w, h, colortype, bitdepth)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_huffman_code_lengths(lengths: *mut c_uint, frequencies: *const c_uint, numcodes: usize, maxbitlen: c_uint) -> Error {
let l = lode_try!(huffman::huffman_code_lengths(slice::from_raw_parts(frequencies, numcodes), maxbitlen));
slice::from_raw_parts_mut(lengths, numcodes).clone_from_slice(&l);
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_palette_clear(info: &mut ColorMode) {
info.palette_clear()
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_palette_add(info: &mut ColorMode, r: u8, g: u8, b: u8, a: u8) -> Error {
lode_error!(info.palette_add(RGBA{r, g, b, a}))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_clear_text(info: &mut Info) {
info.clear_text()
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_add_text(info: &mut Info, key: *const c_char, str: *const c_char) -> Error {
let k = lode_try!(CStr::from_ptr(key).to_str().map_err(|_| Error(89)));
let s = lode_try!(CStr::from_ptr(str).to_str().map_err(|_| Error(89)));
lode_error!(info.add_text(k, s))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_clear_itext(info: &mut Info) {
info.clear_itext();
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_add_itext(info: &mut Info, key: *const c_char, langtag: *const c_char, transkey: *const c_char, str: *const c_char) -> Error {
let k = CStr::from_ptr(key);
let l = CStr::from_ptr(langtag);
let t = CStr::from_ptr(transkey);
let s = CStr::from_ptr(str);
lode_error!(info.push_itext(k.to_bytes(), l.to_bytes(), t.to_bytes(), s.to_bytes()))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_create(out: &mut *mut u8, outsize: &mut usize, length: c_uint, type_: *const [u8; 4], data: *const u8) -> Error {
let mut v = vec_from_raw(*out, *outsize);
let err = lode_error!(rustimpl::add_chunk(&mut v, type_.as_ref().unwrap(), slice::from_raw_parts(data, length as usize)));
let (data, size) = lode_try!(vec_into_raw(v));
*out = data;
*outsize = size;
err
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_length(chunk: *const u8) -> c_uint {
rustimpl::lodepng_chunk_length(slice::from_raw_parts(chunk, 12)) as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_type(type_: &mut [u8; 5], chunk: *const u8) {
let ch = ChunkRef::from_ptr(chunk).unwrap();
let t = ch.name();
type_[0..4].clone_from_slice(&t);
type_[4] = 0;
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_type_equals(chunk: *const u8, name: &[u8; 4]) -> u8 {
if name.iter().any(|&t| t == 0) {
return 0;
}
let ch = ChunkRef::from_ptr(chunk).unwrap();
(name == &ch.name()) as u8
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_data_const(chunk: *const u8) -> *const u8 {
ChunkRef::from_ptr(chunk).unwrap().data().as_ptr()
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_next(chunk: *mut u8) -> *mut u8 {
let len = lodepng_chunk_length(chunk) as usize;
chunk.add(len + 12)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_next_const(chunk: *const u8) -> *const u8 {
let len = lodepng_chunk_length(chunk) as usize;
chunk.add(len + 12)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_ancillary(chunk: *const u8) -> u8 {
ChunkRef::from_ptr(chunk).unwrap().is_ancillary() as u8
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_private(chunk: *const u8) -> u8 {
ChunkRef::from_ptr(chunk).unwrap().is_private() as u8
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_safetocopy(chunk: *const u8) -> u8 {
ChunkRef::from_ptr(chunk).unwrap().is_safe_to_copy() as u8
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_data(chunk_data: *mut u8) -> *mut u8 {
chunk_data.add(8)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_check_crc(chunk: *const u8) -> c_uint {
ChunkRef::from_ptr(chunk).unwrap().check_crc() as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_generate_crc(chunk: *mut u8) {
rustimpl::lodepng_chunk_generate_crc(slice::from_raw_parts_mut(chunk, 0x7FFF_FFFF))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_chunk_append(out: &mut *mut u8, outsize: &mut usize, chunk: *const u8) -> Error {
let mut v = vec_from_raw(*out, *outsize);
rustimpl::chunk_append(&mut v, slice::from_raw_parts(chunk, 0x7FFF_FFFF));
let (data, size) = lode_try!(vec_into_raw(v));
*out = data;
*outsize = size;
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_color_mode_init(info: *mut ColorMode) {
ptr::write(info, ColorMode::new());
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_color_mode_cleanup(info: &mut ColorMode) {
let mut hack = mem::zeroed();
ptr::swap(&mut hack, info);
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_color_mode_equal(a: &ColorMode, b: &ColorMode) -> c_uint {
rustimpl::lodepng_color_mode_equal(a, b) as c_uint
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_color_mode_copy(dest: *mut ColorMode, source: &ColorMode) -> Error {
ptr::write(dest, source.clone());
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_inflate(out: &mut *mut u8, outsize: &mut usize, inp: *const u8, insize: usize, settings: &DecompressSettings) -> Error {
to_vec(out, outsize, rustimpl::lodepng_inflatev(slice::from_raw_parts(inp, insize), settings))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_deflate(out: &mut *mut u8, outsize: &mut usize, inp: *const u8, insize: usize, settings: &CompressSettings) -> Error {
to_vec(out, outsize, rustimpl::lodepng_deflatev(slice::from_raw_parts(inp, insize), settings))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_zlib_decompress(out: &mut *mut u8, outsize: &mut usize, inp: *const u8, insize: usize, settings: &DecompressSettings) -> Error {
to_vec(out, outsize, rustimpl::lodepng_zlib_decompress(slice::from_raw_parts(inp, insize), settings))
}
#[no_mangle]
pub unsafe extern "C" fn zlib_decompress(out: &mut *mut u8, outsize: &mut usize, inp: *const u8, insize: usize, settings: &DecompressSettings) -> Error {
to_vec(out, outsize, rustimpl::zlib_decompress(slice::from_raw_parts(inp, insize), settings))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_zlib_compress(out: &mut *mut u8, outsize: &mut usize, inp: *const u8, insize: usize, settings: &CompressSettings) -> Error {
let mut v = vec_from_raw(*out, *outsize);
let err = lode_error!(rustimpl::lodepng_zlib_compress(&mut v, slice::from_raw_parts(inp, insize), settings));
let (data, size) = lode_try!(vec_into_raw(v));
*out = data;
*outsize = size;
err
}
#[no_mangle]
pub unsafe extern "C" fn zlib_compress(out: &mut *mut u8, outsize: &mut usize, inp: *const u8, insize: usize, settings: &CompressSettings) -> Error {
to_vec(out, outsize, rustimpl::zlib_compress(slice::from_raw_parts(inp, insize), settings))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_compress_settings_init(settings: *mut CompressSettings) {
ptr::write(settings, CompressSettings::new());
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decompress_settings_init(settings: *mut DecompressSettings) {
ptr::write(settings, DecompressSettings::new());
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_crc32(data: *const u8, length: usize) -> c_uint {
rustimpl::lodepng_crc32(slice::from_raw_parts(data, length))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_info_init(info: *mut Info) {
ptr::write(info, Info::new());
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_info_cleanup(info: &mut Info) {
let mut hack = mem::zeroed();
ptr::swap(&mut hack, info);
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_info_copy(dest: *mut Info, source: &Info) -> Error {
ptr::write(dest, source.clone());
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_info_swap(a: &mut Info, b: &mut Info) {
mem::swap(a, b)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_convert(out: *mut u8, image: *const u8, mode_out: &ColorMode, mode_in: &ColorMode, w: c_uint, h: c_uint) -> Error {
lode_error!(rustimpl::lodepng_convert(slice::from_raw_parts_mut(out, 0x1FFF_FFFF), slice::from_raw_parts(image, 0x1FFF_FFFF), mode_out, mode_in, w, h))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_inspect(w_out: &mut c_uint, h_out: &mut c_uint, state: &mut State, inp: *const u8, insize: usize) -> Error {
if inp.is_null() {
return Error(48);
}
let (info, w, h) = lode_try_state!(state.error, rustimpl::lodepng_inspect(&state.decoder, slice::from_raw_parts(inp, insize), false));
state.info_png = info;
*w_out = w as c_uint;
*h_out = h as c_uint;
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode(out: &mut *mut u8, w_out: &mut c_uint, h_out: &mut c_uint, state: &mut State, inp: *const u8, insize: usize) -> Error {
if inp.is_null() || insize == 0 {
return Error(48);
}
*out = ptr::null_mut();
let (v, w, h) = lode_try_state!(state.error, rustimpl::lodepng_decode(state, slice::from_raw_parts(inp, insize)));
*w_out = w as u32;
*h_out = h as u32;
let (data, _) = lode_try!(vec_into_raw(v));
*out = data;
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode_memory(out: &mut *mut u8, w_out: &mut c_uint, h_out: &mut c_uint, inp: *const u8, insize: usize, colortype: ColorType, bitdepth: c_uint) -> Error {
if inp.is_null() || insize == 0 {
return Error(48);
}
*out = ptr::null_mut();
let (v, w, h) = lode_try!(rustimpl::lodepng_decode_memory(slice::from_raw_parts(inp, insize), colortype, bitdepth));
*w_out = w as u32;
*h_out = h as u32;
let (data, _) = lode_try!(vec_into_raw(v));
*out = data;
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode32(out: &mut *mut u8, w: &mut c_uint, h: &mut c_uint, inp: *const u8, insize: usize) -> Error {
lodepng_decode_memory(out, w, h, inp, insize, ColorType::RGBA, 8)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode24(out: &mut *mut u8, w: &mut c_uint, h: &mut c_uint, inp: *const u8, insize: usize) -> Error {
lodepng_decode_memory(out, w, h, inp, insize, ColorType::RGB, 8)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode_file(out: &mut *mut u8, w_out: &mut c_uint, h_out: &mut c_uint, filename: *const c_char, colortype: ColorType, bitdepth: c_uint) -> Error {
*out = ptr::null_mut();
let (v, w, h) = lode_try!(rustimpl::lodepng_decode_file(&c_path(filename), colortype, bitdepth));
*w_out = w as u32;
*h_out = h as u32;
let (data, _) = lode_try!(vec_into_raw(v));
*out = data;
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode32_file(out: &mut *mut u8, w: &mut c_uint, h: &mut c_uint, filename: *const c_char) -> Error {
lodepng_decode_file(out, w, h, filename, ColorType::RGBA, 8)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decode24_file(out: &mut *mut u8, w: &mut c_uint, h: &mut c_uint, filename: *const c_char) -> Error {
lodepng_decode_file(out, w, h, filename, ColorType::RGB, 8)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_decoder_settings_init(settings: *mut DecoderSettings) {
ptr::write(settings, DecoderSettings::new());
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_buffer_file(out: *mut u8, size: usize, filename: *const c_char) -> Error {
lode_error!(rustimpl::lodepng_buffer_file(slice::from_raw_parts_mut(out, size), &c_path(filename)))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_load_file(out: &mut *mut u8, outsize: &mut usize, filename: *const c_char) -> Error {
to_vec(out, outsize, rustimpl::lodepng_load_file(&c_path(filename)))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_save_file(buffer: *const u8, buffersize: usize, filename: *const c_char) -> Error {
lode_error!(rustimpl::lodepng_save_file(slice::from_raw_parts(buffer, buffersize), &c_path(filename)))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode(out: &mut *mut u8, outsize: &mut usize, image: *const u8, w: c_uint, h: c_uint, state: &mut State) -> Error {
*out = ptr::null_mut();
*outsize = 0;
let res = lode_try_state!(state.error, rustimpl::lodepng_encode(slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, state));
let (data, size) = lode_try!(vec_into_raw(res));
*out = data;
*outsize = size;
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_get_color_profile(profile_out: *mut ColorProfile, image: *const u8, w: c_uint, h: c_uint, mode: &ColorMode) -> Error {
let prof = lode_try!(rustimpl::get_color_profile(slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, mode));
ptr::write(profile_out, prof);
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_auto_choose_color(mode_out: &mut ColorMode, image: *const u8, w: c_uint, h: c_uint, mode_in: &ColorMode) -> Error {
let mode = lode_try!(rustimpl::auto_choose_color(slice::from_raw_parts(image, 0x1FFF_FFFF), w as usize, h as usize, mode_in));
ptr::write(mode_out, mode);
Error(0)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_filesize(filename: *const c_char) -> c_long {
rustimpl::lodepng_filesize(&c_path(filename))
.map_or(-1, |l| l as c_long)
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encode_memory(out: &mut *mut u8, outsize: &mut usize, image: *const u8, w: c_uint, h: c_uint, colortype: ColorType, bitdepth: c_uint) -> Error {
to_vec(out, outsize, rustimpl::lodepng_encode_memory(slice::from_raw_parts(image, 0x1FFF_FFFF), w, h, colortype, bitdepth))
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_encoder_settings_init(settings: *mut EncoderSettings) {
ptr::write(settings, EncoderSettings::new());
}
#[no_mangle]
pub unsafe extern "C" fn lodepng_color_profile_init(prof: *mut ColorProfile) {
ptr::write(prof, ColorProfile::new());
}
#[no_mangle]
pub static lodepng_default_compress_settings: CompressSettings = CompressSettings {
btype: 2,
use_lz77: 1,
windowsize: DEFAULT_WINDOWSIZE as u32,
minmatch: 3,
nicematch: 128,
lazymatching: 1,
custom_zlib: None,
custom_deflate: None,
custom_context: 0usize as *mut _,
};
#[no_mangle]
pub static lodepng_default_decompress_settings: DecompressSettings = DecompressSettings {
ignore_adler32: 0,
custom_zlib: None,
custom_inflate: None,
custom_context: 0usize as *mut _,
};
#[cfg(unix)]
unsafe fn c_path<'meh>(filename: *const c_char) -> &'meh Path {
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
assert!(!filename.is_null());
let tmp = CStr::from_ptr(filename);
Path::new(OsStr::from_bytes(tmp.to_bytes()))
}
#[cfg(not(unix))]
unsafe fn c_path(filename: *const c_char) -> PathBuf {
let tmp = CStr::from_ptr(filename);
tmp.to_string_lossy().to_string().into()
}
unsafe fn to_vec(out: &mut *mut u8, outsize: &mut usize, result: Result<Vec<u8>, Error>) -> Error {
match result.and_then(vec_into_raw) {
Ok((data, len)) => {
*out = data;
*outsize = len;
Error(0)
},
Err(err) => {
*out = ptr::null_mut();
*outsize = 0;
err
},
}
}