1 use std::borrow::Cow; 2 use std::io; 3 use std::cmp; 4 use std::mem; 5 use std::iter; 6 use std::io::prelude::*; 7 8 use traits::{Parameter, SetParameter}; 9 use common::Frame; 10 use util; 11 12 mod decoder; 13 pub use self::decoder::{ 14 PLTE_CHANNELS, StreamingDecoder, Decoded, DecodingError, Extensions 15 }; 16 17 const N_CHANNELS: usize = 4; 18 19 impl<T, R> Parameter<Decoder<R>> for T 20 where T: Parameter<StreamingDecoder>, R: Read { 21 type Result = (); set_param(self, this: &mut Decoder<R>)22 fn set_param(self, this: &mut Decoder<R>) { 23 this.decoder.set(self); 24 } 25 26 } 27 28 /// Output mode for the image data 29 #[derive(PartialEq, Debug)] 30 #[repr(u8)] 31 pub enum ColorOutput { 32 /// The decoder expands the image data to 32bit RGBA. 33 /// This affects: 34 /// 35 /// - The buffer buffer of the `Frame` returned by `Reader::read_next_frame`. 36 /// - `Reader::fill_buffer`, `Reader::buffer_size` and `Reader::line_length`. 37 RGBA = 0, 38 /// The decoder returns the raw indexed data. 39 Indexed = 1, 40 } 41 42 impl<R: Read> Parameter<Decoder<R>> for ColorOutput { 43 type Result = (); set_param(self, this: &mut Decoder<R>)44 fn set_param(self, this: &mut Decoder<R>) { 45 this.color_output = self 46 } 47 } 48 49 #[derive(Debug)] 50 /// Memory limit in bytes. `MemoryLimit::Some(0)` means 51 /// that there is no memory limit set. 52 pub struct MemoryLimit(pub u32); 53 54 impl<R: Read> Parameter<Decoder<R>> for MemoryLimit { 55 type Result = (); set_param(self, this: &mut Decoder<R>)56 fn set_param(self, this: &mut Decoder<R>) { 57 let MemoryLimit(limit) = self; 58 this.memory_limit = limit 59 } 60 } 61 62 /// GIF decoder 63 pub struct Decoder<R: Read> { 64 r: R, 65 decoder: StreamingDecoder, 66 memory_limit: u32, 67 color_output: ColorOutput, 68 } 69 70 impl<R: Read> Decoder<R> { 71 /// Creates a new decoder builder new(r: R) -> Decoder<R>72 pub fn new(r: R) -> Decoder<R> { 73 Decoder { 74 r: r, 75 decoder: StreamingDecoder::new(), 76 memory_limit: 50_000_000, // 50 MB 77 color_output: ColorOutput::Indexed 78 } 79 } 80 81 /// Reads the logical screen descriptor including the global color palette 82 /// 83 /// Returns a `Reader`. All decoder configuration has to be done beforehand. read_info(self) -> Result<Reader<R>, DecodingError>84 pub fn read_info(self) -> Result<Reader<R>, DecodingError> { 85 Reader::new(self.r, self.decoder, self.color_output, self.memory_limit).init() 86 } 87 } 88 89 struct ReadDecoder<R: Read> { 90 reader: io::BufReader<R>, 91 decoder: StreamingDecoder, 92 at_eof: bool 93 } 94 95 impl<R: Read> ReadDecoder<R> { decode_next(&mut self) -> Result<Option<Decoded>, DecodingError>96 fn decode_next(&mut self) -> Result<Option<Decoded>, DecodingError> { 97 while !self.at_eof { 98 let (consumed, result) = { 99 let buf = try!(self.reader.fill_buf()); 100 if buf.len() == 0 { 101 return Err(DecodingError::Format( 102 "unexpected EOF" 103 )) 104 } 105 try!(self.decoder.update(buf)) 106 }; 107 self.reader.consume(consumed); 108 match result { 109 Decoded::Nothing => (), 110 Decoded::BlockStart(::common::Block::Trailer) => { 111 self.at_eof = true 112 }, 113 result => return Ok(unsafe{ 114 // FIXME: #6393 115 Some(mem::transmute::<Decoded, Decoded>(result)) 116 }), 117 } 118 } 119 Ok(None) 120 } 121 } 122 123 #[allow(dead_code)] 124 /// GIF decoder 125 pub struct Reader<R: Read> { 126 decoder: ReadDecoder<R>, 127 color_output: ColorOutput, 128 memory_limit: u32, 129 bg_color: Option<u8>, 130 global_palette: Option<Vec<u8>>, 131 current_frame: Frame<'static>, 132 buffer: Vec<u8>, 133 // Offset in current frame 134 offset: usize 135 136 } 137 138 impl<R> Reader<R> where R: Read { new(reader: R, decoder: StreamingDecoder, color_output: ColorOutput, memory_limit: u32 ) -> Reader<R>139 fn new(reader: R, decoder: StreamingDecoder, 140 color_output: ColorOutput, memory_limit: u32 141 ) -> Reader<R> { 142 Reader { 143 decoder: ReadDecoder { 144 reader: io::BufReader::new(reader), 145 decoder: decoder, 146 at_eof: false 147 }, 148 bg_color: None, 149 global_palette: None, 150 buffer: Vec::with_capacity(32), 151 color_output: color_output, 152 memory_limit: memory_limit, 153 current_frame: Frame::default(), 154 offset: 0 155 } 156 } 157 init(mut self) -> Result<Self, DecodingError>158 fn init(mut self) -> Result<Self, DecodingError> { 159 loop { 160 match try!(self.decoder.decode_next()) { 161 Some(Decoded::BackgroundColor(bg_color)) => { 162 self.bg_color = Some(bg_color) 163 } 164 Some(Decoded::GlobalPalette(palette)) => { 165 self.global_palette = if palette.len() > 0 { 166 Some(palette) 167 } else { 168 None 169 }; 170 break 171 }, 172 Some(_) => { 173 // Unreachable since this loop exists after the global 174 // palette has been read. 175 unreachable!() 176 }, 177 None => return Err(DecodingError::Format( 178 "File does not contain any image data" 179 )) 180 } 181 } 182 // If the background color is invalid, ignore it 183 if let &Some(ref palette) = &self.global_palette { 184 if self.bg_color.unwrap_or(0) as usize >= palette.len() { 185 self.bg_color = None; 186 } 187 } 188 Ok(self) 189 } 190 191 /// Returns the next frame info next_frame_info(&mut self) -> Result<Option<&Frame<'static>>, DecodingError>192 pub fn next_frame_info(&mut self) -> Result<Option<&Frame<'static>>, DecodingError> { 193 loop { 194 match try!(self.decoder.decode_next()) { 195 Some(Decoded::Frame(frame)) => { 196 self.current_frame = frame.clone(); 197 if frame.palette.is_none() && self.global_palette.is_none() { 198 return Err(DecodingError::Format( 199 "No color table available for current frame." 200 )) 201 } 202 if self.memory_limit > 0 && ( 203 (frame.width as u32 * frame.height as u32) 204 > self.memory_limit 205 ) { 206 return Err(DecodingError::Format( 207 "Image is too large to decode." 208 )) 209 } 210 break 211 }, 212 Some(_) => (), 213 None => return Ok(None) 214 215 } 216 } 217 Ok(Some(&self.current_frame)) 218 } 219 220 /// Reads the next frame from the image. 221 /// 222 /// Do not call `Self::next_frame_info` beforehand. 223 /// Deinterlaces the result. read_next_frame(&mut self) -> Result<Option<&Frame<'static>>, DecodingError>224 pub fn read_next_frame(&mut self) -> Result<Option<&Frame<'static>>, DecodingError> { 225 if try!(self.next_frame_info()).is_some() { 226 let mut vec = vec![0; self.buffer_size()]; 227 try!(self.read_into_buffer(&mut vec)); 228 self.current_frame.buffer = Cow::Owned(vec); 229 self.current_frame.interlaced = false; 230 Ok(Some(&self.current_frame)) 231 } else { 232 Ok(None) 233 } 234 } 235 236 /// Reads the data of the current frame into a pre-allocated buffer. 237 /// 238 /// `Self::next_frame_info` needs to be called beforehand. 239 /// The length of `buf` must be at least `Self::buffer_size`. 240 /// Deinterlaces the result. read_into_buffer(&mut self, buf: &mut [u8]) -> Result<(), DecodingError>241 pub fn read_into_buffer(&mut self, buf: &mut [u8]) -> Result<(), DecodingError> { 242 if self.current_frame.interlaced { 243 let width = self.line_length(); 244 let height = self.current_frame.height as usize; 245 for row in (InterlaceIterator { len: height, next: 0, pass: 0 }) { 246 if !try!(self.fill_buffer(&mut buf[row*width..][..width])) { 247 return Err(DecodingError::Format("Image truncated")) 248 } 249 } 250 } else { 251 let buf = &mut buf[..self.buffer_size()]; 252 if !try!(self.fill_buffer(buf)) { 253 return Err(DecodingError::Format("Image truncated")) 254 } 255 }; 256 Ok(()) 257 } 258 259 /// Reads data of the current frame into a pre-allocated buffer until the buffer has been 260 /// filled completely. 261 /// 262 /// `Self::next_frame_info` needs to be called beforehand. Returns `true` if the supplied 263 /// buffer could be filled completely. Should not be called after `false` had been returned. fill_buffer(&mut self, mut buf: &mut [u8]) -> Result<bool, DecodingError>264 pub fn fill_buffer(&mut self, mut buf: &mut [u8]) -> Result<bool, DecodingError> { 265 use self::ColorOutput::*; 266 const PLTE_CHANNELS: usize = 3; 267 macro_rules! handle_data( 268 ($data:expr) => { 269 match self.color_output { 270 RGBA => { 271 let transparent = self.current_frame.transparent; 272 let palette: &[u8] = match self.current_frame.palette { 273 Some(ref table) => &*table, 274 None => &*self.global_palette.as_ref().unwrap(), 275 }; 276 let len = cmp::min(buf.len()/N_CHANNELS, $data.len()); 277 for (rgba, &idx) in buf[..len*N_CHANNELS].chunks_mut(N_CHANNELS).zip($data.iter()) { 278 let plte_offset = PLTE_CHANNELS * idx as usize; 279 if palette.len() >= plte_offset + PLTE_CHANNELS { 280 let colors = &palette[plte_offset..]; 281 rgba[0] = colors[0]; 282 rgba[1] = colors[1]; 283 rgba[2] = colors[2]; 284 rgba[3] = if let Some(t) = transparent { 285 if t == idx { 0x00 } else { 0xFF } 286 } else { 287 0xFF 288 } 289 } 290 } 291 (len, N_CHANNELS) 292 }, 293 Indexed => { 294 let len = cmp::min(buf.len(), $data.len()); 295 util::copy_memory(&$data[..len], &mut buf[..len]); 296 (len, 1) 297 } 298 } 299 } 300 ); 301 let buf_len = self.buffer.len(); 302 if buf_len > 0 { 303 let (len, channels) = handle_data!(&self.buffer); 304 // This is WRONG!!!! Cuts form the wrong side… 305 self.buffer.truncate(buf_len-len); 306 let buf_ = buf; buf = &mut buf_[len*channels..]; 307 if buf.len() == 0 { 308 return Ok(true) 309 } 310 } 311 loop { 312 match try!(self.decoder.decode_next()) { 313 Some(Decoded::Data(data)) => { 314 let (len, channels) = handle_data!(data); 315 let buf_ = buf; buf = &mut buf_[len*channels..]; // shorten buf 316 if buf.len() > 0 { 317 continue 318 } else if len < data.len() { 319 self.buffer.extend(data[len..].iter().map(|&v| v)); 320 } 321 return Ok(true) 322 }, 323 Some(_) => return Ok(false), // make sure that no important result is missed 324 None => return Ok(false) 325 326 } 327 } 328 } 329 330 /// Output buffer size buffer_size(&self) -> usize331 pub fn buffer_size(&self) -> usize { 332 self.line_length() * self.current_frame.height as usize 333 } 334 335 /// Line length of the current frame line_length(&self) -> usize336 pub fn line_length(&self) -> usize { 337 use self::ColorOutput::*; 338 match self.color_output { 339 RGBA => self.current_frame.width as usize * N_CHANNELS, 340 Indexed => self.current_frame.width as usize 341 } 342 } 343 344 /// Returns the color palette relevant for the current (next) frame palette(&self) -> Result<&[u8], DecodingError>345 pub fn palette(&self) -> Result<&[u8], DecodingError> { 346 // TODO prevent planic 347 Ok(match self.current_frame.palette { 348 Some(ref table) => &*table, 349 None => &*try!(self.global_palette.as_ref().ok_or(DecodingError::Format( 350 "No color table available for current frame." 351 ))), 352 }) 353 } 354 355 /// The global color palette global_palette(&self) -> Option<&[u8]>356 pub fn global_palette(&self) -> Option<&[u8]> { 357 self.global_palette.as_ref().map(|v| &**v) 358 } 359 360 /// Width of the image width(&self) -> u16361 pub fn width(&self) -> u16 { 362 self.decoder.decoder.width() 363 } 364 365 /// Height of the image height(&self) -> u16366 pub fn height(&self) -> u16 { 367 self.decoder.decoder.height() 368 } 369 370 /// Index of the background color in the global palette bg_color(&self) -> Option<usize>371 pub fn bg_color(&self) -> Option<usize> { 372 self.bg_color.map(|v| v as usize) 373 } 374 } 375 376 struct InterlaceIterator { 377 len: usize, 378 next: usize, 379 pass: usize 380 } 381 382 impl iter::Iterator for InterlaceIterator { 383 type Item = usize; 384 next(&mut self) -> Option<Self::Item>385 fn next(&mut self) -> Option<Self::Item> { 386 if self.len == 0 || self.pass > 3 { 387 return None 388 } 389 let mut next = self.next + [8, 8, 4, 2][self.pass]; 390 while next >= self.len { 391 next = [4, 2, 1, 0][self.pass]; 392 self.pass += 1; 393 } 394 mem::swap(&mut next, &mut self.next); 395 Some(next) 396 } 397 } 398 399 #[cfg(test)] 400 mod test { 401 use std::fs::File; 402 403 use super::{Decoder, InterlaceIterator}; 404 405 /* Commented because test::Bencher is unstable 406 extern crate test; 407 use std::io::prelude::*; 408 #[bench] 409 fn bench_tiny(b: &mut test::Bencher) { 410 let mut data = Vec::new(); 411 File::open("tests/samples/sample_1.gif").unwrap().read_to_end(&mut data).unwrap(); 412 b.iter(|| { 413 let mut decoder = Decoder::new(&*data).read_info().unwrap(); 414 let frame = decoder.read_next_frame().unwrap().unwrap(); 415 test::black_box(frame); 416 }); 417 let mut decoder = Decoder::new(&*data).read_info().unwrap(); 418 b.bytes = decoder.read_next_frame().unwrap().unwrap().buffer.len() as u64 419 } 420 #[bench] 421 fn bench_big(b: &mut test::Bencher) { 422 let mut data = Vec::new(); 423 File::open("tests/sample_big.gif").unwrap().read_to_end(&mut data).unwrap(); 424 b.iter(|| { 425 let mut decoder = Decoder::new(&*data).read_info().unwrap(); 426 let frame = decoder.read_next_frame().unwrap().unwrap(); 427 test::black_box(frame); 428 }); 429 let mut decoder = Decoder::new(&*data).read_info().unwrap(); 430 b.bytes = decoder.read_next_frame().unwrap().unwrap().buffer.len() as u64 431 }*/ 432 433 #[test] test_simple_indexed()434 fn test_simple_indexed() { 435 let mut decoder = Decoder::new(File::open("tests/samples/sample_1.gif").unwrap()).read_info().unwrap(); 436 let frame = decoder.read_next_frame().unwrap().unwrap(); 437 assert_eq!(&*frame.buffer, &[ 438 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 439 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 440 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 441 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 442 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 443 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 444 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 445 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 446 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 447 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 448 ][..]) 449 } 450 451 #[test] test_interlace_iterator()452 fn test_interlace_iterator() { 453 for &(len, expect) in &[ 454 (0, &[][..]), 455 (1, &[0][..]), 456 (2, &[0, 1][..]), 457 (3, &[0, 2, 1][..]), 458 (4, &[0, 2, 1, 3][..]), 459 (5, &[0, 4, 2, 1, 3][..]), 460 (6, &[0, 4, 2, 1, 3, 5][..]), 461 (7, &[0, 4, 2, 6, 1, 3, 5][..]), 462 (8, &[0, 4, 2, 6, 1, 3, 5, 7][..]), 463 (9, &[0, 8, 4, 2, 6, 1, 3, 5, 7][..]), 464 (10, &[0, 8, 4, 2, 6, 1, 3, 5, 7, 9][..]), 465 (11, &[0, 8, 4, 2, 6, 10, 1, 3, 5, 7, 9][..]), 466 (12, &[0, 8, 4, 2, 6, 10, 1, 3, 5, 7, 9, 11][..]), 467 (13, &[0, 8, 4, 12, 2, 6, 10, 1, 3, 5, 7, 9, 11][..]), 468 (14, &[0, 8, 4, 12, 2, 6, 10, 1, 3, 5, 7, 9, 11, 13][..]), 469 (15, &[0, 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13][..]), 470 (16, &[0, 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15][..]), 471 (17, &[0, 8, 16, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15][..]), 472 ] { 473 let iter = InterlaceIterator { len: len, next: 0, pass: 0 }; 474 let lines = iter.collect::<Vec<_>>(); 475 assert_eq!(lines, expect); 476 } 477 } 478 } 479 480 481 #[cfg(feature = "c_api")] 482 mod c_interface { 483 use std::io::prelude::*; 484 use std::ptr; 485 use std::borrow::Cow; 486 487 use libc::c_int; 488 489 use common::Block; 490 491 use c_api::{self, GifWord}; 492 use c_api_utils::{CInterface, copy_colormap, copy_data, saved_images_new}; 493 494 use super::decoder::{Decoded, DecodingError}; 495 496 use super::{Reader}; 497 498 impl<R> Reader<R> where R: Read + 'static { 499 /// Converts `Reader` into `CInterface`. into_c_interface(self) -> Box<CInterface>500 pub fn into_c_interface(self) -> Box<CInterface> { 501 Box::new(self) 502 } 503 } 504 505 impl<R: Read> CInterface for Reader<R> { read_screen_desc(&mut self, this: &mut c_api::GifFileType)506 fn read_screen_desc(&mut self, this: &mut c_api::GifFileType) { 507 this.SWidth = self.width() as GifWord; 508 this.SHeight = self.height() as GifWord; 509 this.SColorResolution = 255;//self.global_palette().len() as GifWord; 510 this.SBackGroundColor = self.bg_color().unwrap_or(0) as GifWord; 511 this.AspectByte = 0; 512 self.offset = 0; 513 } 514 current_image_buffer(&mut self) -> Result<(&[u8], &mut usize), DecodingError>515 fn current_image_buffer(&mut self) -> Result<(&[u8], &mut usize), DecodingError> { 516 if let Cow::Borrowed(_) = self.current_frame.buffer { 517 try!(self.read_next_frame()); 518 } 519 Ok((&self.current_frame.buffer, &mut self.offset)) 520 } 521 last_ext(&self) -> (u8, &[u8], bool)522 fn last_ext(&self) -> (u8, &[u8], bool) { 523 self.decoder.decoder.last_ext() 524 } 525 next_record_type(&mut self) -> Result<Block, DecodingError>526 fn next_record_type(&mut self) -> Result<Block, DecodingError> { 527 loop { 528 match try!(self.decoder.decode_next()) { 529 Some(Decoded::BlockStart(type_)) => return Ok(type_), 530 Some(_) => (), 531 None => return Ok(Block::Trailer) 532 } 533 } 534 } 535 decode_next(&mut self) -> Result<Option<Decoded>, DecodingError>536 fn decode_next(&mut self) -> Result<Option<Decoded>, DecodingError> { 537 self.decoder.decode_next() 538 } 539 540 /* 541 unsafe fn read_to_end(&mut self, this: &mut c_api::GifFileType) -> Result<(), DecodingError> { 542 try!(self.read_screen_desc(this)); 543 try!(self.read_to_end()); 544 this.ImageCount = self.frames().len() as c_int; 545 let images = saved_images_new(this.ImageCount as usize); 546 for (i, frame) in self.frames().iter().enumerate() { 547 *images.offset(i as isize) = c_api::SavedImage { 548 ImageDesc: c_api::GifImageDesc { 549 Left: frame.left as GifWord, 550 Top: frame.top as GifWord, 551 Width: frame.width as GifWord, 552 Height: frame.height as GifWord, 553 Interlace: num::FromPrimitive::from_u8(frame.interlaced as u8).unwrap(), 554 ColorMap: copy_colormap(&frame.palette) 555 }, 556 // on malloc(3) heap 557 RasterBits: copy_data(&*frame.buffer), 558 ExtensionBlockCount: 0, 559 ExtensionBlocks: ptr::null_mut() 560 } 561 562 } 563 this.SavedImages = images; 564 Ok(()) 565 }*/ 566 } 567 } 568