diff --git a/Makefile.in b/Makefile.in index c49cfb6..d56eb57 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,23 +9,23 @@ RUSTFLAGS := $(filter-out -O,$(RUSTFLAGS)) -L ../libpng --opt-level=3 EXT_DEPS ?= .PHONY: all -all: librustpng.dummy +all: libpng-servo.dummy %.o: %.c $(CC) $< -o $@ -c $(CFLAGS) -librustpng.dummy: lib.rs libshim.a $(EXT_DEPS) - $(RUSTC) $(RUSTFLAGS) $< --out-dir . +libpng-servo.dummy: lib.rs libshim.a $(EXT_DEPS) + $(RUSTC) $(RUSTFLAGS) $< --out-dir . -C extra-filename=-servo touch $@ -rustpng-test: lib.rs libshim.a +png-test: lib.rs libshim.a $(RUSTC) $(RUSTFLAGS) $< -o $@ --test libshim.a: shim.o $(AR) rcs libshim.a shim.o -check: rustpng-test - ./rustpng-test +check: png-test + ./png-test .PHONY: clean clean: diff --git a/ffi.rs b/ffi.rs index f867a63..0b9a90f 100644 --- a/ffi.rs +++ b/ffi.rs @@ -33,48 +33,48 @@ pub static INFO_tRNS: c_int = 0x0010; pub type png_struct = c_void; pub type png_info = c_void; -#[link(name = "png")] +#[link(name = "png", kind = "static")] #[link(name = "z")] -#[link(name = "shim")] +#[link(name = "shim", kind = "static")] extern { // libc routines needed - pub fn setjmp(env: *c_void) -> c_int; + pub fn setjmp(env: *mut c_void) -> c_int; // shim routines - pub fn pngshim_jmpbuf(pnt_ptr: *mut png_struct) -> *c_void; + pub fn pngshim_jmpbuf(pnt_ptr: *mut png_struct) -> *mut c_void; // libpng routines - pub fn png_get_header_ver(png_ptr: *png_struct) -> *c_char; - pub fn png_sig_cmp(sig: *u8, start: size_t, num_to_check: size_t) -> c_int; + pub fn png_get_header_ver(png_ptr: *mut png_struct) -> *mut c_char; + pub fn png_sig_cmp(sig: *const u8, start: size_t, num_to_check: size_t) -> c_int; - pub fn png_create_info_struct(png_ptr: *png_struct) -> *mut png_info; - pub fn png_get_io_ptr(png_ptr: *png_struct) -> *mut c_void; + pub fn png_create_info_struct(png_ptr: *mut png_struct) -> *mut png_info; + pub fn png_get_io_ptr(png_ptr: *mut png_struct) -> *mut c_void; pub fn png_set_sig_bytes(png_ptr: *mut png_struct, num_bytes: c_int); - pub fn png_create_read_struct(user_png_ver: *c_char, error_ptr: *c_void, error_fn: *u8, warn_fn: *u8) -> *mut png_struct; - pub fn png_destroy_read_struct(png_ptr_ptr: **png_struct, info_ptr_ptr: **png_info, end_info_ptr_ptr: **png_info); - pub fn png_set_read_fn(png_ptr: *mut png_struct, io_ptr: *mut c_void, read_data_fn: extern "C" fn(*png_struct, *mut u8, size_t)); + pub fn png_create_read_struct(user_png_ver: *const c_char, error_ptr: *mut c_void, error_fn: *mut u8, warn_fn: *mut u8) -> *mut png_struct; + pub fn png_destroy_read_struct(png_ptr_ptr: *mut *mut png_struct, info_ptr_ptr: *mut *mut png_info, end_info_ptr_ptr: *mut *mut png_info); + pub fn png_set_read_fn(png_ptr: *mut png_struct, io_ptr: *mut c_void, read_data_fn: extern "C" fn(*mut png_struct, *mut u8, size_t)); pub fn png_read_info(png_ptr: *mut png_struct, info_ptr: *mut png_info); pub fn png_read_update_info(png_ptr: *mut png_struct, info_ptr: *mut png_info); - pub fn png_read_image(png_ptr: *mut png_struct, row_pointers: **mut u8); - pub fn png_read_png(png_ptr: *mut png_struct, info_ptr: *mut png_info, transforms: c_int, params: *c_void); - - pub fn png_create_write_struct(user_png_ver: *c_char, error_ptr: *c_void, error_fn: *u8, warn_fn: *u8) -> *mut png_struct; - pub fn png_destroy_write_struct(png_ptr_ptr: **png_struct, info_ptr_ptr: **png_info); - pub fn png_set_write_fn(png_ptr: *mut png_struct, io_ptr: *mut c_void, write_data_fn: extern "C" fn(*png_struct, *u8, size_t), output_flush_ptr: extern "C" fn(*png_struct)); - pub fn png_write_png(pnt_ptr: *mut png_struct, info_ptr: *mut png_info, transforms: c_int, params: *c_void); // ?? - - pub fn png_get_IHDR(png_ptr: *png_struct, info_ptr: *png_info, width: *mut u32, height: *mut u32, bit_depth: *mut c_int, color_type: *mut c_int, interlace_method: *mut c_int, compression_method: *mut c_int, filter_method: *mut c_int) -> u32; - pub fn png_get_pHYs(png_ptr: *png_struct, info_ptr: *png_info, res_x: *mut u32, res_y: *mut u32, unit_type: *mut c_int) -> u32; - pub fn png_get_image_width(png_ptr: *png_struct, info_ptr: *png_info) -> u32; - pub fn png_get_image_height(png_ptr: *png_struct, info_ptr: *png_info) -> u32; - pub fn png_get_bit_depth(png_ptr: *png_struct, info_ptr: *png_info) -> u8; - pub fn png_get_color_type(png_ptr: *png_struct, info_ptr: *png_info) -> u8; - pub fn png_get_rows(png_ptr: *png_struct, info_ptr: *png_info) -> **u8; - - pub fn png_set_IHDR(png_ptr: *png_struct, info_ptr: *mut png_info, width: u32, height: u32, bit_depth: c_int, color_type: c_int, interlace_method: c_int, compression_method: c_int, filter_method: c_int); - pub fn png_set_pHYs(png_ptr: *png_struct, info_ptr: *mut png_info, res_x: u32, res_y: u32, unit_type: c_int); - pub fn png_set_rows(png_ptr: *png_struct, info_ptr: *mut png_info, row_pointers: **u8); + pub fn png_read_image(png_ptr: *mut png_struct, row_pointers: *mut *mut u8); + pub fn png_read_png(png_ptr: *mut png_struct, info_ptr: *mut png_info, transforms: c_int, params: *mut c_void); + + pub fn png_create_write_struct(user_png_ver: *const c_char, error_ptr: *mut c_void, error_fn: *mut u8, warn_fn: *mut u8) -> *mut png_struct; + pub fn png_destroy_write_struct(png_ptr_ptr: *mut *mut png_struct, info_ptr_ptr: *mut *mut png_info); + pub fn png_set_write_fn(png_ptr: *mut png_struct, io_ptr: *mut c_void, write_data_fn: extern "C" fn(*mut png_struct, *mut u8, size_t), output_flush_ptr: extern "C" fn(*mut png_struct)); + pub fn png_write_png(pnt_ptr: *mut png_struct, info_ptr: *mut png_info, transforms: c_int, params: *mut c_void); // ?? + + pub fn png_get_IHDR(png_ptr: *mut png_struct, info_ptr: *mut png_info, width: *mut u32, height: *mut u32, bit_depth: *mut c_int, color_type: *mut c_int, interlace_method: *mut c_int, compression_method: *mut c_int, filter_method: *mut c_int) -> u32; + pub fn png_get_pHYs(png_ptr: *mut png_struct, info_ptr: *mut png_info, res_x: *mut u32, res_y: *mut u32, unit_type: *mut c_int) -> u32; + pub fn png_get_image_width(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u32; + pub fn png_get_image_height(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u32; + pub fn png_get_bit_depth(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u8; + pub fn png_get_color_type(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> u8; + pub fn png_get_rows(png_ptr: *mut png_struct, info_ptr: *mut png_info) -> *mut *mut u8; + + pub fn png_set_IHDR(png_ptr: *mut png_struct, info_ptr: *mut png_info, width: u32, height: u32, bit_depth: c_int, color_type: c_int, interlace_method: c_int, compression_method: c_int, filter_method: c_int); + pub fn png_set_pHYs(png_ptr: *mut png_struct, info_ptr: *mut png_info, res_x: u32, res_y: u32, unit_type: c_int); + pub fn png_set_rows(png_ptr: *mut png_struct, info_ptr: *mut png_info, row_pointers: *mut *mut u8); pub fn png_set_packing(png_ptr: *mut png_struct); pub fn png_set_palette_to_rgb(png_ptr: *mut png_struct); diff --git a/lib.rs b/lib.rs index 99f675b..6d01ddc 100644 --- a/lib.rs +++ b/lib.rs @@ -7,9 +7,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![crate_id = "github.com/mozilla-servo/rust-png#png:0.1"] -#![crate_type = "lib"] -#![crate_type = "dylib"] +#![crate_name = "png"] #![crate_type = "rlib"] extern crate libc; @@ -54,7 +52,7 @@ pub fn is_png(image: &[u8]) -> bool { } } -pub extern fn read_data(png_ptr: *ffi::png_struct, data: *mut u8, length: size_t) { +pub extern fn read_data(png_ptr: *mut ffi::png_struct, data: *mut u8, length: size_t) { unsafe { let io_ptr = ffi::png_get_io_ptr(png_ptr); let image_data: &mut ImageData = mem::transmute(io_ptr); @@ -81,24 +79,21 @@ pub fn load_png(path: &Path) -> Result { pub fn load_png_from_memory(image: &[u8]) -> Result { unsafe { - let png_ptr = ffi::png_create_read_struct(ffi::png_get_header_ver(ptr::null()), - ptr::null(), - ptr::null(), - ptr::null()); + let mut png_ptr = ffi::png_create_read_struct(&*ffi::png_get_header_ver(ptr::mut_null()), + ptr::mut_null(), + ptr::mut_null(), + ptr::mut_null()); if png_ptr.is_null() { return Err("could not create read struct".to_string()); } - let info_ptr = ffi::png_create_info_struct(&*png_ptr); + let mut info_ptr = ffi::png_create_info_struct(png_ptr); if info_ptr.is_null() { - let png_ptr: *ffi::png_struct = &*png_ptr; - ffi::png_destroy_read_struct(&png_ptr, ptr::null(), ptr::null()); + ffi::png_destroy_read_struct(&mut png_ptr, ptr::mut_null(), ptr::mut_null()); return Err("could not create info struct".to_string()); } let res = ffi::setjmp(ffi::pngshim_jmpbuf(png_ptr)); if res != 0 { - let png_ptr: *ffi::png_struct = &*png_ptr; - let info_ptr: *ffi::png_info = &*info_ptr; - ffi::png_destroy_read_struct(&png_ptr, &info_ptr, ptr::null()); + ffi::png_destroy_read_struct(&mut png_ptr, &mut info_ptr, ptr::mut_null()); return Err("error reading png".to_string()); } @@ -110,10 +105,10 @@ pub fn load_png_from_memory(image: &[u8]) -> Result { ffi::png_set_read_fn(png_ptr, mem::transmute(&mut image_data), read_data); ffi::png_read_info(png_ptr, info_ptr); - let width = ffi::png_get_image_width(&*png_ptr, &*info_ptr); - let height = ffi::png_get_image_height(&*png_ptr, &*info_ptr); - let bit_depth = ffi::png_get_bit_depth(&*png_ptr, &*info_ptr); - let color_type = ffi::png_get_color_type(&*png_ptr, &*info_ptr); + let width = ffi::png_get_image_width(png_ptr, info_ptr); + let height = ffi::png_get_image_height(png_ptr, info_ptr); + let bit_depth = ffi::png_get_bit_depth(png_ptr, info_ptr); + let color_type = ffi::png_get_color_type(png_ptr, info_ptr); // we convert palette to rgb if color_type as c_int == ffi::COLOR_TYPE_PALETTE { @@ -134,8 +129,8 @@ pub fn load_png_from_memory(image: &[u8]) -> Result { ffi::png_set_interlace_handling(png_ptr); ffi::png_read_update_info(png_ptr, info_ptr); - let updated_bit_depth = ffi::png_get_bit_depth(&*png_ptr, &*info_ptr); - let updated_color_type = ffi::png_get_color_type(&*png_ptr, &*info_ptr); + let updated_bit_depth = ffi::png_get_bit_depth(png_ptr, info_ptr); + let updated_color_type = ffi::png_get_color_type(png_ptr, info_ptr); let (color_type, pixel_width) = match (updated_color_type as c_int, updated_bit_depth) { (ffi::COLOR_TYPE_RGB, 8) | @@ -148,15 +143,13 @@ pub fn load_png_from_memory(image: &[u8]) -> Result { let mut image_data = Vec::from_elem((width * height * pixel_width) as uint, 0u8); let image_buf = image_data.as_mut_ptr(); - let row_pointers: Vec<*mut u8> = Vec::from_fn(height as uint, |idx| { + let mut row_pointers: Vec<*mut u8> = Vec::from_fn(height as uint, |idx| { image_buf.offset((((width * pixel_width) as uint) * idx) as int) }); - ffi::png_read_image(png_ptr, row_pointers.as_ptr()); + ffi::png_read_image(png_ptr, row_pointers.as_mut_ptr()); - let png_ptr: *ffi::png_struct = &*png_ptr; - let info_ptr: *ffi::png_info = &*info_ptr; - ffi::png_destroy_read_struct(&png_ptr, &info_ptr, ptr::null()); + ffi::png_destroy_read_struct(&mut png_ptr, &mut info_ptr, ptr::mut_null()); Ok(Image { width: width, @@ -167,11 +160,11 @@ pub fn load_png_from_memory(image: &[u8]) -> Result { } } -pub extern fn write_data(png_ptr: *ffi::png_struct, data: *u8, length: size_t) { +pub extern fn write_data(png_ptr: *mut ffi::png_struct, data: *mut u8, length: size_t) { unsafe { let io_ptr = ffi::png_get_io_ptr(png_ptr); let writer: &mut &mut io::Writer = mem::transmute(io_ptr); - slice::raw::buf_as_slice(data, length as uint, |buf| { + slice::raw::buf_as_slice(&*data, length as uint, |buf| { match writer.write(buf) { Err(e) => fail!("{}", e.desc), _ => {} @@ -180,7 +173,7 @@ pub extern fn write_data(png_ptr: *ffi::png_struct, data: *u8, length: size_t) { } } -pub extern fn flush_data(png_ptr: *ffi::png_struct) { +pub extern fn flush_data(png_ptr: *mut ffi::png_struct) { unsafe { let io_ptr = ffi::png_get_io_ptr(png_ptr); let writer: &mut &mut io::Writer = mem::transmute(io_ptr); @@ -191,7 +184,7 @@ pub extern fn flush_data(png_ptr: *ffi::png_struct) { } } -pub fn store_png(img: &Image, path: &Path) -> Result<(),String> { +pub fn store_png(img: &mut Image, path: &Path) -> Result<(),String> { let mut file = match File::create(path) { Ok(f) => f, Err(e) => return Err(format!("{}", e)) @@ -203,24 +196,21 @@ pub fn store_png(img: &Image, path: &Path) -> Result<(),String> { let writer = &mut writer; unsafe { - let png_ptr = ffi::png_create_write_struct(ffi::png_get_header_ver(ptr::null()), - ptr::null(), - ptr::null(), - ptr::null()); + let mut png_ptr = ffi::png_create_write_struct(&*ffi::png_get_header_ver(ptr::mut_null()), + ptr::mut_null(), + ptr::mut_null(), + ptr::mut_null()); if png_ptr.is_null() { return Err("could not create write struct".to_string()); } - let info_ptr = ffi::png_create_info_struct(&*png_ptr); + let mut info_ptr = ffi::png_create_info_struct(png_ptr); if info_ptr.is_null() { - let png_ptr: *ffi::png_struct = &*png_ptr; - ffi::png_destroy_write_struct(&png_ptr, ptr::null()); + ffi::png_destroy_write_struct(&mut png_ptr, ptr::mut_null()); return Err("could not create info struct".to_string()); } let res = ffi::setjmp(ffi::pngshim_jmpbuf(png_ptr)); if res != 0 { - let png_ptr: *ffi::png_struct = &*png_ptr; - let info_ptr: *ffi::png_info = &*info_ptr; - ffi::png_destroy_write_struct(&png_ptr, &info_ptr); + ffi::png_destroy_write_struct(&mut png_ptr, &mut info_ptr); return Err("error writing png".to_string()); } @@ -234,20 +224,18 @@ pub fn store_png(img: &Image, path: &Path) -> Result<(),String> { _ => fail!("bad color type"), }; - ffi::png_set_IHDR(&*png_ptr, info_ptr, img.width, img.height, bit_depth, color_type, + ffi::png_set_IHDR(png_ptr, info_ptr, img.width, img.height, bit_depth, color_type, ffi::INTERLACE_NONE, ffi::COMPRESSION_TYPE_DEFAULT, ffi::FILTER_NONE); - let image_buf = img.pixels.as_ptr(); - let row_pointers: Vec<*u8> = Vec::from_fn(img.height as uint, |idx| { + let image_buf = img.pixels.as_mut_ptr(); + let mut row_pointers: Vec<*mut u8> = Vec::from_fn(img.height as uint, |idx| { image_buf.offset((((img.width * pixel_width) as uint) * idx) as int) }); - ffi::png_set_rows(&*png_ptr, info_ptr, row_pointers.as_ptr()); + ffi::png_set_rows(png_ptr, info_ptr, row_pointers.as_mut_ptr()); - ffi::png_write_png(png_ptr, info_ptr, ffi::TRANSFORM_IDENTITY, ptr::null()); + ffi::png_write_png(png_ptr, info_ptr, ffi::TRANSFORM_IDENTITY, ptr::mut_null()); - let png_ptr: *ffi::png_struct = &*png_ptr; - let info_ptr: *ffi::png_info = &*info_ptr; - ffi::png_destroy_write_struct(&png_ptr, &info_ptr); + ffi::png_destroy_write_struct(&mut png_ptr, &mut info_ptr); } Ok(()) } @@ -330,13 +318,13 @@ mod test { #[test] fn test_store() { - let img = Image { + let mut img = Image { width: 10, height: 10, color_type: RGB8, pixels: Vec::from_elem(10 * 10 * 3, 100u8), }; - let res = store_png(&img, &Path::new("test/store.png")); + let res = store_png(&mut img, &Path::new("test/store.png")); assert!(res.is_ok()); } }