diff --git a/src/lib.rs b/src/lib.rs index 3b54695..6166a77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,7 @@ pub struct Image { // to the data vector. struct ImageData<'a> { data: &'a [u8], - offset: uint, + offset: usize, } pub fn is_png(image: &[u8]) -> bool { @@ -53,13 +53,12 @@ pub extern fn read_data(png_ptr: *mut ffi::png_struct, data: *mut u8, length: si unsafe { let io_ptr = ffi::RUST_png_get_io_ptr(png_ptr); let image_data: &mut ImageData = mem::transmute(io_ptr); - let len = length as uint; - slice::raw::mut_buf_as_slice(data, len, |buf| { - let end_pos = std::cmp::min(image_data.data.len()-image_data.offset, len); - let src = image_data.data.slice(image_data.offset, image_data.offset+end_pos); - ptr::copy_memory(buf.as_mut_ptr(), src.as_ptr(), src.len()); - image_data.offset += end_pos; - }); + let len = length as usize; + let buf = slice::from_raw_mut_buf(&data, len); + let end_pos = std::cmp::min(image_data.data.len() - image_data.offset, len); + let src = image_data.data.slice(image_data.offset, image_data.offset + end_pos); + ptr::copy_memory(buf.as_mut_ptr(), src.as_ptr(), src.len()); + image_data.offset += end_pos; } } @@ -130,21 +129,14 @@ pub fn load_png_from_memory(image: &[u8]) -> Result { let updated_bit_depth = ffi::RUST_png_get_bit_depth(png_ptr, info_ptr); let updated_color_type = ffi::RUST_png_get_color_type(png_ptr, info_ptr); + let pixel_width = pixel_width_by_color_type(updated_color_type, updated_bit_depth); - let (color_type, pixel_width) = match (updated_color_type as c_int, updated_bit_depth) { - (ffi::COLOR_TYPE_RGB, 8) | - (ffi::COLOR_TYPE_RGBA, 8) | - (ffi::COLOR_TYPE_PALETTE, 8) => (PixelsByColorType::RGBA8, 4), - (ffi::COLOR_TYPE_GRAY, 8) => (PixelsByColorType::K8, 1), - (ffi::COLOR_TYPE_GA, 8) => (PixelsByColorType::KA8, 2), - _ => panic!("color type not supported"), - }; - - let mut image_data = Vec::from_elem((width * height * pixel_width) as uint, 0u8); + let image_data_size = (width * height * pixel_width) as usize; + let mut image_data: Vec = std::iter::repeat(0u8).take(image_data_size).collect(); let image_buf = image_data.as_mut_ptr(); - 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) - }); + let mut row_pointers: Vec<*mut u8> = range(0, height as usize).map(|idx| { + image_buf.offset((((width * pixel_width) as usize) * idx) as isize) + }).collect(); ffi::RUST_png_read_image(png_ptr, row_pointers.as_mut_ptr()); @@ -153,21 +145,50 @@ pub fn load_png_from_memory(image: &[u8]) -> Result { Ok(Image { width: width, height: height, - pixels: color_type(image_data), + pixels: pixels_by_color_type(updated_color_type, + updated_bit_depth, + image_data) }) } } +fn pixel_width_by_color_type(color_type: u8, bit_depth: u8) -> u32 { + match (color_type as c_int, bit_depth) { + (ffi::COLOR_TYPE_RGB, 8) | + (ffi::COLOR_TYPE_RGBA, 8) | + (ffi::COLOR_TYPE_PALETTE, 8) => 4, + (ffi::COLOR_TYPE_GRAY, 8) => 1, + (ffi::COLOR_TYPE_GA, 8) => 2, + _ => panic!("color type not supported"), + } +} + +fn pixels_by_color_type(color_type: u8, bit_depth: u8, image_data: Vec) + -> PixelsByColorType +{ + match (color_type as c_int, bit_depth) { + (ffi::COLOR_TYPE_RGB, 8) | + (ffi::COLOR_TYPE_RGBA, 8) | + (ffi::COLOR_TYPE_PALETTE, 8) => + PixelsByColorType::RGBA8(image_data), + (ffi::COLOR_TYPE_GRAY, 8) => + PixelsByColorType::K8(image_data), + (ffi::COLOR_TYPE_GA, 8) => + PixelsByColorType::KA8(image_data), + _ => panic!("color type not supported") + } +} + pub extern fn write_data(png_ptr: *mut ffi::png_struct, data: *mut u8, length: size_t) { unsafe { let io_ptr = ffi::RUST_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| { - match writer.write(buf) { - Err(e) => panic!("{}", e.desc), - _ => {} - } - }); + let const_data: *const u8 = mem::transmute(data); + let buf = slice::from_raw_buf(&const_data, length as usize); + match writer.write(buf) { + Err(e) => panic!("{}", e.desc), + _ => {} + } } } @@ -224,9 +245,9 @@ pub fn store_png(img: &mut Image, path: &Path) -> Result<(),String> { ffi::RUST_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 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) - }); + let mut row_pointers: Vec<*mut u8> = range(0, img.height as usize).map(|idx| { + image_buf.offset((((img.width * pixel_width) as usize) * idx) as isize) + }).collect(); ffi::RUST_png_set_rows(png_ptr, info_ptr, row_pointers.as_mut_ptr()); ffi::RUST_png_write_png(png_ptr, info_ptr, ffi::TRANSFORM_IDENTITY, ptr::null_mut()); @@ -245,7 +266,8 @@ mod test { use std::io::File; use super::{ffi, load_png, load_png_from_memory, store_png}; - use super::{RGB8, RGBA8, K8, KA8, Image}; + use super::Image; + use super::PixelsByColorType::{RGB8, RGBA8, K8, KA8}; #[test] fn test_valid_png() { @@ -255,7 +277,7 @@ mod test { Err(e) => panic!(e.desc), }; - let mut buf = Vec::from_elem(1024, 0u8); + let mut buf: Vec = range(0, 1024).map(|_| 0u8).collect(); let count = reader.read(buf.slice_mut(0, 1024)).unwrap(); assert!(count >= 8); unsafe { @@ -332,7 +354,7 @@ mod test { let mut img = Image { width: 10, height: 10, - pixels: RGB8(Vec::from_elem(10 * 10 * 3, 100u8)), + pixels: RGB8(range(0, 10 * 10 * 3).map(|_| 100u8).collect::>()) }; let res = store_png(&mut img, &Path::new("test/store.png")); assert!(res.is_ok());