diff --git a/.travis.yml b/.travis.yml index cb985ec329..4ef49f9af9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ env: - FEATURES='' - FEATURES='gif_codec' - FEATURES='jpeg' - - FEATURES='png' + - FEATURES='png_codec' - FEATURES='ppm' - FEATURES='tga' - FEATURES='tiff' diff --git a/Cargo.toml b/Cargo.toml index 84027575e3..02c3d06698 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,12 +31,16 @@ glob = "0.2.10" version = "0.5" optional = true +[dependencies.png] +version = "0.3" +optional = true + [features] -default = ["gif_codec", "jpeg", "png", "ppm", "tga", "tiff", "webp", "bmp"] +default = ["gif_codec", "jpeg", "png_codec", "ppm", "tga", "tiff", "webp", "bmp"] gif_codec = ["gif"] jpeg = [] -png = [] +png_codec = ["png"] ppm = [] tga = [] tiff = [] diff --git a/src/dynimage.rs b/src/dynimage.rs index 7ab9880de8..33b236a9f8 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -14,7 +14,7 @@ use gif; use webp; #[cfg(feature = "jpeg")] use jpeg; -#[cfg(feature = "png")] +#[cfg(feature = "png_codec")] use png; #[cfg(feature = "tiff")] use tiff; @@ -350,9 +350,9 @@ impl DynamicImage { let color = self.color(); match format { - #[cfg(feature = "png")] + #[cfg(feature = "png_codec")] image::ImageFormat::PNG => { - let mut p = png::PNGEncoder::new(w); + let p = png::PNGEncoder::new(w); try!(p.encode(&bytes, width, height, color)); Ok(()) @@ -559,7 +559,7 @@ pub fn save_buffer

(path: P, buf: &[u8], width: u32, height: u32, color: color #[cfg(feature = "jpeg")] "jpg" | "jpeg" => jpeg::JPEGEncoder::new(fout).encode(buf, width, height, color), - #[cfg(feature = "png")] + #[cfg(feature = "png_codec")] "png" => png::PNGEncoder::new(fout).encode(buf, width, height, color), #[cfg(feature = "ppm")] "ppm" => ppm::PPMEncoder::new(fout).encode(buf, width, height, color), @@ -573,7 +573,7 @@ pub fn save_buffer

(path: P, buf: &[u8], width: u32, height: u32, color: color /// Create a new image from a Reader pub fn load(r: R, format: ImageFormat) -> ImageResult { match format { - #[cfg(feature = "png")] + #[cfg(feature = "png_codec")] image::ImageFormat::PNG => decoder_to_image(png::PNGDecoder::new(BufReader::new(r))), #[cfg(feature = "gif_codec")] image::ImageFormat::GIF => decoder_to_image(gif::Decoder::new(BufReader::new(r))), diff --git a/src/image.rs b/src/image.rs index 884aa3bc0f..9cce3cbae4 100644 --- a/src/image.rs +++ b/src/image.rs @@ -153,6 +153,12 @@ pub trait ImageDecoder: Sized { /// Returns the length in bytes of one decoded row of the image fn row_len(&mut self) -> ImageResult; + /// Reads one row from the image into buf and returns the row index + fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult; + + /// Decodes the entire image and return it as a Vector + fn read_image(&mut self) -> ImageResult; + /// Returns true if the image is animated fn is_animated(&mut self) -> ImageResult { // since most image formats do not support animation @@ -168,12 +174,6 @@ pub trait ImageDecoder: Sized { ])) } - /// Reads one row from the image into buf and returns the row index - fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult; - - /// Decodes the entire image and return it as a Vector - fn read_image(&mut self) -> ImageResult; - /// Decodes a specific region of the image, represented by the rectangle /// starting from ```x``` and ```y``` and having ```length``` and ```width``` fn load_rect(&mut self, x: u32, y: u32, length: u32, width: u32) -> ImageResult> { diff --git a/src/imageops/sample.rs b/src/imageops/sample.rs index 67f878d5b9..02f1985eeb 100644 --- a/src/imageops/sample.rs +++ b/src/imageops/sample.rs @@ -476,7 +476,7 @@ mod tests { use std::path::Path; #[bench] - #[cfg(feature = "png")] + #[cfg(feature = "png_codec")] fn bench_resize(b: &mut test::Bencher) { let img = ::open(&Path::new("./examples/fractal.png")).unwrap(); b.iter(|| { diff --git a/src/lib.rs b/src/lib.rs index 57f554a700..58dd742cf8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,7 +106,7 @@ pub mod imageops; pub mod webp; #[cfg(feature = "ppm")] pub mod ppm; -#[cfg(feature = "png")] +#[cfg(feature = "png_codec")] pub mod png; #[cfg(feature = "jpeg")] pub mod jpeg; diff --git a/src/png.rs b/src/png.rs new file mode 100644 index 0000000000..56e439dd5f --- /dev/null +++ b/src/png.rs @@ -0,0 +1,154 @@ + +//! Decoding and Encoding of PNG Images +//! +//! PNG (Portable Network Graphics) is an image format that supports lossless compression. +//! +//! # Related Links +//! * http://www.w3.org/TR/PNG/ - The PNG Specification +//! + +extern crate png; + +use self::png::HasParameters; + +use std::io::{self, Read, Write}; + +use image::{ImageError, ImageResult, DecodingResult, ImageDecoder}; +use color::ColorType; + +enum Either { + Left(T), + Right(U) +} + +/// PNG decoder +pub struct PNGDecoder { + inner: Option, png::Reader>> +} + +impl PNGDecoder { + /// Creates a new decoder that decodes from the stream ```r``` + pub fn new(r: R) -> PNGDecoder { + PNGDecoder { + inner: Some(Either::Left(png::Decoder::new(r))) + } + } + + // Converts the inner decoder to a reader + fn get_reader(&mut self) -> Result<&mut png::Reader, png::DecodingError> { + let inner = self.inner.take().unwrap(); + self.inner = Some(match inner { + Either::Left(decoder) => { + let (_, reader) = try!(decoder.read_info()); + Either::Right(reader) + }, + Either::Right(reader) => Either::Right(reader) + }); + match self.inner { + Some(Either::Right(ref mut reader)) => Ok(reader), + _ => unreachable!() + } + } +} + +impl ImageDecoder for PNGDecoder { + fn dimensions(&mut self) -> ImageResult<(u32, u32)> { + let reader = try!(self.get_reader()); + Ok(reader.info().size()) + } + + fn colortype(&mut self) -> ImageResult { + let reader = try!(self.get_reader()); + Ok(reader.output_color_type().into()) + } + + fn row_len(&mut self) -> ImageResult { + let reader = try!(self.get_reader()); + let width = reader.info().width; + Ok(reader.output_line_size(width)) + } + + fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult { + match try!(try!(self.get_reader()).next_row()) { + Some(line) => { + ::copy_memory(line, &mut buf[..line.len()]); + Ok(line.len() as u32) + }, + None => Err(ImageError::ImageEnd) + } + } + + fn read_image(&mut self) -> ImageResult { + let reader = try!(self.get_reader()); + let mut data = vec![0; reader.output_buffer_size()]; + try!(reader.next_frame(&mut data)); + Ok(DecodingResult::U8(data)) + } +} + +/// PNG encoder +pub struct PNGEncoder { + w: W +} + +impl PNGEncoder { + /// Create a new encoder that writes its output to ```w``` + pub fn new(w: W) -> PNGEncoder { + PNGEncoder { + w: w + } + } + + /// Encodes the image ```image``` + /// that has dimensions ```width``` and ```height``` + /// and ```ColorType``` ```c``` + pub fn encode(self, data: &[u8], width: u32, height: u32, color: ColorType) -> io::Result<()> { + let (ct, bits) = color.into(); + let mut encoder = png::Encoder::new(self.w, width, height); + encoder.set(ct).set(bits); + let mut writer = try!(encoder.write_header()); + writer.write_image_data(data).map_err(|e| e.into()) + } +} + +impl From<(png::ColorType, png::BitDepth)> for ColorType { + fn from((ct, bits): (png::ColorType, png::BitDepth)) -> ColorType { + use self::png::ColorType::*; + let bits = bits as u8; + match ct { + Grayscale => ColorType::Gray(bits), + RGB => ColorType::RGB(bits), + Indexed => ColorType::Palette(bits), + GrayscaleAlpha => ColorType::GrayA(bits), + RGBA => ColorType::RGBA(bits) + } + } +} + +impl From for (png::ColorType, png::BitDepth) { + fn from(ct: ColorType) -> (png::ColorType, png::BitDepth) { + use self::png::ColorType::*; + let (ct, bits) = match ct { + ColorType::Gray(bits) => (Grayscale, bits), + ColorType::RGB(bits) => (RGB, bits), + ColorType::Palette(bits) => (Indexed, bits), + ColorType::GrayA(bits) => (GrayscaleAlpha, bits), + ColorType::RGBA(bits) => (RGBA, bits) + }; + (ct, png::BitDepth::from_u8(bits).unwrap()) + } +} + +impl From for ImageError { + fn from(err: png::DecodingError) -> ImageError { + use self::png::DecodingError::*; + match err { + IoError(err) => ImageError::IoError(err), + Format(desc) => ImageError::FormatError(desc.into_owned()), + InvalidSignature => ImageError::FormatError("invalid signature".into()), + CrcMismatch { .. } => ImageError::FormatError("CRC error".into()), + Other(desc) => ImageError::FormatError(desc.into_owned()), + CorruptFlateStream => ImageError::FormatError("compressed data stream corrupted".into()) + } + } +} \ No newline at end of file diff --git a/src/png/decoder.rs b/src/png/decoder.rs deleted file mode 100644 index 4cb22efba8..0000000000 --- a/src/png/decoder.rs +++ /dev/null @@ -1,864 +0,0 @@ -use std::io::{ self, Read }; -use std::{ cmp, str }; -use std::iter::repeat; -use num::FromPrimitive; -use byteorder::{ ReadBytesExt, BigEndian }; -use num::range_step; - -use image::{ - DecodingResult, - ImageResult, - ImageDecoder, - ImageError -}; -use color::{ self, ColorType }; - -use super::filter::unfilter; -use super::hash::Crc32; -use super::zlib::ZlibDecoder; - -use utils::expand_packed; - - -pub static PNGSIGNATURE: [u8; 8] = [137, 80, 78, 71, 13, 10, 26, 10]; - - -#[derive(Clone, Copy, PartialEq)] -enum PNGState { - Start, - HaveSignature, - HaveIHDR, - HavePLTE, - HaveFirstIDat, - #[allow(dead_code)] - HaveLastIDat, - #[allow(dead_code)] - HaveIEND -} - -enum_from_primitive! { -#[derive(Clone, Copy, Debug, PartialEq)] -enum InterlaceMethod { - None = 0, - Adam7 = 1 -} -} - -/// This iterator iterates over the different passes of an image Adam7 encoded -/// PNG image -/// The glorious pattern is: -/// 16462646 -/// 77777777 -/// 56565656 -/// 77777777 -/// 36463646 -/// 77777777 -/// 56565656 -/// 77777777 -/// -#[derive(Clone, Copy)] -struct Adam7Iterator { - line: u32, - lines: u32, - line_width: u32, - current_pass: u8, - width: u32, - height: u32, -} - -impl Adam7Iterator { - pub fn new(width: u32, height: u32) -> Adam7Iterator { - let mut this = Adam7Iterator { - line: 0, - lines: 0, - line_width: 0, - current_pass: 1, - width: width, - height: height - }; - this.init_pass(); - this - } - - /// Calculates the bounds of the current pass - fn init_pass(&mut self) { - let w = self.width as f64; - let h = self.height as f64; - let (line_width, lines) = match self.current_pass { - 1 => (w/8.0, h/8.0), - 2 => ((w-4.0)/8.0, h/8.0), - 3 => (w/4.0, (h-4.0)/8.0), - 4 => ((w-2.0)/4.0, h/4.0), - 5 => (w/2.0, (h-2.0)/4.0), - 6 => ((w-1.0)/2.0, h/2.0), - 7 => (w, (h-1.0)/2.0), - _ => unreachable!() - }; - self.line_width = line_width.ceil() as u32; - self.lines = lines.ceil() as u32; - self.line = 0; - } -} - -/// Iterates over the (passes, lines, widths) -impl Iterator for Adam7Iterator { - type Item = (u8, u32, u32); - fn next(&mut self) -> Option<(u8, u32, u32)> { - if self.line < self.lines { - let this_line = self.line; - self.line += 1; - Some((self.current_pass, this_line, self.line_width)) - } else if self.current_pass < 7 { - self.current_pass += 1; - self.init_pass(); - self.next() - } else { - None - } - } -} - - -/// The representation of a PNG decoder -/// -/// Currently does not support decoding of interlaced images -pub struct PNGDecoder { - z: ZlibDecoder>, - crc: Crc32, - previous: Vec, - state: PNGState, - - width: u32, - height: u32, - - bit_depth: u8, - data_color_type: u8, - data_pixel_type: ColorType, - - palette: Option>, - trns: Option>, - - interlace_method: InterlaceMethod, - pass_iterator: Option, - - chunk_length: u32, - chunk_type: Vec, - - bpp: u8, - bits_per_pixel: u8, - decoded_rows: u32, -} - -impl PNGDecoder { - /// Create a new decoder that decodes from the stream ```r``` - pub fn new(r: R) -> PNGDecoder { - let idat_reader = IDATReader::new(r); - - PNGDecoder { - previous: Vec::new(), - state: PNGState::Start, - z: ZlibDecoder::new(idat_reader), - crc: Crc32::new(), - - width: 0, - height: 0, - - bit_depth: 0, - data_color_type: 0, - data_pixel_type: ColorType::Gray(1), - - palette: None, - trns: None, - - interlace_method: InterlaceMethod::None, - pass_iterator: None, - - chunk_length: 0, - chunk_type: Vec::new(), - - bpp: 0, - bits_per_pixel: 0, - decoded_rows: 0, - } - } - - /// Returns a reference to the color palette used for indexed - /// color images. - /// Each array element is a tuple of RGB values. - pub fn palette <'a>(&'a self) -> &'a [(u8, u8, u8)] { - match self.palette { - Some(ref p) => &p, - None => &[] - } - } - - fn read_signature(&mut self) -> ImageResult { - let mut png = Vec::with_capacity(8); - try!(self.z.inner().r.by_ref().take(8).read_to_end(&mut png)); - - Ok(&png == &PNGSIGNATURE) - } - - fn parse_ihdr(&mut self, buf: Vec) -> ImageResult<()> { - self.crc.update(&*buf); - let mut m = io::Cursor::new(buf); - - self.width = try!(m.read_u32::()); - self.height = try!(m.read_u32::()); - - self.bit_depth = try!(try!(m.by_ref().bytes().next().ok_or(ImageError::ImageEnd))); - self.data_color_type = try!(try!(m.by_ref().bytes().next().ok_or(ImageError::ImageEnd))); - - self.data_pixel_type = match (self.data_color_type, self.bit_depth) { - (0, 1) => ColorType::Gray(1), - (0, 2) => ColorType::Gray(2), - (0, 4) => ColorType::Gray(4), - (0, 8) => ColorType::Gray(8), - (0, 16) => ColorType::Gray(16), - (2, 8) => ColorType::RGB(8), - (2, 16) => ColorType::RGB(16), - (3, 1) => ColorType::RGB(8), - (3, 2) => ColorType::RGB(8), - (3, 4) => ColorType::RGB(8), - (3, 8) => ColorType::RGB(8), - (4, 8) => ColorType::GrayA(8), - (4, 16) => ColorType::GrayA(16), - (6, 8) => ColorType::RGBA(8), - (6, 16) => ColorType::RGBA(16), - (_, _) => return Err(ImageError::FormatError( - "Invalid color/bit depth combination.".to_string() - )) - }; - - let compression_method = try!(try!(m.by_ref().bytes().next().ok_or(ImageError::ImageEnd))); - if compression_method != 0 { - return Err(ImageError::UnsupportedError(format!( - "The compression method {} is not supported.", - compression_method - ))) - } - - let filter_method = try!(try!(m.by_ref().bytes().next().ok_or(ImageError::ImageEnd))); - if filter_method != 0 { - return Err(ImageError::UnsupportedError(format!( - "The filter method {} is not supported.", - filter_method - ))) - } - - self.interlace_method = match FromPrimitive::from_u8(try!(try!(m.by_ref().bytes().next().ok_or(ImageError::ImageEnd)))) { - Some(method) => method, - None => return Err(ImageError::UnsupportedError( - "Unsupported interlace method.".to_string() - )) - }; - if self.interlace_method == InterlaceMethod::Adam7 { - self.pass_iterator = Some(Adam7Iterator::new(self.width, self.height)) - } - - let channels = match self.data_color_type { - 0 => 1, - 2 => 3, - 3 => 1, - 4 => 2, - 6 => 4, - _ => return Err(ImageError::FormatError("Unknown color type.".to_string())) - }; - - self.bits_per_pixel = channels * self.bit_depth; - self.bpp = (self.bits_per_pixel + 7) / 8; - self.previous = repeat(0u8).take(self.raw_row_length(self.width) as usize).collect(); - - Ok(()) - } - - fn raw_row_length(&self, width: u32) -> u32 { - (self.bits_per_pixel as u32 * width + 7) / 8 - } - - fn parse_trns(&mut self, len: usize) -> ImageResult<()> { - let length = match self.data_color_type { - 0 => 2, - 2 => 6, - 3 => len, - _ => { - return Err(ImageError::FormatError(format!( - "tRNS chunk may not appear for color type {}", self.data_color_type - ))) - } - }; - if length != len { - return Err(ImageError::FormatError("Invalid tRNS chunk signature.".to_string())) - } - let mut buf = Vec::with_capacity(length as usize); - try!(self.z.inner().r.by_ref().take(length as u64).read_to_end(&mut buf)); - self.crc.update(&*buf); - self.trns = Some(buf); - return Ok(()) - } - - fn parse_plte(&mut self, buf: Vec) -> ImageResult<()> { - self.crc.update(&*buf); - - let len = buf.len() / 3; - - if len > 256 || len > (1 << self.bit_depth as usize) || buf.len() % 3 != 0{ - return Err(ImageError::FormatError("Color palette malformed.".to_string())) - } - - let p: Vec<(u8, u8, u8)> = (0usize..256).map(|i| { - if i < len { - let r = buf[3 * i]; - let g = buf[3 * i + 1]; - let b = buf[3 * i + 2]; - - (r, g, b) - } else { - (0, 0, 0) - } - }).collect(); - - self.palette = Some(p); - - Ok(()) - } - - fn read_metadata(&mut self) -> ImageResult<()> { - if !try!(self.read_signature()) { - return Err(ImageError::FormatError("Could not read PNG signature.".to_string())) - } - - self.state = PNGState::HaveSignature; - - loop { - let length = try!(self.z.inner().r.read_u32::()); - let mut chunk = Vec::with_capacity(4); - try!(self.z.inner().r.by_ref().take(4).read_to_end(&mut chunk)); - - self.chunk_length = length; - self.chunk_type = chunk.clone(); - - self.crc.update(&*chunk); - - match (&*self.chunk_type, self.state) { - (b"IHDR", PNGState::HaveSignature) => { - if length != 13 { - return Err(ImageError::FormatError("Invalid PNG signature.".to_string())) - } - - let mut d = Vec::with_capacity(length as usize); - try!(self.z.inner().r.by_ref().take(length as u64).read_to_end(&mut d)); - try!(self.parse_ihdr(d)); - - self.state = PNGState::HaveIHDR; - } - - (b"PLTE", PNGState::HaveIHDR) => { - let mut d = Vec::with_capacity(length as usize); - try!(self.z.inner().r.by_ref().take(length as u64).read_to_end(&mut d)); - try!(self.parse_plte(d)); - self.state = PNGState::HavePLTE; - } - - (b"tRNS", _) => { - try!(self.parse_trns(length as usize)); - } - - (b"IDAT", PNGState::HaveIHDR) if self.data_color_type != 3 => { - self.state = PNGState::HaveFirstIDat; - self.z.inner().set_inital_length(self.chunk_length); - self.z.inner().crc.update(&self.chunk_type); - - break; - } - - (b"IDAT", PNGState::HavePLTE) if self.data_color_type == 3 => { - self.state = PNGState::HaveFirstIDat; - self.z.inner().set_inital_length(self.chunk_length); - self.z.inner().crc.update(&self.chunk_type); - - break; - } - - _ => { - let mut b = Vec::with_capacity(length as usize); - try!(self.z.inner().r.by_ref().take(length as u64).read_to_end(&mut b)); - self.crc.update(&*b); - } - } - - let chunk_crc = try!(self.z.inner().r.read_u32::()); - let crc = self.crc.checksum(); - - if crc != chunk_crc { - return Err(ImageError::FormatError("CRC checksum invalid.".to_string())) - } - - self.crc.reset(); - } - - Ok(()) - } - - fn extract_scanline(&mut self, buf: &mut [u8], rlength: u32) -> ImageResult { - let filter_type = match FromPrimitive::from_u8(try!(try!(self.z.by_ref().bytes().next().ok_or(ImageError::ImageEnd)))) { - Some(v) => v, - _ => return Err(ImageError::FormatError("Unknown filter type.".to_string())) - }; - - { - let mut read = 0usize; - let read_buffer = &mut buf[..rlength as usize]; - while read < rlength as usize { - let r = try!(self.z.read(&mut read_buffer[read..])); - read += r; - } - } - - unfilter(filter_type, self.bpp as usize, &self.previous, &mut buf[..rlength as usize]); - ::copy_memory(&buf[..rlength as usize], &mut self.previous); - - - if let Some(ref palette) = self.palette { - expand_palette(buf, &palette, rlength as usize, self.bit_depth, self.trns.as_ref().map(|v| &**v)); - } else if let Some(ref trns) = self.trns { - let mut _trns = [0u8; 4]; - let trns = match self.data_color_type { - 0 => { - _trns[0] = trns[1]; - &_trns[..1] - }, - 2 => { - _trns[0] = trns[1]; - _trns[2] = trns[5]; - _trns[1] = trns[3]; - &_trns[..3] - }, - // panic is ok this should have been catched earlier - _ => panic!("invalid color type for transparency") - }; - if self.bit_depth < 8 { - expand_trns_line_nbits( - buf, - trns[0], - self.bit_depth - ); - } else { - expand_trns_line( - buf, - trns, - color::num_components(self.data_pixel_type) - ); - } - } - - self.decoded_rows += 1; - - Ok(self.decoded_rows) - } -} - -impl ImageDecoder for PNGDecoder { - fn dimensions(&mut self) -> ImageResult<(u32, u32)> { - if self.state == PNGState::Start { - let _ = try!(self.read_metadata()); - } - - Ok((self.width, self.height)) - } - - fn colortype(&mut self) -> ImageResult { - if self.state == PNGState::Start { - let _ = try!(self.read_metadata()); - } - let bits = self.bit_depth; - if self.trns.is_some() { - Ok(match self.data_pixel_type { - ColorType::RGB(n) => ColorType::RGBA(n), - ColorType::Gray(_) if bits == 1 || bits == 2 || bits == 4 => ColorType::GrayA(8), - _ => return Err(ImageError::FormatError( - "Invalid transparency data".to_string() - )) - }) - } else { - Ok(self.data_pixel_type) - } - } - - fn row_len(&mut self) -> ImageResult { - if self.state == PNGState::Start { - let _ = try!(self.read_metadata()); - } - - let bits = color::bits_per_pixel(try!(self.colortype())); - - Ok((bits * self.width as usize + 7) / 8) - } - - fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult { - if self.state == PNGState::Start { - let _ = try!(self.read_metadata()); - } - if self.interlace_method != InterlaceMethod::None { - return Err(ImageError::UnsupportedError("Image is interlaced, extraction of single scanlines is unsupported".to_string())) - } - let rlength = self.raw_row_length(self.width); - self.extract_scanline(buf, rlength) - } - - fn read_image(&mut self) -> ImageResult { - if self.state == PNGState::Start { - let _ = try!(self.read_metadata()); - } - let max_rowlen = try!(self.row_len()); - let mut buf: Vec = repeat(0u8).take(max_rowlen * self.height as usize).collect(); - if let Some(pass_iterator) = self.pass_iterator { // Method == Adam7 - let mut pass_buf: Vec = repeat(0u8).take(max_rowlen).collect(); - let mut old_pass = 1; - let bytes = color::bits_per_pixel(try!(self.colortype()))/8; - for (pass, line, width) in pass_iterator { - let rlength = self.raw_row_length(width); - if old_pass != pass { - // new subimage, reset previous - for v in self.previous.iter_mut() { - *v = 0; - } - } - let bits = color::bits_per_pixel(try!(self.colortype())); - let _ = try!( - self.extract_scanline(&mut pass_buf[.. - ((bits * width as usize + 7) / 8) - ], rlength) - ); - expand_pass( - &mut buf, self.width * bytes as u32, - &mut pass_buf[..width as usize * bytes], pass, line, bytes as u8 - ); - old_pass = pass; - } - Ok(DecodingResult::U8(buf)) - } else { - for chunk in buf.chunks_mut(max_rowlen) { - let _ = try!(self.read_scanline(chunk)); - } - Ok(DecodingResult::U8(buf)) - } - } -} - -macro_rules! expand_pass( - ($img:expr, $scanline:expr, $j:ident, $pos:expr, $bytes_pp:expr) => { - for ($j, pixel) in $scanline.chunks($bytes_pp).enumerate() { - for (offset, val) in pixel.iter().enumerate() { - $img[$pos + offset] = *val - } - } - } -); - -fn expand_pass( - img: &mut[u8], width: u32, scanline: &mut[u8], - pass: u8, line_no: u32, bytes_pp: u8) { - let line_no = line_no as usize; - let width = width as usize; - let bytes_pp = bytes_pp as usize; - match pass { - 1 => expand_pass!(img, scanline, j, 8*line_no * width + bytes_pp * j*8 , bytes_pp), - 2 => expand_pass!(img, scanline, j, 8*line_no * width + bytes_pp *(j*8 + 4), bytes_pp), - 3 => expand_pass!(img, scanline, j, (8*line_no+4) * width + bytes_pp * j*4 , bytes_pp), - 4 => expand_pass!(img, scanline, j, 4*line_no * width + bytes_pp *(j*4 + 2), bytes_pp), - 5 => expand_pass!(img, scanline, j, (4*line_no+2) * width + bytes_pp * j*2 , bytes_pp), - 6 => expand_pass!(img, scanline, j, 2*line_no * width + bytes_pp *(j*2+1) , bytes_pp), - 7 => expand_pass!(img, scanline, j, (2*line_no+1) * width + bytes_pp * j , bytes_pp), - _ => {} - } -} - -fn expand_trns_line(buf: &mut[u8], trns: &[u8], channels: usize) { - let channels = channels as isize; - let i = range_step(buf.len() as isize / (channels+1) * channels - channels, -channels, -channels); - let j = range_step(buf.len() as isize - (channels+1), -(channels+1), -(channels+1)); - let channels = channels as usize; - for (i, j) in i.zip(j) { - let i_pixel = i as usize; - let j_chunk = j as usize; - if &buf[i_pixel..i_pixel+channels] == trns { - buf[j_chunk+channels] = 0 - } else { - buf[j_chunk+channels] = 0xFF - } - for k in (0..channels).rev() { - buf[j_chunk+k] = buf[i_pixel+k]; - } - } -} - -fn expand_trns_line_nbits(buf: &mut[u8], trns: u8, bit_depth: u8) { - let scaling_factor = (255)/((1u16 << bit_depth) - 1) as u8; - expand_packed(buf, 2, bit_depth, |pixel, chunk| { - if pixel == trns { - chunk[1] = 0 - } else { - chunk[1] = 0xFF - } - chunk[0] = pixel * scaling_factor - }) -} - -fn expand_palette(buf: &mut[u8], palette: &[(u8, u8, u8)], - entries: usize, bit_depth: u8, trns: Option<&[u8]>) { - let bpp = 8 / bit_depth as usize; - let extra = if trns.is_some() { entries * bpp } else { 0 }; - assert_eq!(buf.len(), 3 * (entries * bpp - buf.len() % bpp) + extra); - if let Some(trns) = trns { - expand_packed(buf, 4, bit_depth, |i, chunk| { - let ((r, g, b), a) = ( - palette[i as usize], - *trns.get(i as usize).unwrap_or(&0xFF) - ); - chunk[0] = r; - chunk[1] = g; - chunk[2] = b; - chunk[3] = a; - }) - } else { - expand_packed(buf, 3, bit_depth, |i, chunk| { - let (r, g, b) = palette[i as usize]; - chunk[0] = r; - chunk[1] = g; - chunk[2] = b; - }) - } -} - -pub struct IDATReader { - pub r: R, - pub crc: Crc32, - - eof: bool, - chunk_length: u32, -} - -impl IDATReader { - pub fn new(r: R) -> IDATReader { - IDATReader { - r: r, - crc: Crc32::new(), - eof: false, - chunk_length: 0, - } - } - - pub fn set_inital_length(&mut self, len: u32) { - self.chunk_length = len; - } -} - -impl Read for IDATReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - if self.eof { - return Ok(0); - } - - let len = buf.len(); - let mut start = 0; - - while start < len { - let m = cmp::min(len - start, self.chunk_length as usize); - - let slice = &mut buf[start..start + m]; - let r = try!(self.r.read(slice)); - - start += r; - - self.chunk_length -= r as u32; - self.crc.update(&*slice); - - if self.chunk_length == 0 { - let chunk_crc = try!(self.r.read_u32::()); - let crc = self.crc.checksum(); - - if crc != chunk_crc { - return Ok(0); - } - - self.crc.reset(); - self.chunk_length = try!(self.r.read_u32::()); - - let mut v = Vec::with_capacity(4); - try!(self.r.by_ref().take(4).read_to_end(&mut v)); - self.crc.update(&v); - - match str::from_utf8(&v) { - Ok("IDAT") => (), - _ => { - self.eof = true; - break - } - } - } - } - - Ok(start) - } -} - -#[cfg(test)] -mod tests { - extern crate glob; - - use std::io::{self, Read}; - use std::fs::File; - use std::ffi::OsStr; - use std::path::{Path, PathBuf}; - use test; - - use image::{ - ImageDecoder, - ImageResult, - DecodingResult - }; - - use super::PNGDecoder; - - /// Filters the testsuite images for certain features - fn get_testimages(feature: &str, color_type: &str, test_interlaced: bool) -> Vec { - // Find the files matching "./src/png/testdata/pngsuite/*.png". - let pattern: PathBuf = [".", "src", "png", "testdata", "pngsuite", "*.png"].iter().collect(); - - let paths = glob::glob(&pattern.display().to_string()).unwrap().filter_map(Result::ok) - .filter(|ref p| p.file_name().and_then(OsStr::to_str).unwrap().starts_with(feature)) - .filter(|ref p| p.file_name().and_then(OsStr::to_str).unwrap().contains(color_type)); - - let ret: Vec = if test_interlaced { - paths.collect() - } else { - paths.filter(|ref p| !p.file_name().and_then(OsStr::to_str) - .unwrap() - [2..] - .contains("i")) - .collect() - }; - - assert!(ret.len() > 0); // fail if no testimages are available - ret - } - - fn load_image

(path: P) -> ImageResult where P: AsRef { - PNGDecoder::new(try!(File::open(path))).read_image() - } - - #[test] - /// Test image filters - fn test_filters() { - let images = get_testimages("f", "", false); - - for path in images.iter() { - assert!(match load_image(path) { - Ok(_) => true, - Err(err) => { println!("file {:?}, failed with {:?}", path.display(), err); false } - }) - } - } - #[test] - /// Test basic formats filters - fn test_basic() { - let images = get_testimages("b", "", false); - - for path in images.iter() { - assert!(match load_image(path) { - Ok(_) => true, - Err(err) => {println!("file {:?}, failed with {:?}", path.display(), err); false } - }) - } - } - - #[test] - /// Chunk ordering - fn test_chunk_ordering() { - let images = get_testimages("o", "", false); - - for path in images.iter() { - assert!(match load_image(path) { - Ok(_) => { true }, - Err(err) => {println!("file {:?}, failed with {:?}", path.display(), err); false } - }) - } - } - - //#[test] - //fn render_all() { - // let images = get_testimages("f", "", true) - // + get_testimages("b", "", true) - // + get_testimages("o", "", true); - // - // for path in images.iter() { - // match ::open(path) { - // Err(_) => {}, - // Ok(im) => { - // let filename = path.filename_str().unwrap().to_string(); - // let p1 = "target"; - // let p2 = "reference renderings"; - // let _ = old_io::fs::mkdir(&Path::new(".").join_many( - // [p1.as_slice(), p2.as_slice()]), - // old_io::UserRWX - // ); - // let p = Path::new(".").join_many([p1.as_slice(), p2.as_slice(), - // filename.as_slice()]); - // let fout = File::create(&p).unwrap(); - // - // // Write the contents of this image to the Writer in PNG format. - // let _ = im.save(fout, ::PNG); - // } - // }; - // } - //} - - #[test] - /// Test corrupted images, they should all fail - fn test_corrupted() { - let images = get_testimages("x", "", true); - let num_images = images.len(); - let mut fails = 0; - - for path in images.iter() { - match load_image(path) { - Ok(_) => println!("corrupted file {} did not fail", path.display()), - Err(_) => { - fails += 1; - } - } - } - - assert_eq!(num_images, fails) - } - #[bench] - /// Test basic formats filters - fn bench_read_small_files(b: &mut test::Bencher) { - let image_data: Vec> = get_testimages("b", "2c", false).iter().map(|path| { - let mut buf = Vec::new(); - File::open(path).unwrap().read_to_end(&mut buf).unwrap(); - buf - }).collect(); - b.iter(|| { - for data in image_data.clone().into_iter() { - let data = io::Cursor::new(data); - let _ = PNGDecoder::new(data).read_image().unwrap(); - } - }); - b.bytes = image_data.iter().map(|v| v.len()).fold(0, |a, b| a + b) as u64 - } - #[bench] - /// Test basic formats filters - fn bench_read_big_file(b: &mut test::Bencher) { - let mut image_data = Vec::new(); - File::open( - &PathBuf::from(".").join("examples").join("fractal.png") - ).unwrap().read_to_end(&mut image_data).unwrap(); - b.iter(|| { - let image_data = io::Cursor::new(image_data.clone()); - let _ = PNGDecoder::new(image_data).read_image().unwrap(); - }); - b.bytes = image_data.len() as u64 - } -} diff --git a/src/png/deflate.rs b/src/png/deflate.rs deleted file mode 100644 index a893959a3c..0000000000 --- a/src/png/deflate.rs +++ /dev/null @@ -1,88 +0,0 @@ -/*! -A DEFLATE encoder (RFC 1951). -*/ -use std::io::{self, Write}; -use byteorder::{WriteBytesExt, LittleEndian}; - -/// A DEFLATE encoder (RFC 1951). -// TODO: this deflater only uses non-compressed blocks -// this is easier to implement but not very efficient -pub struct Deflater where W: Write { - writer: Option, - buf: Vec, -} - -impl Deflater where W: Write { - /// Creates a new encoder that writes to the underlying writer. - pub fn new(writer: W) -> Deflater { - Deflater { - writer: Some(writer), - buf: Vec::with_capacity(65535), - } - } - - /// Stops encoding and returns the underlying writer. - pub fn into_inner(mut self) -> io::Result { - try!(self.flush_buf(true)); - Ok(self.writer.take().unwrap()) - } - - /// Encodes the buffer into a block and writes it to the output. - /// - /// `last` indicates whether this is the last block. - fn flush_buf(&mut self, last: bool) -> io::Result<()> { - if self.buf.len() == 0 { - return Ok(()); - } - - assert!(self.buf.len() <= u16::max_value() as usize); - let len = self.buf.len() as u16; - let nlen = !len; // one's complement - - let writer = self.writer.as_mut().unwrap(); - try!(writer.write_u8(if last { 1 } else { 0 })); // bits and stuff - try!(writer.write_u16::(len)); - try!(writer.write_u16::(nlen)); - try!(writer.write_all(&self.buf)); - - self.buf.clear(); - - Ok(()) - } -} - -impl Write for Deflater where W: Write { - fn write(&mut self, mut buf: &[u8]) -> io::Result { - let total_written = buf.len(); - - loop { - if self.buf.len() + buf.len() >= u16::max_value() as usize { - let rest = u16::max_value() as usize - self.buf.len(); - self.buf.extend(buf.iter().take(rest).cloned()); - buf = &buf[rest..]; - try!(self.flush_buf(false)); - continue; - - } else { - self.buf.extend(buf.iter().cloned()); - break; - } - } - - Ok(total_written) - } - - fn flush(&mut self) -> io::Result<()> { - try!(self.flush_buf(false)); - self.writer.as_mut().unwrap().flush() - } -} - -impl Drop for Deflater where W: Write { - fn drop(&mut self) { - if self.writer.is_some() { - let _ = self.flush_buf(true); - let _ = self.writer.as_mut().unwrap().flush(); - } - } -} diff --git a/src/png/encoder.rs b/src/png/encoder.rs deleted file mode 100644 index 832964d802..0000000000 --- a/src/png/encoder.rs +++ /dev/null @@ -1,176 +0,0 @@ -//! A PNG Encoder -//! -//! This implementation uses the ```flate``` crate for compression -//! and selects the filter type using the sum of absolute differences method. -//! -//! For each row the filter method that produces the lowest integer when its bytes -//! are interpreted as signed numbers and summed is chosen as the filter. - -use std::io; -use std::io::Write; -use num::FromPrimitive; -use std::iter::repeat; -use byteorder::{WriteBytesExt, BigEndian}; - -use color; -use super::hash::Crc32; - -use super::filter::filter; -use super::decoder::PNGSIGNATURE; -use super::zlib::ZlibEncoder; - -/// The representation of a PNG encoder -pub struct PNGEncoder<'a, W: 'a> { - w: &'a mut W, - crc: Crc32 -} - -impl<'a, W: Write> PNGEncoder<'a, W> { - /// Create a new encoder that writes its output to ```w``` - pub fn new(w: &mut W) -> PNGEncoder { - PNGEncoder { - w: w, - crc: Crc32::new() - } - } - - /// Encodes the image ```image``` - /// that has dimensions ```width``` and ```height``` - /// and ```ColorType``` ```c``` - pub fn encode(&mut self, - image: &[u8], - width: u32, - height: u32, - c: color::ColorType) -> io::Result<()> { - - let _ = try!(self.write_signature()); - let (bytes, bpp) = build_ihdr(width, height, c); - - let _ = try!(self.write_chunk("IHDR", &bytes)); - let compressed_bytes = try!(build_idat(image, bpp, width)); - - for chunk in compressed_bytes.chunks(1024 * 256) { - let _ = try!(self.write_chunk("IDAT", chunk)); - } - - self.write_chunk("IEND", &[]) - } - - fn write_signature(&mut self) -> io::Result<()> { - self.w.write_all(&PNGSIGNATURE) - } - - fn write_chunk(&mut self, name: &str, buf: &[u8]) -> io::Result<()> { - self.crc.reset(); - self.crc.update(name.as_bytes()); - self.crc.update(&buf); - - let crc = self.crc.checksum(); - - let _ = try!(self.w.write_u32::(buf.len() as u32)); - let _ = try!(write!(self.w, "{}", name)); - let _ = try!(self.w.write_all(buf)); - let _ = try!(self.w.write_u32::(crc)); - - Ok(()) - } -} - -fn build_ihdr(width: u32, height: u32, c: color::ColorType) -> (Vec, usize) { - let mut m = Vec::with_capacity(13); - - let _ = m.write_u32::(width); - let _ = m.write_u32::(height); - - let (colortype, bit_depth) = match c { - color::ColorType::Gray(1) => (0, 1), - color::ColorType::Gray(2) => (0, 2), - color::ColorType::Gray(4) => (0, 4), - color::ColorType::Gray(8) => (0, 8), - color::ColorType::Gray(16) => (0, 16), - color::ColorType::RGB(8) => (2, 8), - color::ColorType::RGB(16) => (2, 16), - color::ColorType::Palette(1) => (3, 1), - color::ColorType::Palette(2) => (3, 2), - color::ColorType::Palette(4) => (3, 4), - color::ColorType::Palette(8) => (3, 8), - color::ColorType::GrayA(8) => (4, 8), - color::ColorType::GrayA(16) => (4, 16), - color::ColorType::RGBA(8) => (6, 8), - color::ColorType::RGBA(16) => (6, 16), - _ => panic!("unsupported color type and bitdepth") - }; - - let _ = m.write_all(&[bit_depth]); - let _ = m.write_all(&[colortype]); - - // Compression method, filter method and interlace - let _ = m.write_all(&[0]); - let _ = m.write_all(&[0]); - let _ = m.write_all(&[0]); - - let channels = match colortype { - 0 => 1, - 2 => 3, - 3 => 3, - 4 => 2, - 6 => 4, - _ => panic!("unknown colour type") - }; - - let bpp = ((channels * bit_depth + 7) / 8) as usize; - - (m, bpp) -} - -fn sum_abs_difference(buf: &[u8]) -> i32 { - buf.iter().fold(0i32, | sum, &b | sum + if b < 128 {b as i32} else {256 - b as i32}) -} - -fn select_filter(rowlength: usize, bpp: usize, previous: &[u8], current_s: &mut [u8]) -> u8 { - let mut sum = sum_abs_difference(¤t_s[..rowlength]); - let mut method = 0; - - for (i, current) in current_s.chunks_mut(rowlength).enumerate() { - filter(FromPrimitive::from_u8(i as u8 + 1).unwrap(), bpp, previous, current); - - let this_sum = sum_abs_difference(current); - - if this_sum < sum { - sum = this_sum; - method = i as u8 + 1; - } - } - - method -} - -fn build_idat(image: &[u8], bpp: usize, width: u32) -> io::Result> { - let rowlen = bpp * width as usize; - - let mut p: Vec = repeat(0u8).take(rowlen).collect(); - let mut c: Vec = repeat(0u8).take(4 * rowlen).collect(); - let mut e = try!(ZlibEncoder::new(Vec::new())); - - for row in image.chunks(rowlen) { - for s in c.chunks_mut(rowlen) { - ::copy_memory(row, s); - } - - let filter = select_filter(rowlen, bpp, &p, &mut c); - - try!(e.write_all(&[filter])); - - match filter { - 0 => try!(e.write_all(row)), - _ => { - let stride = (filter as usize - 1) * rowlen; - try!(e.write_all(&c[stride..stride + rowlen])) - } - } - - ::copy_memory(row, &mut p); - } - - e.into_inner() -} diff --git a/src/png/filter.rs b/src/png/filter.rs deleted file mode 100644 index ceff022796..0000000000 --- a/src/png/filter.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::num::Wrapping as w; - -enum_from_primitive! { -#[derive(Debug)] -pub enum FilterType { - NoFilter = 0, - Sub = 1, - Up = 2, - Avg = 3, - Paeth = 4 -} -} - -fn filter_paeth(a: u8, b: u8, c: u8) -> u8 { - let ia = a as i16; - let ib = b as i16; - let ic = c as i16; - - let p = ia + ib - ic; - - let pa = (p - ia).abs(); - let pb = (p - ib).abs(); - let pc = (p - ic).abs(); - - if pa <= pb && pa <= pc { - a - } else if pb <= pc { - b - } else { - c - } -} - -pub fn unfilter(filter: FilterType, bpp: usize, previous: &[u8], current: &mut [u8]) { - let len = current.len(); - - match filter { - FilterType::NoFilter => (), - FilterType::Sub => { - for i in (bpp..len) { - current[i] = (w(current[i]) + w(current[i - bpp])).0; - } - } - FilterType::Up => { - for i in (0..len) { - current[i] = (w(current[i]) + w(previous[i])).0; - } - } - FilterType::Avg => { - for i in (0..bpp) { - current[i] = (w(current[i]) + w(previous[i] / 2)).0; - } - - for i in (bpp..len) { - current[i] = (w(current[i]) + w(((current[i - bpp] as i16 + previous[i] as i16) / 2) as u8)).0; - } - } - FilterType::Paeth => { - for i in (0..bpp) { - current[i] = (w(current[i]) + w(filter_paeth(0, previous[i], 0))).0; - } - - for i in (bpp..len) { - current[i] = (w(current[i]) + w(filter_paeth(current[i - bpp], previous[i], previous[i - bpp]))).0; - } - } - } -} - -pub fn filter(method: FilterType, bpp: usize, previous: &[u8], current: &mut [u8]) { - let len = current.len(); - - match method { - FilterType::NoFilter => (), - FilterType::Sub => { - for i in (bpp..len).rev() { - current[i] = (w(current[i]) - w(current[i - bpp])).0; - } - } - FilterType::Up => { - for i in (0..len) { - current[i] = (w(current[i]) - w(previous[i])).0; - } - } - FilterType::Avg => { - for i in (bpp..len).rev() { - current[i] = (w(current[i]) - w(((current[i - bpp] as i16 + previous[i] as i16) / 2) as u8)).0; - } - - for i in (0..bpp) { - current[i] = (w(current[i]) - w(previous[i] / 2)).0; - } - } - FilterType::Paeth => { - for i in (bpp..len).rev() { - current[i] = (w(current[i]) - w(filter_paeth(current[i - bpp], previous[i], previous[i - bpp]))).0; - } - - for i in (0..bpp) { - current[i] = (w(current[i]) - w(filter_paeth(0, previous[i], 0))).0; - } - } - } -} diff --git a/src/png/hash.rs b/src/png/hash.rs deleted file mode 100644 index 4bd29e2cd8..0000000000 --- a/src/png/hash.rs +++ /dev/null @@ -1,130 +0,0 @@ -//! This module provides implementations of common hashing algorithms. -//! -//! # Related Links -//! *http://tools.ietf.org/html/rfc1950 - Adler-32 checksum specification -//! -//! *http://en.wikipedia.org/wiki/Cyclic_redundancy_check - Cyclic Redundancy Check - -/// An Implementation of the Adler-32 checksum -#[derive(Clone, Copy)] -pub struct Adler32 { - s1: u32, - s2: u32 -} - -impl Adler32 { - /// Create a new hasher. - pub fn new() -> Adler32 { - Adler32 {s1: 1, s2: 0} - } - - /// Update the internal hasher with the bytes from ```buf``` - pub fn update(&mut self, buf: &[u8]) { - for &byte in buf { - self.s1 = self.s1 + byte as u32; - self.s2 = self.s1 + self.s2; - - self.s1 %= 65521; - self.s2 %= 65521; - } - } - - /// Return the computed hash. - pub fn checksum(&self) -> u32 { - (self.s2 << 16) | self.s1 - } - - /// Reset this hasher to its initial state. - pub fn reset(&mut self) { - self.s1 = 1; - self.s2 = 0; - } -} - -const CRC_TABLE: [u32; 256] = [ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d -]; - -/// An Implementation of the Crc-32 checksum -#[derive(Clone, Copy)] -pub struct Crc32 { - crc: u32, -} - -impl Crc32 { - /// Create a new hasher. - pub fn new() -> Crc32 { - Crc32 {crc: 0xFFFFFFFF} - } - - /// Update the internal hasher with the bytes from ```buf``` - pub fn update(&mut self, buf: &[u8]) { - for &byte in buf { - let a = (self.crc ^ byte as u32) & 0xFF; - let b = self.crc >> 8; - - self.crc = CRC_TABLE[a as usize] ^ b; - } - } - - /// Return the computed hash. - pub fn checksum(&self) -> u32 { - self.crc ^ 0xFFFFFFFF - } - - /// Reset this hasher to its initial state. - pub fn reset(&mut self) { - self.crc = 0xFFFFFFFF; - } -} diff --git a/src/png/inflate.rs b/src/png/inflate.rs deleted file mode 100644 index 21284a7a65..0000000000 --- a/src/png/inflate.rs +++ /dev/null @@ -1,429 +0,0 @@ -//! An Implementation of RFC 1951 -//! -//! The DEFLATE compression algorithm -//! -//! # Related Links -//! *http://tools.ietf.org/html/rfc1951 - DEFLATE Compressed Data Format Specification - -use std::cmp; -use std::iter::repeat; -use std::num::Wrapping as w; -use std::io::{self, Read}; -use byteorder::ReadBytesExt; - -static LITERALLENGTHCODES: u16 = 286; -static DISTANCECODES: u16 = 30; -static CODEORDER: [u8; 19] = [ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 -]; -static LENGTHS: [u16; 29] = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, - 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, - 67, 83, 99, 115, 131, 163, 195, 227, 258 -]; -static EXTRA_LENGTHS: [u8; 29] = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 0 -]; -static DISTANCES: [u16; 30] = [ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, - 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, - 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 -]; -static EXTRA_DISTANCES: [u8; 30] = [ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 -]; - -static TABLESIZE: u8 = 9; - -#[derive(PartialEq, Clone)] -enum TableElement { - Symbol(u16, u8), - Table(u16, Vec), - Nothing -} - -impl TableElement { - pub fn put(&mut self, index: u16, elem: TableElement) { - match *self { - TableElement::Table(_, ref mut a) => a[index as usize] = elem, - _ => panic!("requires Table()"), - } - } -} - -enum BlockType { - Stored, - Compressed -} - -/// A DEFLATE compressed stream decoder. -pub struct Inflater { - h: - HuffReader, - - buf: Vec, - pos: u64, - - finished: bool, - btype: BlockType, - block_length: u32, - - ctable: Vec, - lltable: Vec, - dtable: Vec, -} - -impl Inflater { - /// Create a new decoder that decodes from a Reader - pub fn new(r: R) -> Inflater { - Inflater { - h: HuffReader::new(r), - - buf: Vec::new(), - pos: 0, - - finished: false, - block_length: 0, - btype: BlockType::Stored, - - ctable: Vec::new(), - lltable: Vec::new(), - dtable: Vec::new(), - } - } - - /// Indicate whether the end of the stream has been reached. - pub fn eof(&self) -> bool { - self.finished && (self.pos as usize == self.buf.len()) - } - - /// Return a mutable reference to the wrapped Reader - pub fn inner(&mut self) -> &mut R { - &mut self.h.r - } - - fn read_block_type(&mut self) -> io::Result<()> { - let is_final = try!(self.h.receive(1)); - self.finished = is_final == 1; - - let bits = try!(self.h.receive(2)); - match bits { - 0b00 => { - let _ = try!(self.read_stored_block_length()); - self.btype = BlockType::Stored; - } - 0b01 => { - self.create_fixed_tables(); - self.btype = BlockType::Compressed; - } - 0b10 => { - let _ = try!(self.read_dynamic_tables()); - self.btype = BlockType::Compressed; - } - _ => panic!("reserved block type") - } - - Ok(()) - } - - fn read_dynamic_tables(&mut self) -> io::Result<()> { - let totalcodes = LITERALLENGTHCODES + DISTANCECODES; - - let hlit = try!(self.h.receive(5)) + 257; - let hdist = try!(self.h.receive(5)) + 1; - let hclen = try!(self.h.receive(4)) + 4; - - let mut code_lengths: Vec = repeat(0u8).take(CODEORDER.len()).collect(); - - for i in (0..hclen as usize) { - let length = try!(self.h.receive(3)); - code_lengths[CODEORDER[i] as usize] = length as u8; - } - - self.ctable = table_from_lengths(&code_lengths); - let mut all_lengths: Vec = repeat(0u8).take(totalcodes as usize).collect(); - - let mut i = 0; - while i < hlit + hdist { - let s = try!(self.h.decode_symbol(&self.ctable)); - - match s { - 0 ... 15 => { - all_lengths[i as usize] = s as u8; - i += 1; - } - - 16 => { - let repeat = 3 + try!(self.h.receive(2)); - - for _ in (0..repeat) { - all_lengths[i as usize] = all_lengths[i as usize - 1]; - i += 1; - } - } - - 17 => i += 3 + try!(self.h.receive(3)), - - 18 => i += 11 + try!(self.h.receive(7)), - - _ => panic!("out of range code length code symbol") - } - } - - let ll_lengths = &all_lengths[..hlit as usize]; - let d_lengths = &all_lengths[hlit as usize..]; - - self.lltable = table_from_lengths(ll_lengths); - self.dtable = table_from_lengths(d_lengths); - - Ok(()) - } - - fn create_fixed_tables(&mut self) { - let lengths: Vec = (0u32..288).map(|i| - if i < 144 { 8u8 } - else if i < 256 { 9u8 } - else if i < 280 { 7u8 } - else { 8u8 } - ).collect(); - self.lltable = table_from_lengths(&lengths); - - let lengths: Vec = repeat(5u8).take(DISTANCECODES as usize).collect(); - self.dtable = table_from_lengths(&lengths); - } - - fn read_stored_block_length(&mut self) -> io::Result<()> { - self.h.byte_align(); - - let len = try!(self.h.receive(16)); - let _nlen = try!(self.h.receive(16)); - - self.block_length = len as u32; - - Ok(()) - } - - fn read_stored_block(&mut self) -> io::Result<()> { - while self.block_length > 0 { - let a = try!(self.h.receive(8)); - self.buf.push(a as u8); - self.block_length -= 1; - } - - Ok(()) - } - - fn read_compressed_block(&mut self) -> io::Result<()> { - loop { - let s = try!(self.h.decode_symbol(&self.lltable)); - - match s { - literal @ 0 ... 255 => self.buf.push(literal as u8), - - 256 => break, - - length @ 257 ... 285 => { - let length = length - 257; - - let bits = EXTRA_LENGTHS[length as usize]; - let extra = try!(self.h.receive(bits)); - - let length = LENGTHS[length as usize] + extra; - - let distance = try!(self.h.decode_symbol(&self.dtable)); - - let bits = EXTRA_DISTANCES[distance as usize]; - let extra = try!(self.h.receive(bits)); - - let distance = DISTANCES[distance as usize] + extra; - - let len = self.buf.len(); - for i in (0..length) { - let s = self.buf[len - distance as usize + i as usize]; - self.buf.push(s); - } - } - - _ => panic!("out of range symbol") - } - } - - Ok(()) - } -} - -impl Read for Inflater { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - if self.pos as usize == self.buf.len() { - if self.finished { - return Ok(0); - } - - let _ = try!(self.read_block_type()); - let _ = match self.btype { - BlockType::Stored => try!(self.read_stored_block()), - BlockType::Compressed => try!(self.read_compressed_block()) - }; - } - - let n = cmp::min(buf.len(), self.buf.len() - self.pos as usize); - for i in (0usize..n) { - buf[i] = self.buf[self.pos as usize + i]; - } - - self.pos += n as u64; - Ok(n) - } -} - -fn reverse(a: u16) -> u16 { - let b = (((!0x5555) & a) >> 1) | ((0x5555 & a) << 1); - let c = (((!0x3333) & b) >> 2) | ((0x3333 & b) << 2); - let d = (((!0x0F0F) & c) >> 4) | ((0x0F0F & c) << 4); - - (((!0x00FF) & d) >> 8) | ((0x00FF & d) << 8) -} - -fn table_from_lengths(lengths: &[u8]) -> Vec { - let mut max_len = 0; - let mut code = 0u16; - let mut next_code: Vec = repeat(0u16).take(16).collect(); - let mut bl_count: Vec> = repeat(w(0u8)).take(16).collect(); - - for &len in lengths.iter() { - bl_count[len as usize] = bl_count[len as usize] + w(1); - if len > max_len { - max_len = len; - } - } - - let max_overflow = (w(max_len) - w(TABLESIZE)).0; - bl_count[0] = w(0); - - for bits in (1usize..16) { - code = (code + bl_count[bits - 1].0 as u16) << 1; - next_code[bits] = code; - } - - let mut lut: Vec = repeat(TableElement::Nothing).take(1 << TABLESIZE as usize).collect(); - - for (i, &len) in lengths.iter().enumerate() { - if len == 0 { - continue - } - - let code = next_code[len as usize]; - let code = reverse(code) >> (16 - len) as usize; - - if len <= TABLESIZE { - let r = TABLESIZE - len; - - for j in (0u16..1 << r as usize) { - let index = (j << len as usize) + code; - lut[index as usize] = TableElement::Symbol(i as u16, len); - } - } else { - let index = code & ((1 << TABLESIZE as usize) - 1); - - if lut[index as usize] == TableElement::Nothing { - let mask = (1 << max_overflow) - 1; - let array: Vec = repeat(TableElement::Nothing).take(1 << max_overflow).collect(); - - lut[index as usize] = TableElement::Table(mask, array); - } - - let code = code >> TABLESIZE as usize; - let r = max_len - len; - - for j in (0u16..1 << r as usize) { - let k = (j << (len - TABLESIZE) as usize) + code; - let s = TableElement::Symbol(i as u16, len - TABLESIZE); - - lut[index as usize].put(k, s); - } - } - - next_code[len as usize] += 1; - } - - lut -} - -struct HuffReader { - pub r: R, - - bits: u32, - num_bits: u8, -} - -impl HuffReader { - pub fn new(r: R) -> HuffReader { - HuffReader {r: r, bits: 0, num_bits: 0} - } - - pub fn guarantee(&mut self, n: u8) -> io::Result<()> { - while self.num_bits < n { - let byte = try!(self.r.read_u8()); - - self.bits |= (byte as u32) << self.num_bits as usize; - self.num_bits += 8; - } - - Ok(()) - } - - pub fn byte_align(&mut self) { - let n = self.num_bits & 0b111; - - self.bits >>= n as usize; - self.num_bits -= n as u8; - } - - pub fn consume(&mut self, n: u8) { - self.bits >>= n as usize; - self.num_bits -= n; - } - - pub fn receive(&mut self, n: u8) -> io::Result { - let _ = try!(self.guarantee(n)); - - let val = self.bits & ((1 << n as usize) - 1); - self.consume(n); - - Ok(val as u16) - } - - pub fn decode_symbol(&mut self, table: &[TableElement]) -> io::Result { - let _ = try!(self.guarantee(1)); - - loop { - let index = self.bits & ((1 << TABLESIZE as usize) - 1); - - let (val, size) = match table[index as usize] { - TableElement::Symbol(val, size) => (val, size), - - TableElement::Table(mask, ref a) => { - let index = (self.bits >> TABLESIZE as usize) & mask as u32; - - match a[index as usize] { - TableElement::Symbol(val, size) => (val, size + TABLESIZE), - _ => panic!("bad huffman code") - } - } - - TableElement::Nothing => panic!("bad huffman code") - }; - - if size <= self.num_bits { - self.consume(size); - return Ok(val) - } - - let _ = try!(self.guarantee(size)); - } - } -} diff --git a/src/png/mod.rs b/src/png/mod.rs deleted file mode 100644 index 0e5ea78e3d..0000000000 --- a/src/png/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Decoding and Encoding of PNG Images -//! -//! PNG (Portable Network Graphics) is an image format that supports lossless compression. -//! -//! # Related Links -//! * http://www.w3.org/TR/PNG/ - The PNG Specification -//! - -pub use self::decoder::PNGDecoder; -pub use self::encoder::PNGEncoder; - -mod filter; -mod decoder; -mod encoder; -pub mod zlib; -pub mod deflate; -pub mod inflate; -pub mod hash; \ No newline at end of file diff --git a/src/png/testdata/pngsuite/PngSuite.LICENSE b/src/png/testdata/pngsuite/PngSuite.LICENSE deleted file mode 100644 index 8d4d1d0777..0000000000 --- a/src/png/testdata/pngsuite/PngSuite.LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -PngSuite --------- - -Permission to use, copy, modify and distribute these images for any -purpose and without fee is hereby granted. - - -(c) Willem van Schaik, 1996, 2011 - diff --git a/src/png/testdata/pngsuite/PngSuite.README b/src/png/testdata/pngsuite/PngSuite.README deleted file mode 100644 index 94df6ccffa..0000000000 --- a/src/png/testdata/pngsuite/PngSuite.README +++ /dev/null @@ -1,25 +0,0 @@ - PNGSUITE ----------------- - - testset for PNG-(de)coders - created by Willem van Schaik ------------------------------------- - -This is a collection of graphics images created to test the png applications -like viewers, converters and editors. All (as far as that is possible) -formats supported by the PNG standard are represented. - -The suite consists of the following files: - -- PngSuite.README - this file -- PngSuite.LICENSE - the PngSuite is freeware -- PngSuite.png - image with PngSuite logo -- PngSuite.tgz - archive of all PNG testfiles -- PngSuite.zip - same in .zip format for PCs - - --------- - (c) Willem van Schaik - willem@schaik.com - Calgary, April 2011 - diff --git a/src/png/testdata/pngsuite/PngSuite.png b/src/png/testdata/pngsuite/PngSuite.png deleted file mode 100644 index 205460d828..0000000000 Binary files a/src/png/testdata/pngsuite/PngSuite.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi0g01.png b/src/png/testdata/pngsuite/basi0g01.png deleted file mode 100644 index 556fa72704..0000000000 Binary files a/src/png/testdata/pngsuite/basi0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi0g02.png b/src/png/testdata/pngsuite/basi0g02.png deleted file mode 100644 index ce09821ef1..0000000000 Binary files a/src/png/testdata/pngsuite/basi0g02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi0g04.png b/src/png/testdata/pngsuite/basi0g04.png deleted file mode 100644 index 3853273f93..0000000000 Binary files a/src/png/testdata/pngsuite/basi0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi0g08.png b/src/png/testdata/pngsuite/basi0g08.png deleted file mode 100644 index faed8bec44..0000000000 Binary files a/src/png/testdata/pngsuite/basi0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi0g16.png b/src/png/testdata/pngsuite/basi0g16.png deleted file mode 100644 index a9f28165ef..0000000000 Binary files a/src/png/testdata/pngsuite/basi0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi2c08.png b/src/png/testdata/pngsuite/basi2c08.png deleted file mode 100644 index 2aab44d42b..0000000000 Binary files a/src/png/testdata/pngsuite/basi2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi2c16.png b/src/png/testdata/pngsuite/basi2c16.png deleted file mode 100644 index cd7e50f914..0000000000 Binary files a/src/png/testdata/pngsuite/basi2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi3p01.png b/src/png/testdata/pngsuite/basi3p01.png deleted file mode 100644 index 00a7cea6c2..0000000000 Binary files a/src/png/testdata/pngsuite/basi3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi3p01_2.png b/src/png/testdata/pngsuite/basi3p01_2.png deleted file mode 100644 index 7b13f77b95..0000000000 Binary files a/src/png/testdata/pngsuite/basi3p01_2.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi3p02.png b/src/png/testdata/pngsuite/basi3p02.png deleted file mode 100644 index bb16b44b30..0000000000 Binary files a/src/png/testdata/pngsuite/basi3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi3p02_2.png b/src/png/testdata/pngsuite/basi3p02_2.png deleted file mode 100644 index 8f75932087..0000000000 Binary files a/src/png/testdata/pngsuite/basi3p02_2.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi3p04.png b/src/png/testdata/pngsuite/basi3p04.png deleted file mode 100644 index b4e888e247..0000000000 Binary files a/src/png/testdata/pngsuite/basi3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi3p08.png b/src/png/testdata/pngsuite/basi3p08.png deleted file mode 100644 index 50a6d1cac7..0000000000 Binary files a/src/png/testdata/pngsuite/basi3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi4a08.png b/src/png/testdata/pngsuite/basi4a08.png deleted file mode 100644 index 398132be5f..0000000000 Binary files a/src/png/testdata/pngsuite/basi4a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi4a16.png b/src/png/testdata/pngsuite/basi4a16.png deleted file mode 100644 index 51192e7311..0000000000 Binary files a/src/png/testdata/pngsuite/basi4a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi6a08.png b/src/png/testdata/pngsuite/basi6a08.png deleted file mode 100644 index aecb32e0d9..0000000000 Binary files a/src/png/testdata/pngsuite/basi6a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basi6a16.png b/src/png/testdata/pngsuite/basi6a16.png deleted file mode 100644 index 4181533ad8..0000000000 Binary files a/src/png/testdata/pngsuite/basi6a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn0g01.png b/src/png/testdata/pngsuite/basn0g01.png deleted file mode 100644 index 1d722423aa..0000000000 Binary files a/src/png/testdata/pngsuite/basn0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn0g02.png b/src/png/testdata/pngsuite/basn0g02.png deleted file mode 100644 index 508332418f..0000000000 Binary files a/src/png/testdata/pngsuite/basn0g02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn0g04.png b/src/png/testdata/pngsuite/basn0g04.png deleted file mode 100644 index 0bf3687863..0000000000 Binary files a/src/png/testdata/pngsuite/basn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn0g08.png b/src/png/testdata/pngsuite/basn0g08.png deleted file mode 100644 index 23c82379a2..0000000000 Binary files a/src/png/testdata/pngsuite/basn0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn0g16.png b/src/png/testdata/pngsuite/basn0g16.png deleted file mode 100644 index e7c82f78eb..0000000000 Binary files a/src/png/testdata/pngsuite/basn0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn2c08.png b/src/png/testdata/pngsuite/basn2c08.png deleted file mode 100644 index db5ad15865..0000000000 Binary files a/src/png/testdata/pngsuite/basn2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn2c16.png b/src/png/testdata/pngsuite/basn2c16.png deleted file mode 100644 index 50c1cb91a0..0000000000 Binary files a/src/png/testdata/pngsuite/basn2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn3p01.png b/src/png/testdata/pngsuite/basn3p01.png deleted file mode 100644 index b145c2b8ef..0000000000 Binary files a/src/png/testdata/pngsuite/basn3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn3p02.png b/src/png/testdata/pngsuite/basn3p02.png deleted file mode 100644 index 8985b3d818..0000000000 Binary files a/src/png/testdata/pngsuite/basn3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn3p04.png b/src/png/testdata/pngsuite/basn3p04.png deleted file mode 100644 index 0fbf9e827b..0000000000 Binary files a/src/png/testdata/pngsuite/basn3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn3p08.png b/src/png/testdata/pngsuite/basn3p08.png deleted file mode 100644 index 0ddad07e5f..0000000000 Binary files a/src/png/testdata/pngsuite/basn3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn4a08.png b/src/png/testdata/pngsuite/basn4a08.png deleted file mode 100644 index 3e13052201..0000000000 Binary files a/src/png/testdata/pngsuite/basn4a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn4a16.png b/src/png/testdata/pngsuite/basn4a16.png deleted file mode 100644 index 8243644d07..0000000000 Binary files a/src/png/testdata/pngsuite/basn4a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn6a08.png b/src/png/testdata/pngsuite/basn6a08.png deleted file mode 100644 index e608738763..0000000000 Binary files a/src/png/testdata/pngsuite/basn6a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/basn6a16.png b/src/png/testdata/pngsuite/basn6a16.png deleted file mode 100644 index 984a99525f..0000000000 Binary files a/src/png/testdata/pngsuite/basn6a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgai4a08.png b/src/png/testdata/pngsuite/bgai4a08.png deleted file mode 100644 index 398132be5f..0000000000 Binary files a/src/png/testdata/pngsuite/bgai4a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgai4a16.png b/src/png/testdata/pngsuite/bgai4a16.png deleted file mode 100644 index 51192e7311..0000000000 Binary files a/src/png/testdata/pngsuite/bgai4a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgan6a08.png b/src/png/testdata/pngsuite/bgan6a08.png deleted file mode 100644 index e608738763..0000000000 Binary files a/src/png/testdata/pngsuite/bgan6a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgan6a16.png b/src/png/testdata/pngsuite/bgan6a16.png deleted file mode 100644 index 984a99525f..0000000000 Binary files a/src/png/testdata/pngsuite/bgan6a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgbn4a08.png b/src/png/testdata/pngsuite/bgbn4a08.png deleted file mode 100644 index 7cbefc3bff..0000000000 Binary files a/src/png/testdata/pngsuite/bgbn4a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bggn4a16.png b/src/png/testdata/pngsuite/bggn4a16.png deleted file mode 100644 index 13fd85ba19..0000000000 Binary files a/src/png/testdata/pngsuite/bggn4a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgwn6a08.png b/src/png/testdata/pngsuite/bgwn6a08.png deleted file mode 100644 index a67ff205bb..0000000000 Binary files a/src/png/testdata/pngsuite/bgwn6a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/bgyn6a16.png b/src/png/testdata/pngsuite/bgyn6a16.png deleted file mode 100644 index ae3e9be58a..0000000000 Binary files a/src/png/testdata/pngsuite/bgyn6a16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ccwn2c08.png b/src/png/testdata/pngsuite/ccwn2c08.png deleted file mode 100644 index 47c24817b7..0000000000 Binary files a/src/png/testdata/pngsuite/ccwn2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ccwn3p08.png b/src/png/testdata/pngsuite/ccwn3p08.png deleted file mode 100644 index 8bb2c10981..0000000000 Binary files a/src/png/testdata/pngsuite/ccwn3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cdfn2c08.png b/src/png/testdata/pngsuite/cdfn2c08.png deleted file mode 100644 index 559e5261e7..0000000000 Binary files a/src/png/testdata/pngsuite/cdfn2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cdhn2c08.png b/src/png/testdata/pngsuite/cdhn2c08.png deleted file mode 100644 index 3e07e8ecbd..0000000000 Binary files a/src/png/testdata/pngsuite/cdhn2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cdsn2c08.png b/src/png/testdata/pngsuite/cdsn2c08.png deleted file mode 100644 index 076c32cc08..0000000000 Binary files a/src/png/testdata/pngsuite/cdsn2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cdun2c08.png b/src/png/testdata/pngsuite/cdun2c08.png deleted file mode 100644 index 846033be6b..0000000000 Binary files a/src/png/testdata/pngsuite/cdun2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ch1n3p04.png b/src/png/testdata/pngsuite/ch1n3p04.png deleted file mode 100644 index 17cd12dfc9..0000000000 Binary files a/src/png/testdata/pngsuite/ch1n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ch2n3p08.png b/src/png/testdata/pngsuite/ch2n3p08.png deleted file mode 100644 index 25c17987a7..0000000000 Binary files a/src/png/testdata/pngsuite/ch2n3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cm0n0g04.png b/src/png/testdata/pngsuite/cm0n0g04.png deleted file mode 100644 index 9fba5db3b8..0000000000 Binary files a/src/png/testdata/pngsuite/cm0n0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cm7n0g04.png b/src/png/testdata/pngsuite/cm7n0g04.png deleted file mode 100644 index f7dc46e685..0000000000 Binary files a/src/png/testdata/pngsuite/cm7n0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cm9n0g04.png b/src/png/testdata/pngsuite/cm9n0g04.png deleted file mode 100644 index dd70911adc..0000000000 Binary files a/src/png/testdata/pngsuite/cm9n0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cs3n2c16.png b/src/png/testdata/pngsuite/cs3n2c16.png deleted file mode 100644 index bf5fd20a20..0000000000 Binary files a/src/png/testdata/pngsuite/cs3n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cs3n3p08.png b/src/png/testdata/pngsuite/cs3n3p08.png deleted file mode 100644 index f4a66237bf..0000000000 Binary files a/src/png/testdata/pngsuite/cs3n3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cs5n2c08.png b/src/png/testdata/pngsuite/cs5n2c08.png deleted file mode 100644 index 40f947c33e..0000000000 Binary files a/src/png/testdata/pngsuite/cs5n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cs5n3p08.png b/src/png/testdata/pngsuite/cs5n3p08.png deleted file mode 100644 index dfd6e6e6ec..0000000000 Binary files a/src/png/testdata/pngsuite/cs5n3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cs8n2c08.png b/src/png/testdata/pngsuite/cs8n2c08.png deleted file mode 100644 index 8e01d3294f..0000000000 Binary files a/src/png/testdata/pngsuite/cs8n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cs8n3p08.png b/src/png/testdata/pngsuite/cs8n3p08.png deleted file mode 100644 index a44066eb6e..0000000000 Binary files a/src/png/testdata/pngsuite/cs8n3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ct0n0g04.png b/src/png/testdata/pngsuite/ct0n0g04.png deleted file mode 100644 index 40d1e062f8..0000000000 Binary files a/src/png/testdata/pngsuite/ct0n0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ct1n0g04.png b/src/png/testdata/pngsuite/ct1n0g04.png deleted file mode 100644 index 3ba110aa76..0000000000 Binary files a/src/png/testdata/pngsuite/ct1n0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cten0g04.png b/src/png/testdata/pngsuite/cten0g04.png deleted file mode 100644 index a6a56faf2b..0000000000 Binary files a/src/png/testdata/pngsuite/cten0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ctfn0g04.png b/src/png/testdata/pngsuite/ctfn0g04.png deleted file mode 100644 index 353873ebbd..0000000000 Binary files a/src/png/testdata/pngsuite/ctfn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ctgn0g04.png b/src/png/testdata/pngsuite/ctgn0g04.png deleted file mode 100644 index 453f2b0a49..0000000000 Binary files a/src/png/testdata/pngsuite/ctgn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/cthn0g04.png b/src/png/testdata/pngsuite/cthn0g04.png deleted file mode 100644 index 8fce253e6d..0000000000 Binary files a/src/png/testdata/pngsuite/cthn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ctjn0g04.png b/src/png/testdata/pngsuite/ctjn0g04.png deleted file mode 100644 index a77b8d2fee..0000000000 Binary files a/src/png/testdata/pngsuite/ctjn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ctzn0g04.png b/src/png/testdata/pngsuite/ctzn0g04.png deleted file mode 100644 index b4401c9cfc..0000000000 Binary files a/src/png/testdata/pngsuite/ctzn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f00n0g08.png b/src/png/testdata/pngsuite/f00n0g08.png deleted file mode 100644 index 45a0075967..0000000000 Binary files a/src/png/testdata/pngsuite/f00n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f00n2c08.png b/src/png/testdata/pngsuite/f00n2c08.png deleted file mode 100644 index d6a1ffff62..0000000000 Binary files a/src/png/testdata/pngsuite/f00n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f01n0g08.png b/src/png/testdata/pngsuite/f01n0g08.png deleted file mode 100644 index 4a1107b463..0000000000 Binary files a/src/png/testdata/pngsuite/f01n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f01n2c08.png b/src/png/testdata/pngsuite/f01n2c08.png deleted file mode 100644 index 26fee958ce..0000000000 Binary files a/src/png/testdata/pngsuite/f01n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f02n0g08.png b/src/png/testdata/pngsuite/f02n0g08.png deleted file mode 100644 index bfe410c5e7..0000000000 Binary files a/src/png/testdata/pngsuite/f02n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f02n2c08.png b/src/png/testdata/pngsuite/f02n2c08.png deleted file mode 100644 index e590f12348..0000000000 Binary files a/src/png/testdata/pngsuite/f02n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f03n0g08.png b/src/png/testdata/pngsuite/f03n0g08.png deleted file mode 100644 index ed01e2923c..0000000000 Binary files a/src/png/testdata/pngsuite/f03n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f03n2c08.png b/src/png/testdata/pngsuite/f03n2c08.png deleted file mode 100644 index 758115059d..0000000000 Binary files a/src/png/testdata/pngsuite/f03n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f04n0g08.png b/src/png/testdata/pngsuite/f04n0g08.png deleted file mode 100644 index 663fdae3e7..0000000000 Binary files a/src/png/testdata/pngsuite/f04n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f04n2c08.png b/src/png/testdata/pngsuite/f04n2c08.png deleted file mode 100644 index 3c8b5116e7..0000000000 Binary files a/src/png/testdata/pngsuite/f04n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/f99n0g04.png b/src/png/testdata/pngsuite/f99n0g04.png deleted file mode 100644 index 0b521c1d56..0000000000 Binary files a/src/png/testdata/pngsuite/f99n0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g03n0g16.png b/src/png/testdata/pngsuite/g03n0g16.png deleted file mode 100644 index 41083ca80f..0000000000 Binary files a/src/png/testdata/pngsuite/g03n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g03n2c08.png b/src/png/testdata/pngsuite/g03n2c08.png deleted file mode 100644 index a9354dbee6..0000000000 Binary files a/src/png/testdata/pngsuite/g03n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g03n3p04.png b/src/png/testdata/pngsuite/g03n3p04.png deleted file mode 100644 index 60396c95af..0000000000 Binary files a/src/png/testdata/pngsuite/g03n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g04n0g16.png b/src/png/testdata/pngsuite/g04n0g16.png deleted file mode 100644 index 32395b76c9..0000000000 Binary files a/src/png/testdata/pngsuite/g04n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g04n2c08.png b/src/png/testdata/pngsuite/g04n2c08.png deleted file mode 100644 index a652b0ce87..0000000000 Binary files a/src/png/testdata/pngsuite/g04n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g04n3p04.png b/src/png/testdata/pngsuite/g04n3p04.png deleted file mode 100644 index 5661cc3131..0000000000 Binary files a/src/png/testdata/pngsuite/g04n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g05n0g16.png b/src/png/testdata/pngsuite/g05n0g16.png deleted file mode 100644 index 70b37f01e2..0000000000 Binary files a/src/png/testdata/pngsuite/g05n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g05n2c08.png b/src/png/testdata/pngsuite/g05n2c08.png deleted file mode 100644 index 932c136536..0000000000 Binary files a/src/png/testdata/pngsuite/g05n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g05n3p04.png b/src/png/testdata/pngsuite/g05n3p04.png deleted file mode 100644 index 9619930585..0000000000 Binary files a/src/png/testdata/pngsuite/g05n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g07n0g16.png b/src/png/testdata/pngsuite/g07n0g16.png deleted file mode 100644 index d6a47c2d57..0000000000 Binary files a/src/png/testdata/pngsuite/g07n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g07n2c08.png b/src/png/testdata/pngsuite/g07n2c08.png deleted file mode 100644 index 597346460f..0000000000 Binary files a/src/png/testdata/pngsuite/g07n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g07n3p04.png b/src/png/testdata/pngsuite/g07n3p04.png deleted file mode 100644 index c73fb61365..0000000000 Binary files a/src/png/testdata/pngsuite/g07n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g10n0g16.png b/src/png/testdata/pngsuite/g10n0g16.png deleted file mode 100644 index 85f2c958e9..0000000000 Binary files a/src/png/testdata/pngsuite/g10n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g10n2c08.png b/src/png/testdata/pngsuite/g10n2c08.png deleted file mode 100644 index b3039970c1..0000000000 Binary files a/src/png/testdata/pngsuite/g10n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g10n3p04.png b/src/png/testdata/pngsuite/g10n3p04.png deleted file mode 100644 index 1b6a6be2ca..0000000000 Binary files a/src/png/testdata/pngsuite/g10n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g25n0g16.png b/src/png/testdata/pngsuite/g25n0g16.png deleted file mode 100644 index a9f6787c7a..0000000000 Binary files a/src/png/testdata/pngsuite/g25n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g25n2c08.png b/src/png/testdata/pngsuite/g25n2c08.png deleted file mode 100644 index 03f505a64b..0000000000 Binary files a/src/png/testdata/pngsuite/g25n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/g25n3p04.png b/src/png/testdata/pngsuite/g25n3p04.png deleted file mode 100644 index 4f943c6175..0000000000 Binary files a/src/png/testdata/pngsuite/g25n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi1n0g16.png b/src/png/testdata/pngsuite/oi1n0g16.png deleted file mode 100644 index e7c82f78eb..0000000000 Binary files a/src/png/testdata/pngsuite/oi1n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi1n2c16.png b/src/png/testdata/pngsuite/oi1n2c16.png deleted file mode 100644 index 50c1cb91a0..0000000000 Binary files a/src/png/testdata/pngsuite/oi1n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi2n0g16.png b/src/png/testdata/pngsuite/oi2n0g16.png deleted file mode 100644 index 14d64c583d..0000000000 Binary files a/src/png/testdata/pngsuite/oi2n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi2n2c16.png b/src/png/testdata/pngsuite/oi2n2c16.png deleted file mode 100644 index 4c2e3e3352..0000000000 Binary files a/src/png/testdata/pngsuite/oi2n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi4n0g16.png b/src/png/testdata/pngsuite/oi4n0g16.png deleted file mode 100644 index 69e73ede31..0000000000 Binary files a/src/png/testdata/pngsuite/oi4n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi4n2c16.png b/src/png/testdata/pngsuite/oi4n2c16.png deleted file mode 100644 index 93691e373a..0000000000 Binary files a/src/png/testdata/pngsuite/oi4n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi9n0g16.png b/src/png/testdata/pngsuite/oi9n0g16.png deleted file mode 100644 index 9248413576..0000000000 Binary files a/src/png/testdata/pngsuite/oi9n0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/oi9n2c16.png b/src/png/testdata/pngsuite/oi9n2c16.png deleted file mode 100644 index f0512e49f2..0000000000 Binary files a/src/png/testdata/pngsuite/oi9n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/pp0n2c16.png b/src/png/testdata/pngsuite/pp0n2c16.png deleted file mode 100644 index 8f2aad7335..0000000000 Binary files a/src/png/testdata/pngsuite/pp0n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/pp0n6a08.png b/src/png/testdata/pngsuite/pp0n6a08.png deleted file mode 100644 index 4ed7a30e4d..0000000000 Binary files a/src/png/testdata/pngsuite/pp0n6a08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ps1n0g08.png b/src/png/testdata/pngsuite/ps1n0g08.png deleted file mode 100644 index 99625fa4ba..0000000000 Binary files a/src/png/testdata/pngsuite/ps1n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ps1n2c16.png b/src/png/testdata/pngsuite/ps1n2c16.png deleted file mode 100644 index 0c7a6b380e..0000000000 Binary files a/src/png/testdata/pngsuite/ps1n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ps2n0g08.png b/src/png/testdata/pngsuite/ps2n0g08.png deleted file mode 100644 index 90b2979685..0000000000 Binary files a/src/png/testdata/pngsuite/ps2n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/ps2n2c16.png b/src/png/testdata/pngsuite/ps2n2c16.png deleted file mode 100644 index a4a181e4ec..0000000000 Binary files a/src/png/testdata/pngsuite/ps2n2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s01i3p01.png b/src/png/testdata/pngsuite/s01i3p01.png deleted file mode 100644 index 6c0fad1fc9..0000000000 Binary files a/src/png/testdata/pngsuite/s01i3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s01n3p01.png b/src/png/testdata/pngsuite/s01n3p01.png deleted file mode 100644 index cb2c8c7826..0000000000 Binary files a/src/png/testdata/pngsuite/s01n3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s02i3p01.png b/src/png/testdata/pngsuite/s02i3p01.png deleted file mode 100644 index 2defaed911..0000000000 Binary files a/src/png/testdata/pngsuite/s02i3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s02n3p01.png b/src/png/testdata/pngsuite/s02n3p01.png deleted file mode 100644 index 2b1b669643..0000000000 Binary files a/src/png/testdata/pngsuite/s02n3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s03i3p01.png b/src/png/testdata/pngsuite/s03i3p01.png deleted file mode 100644 index c23fdc4631..0000000000 Binary files a/src/png/testdata/pngsuite/s03i3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s03n3p01.png b/src/png/testdata/pngsuite/s03n3p01.png deleted file mode 100644 index 6d96ee4f87..0000000000 Binary files a/src/png/testdata/pngsuite/s03n3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s04i3p01.png b/src/png/testdata/pngsuite/s04i3p01.png deleted file mode 100644 index 0e710c2c39..0000000000 Binary files a/src/png/testdata/pngsuite/s04i3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s04n3p01.png b/src/png/testdata/pngsuite/s04n3p01.png deleted file mode 100644 index 956396c45b..0000000000 Binary files a/src/png/testdata/pngsuite/s04n3p01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s05i3p02.png b/src/png/testdata/pngsuite/s05i3p02.png deleted file mode 100644 index d14cbd351a..0000000000 Binary files a/src/png/testdata/pngsuite/s05i3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s05n3p02.png b/src/png/testdata/pngsuite/s05n3p02.png deleted file mode 100644 index bf940f0576..0000000000 Binary files a/src/png/testdata/pngsuite/s05n3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s06i3p02.png b/src/png/testdata/pngsuite/s06i3p02.png deleted file mode 100644 index 456ada3200..0000000000 Binary files a/src/png/testdata/pngsuite/s06i3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s06n3p02.png b/src/png/testdata/pngsuite/s06n3p02.png deleted file mode 100644 index 501064dc25..0000000000 Binary files a/src/png/testdata/pngsuite/s06n3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s07i3p02.png b/src/png/testdata/pngsuite/s07i3p02.png deleted file mode 100644 index 44b66bab9e..0000000000 Binary files a/src/png/testdata/pngsuite/s07i3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s07n3p02.png b/src/png/testdata/pngsuite/s07n3p02.png deleted file mode 100644 index 6a582593d6..0000000000 Binary files a/src/png/testdata/pngsuite/s07n3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s08i3p02.png b/src/png/testdata/pngsuite/s08i3p02.png deleted file mode 100644 index acf74f3fc4..0000000000 Binary files a/src/png/testdata/pngsuite/s08i3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s08n3p02.png b/src/png/testdata/pngsuite/s08n3p02.png deleted file mode 100644 index b7094e1b4f..0000000000 Binary files a/src/png/testdata/pngsuite/s08n3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s09i3p02.png b/src/png/testdata/pngsuite/s09i3p02.png deleted file mode 100644 index 0bfae8e456..0000000000 Binary files a/src/png/testdata/pngsuite/s09i3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s09n3p02.png b/src/png/testdata/pngsuite/s09n3p02.png deleted file mode 100644 index 711ab82451..0000000000 Binary files a/src/png/testdata/pngsuite/s09n3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s32i3p04.png b/src/png/testdata/pngsuite/s32i3p04.png deleted file mode 100644 index 0841910b72..0000000000 Binary files a/src/png/testdata/pngsuite/s32i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s32n3p04.png b/src/png/testdata/pngsuite/s32n3p04.png deleted file mode 100644 index fa58e3e3f6..0000000000 Binary files a/src/png/testdata/pngsuite/s32n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s33i3p04.png b/src/png/testdata/pngsuite/s33i3p04.png deleted file mode 100644 index ab0dc14aba..0000000000 Binary files a/src/png/testdata/pngsuite/s33i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s33n3p04.png b/src/png/testdata/pngsuite/s33n3p04.png deleted file mode 100644 index 764f1a3dc7..0000000000 Binary files a/src/png/testdata/pngsuite/s33n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s34i3p04.png b/src/png/testdata/pngsuite/s34i3p04.png deleted file mode 100644 index bd99039be4..0000000000 Binary files a/src/png/testdata/pngsuite/s34i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s34n3p04.png b/src/png/testdata/pngsuite/s34n3p04.png deleted file mode 100644 index 9cbc68b3b9..0000000000 Binary files a/src/png/testdata/pngsuite/s34n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s35i3p04.png b/src/png/testdata/pngsuite/s35i3p04.png deleted file mode 100644 index e2a5e0a659..0000000000 Binary files a/src/png/testdata/pngsuite/s35i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s35n3p04.png b/src/png/testdata/pngsuite/s35n3p04.png deleted file mode 100644 index 90b892ebaf..0000000000 Binary files a/src/png/testdata/pngsuite/s35n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s36i3p04.png b/src/png/testdata/pngsuite/s36i3p04.png deleted file mode 100644 index eb61b6f9a3..0000000000 Binary files a/src/png/testdata/pngsuite/s36i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s36n3p04.png b/src/png/testdata/pngsuite/s36n3p04.png deleted file mode 100644 index b38d179774..0000000000 Binary files a/src/png/testdata/pngsuite/s36n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s37i3p04.png b/src/png/testdata/pngsuite/s37i3p04.png deleted file mode 100644 index 6e2b1e9b79..0000000000 Binary files a/src/png/testdata/pngsuite/s37i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s37n3p04.png b/src/png/testdata/pngsuite/s37n3p04.png deleted file mode 100644 index 4d3054da51..0000000000 Binary files a/src/png/testdata/pngsuite/s37n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s38i3p04.png b/src/png/testdata/pngsuite/s38i3p04.png deleted file mode 100644 index a0a8a140ad..0000000000 Binary files a/src/png/testdata/pngsuite/s38i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s38n3p04.png b/src/png/testdata/pngsuite/s38n3p04.png deleted file mode 100644 index 1233ed048e..0000000000 Binary files a/src/png/testdata/pngsuite/s38n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s39i3p04.png b/src/png/testdata/pngsuite/s39i3p04.png deleted file mode 100644 index 04fee93eae..0000000000 Binary files a/src/png/testdata/pngsuite/s39i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s39n3p04.png b/src/png/testdata/pngsuite/s39n3p04.png deleted file mode 100644 index c750100d55..0000000000 Binary files a/src/png/testdata/pngsuite/s39n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s40i3p04.png b/src/png/testdata/pngsuite/s40i3p04.png deleted file mode 100644 index 68f358b822..0000000000 Binary files a/src/png/testdata/pngsuite/s40i3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/s40n3p04.png b/src/png/testdata/pngsuite/s40n3p04.png deleted file mode 100644 index 864b6b9673..0000000000 Binary files a/src/png/testdata/pngsuite/s40n3p04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbbn0g04.png b/src/png/testdata/pngsuite/tbbn0g04.png deleted file mode 100644 index 39a7050d27..0000000000 Binary files a/src/png/testdata/pngsuite/tbbn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbbn2c16.png b/src/png/testdata/pngsuite/tbbn2c16.png deleted file mode 100644 index dd3168e5c8..0000000000 Binary files a/src/png/testdata/pngsuite/tbbn2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbbn3p08.png b/src/png/testdata/pngsuite/tbbn3p08.png deleted file mode 100644 index 0ede3574db..0000000000 Binary files a/src/png/testdata/pngsuite/tbbn3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbgn2c16.png b/src/png/testdata/pngsuite/tbgn2c16.png deleted file mode 100644 index 85cec395c0..0000000000 Binary files a/src/png/testdata/pngsuite/tbgn2c16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbgn3p08.png b/src/png/testdata/pngsuite/tbgn3p08.png deleted file mode 100644 index 8cf2e6fb6a..0000000000 Binary files a/src/png/testdata/pngsuite/tbgn3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbrn2c08.png b/src/png/testdata/pngsuite/tbrn2c08.png deleted file mode 100644 index 5cca0d6210..0000000000 Binary files a/src/png/testdata/pngsuite/tbrn2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbwn0g16.png b/src/png/testdata/pngsuite/tbwn0g16.png deleted file mode 100644 index 99bdeed2b3..0000000000 Binary files a/src/png/testdata/pngsuite/tbwn0g16.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbwn3p08.png b/src/png/testdata/pngsuite/tbwn3p08.png deleted file mode 100644 index eacab7a144..0000000000 Binary files a/src/png/testdata/pngsuite/tbwn3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tbyn3p08.png b/src/png/testdata/pngsuite/tbyn3p08.png deleted file mode 100644 index 656db0989a..0000000000 Binary files a/src/png/testdata/pngsuite/tbyn3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tm3n3p02.png b/src/png/testdata/pngsuite/tm3n3p02.png deleted file mode 100644 index fb3ef1d0c5..0000000000 Binary files a/src/png/testdata/pngsuite/tm3n3p02.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tp0n0g08.png b/src/png/testdata/pngsuite/tp0n0g08.png deleted file mode 100644 index 333465fcdc..0000000000 Binary files a/src/png/testdata/pngsuite/tp0n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tp0n2c08.png b/src/png/testdata/pngsuite/tp0n2c08.png deleted file mode 100644 index fc6e42cb42..0000000000 Binary files a/src/png/testdata/pngsuite/tp0n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tp0n3p08.png b/src/png/testdata/pngsuite/tp0n3p08.png deleted file mode 100644 index 69a69e5872..0000000000 Binary files a/src/png/testdata/pngsuite/tp0n3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/tp1n3p08.png b/src/png/testdata/pngsuite/tp1n3p08.png deleted file mode 100644 index a6c9f35a86..0000000000 Binary files a/src/png/testdata/pngsuite/tp1n3p08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xc1n0g08.png b/src/png/testdata/pngsuite/xc1n0g08.png deleted file mode 100644 index 9404227370..0000000000 Binary files a/src/png/testdata/pngsuite/xc1n0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xc9n2c08.png b/src/png/testdata/pngsuite/xc9n2c08.png deleted file mode 100644 index b11c2a7b40..0000000000 Binary files a/src/png/testdata/pngsuite/xc9n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xcrn0g04.png b/src/png/testdata/pngsuite/xcrn0g04.png deleted file mode 100644 index 48abba193a..0000000000 Binary files a/src/png/testdata/pngsuite/xcrn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xcsn0g01.png b/src/png/testdata/pngsuite/xcsn0g01.png deleted file mode 100644 index 9863a262ca..0000000000 Binary files a/src/png/testdata/pngsuite/xcsn0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xd0n2c08.png b/src/png/testdata/pngsuite/xd0n2c08.png deleted file mode 100644 index 2f001610a8..0000000000 Binary files a/src/png/testdata/pngsuite/xd0n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xd3n2c08.png b/src/png/testdata/pngsuite/xd3n2c08.png deleted file mode 100644 index 9e4a3ff7ac..0000000000 Binary files a/src/png/testdata/pngsuite/xd3n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xd9n2c08.png b/src/png/testdata/pngsuite/xd9n2c08.png deleted file mode 100644 index 2c3b91aa4f..0000000000 Binary files a/src/png/testdata/pngsuite/xd9n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xdtn0g01.png b/src/png/testdata/pngsuite/xdtn0g01.png deleted file mode 100644 index 1a81abef82..0000000000 Binary files a/src/png/testdata/pngsuite/xdtn0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xhdn0g08.png b/src/png/testdata/pngsuite/xhdn0g08.png deleted file mode 100644 index fcb8737fa2..0000000000 Binary files a/src/png/testdata/pngsuite/xhdn0g08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xlfn0g04.png b/src/png/testdata/pngsuite/xlfn0g04.png deleted file mode 100644 index d9ec53ed94..0000000000 Binary files a/src/png/testdata/pngsuite/xlfn0g04.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xs1n0g01.png b/src/png/testdata/pngsuite/xs1n0g01.png deleted file mode 100644 index 1817c5144f..0000000000 Binary files a/src/png/testdata/pngsuite/xs1n0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xs2n0g01.png b/src/png/testdata/pngsuite/xs2n0g01.png deleted file mode 100644 index b8147f2a84..0000000000 Binary files a/src/png/testdata/pngsuite/xs2n0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xs4n0g01.png b/src/png/testdata/pngsuite/xs4n0g01.png deleted file mode 100644 index 45237a1d29..0000000000 Binary files a/src/png/testdata/pngsuite/xs4n0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/xs7n0g01.png b/src/png/testdata/pngsuite/xs7n0g01.png deleted file mode 100644 index 3f307f14ea..0000000000 Binary files a/src/png/testdata/pngsuite/xs7n0g01.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/z00n2c08.png b/src/png/testdata/pngsuite/z00n2c08.png deleted file mode 100644 index 7669eb8385..0000000000 Binary files a/src/png/testdata/pngsuite/z00n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/z03n2c08.png b/src/png/testdata/pngsuite/z03n2c08.png deleted file mode 100644 index bfb10de8de..0000000000 Binary files a/src/png/testdata/pngsuite/z03n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/z06n2c08.png b/src/png/testdata/pngsuite/z06n2c08.png deleted file mode 100644 index b90ebc10f5..0000000000 Binary files a/src/png/testdata/pngsuite/z06n2c08.png and /dev/null differ diff --git a/src/png/testdata/pngsuite/z09n2c08.png b/src/png/testdata/pngsuite/z09n2c08.png deleted file mode 100644 index 5f191a78ee..0000000000 Binary files a/src/png/testdata/pngsuite/z09n2c08.png and /dev/null differ diff --git a/src/png/zlib.rs b/src/png/zlib.rs deleted file mode 100644 index df7a9b4583..0000000000 --- a/src/png/zlib.rs +++ /dev/null @@ -1,189 +0,0 @@ -//! An Implementation of RFC 1950 -//! -//! Decoding of zlib compressed streams. -//! -//! # Related Links -//! *http://tools.ietf.org/html/rfc1950 - ZLIB Compressed Data Format Specification - -use std::io::{self, Read, Write}; -use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian}; - -use super::hash::Adler32; -use super::deflate::Deflater; -use super::inflate::Inflater; - -enum ZlibState { - Start, - CompressedData, - End -} - -/// A Zlib compressed stream decoder. -pub struct ZlibDecoder { - inflate: Inflater, - adler: Adler32, - state: ZlibState, -} - -/// A Zlib compressed stream encoder. -pub struct ZlibEncoder where W: Write { - deflate: Option>, - adler: Adler32, -} - -impl ZlibDecoder { - /// Create a new decoder that decodes from a Reader - pub fn new(r: R) -> ZlibDecoder { - ZlibDecoder { - inflate: Inflater::new(r), - adler: Adler32::new(), - state: ZlibState::Start, - } - } - - /// Return a mutable reference to the wrapped Reader - pub fn inner(&mut self) -> &mut R { - self.inflate.inner() - } - - fn read_header(&mut self) -> io::Result<()> { - let cmf = try!(self.inner().read_u8()); - let _cm = cmf & 0x0F; - let _cinfo = cmf >> 4; - - let flg = try!(self.inner().read_u8()); - let fdict = (flg & 0b100000) != 0; - if fdict { - let _dictid = try!(self.inner().read_u32::()); - panic!("invalid png: zlib detected fdict true") - } - - assert!((cmf as u16 * 256 + flg as u16) % 31 == 0); - - Ok(()) - } - - fn read_checksum(&mut self) -> io::Result<()> { - let stream_adler32 = try!(self.inner().read_u32::()); - let adler32 = self.adler.checksum(); - - assert_eq!(adler32, stream_adler32); - self.adler.reset(); - - Ok(()) - } -} - -impl Read for ZlibDecoder { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - match self.state { - ZlibState::CompressedData => { - match self.inflate.read(buf) { - Ok(n) => { - self.adler.update(&buf[..n]); - - if self.inflate.eof() { - let _ = try!(self.read_checksum()); - self.state = ZlibState::End; - } - - Ok(n) - } - - e => e - } - } - - ZlibState::Start => { - let _ = try!(self.read_header()); - self.state = ZlibState::CompressedData; - self.read(buf) - } - - ZlibState::End => Ok(0) - } - } -} - -impl ZlibEncoder where W: Write { - /// Builds a new encoder. - pub fn new(mut writer: W) -> io::Result> { - // writing CMF and FLG - let cm: u8 = 8; - let cinfo: u8 = 7; // FIXME: - let cmf: u8 = cinfo << 4 | cm; - - let fdict: u8 = 0; - let flevel: u8 = 0; - let fcheck: u8 = 31 - ((cmf as u16 * 256 | (flevel << 6 | fdict << 5) as u16) % 31) as u8; - let flg = flevel << 6 | fdict << 5 | fcheck; - - assert!((cmf as u16 * 256 + flg as u16) % 31 == 0); - - try!(writer.write_all(&[cmf, flg])); - - Ok(ZlibEncoder { - deflate: Some(Deflater::new(writer)), - adler: Adler32::new(), - }) - } - - /// Finish writing and returns the underlying writer. - pub fn into_inner(mut self) -> io::Result { - let mut stream = try!(self.deflate.take().unwrap().into_inner()); - try!(stream.write_u32::(self.adler.checksum())); - Ok(stream) - } -} - -impl Write for ZlibEncoder where W: Write { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.adler.update(buf); - try!(self.deflate.as_mut().unwrap().write(buf)); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - self.deflate.as_mut().unwrap().flush() - } -} - -impl Drop for ZlibEncoder where W: Write { - fn drop(&mut self) { - if let Some(deflate) = self.deflate.take() { - let mut stream = match deflate.into_inner() { - Ok(s) => s, - Err(_) => return - }; - - let _ = stream.write_u32::(self.adler.checksum()); - let _ = stream.flush(); - } - } -} - -#[cfg(test)] -mod tests { - use std::io::{Cursor, Read, Write}; - use super::{ZlibEncoder, ZlibDecoder}; - - #[test] - fn roundtrip() { - let mut input = Vec::new(); - let mut encoded = ZlibEncoder::new(Vec::new()).unwrap(); - - // TODO: generate random data - for n in (0u8 .. 200) { - input.push(n); - encoded.write(&[n]).unwrap(); - } - - let encoded = encoded.into_inner().unwrap(); - - let mut decoder = ZlibDecoder::new(Cursor::new(encoded)); - let mut ret = Vec::new(); - decoder.read_to_end(&mut ret).unwrap(); - - assert_eq!(ret, input); - } -}