From 3f8ee13aa4cbba501c3a9e54b861f2c637c8a5d9 Mon Sep 17 00:00:00 2001 From: nwin Date: Fri, 13 Mar 2015 16:15:44 +0100 Subject: [PATCH] Remove ArrayLike trait and remove ad_slice/_mut --- src/buffer.rs | 179 ++++++++++++++++++++++++--------------------- src/gif/encoder.rs | 6 +- 2 files changed, 97 insertions(+), 88 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index 0593e8c538..dbf3023228 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,6 +1,6 @@ use std::slice::{ Chunks, ChunksMut }; use std::any::TypeId; -use std::ops::{ Index, IndexMut }; +use std::ops::{ Deref, DerefMut, Index, IndexMut }; use std::marker::PhantomData; use std::num::Int; use std::iter::repeat; @@ -11,28 +11,6 @@ use color::{ Rgb, Rgba, Luma, LumaA, FromColor, ColorType }; use image::GenericImage; use dynimage::save_buffer; -/// Mutable equivalent to AsSlice. -/// Should be replaced by a stdlib impl as soon it exists -pub trait AsMutSlice { - /// Work with `self` as a mutable slice. - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T]; -} - -impl AsMutSlice for [T] { - #[inline(always)] - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { self } -} - - -impl AsMutSlice for Vec { - #[inline(always)] - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() } -} - -/// And array-like type that behaves like Vec or [T]. -pub trait ArrayLike: Index + IndexMut + AsSlice + AsMutSlice {} -impl + IndexMut + AsSlice + AsMutSlice, T> ArrayLike for A { } - /// A generalized pixel. /// /// A pixel object is usually not used standalone but as a view into an image buffer. @@ -226,8 +204,6 @@ impl<'a, P: Pixel + 'a> Iterator for EnumeratePixelsMut<'a, P> where P::Subpixel } } - - /// Generic image buffer pub struct ImageBuffer { width: u32, @@ -238,9 +214,10 @@ pub struct ImageBuffer { } // generic implementation, shared along all image buffers -impl> - ImageBuffer - where P::Subpixel: 'static { +impl ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref { /// Contructs a buffer from a generic container /// (for example a `Vec` or a slice) @@ -283,16 +260,6 @@ impl> self.height } - /// The raw image data as a slice. - pub fn as_slice(& self) -> &[P::Subpixel] { - self.data.as_slice() - } - - /// The raw image data as a slice. - pub fn as_mut_slice(&mut self) -> &mut [P::Subpixel] { - self.data.as_mut_slice() - } - /// Returns an iterator over the pixels of this image. pub fn pixels<'a>(&'a self) -> Pixels<'a, P> { Pixels { @@ -302,17 +269,6 @@ impl> } } - /// Returns an iterator over the mutable pixels of this image. - /// The iterator yields the coordinates of each pixel - /// along with a mutable reference to them. - pub fn pixels_mut(&mut self) -> PixelsMut

{ - PixelsMut { - chunks: self.data.as_mut_slice().chunks_mut( -

::channel_count() as usize - ) - } - } - /// Enumerates over the pixels of the image. /// The iterator yields the coordinates of each pixel /// along with a reference to them. @@ -325,17 +281,6 @@ impl> } } - /// Enumerates over the pixels of the image. - pub fn enumerate_pixels_mut<'a>(&'a mut self) -> EnumeratePixelsMut<'a, P> { - let width = self.width; - EnumeratePixelsMut { - pixels: self.pixels_mut(), - x: 0, - y: 0, - width: width - } - } - /// Gets a reference to the pixel at location `(x, y)` /// /// # Panics @@ -348,6 +293,34 @@ impl> &self.data.as_slice()[index .. index + no_channels] ) } +} + +impl ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref + DerefMut { + + /// Returns an iterator over the mutable pixels of this image. + /// The iterator yields the coordinates of each pixel + /// along with a mutable reference to them. + pub fn pixels_mut(&mut self) -> PixelsMut

{ + PixelsMut { + chunks: self.data.as_mut_slice().chunks_mut( +

::channel_count() as usize + ) + } + } + + /// Enumerates over the pixels of the image. + pub fn enumerate_pixels_mut<'a>(&'a mut self) -> EnumeratePixelsMut<'a, P> { + let width = self.width; + EnumeratePixelsMut { + pixels: self.pixels_mut(), + x: 0, + y: 0, + width: width + } + } /// Gets a reference to the mutable pixel at location `(x, y)` /// @@ -372,8 +345,9 @@ impl> } } -impl + 'static, Container: ArrayLike> - ImageBuffer { +impl ImageBuffer +where P: Pixel + 'static, + Container: Deref { /// Saves the buffer to a file at the path specified. /// /// The image format is derived from the file extension. @@ -388,7 +362,50 @@ impl + 'static, Container: ArrayLike> } } -impl + Clone> Clone for ImageBuffer { +impl Deref for ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref { + type Target = [P::Subpixel]; + + fn deref<'a>(&'a self) -> &'a ::Target { + &*self.data + } +} + +impl DerefMut for ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref + DerefMut { + fn deref_mut<'a>(&'a mut self) -> &'a mut ::Target { + &mut *self.data + } +} + +impl Index<(u32, u32)> for ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref { + type Output = P; + + fn index(&self, &(x, y): &(u32, u32)) -> &P { + self.get_pixel(x, y) + } +} + +impl IndexMut<(u32, u32)> for ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref + DerefMut { + + fn index_mut(&mut self, &(x, y): &(u32, u32)) -> &mut P { + self.get_pixel_mut(x, y) + } +} + +impl Clone for ImageBuffer +where P: Pixel, + Container: Deref + Clone { fn clone(&self) -> ImageBuffer { ImageBuffer { @@ -401,8 +418,10 @@ impl + Clone> Clone for ImageBuffer< } } -impl> GenericImage - for ImageBuffer where P::Subpixel: 'static { +impl GenericImage for ImageBuffer +where P: Pixel + 'static, + Container: Deref + DerefMut, + P::Subpixel: 'static { type Pixel = P; @@ -433,24 +452,6 @@ impl> GenericImage } } -impl> Index<(u32, u32)> - for ImageBuffer where P::Subpixel: 'static { - - type Output = P; - - fn index(&self, &(x, y): &(u32, u32)) -> &P { - self.get_pixel(x, y) - } -} - -impl> IndexMut<(u32, u32)> - for ImageBuffer where P::Subpixel: 'static { - - fn index_mut(&mut self, &(x, y): &(u32, u32)) -> &mut P { - self.get_pixel_mut(x, y) - } -} - // concrete implementation for `Vec`-baked buffers // TODO: I think that rustc does not "see" this impl any more: the impl with // Container meets the same requirements. At least, I got compile errors that @@ -458,7 +459,7 @@ impl> IndexMut<(u32, u32)> // `into_vec` is redundant anyway, because `into_raw` will give you the vector, // and it is more generic. impl ImageBuffer> - where P::Subpixel: 'static { +where P::Subpixel: 'static { /// Creates a new image buffer based on a `Vec`. pub fn new(width: u32, height: u32) -> ImageBuffer> { @@ -565,7 +566,7 @@ impl GrayImage { impl<'a, 'b, Container, FromType: Pixel + 'static, ToType: Pixel + 'static> ConvertBuffer>> for ImageBuffer - where Container: ArrayLike, + where Container: Deref, ToType: FromColor, FromType::Subpixel: 'static, ToType::Subpixel: 'static { @@ -596,6 +597,14 @@ mod test { use color; use test; + #[test] + /// Tests if image buffers from slices work + fn slice_buffer() { + let data = [0; 9]; + let buf: ImageBuffer, _> = ImageBuffer::from_raw(3, 3, &data[..]).unwrap(); + assert_eq!(&*buf, &data[..]) + } + #[test] fn test_get_pixel() { let mut a: RgbImage = ImageBuffer::new(10, 10); diff --git a/src/gif/encoder.rs b/src/gif/encoder.rs index a72f87c78c..987e3af89a 100644 --- a/src/gif/encoder.rs +++ b/src/gif/encoder.rs @@ -1,5 +1,4 @@ - -use buffer::{ImageBuffer, Pixel, ArrayLike}; +use std::ops::{Deref, DerefMut}; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -7,6 +6,7 @@ use std::old_io; use std::old_io::IoResult; use std::num::Int; +use buffer::{ImageBuffer, Pixel}; use color::{Rgb, Rgba}; use utils::lzw; use utils::bitstream::LsbWriter; @@ -42,7 +42,7 @@ pub struct Encoder { const TRANSPARENT: Rgba = Rgba([0, 0, 0, 0]); impl Encoder, Container>> -where Container: ArrayLike { +where Container: Deref + DerefMut { /// Creates a new GIF encoder pub fn new(image: ImageBuffer, Container>, bg_color: Option>,