forked from kornelski/pngquant
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrwpng_cocoa.rs
57 lines (51 loc) · 1.63 KB
/
rwpng_cocoa.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use libc::{FILE, fileno, malloc};
use std::fs::File;
use std::io::prelude::*;
use std::os::unix::io::FromRawFd;
use cocoa_image;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
#[allow(non_camel_case_types)]
pub enum pngquant_error {
SUCCESS = 0,
MISSING_ARGUMENT = 1,
READ_ERROR = 2,
INVALID_ARGUMENT = 4,
NOT_OVERWRITING_ERROR = 15,
CANT_WRITE_ERROR = 16,
OUT_OF_MEMORY_ERROR = 17,
WRONG_ARCHITECTURE = 18, // Missing SSE
PNG_OUT_OF_MEMORY_ERROR = 24,
LIBPNG_FATAL_ERROR = 25,
WRONG_INPUT_COLOR_TYPE = 26,
LIBPNG_INIT_ERROR = 35,
TOO_LARGE_FILE = 98,
TOO_LOW_QUALITY = 99,
}
#[no_mangle]
pub extern "C" fn rwpng_read_image32_cocoa(file_handle: *mut FILE, width: &mut u32, height: &mut u32, file_size: &mut usize, out: &mut *mut cocoa_image::RGBA8) -> pngquant_error {
let mut file = unsafe {
File::from_raw_fd(fileno(file_handle))
};
let mut data = Vec::new();
match file.read_to_end(&mut data) {
Ok(_) => {},
Err(_) => return pngquant_error::READ_ERROR,
};
let image = match cocoa_image::decode_image_as_rgba(&data) {
Ok(img) => img,
Err(_) => return pngquant_error::LIBPNG_FATAL_ERROR,
};
*file_size = data.len();
*width = image.width() as u32;
*height = image.height() as u32;
unsafe {
*out = malloc(image.buf.len() * ::std::mem::size_of::<cocoa_image::RGBA8>()) as *mut _;
if (*out).is_null() {
return pngquant_error::OUT_OF_MEMORY_ERROR;
}
::std::slice::from_raw_parts_mut((*out), image.buf.len()).clone_from_slice(&image.buf);
}
pngquant_error::SUCCESS
}