1use std::io::{Cursor,Read};
4use std::mem;
5use std::ptr;
6use std::slice;
7use libc::{c_uchar,c_uint,size_t};
8
9use ::{BayerDepth,BayerError,BayerResult,CFA,RasterDepth,RasterMut};
10use demosaic;
11
12pub struct CRasterMut;
14
15macro_rules! printerrorln {
17 ($e:expr) => {{
18 println!("{}:{} - {}", file!(), line!(), $e);
19 }};
20 ($fmt:expr, $arg:tt) => {{
21 print!("{}:{} - ", file!(), line!());
22 println!($fmt, $arg);
23 }};
24}
25
26unsafe fn transmute_raster_mut<'a>(dst: *mut CRasterMut)
27 -> &'a mut RasterMut<'a> {
28 let ptr: *mut RasterMut = mem::transmute(dst);
29 &mut *ptr
30}
31
32fn run_demosaic<F>(file: &'static str, line: u32,
33 run: F,
34 src: *const c_uchar, src_len: size_t,
35 depth: c_uint, be: c_uint, cfa: c_uint,
36 dst: *mut CRasterMut)
37 -> c_uint
38 where F: FnOnce(&mut Read, BayerDepth, CFA, &mut RasterMut) -> BayerResult<()> {
39 if src.is_null() || dst.is_null() {
40 println!("{} {} - bad input parameters", file, line);
41 return 1;
42 }
43
44 let depth = match (depth, be) {
45 (8, _) => BayerDepth::Depth8,
46 (16, 0) => BayerDepth::Depth16LE,
47 (16, _) => BayerDepth::Depth16BE,
48 _ => {
49 println!("{} {} - invalid depth", file, line);
50 return 2;
51 }
52 };
53
54 let cfa = match cfa {
55 0 => CFA::BGGR,
56 1 => CFA::GBRG,
57 2 => CFA::GRBG,
58 3 => CFA::RGGB,
59 _ => {
60 println!("{} {} - invalid cfa", file, line);
61 return 1;
62 }
63 };
64
65 let src_slice = unsafe{ slice::from_raw_parts(src, src_len) };
66 let dst_raster = unsafe{ transmute_raster_mut(dst) };
67
68 match run(&mut Cursor::new(&src_slice[..]), depth, cfa, dst_raster) {
69 Ok(_) => 0,
70 Err(BayerError::WrongResolution) => 2,
71 Err(BayerError::WrongDepth) => 3,
72 Err(_) => 1,
73 }
74}
75
76#[no_mangle]
82pub extern "C" fn bayerrs_demosaic_none(
83 src: *const c_uchar, src_len: size_t,
84 depth: c_uint, be: c_uint, cfa: c_uint,
85 dst: *mut CRasterMut)
86 -> c_uint {
87 run_demosaic(file!(), line!(),
88 demosaic::none::run,
89 src, src_len, depth, be, cfa, dst)
90}
91
92#[no_mangle]
94pub extern "C" fn bayerrs_demosaic_nearest_neighbour(
95 src: *const c_uchar, src_len: size_t,
96 depth: c_uint, be: c_uint, cfa: c_uint,
97 dst: *mut CRasterMut)
98 -> c_uint {
99 run_demosaic(file!(), line!(),
100 demosaic::nearestneighbour::run,
101 src, src_len, depth, be, cfa, dst)
102}
103
104#[no_mangle]
106pub extern "C" fn bayerrs_demosaic_linear(
107 src: *const c_uchar, src_len: size_t,
108 depth: c_uint, be: c_uint, cfa: c_uint,
109 dst: *mut CRasterMut)
110 -> c_uint {
111 run_demosaic(file!(), line!(),
112 demosaic::linear::run,
113 src, src_len, depth, be, cfa, dst)
114}
115
116#[no_mangle]
118pub extern "C" fn bayerrs_demosaic_cubic(
119 src: *const c_uchar, src_len: size_t,
120 depth: c_uint, be: c_uint, cfa: c_uint,
121 dst: *mut CRasterMut)
122 -> c_uint {
123 run_demosaic(file!(), line!(),
124 demosaic::cubic::run,
125 src, src_len, depth, be, cfa, dst)
126}
127
128#[no_mangle]
134pub extern "C" fn bayerrs_raster_mut_alloc(
135 x: size_t, y: size_t, w: size_t, h: size_t, stride: size_t, depth: c_uint,
136 buf: *mut c_uchar, buf_len: size_t)
137 -> *mut CRasterMut {
138 if buf.is_null() {
139 printerrorln!("bad input parameters");
140 return ptr::null_mut();
141 }
142
143 let depth = match depth {
144 8 => RasterDepth::Depth8,
145 16 => RasterDepth::Depth16,
146 _ => {
147 printerrorln!("bad input parameters");
148 return ptr::null_mut();
149 }
150 };
151
152 let buf_slice = unsafe{ slice::from_raw_parts_mut(buf, buf_len) };
153 let raster = RasterMut::with_offset(x, y, w, h, stride, depth, buf_slice);
154 let rptr = Box::into_raw(Box::new(raster));
155 let cptr: *mut CRasterMut = unsafe{ mem::transmute(rptr) };
156 cptr
157}
158
159#[no_mangle]
161pub extern "C" fn bayerrs_raster_mut_free(raster: *mut CRasterMut) {
162 if raster.is_null() {
163 return;
164 }
165
166 let rptr: *mut RasterMut = unsafe{ mem::transmute(raster) };
167 let _raster = unsafe{ Box::from_raw(rptr) };
168}