1 use std::cmp; 2 use std::mem; 3 use std::default::Default; 4 5 use std::io; 6 use std::io::prelude::*; 7 8 use std::fmt; 9 use std::error; 10 11 use lzw; 12 13 use traits::Parameter; 14 use common::{Frame, Block, Extension, DisposalMethod}; 15 16 /// GIF palettes are RGB 17 pub const PLTE_CHANNELS: usize = 3; 18 19 #[derive(Debug)] 20 /// Decoding error. 21 pub enum DecodingError { 22 /// Returned if the image is found to be malformed. 23 Format(&'static str), 24 /// Internal (logic) error. 25 Internal(&'static str), 26 /// Wraps `std::io::Error`. 27 Io(io::Error), 28 } 29 30 impl fmt::Display for DecodingError { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result31 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 32 match *self { 33 DecodingError::Format(ref d) => d.fmt(fmt), 34 DecodingError::Internal(ref d) => d.fmt(fmt), 35 DecodingError::Io(ref err) => err.fmt(fmt), 36 } 37 } 38 } 39 40 impl error::Error for DecodingError { description(&self) -> &str41 fn description(&self) -> &str { 42 match *self { 43 DecodingError::Format(ref d) => d, 44 DecodingError::Internal(ref d) => d, 45 DecodingError::Io(ref err) => err.description(), 46 } 47 } 48 cause(&self) -> Option<&error::Error>49 fn cause(&self) -> Option<&error::Error> { 50 match *self { 51 DecodingError::Io(ref err) => Some(err), 52 _ => None, 53 } 54 } 55 } 56 57 impl From<io::Error> for DecodingError { from(err: io::Error) -> Self58 fn from(err: io::Error) -> Self { 59 DecodingError::Io(err) 60 } 61 } 62 63 /// Configures how extensions should be handled 64 #[derive(PartialEq, Debug)] 65 pub enum Extensions { 66 /// Saves all extention data 67 Save, 68 /// Skips the data of unknown extensions 69 /// and extracts the data from known ones 70 Skip 71 } 72 73 impl Parameter<StreamingDecoder> for Extensions { 74 type Result = (); set_param(self, this: &mut StreamingDecoder)75 fn set_param(self, this: &mut StreamingDecoder) { 76 this.skip_extensions = match self { 77 Extensions::Skip => true, 78 Extensions::Save => false, 79 80 } 81 } 82 } 83 84 /// Indicates whether a certain object has been decoded 85 #[derive(Debug)] 86 pub enum Decoded<'a> { 87 /// Decoded nothing. 88 Nothing, 89 /// Global palette. 90 GlobalPalette(Vec<u8>), 91 /// Index of the background color in the global palette. 92 BackgroundColor(u8), 93 /// Decoded the image trailer. 94 Trailer, 95 /// The start of a block. 96 BlockStart(Block), 97 /// Decoded a sub-block. More sub-block are available. 98 SubBlockFinished(u8, &'a [u8]), 99 /// Decoded the last (or only) sub-block of a block. 100 BlockFinished(u8, &'a [u8]), 101 /// Decoded all information of the next frame. 102 /// The returned frame does **not** any image data. 103 Frame(&'a Frame<'static>), 104 /// Decoded some data of the current frame. 105 Data(&'a [u8]), 106 /// No more data available the current frame. 107 DataEnd, 108 109 } 110 111 /// Internal state of the GIF decoder 112 #[derive(Debug)] 113 enum State { 114 Magic(usize, [u8; 6]), 115 U16Byte1(U16Value, u8), 116 U16(U16Value), 117 Byte(ByteValue), 118 GlobalPalette(usize), 119 BlockStart(Option<Block>), 120 BlockEnd(u8), 121 ExtensionBlock(u8), 122 SkipBlock(usize), 123 LocalPalette(usize), 124 LzwInit(u8), 125 DecodeSubBlock(usize), 126 FrameDecoded, 127 Trailer 128 } 129 use self::State::*; 130 131 /// U16 values that may occur in a GIF image 132 #[derive(Debug)] 133 enum U16Value { 134 /// Logical screen descriptor width 135 ScreenWidth, 136 /// Logical screen descriptor height 137 ScreenHeight, 138 /// Delay time 139 Delay, 140 /// Left frame offset 141 ImageLeft, 142 /// Top frame offset 143 ImageTop, 144 /// Frame width 145 ImageWidth, 146 /// Frame height 147 ImageHeight, 148 } 149 150 /// Single byte screen descriptor values 151 #[derive(Debug)] 152 enum ByteValue { 153 GlobalFlags, 154 Background { table_size: usize }, 155 AspectRatio { table_size: usize }, 156 ControlFlags, 157 ImageFlags, 158 TransparentIdx, 159 CodeSize, 160 } 161 162 /// GIF decoder which supports streaming 163 #[derive(Debug)] 164 pub struct StreamingDecoder { 165 state: Option<State>, 166 lzw_reader: Option<lzw::Decoder<lzw::LsbReader>>, 167 skip_extensions: bool, 168 version: &'static str, 169 width: u16, 170 height: u16, 171 global_color_table: Vec<u8>, 172 background_color: [u8; 4], 173 /// ext buffer 174 ext: (u8, Vec<u8>, bool), 175 /// Frame data 176 current: Option<Frame<'static>>, 177 } 178 179 impl StreamingDecoder { 180 /// Creates a new streaming decoder new() -> StreamingDecoder181 pub fn new() -> StreamingDecoder { 182 StreamingDecoder { 183 state: Some(Magic(0, [0; 6])), 184 lzw_reader: None, 185 skip_extensions: true, 186 version: "", 187 width: 0, 188 height: 0, 189 global_color_table: Vec::new(), 190 background_color: [0, 0, 0, 0xFF], 191 ext: (0, Vec::with_capacity(256), true), // 0xFF + 1 byte length 192 current: None 193 } 194 } 195 196 /// Updates the internal state of the decoder. 197 /// 198 /// Returns the number of bytes consumed from the input buffer 199 /// and the last decoding result. update<'a>(&'a mut self, mut buf: &[u8]) -> Result<(usize, Decoded<'a>), DecodingError>200 pub fn update<'a>(&'a mut self, mut buf: &[u8]) 201 -> Result<(usize, Decoded<'a>), DecodingError> { 202 // NOTE: Do not change the function signature without double-checking the 203 // unsafe block! 204 let len = buf.len(); 205 while buf.len() > 0 && self.state.is_some() { 206 match self.next_state(buf) { 207 Ok((bytes, Decoded::Nothing)) => { 208 buf = &buf[bytes..] 209 } 210 Ok((bytes, Decoded::Trailer)) => { 211 buf = &buf[bytes..]; 212 break 213 } 214 Ok((bytes, result)) => { 215 buf = &buf[bytes..]; 216 return Ok( 217 (len-buf.len(), 218 // This transmute just casts the lifetime away. Since Rust only 219 // has SESE regions, this early return cannot be worked out and 220 // such that the borrow region of self includes the whole block. 221 // The explixit lifetimes in the function signature ensure that 222 // this is safe. 223 // ### NOTE 224 // To check that everything is sound, return the result without 225 // the match (e.g. `return Ok(try!(self.next_state(buf)))`). If 226 // it compiles the returned lifetime is correct. 227 unsafe { 228 mem::transmute::<Decoded, Decoded>(result) 229 } 230 )) 231 } 232 Err(err) => return Err(err) 233 } 234 } 235 Ok((len-buf.len(), Decoded::Nothing)) 236 237 } 238 239 /// Returns the data of the last extension that has been decoded. last_ext(&self) -> (u8, &[u8], bool)240 pub fn last_ext(&self) -> (u8, &[u8], bool) { 241 (self.ext.0, &*self.ext.1, self.ext.2) 242 } 243 244 #[inline(always)] 245 /// Current frame info as a mutable ref. current_frame_mut<'a>(&'a mut self) -> &'a mut Frame<'static>246 pub fn current_frame_mut<'a>(&'a mut self) -> &'a mut Frame<'static> { 247 self.current.as_mut().unwrap() 248 } 249 250 #[inline(always)] 251 /// Current frame info as a ref. current_frame<'a>(&'a self) -> &'a Frame<'static>252 pub fn current_frame<'a>(&'a self) -> &'a Frame<'static> { 253 self.current.as_ref().unwrap() 254 } 255 256 /// Width of the image width(&self) -> u16257 pub fn width(&self) -> u16 { 258 self.width 259 } 260 261 /// Height of the image height(&self) -> u16262 pub fn height(&self) -> u16 { 263 self.height 264 } 265 next_state<'a>(&'a mut self, buf: &[u8]) -> Result<(usize, Decoded<'a>), DecodingError>266 fn next_state<'a>(&'a mut self, buf: &[u8]) -> Result<(usize, Decoded<'a>), DecodingError> { 267 macro_rules! goto ( 268 ($n:expr, $state:expr) => ({ 269 self.state = Some($state); 270 Ok(($n, Decoded::Nothing)) 271 }); 272 ($state:expr) => ({ 273 self.state = Some($state); 274 Ok((1, Decoded::Nothing)) 275 }); 276 ($n:expr, $state:expr, emit $res:expr) => ({ 277 self.state = Some($state); 278 Ok(($n, $res)) 279 }); 280 ($state:expr, emit $res:expr) => ({ 281 self.state = Some($state); 282 Ok((1, $res)) 283 }) 284 ); 285 286 let b = buf[0]; 287 288 // Driver should ensure that state is never None 289 let state = self.state.take().unwrap(); 290 //println!("{:?}", state); 291 292 match state { 293 Magic(i, mut version) => if i < 6 { 294 version[i] = b; 295 goto!(Magic(i+1, version)) 296 } else if &version[..3] == b"GIF" { 297 self.version = match &version[3..] { 298 b"87a" => "87a", 299 b"89a" => "89a", 300 _ => return Err(DecodingError::Format("unsupported GIF version")) 301 }; 302 goto!(U16Byte1(U16Value::ScreenWidth, b)) 303 } else { 304 Err(DecodingError::Format("malformed GIF header")) 305 }, 306 U16(next) => goto!(U16Byte1(next, b)), 307 U16Byte1(next, value) => { 308 use self::U16Value::*; 309 let value = ((b as u16) << 8) | value as u16; 310 match (next, value) { 311 (ScreenWidth, width) => { 312 self.width = width; 313 goto!(U16(U16Value::ScreenHeight)) 314 }, 315 (ScreenHeight, height) => { 316 self.height = height; 317 goto!(Byte(ByteValue::GlobalFlags)) 318 }, 319 (Delay, delay) => { 320 self.ext.1.push(value as u8); 321 self.ext.1.push(b); 322 self.current_frame_mut().delay = delay; 323 goto!(Byte(ByteValue::TransparentIdx)) 324 }, 325 (ImageLeft, left) => { 326 self.current_frame_mut().left = left; 327 goto!(U16(U16Value::ImageTop)) 328 }, 329 (ImageTop, top) => { 330 self.current_frame_mut().top = top; 331 goto!(U16(U16Value::ImageWidth)) 332 }, 333 (ImageWidth, width) => { 334 self.current_frame_mut().width = width; 335 goto!(U16(U16Value::ImageHeight)) 336 }, 337 (ImageHeight, height) => { 338 self.current_frame_mut().height = height; 339 goto!(Byte(ByteValue::ImageFlags)) 340 } 341 } 342 } 343 Byte(value) => { 344 use self::ByteValue::*; 345 match value { 346 GlobalFlags => { 347 let global_table = b & 0x80 != 0; 348 let entries = if global_table { 349 let entries = PLTE_CHANNELS*(1 << ((b & 0b111) + 1) as usize); 350 self.global_color_table.reserve_exact(entries); 351 entries 352 } else { 353 0usize 354 }; 355 goto!(Byte(Background { table_size: entries })) 356 }, 357 Background { table_size } => { 358 goto!( 359 Byte(AspectRatio { table_size: table_size }), 360 emit Decoded::BackgroundColor(b) 361 ) 362 }, 363 AspectRatio { table_size } => { 364 goto!(GlobalPalette(table_size)) 365 }, 366 ControlFlags => { 367 self.ext.1.push(b); 368 let control_flags = b; 369 if control_flags & 1 != 0 { 370 // Set to Some(...), gets overwritten later 371 self.current_frame_mut().transparent = Some(0) 372 } 373 self.current_frame_mut().needs_user_input = 374 control_flags & 0b10 != 0; 375 self.current_frame_mut().dispose = match DisposalMethod::from_u8( 376 (control_flags & 0b11100) >> 2 377 ) { 378 Some(method) => method, 379 None => DisposalMethod::Any 380 }; 381 goto!(U16(U16Value::Delay)) 382 } 383 TransparentIdx => { 384 self.ext.1.push(b); 385 if let Some(ref mut idx) = self.current_frame_mut().transparent { 386 *idx = b 387 } 388 goto!(SkipBlock(0)) 389 //goto!(AwaitBlockEnd) 390 } 391 ImageFlags => { 392 let local_table = (b & 0b1000_0000) != 0; 393 let interlaced = (b & 0b0100_0000) != 0; 394 let table_size = b & 0b0000_0111; 395 396 self.current_frame_mut().interlaced = interlaced; 397 if local_table { 398 let entries = PLTE_CHANNELS * (1 << (table_size + 1)); 399 400 self.current_frame_mut().palette = 401 Some(Vec::with_capacity(entries)); 402 goto!(LocalPalette(entries)) 403 } else { 404 goto!(Byte(CodeSize)) 405 } 406 }, 407 CodeSize => goto!(LzwInit(b)) 408 } 409 } 410 GlobalPalette(left) => { 411 let n = cmp::min(left, buf.len()); 412 if left > 0 { 413 self.global_color_table.extend(buf[..n].iter().cloned()); 414 goto!(n, GlobalPalette(left - n)) 415 } else { 416 let idx = self.background_color[0]; 417 match self.global_color_table.chunks(PLTE_CHANNELS).nth(idx as usize) { 418 Some(chunk) => for i in 0..PLTE_CHANNELS { 419 self.background_color[i] = chunk[i] 420 }, 421 None => self.background_color[0] = 0 422 } 423 goto!(BlockStart(Block::from_u8(b)), emit Decoded::GlobalPalette( 424 mem::replace(&mut self.global_color_table, Vec::new()) 425 )) 426 } 427 } 428 BlockStart(type_) => { 429 use common::Block::*; 430 match type_ { 431 Some(Image) => { 432 self.add_frame(); 433 goto!(U16Byte1(U16Value::ImageLeft, b), emit Decoded::BlockStart(Image)) 434 } 435 Some(Extension) => goto!(ExtensionBlock(b), emit Decoded::BlockStart(Extension)), 436 Some(Trailer) => goto!(0, State::Trailer, emit Decoded::BlockStart(Trailer)), 437 None => { 438 return Err(DecodingError::Format( 439 "unknown block type encountered" 440 ))} 441 } 442 } 443 BlockEnd(terminator) => { 444 if terminator == 0 { 445 if b == Block::Trailer as u8 { 446 goto!(0, BlockStart(Some(Block::Trailer))) 447 } else { 448 goto!(BlockStart(Block::from_u8(b))) 449 } 450 } else { 451 return Err(DecodingError::Format( 452 "expected block terminator not found" 453 )) 454 } 455 } 456 ExtensionBlock(type_) => { 457 use common::Extension::*; 458 self.ext.0 = type_; 459 self.ext.1.clear(); 460 self.ext.1.push(b); 461 if let Some(ext) = Extension::from_u8(type_) { 462 match ext { 463 Control => { 464 goto!(try!(self.read_control_extension(b))) 465 } 466 Text | Comment | Application => { 467 goto!(SkipBlock(b as usize)) 468 } 469 } 470 } else { 471 return Err(DecodingError::Format( 472 "unknown extention block encountered" 473 )) 474 } 475 } 476 SkipBlock(left) => { 477 let n = cmp::min(left, buf.len()); 478 if left > 0 { 479 self.ext.1.push(b); 480 goto!(n, SkipBlock(left - n)) 481 } else { 482 if b == 0 { 483 self.ext.2 = true; 484 goto!(BlockEnd(b), emit Decoded::BlockFinished(self.ext.0, &self.ext.1)) 485 } else { 486 self.ext.2 = false; 487 goto!(SkipBlock(b as usize), emit Decoded::SubBlockFinished(self.ext.0,&self.ext.1)) 488 } 489 490 } 491 } 492 LocalPalette(left) => { 493 let n = cmp::min(left, buf.len()); 494 if left > 0 { 495 496 self.current_frame_mut().palette 497 .as_mut().unwrap().extend(buf[..n].iter().cloned()); 498 goto!(n, LocalPalette(left - n)) 499 } else { 500 goto!(LzwInit(b)) 501 } 502 } 503 LzwInit(code_size) => { 504 // LZW spec: max 12 bits per code 505 if code_size > 11 { 506 return Err(DecodingError::Format( 507 "invalid minimal code size" 508 )) 509 } 510 self.lzw_reader = Some(lzw::Decoder::new(lzw::LsbReader::new(), code_size)); 511 goto!(DecodeSubBlock(b as usize), emit Decoded::Frame(self.current_frame_mut())) 512 } 513 DecodeSubBlock(left) => { 514 if left > 0 { 515 let n = cmp::min(left, buf.len()); 516 let decoder = self.lzw_reader.as_mut().unwrap(); 517 let (consumed, bytes) = try!(decoder.decode_bytes(&buf[..n])); 518 goto!(consumed, DecodeSubBlock(left - consumed), emit Decoded::Data(bytes)) 519 } else if b != 0 { // decode next sub-block 520 goto!(DecodeSubBlock(b as usize)) 521 } else { 522 // The end of the lzw stream is only reached if left == 0 and an additional call 523 // to `decode_bytes` results in an empty slice. 524 let decoder = self.lzw_reader.as_mut().unwrap(); 525 let (_, bytes) = try!(decoder.decode_bytes(&[])); 526 if bytes.len() > 0 { 527 goto!(0, DecodeSubBlock(0), emit Decoded::Data(bytes)) 528 } else { 529 // end of image data reached 530 self.current = None; 531 goto!(0, FrameDecoded, emit Decoded::DataEnd) 532 } 533 } 534 } 535 FrameDecoded => { 536 goto!(BlockEnd(b)) 537 } 538 Trailer => { 539 self.state = None; 540 Ok((1, Decoded::Trailer)) 541 //panic!("EOF {:?}", self) 542 } 543 } 544 } 545 read_control_extension(&mut self, b: u8) -> Result<State, DecodingError>546 fn read_control_extension(&mut self, b: u8) -> Result<State, DecodingError> { 547 self.add_frame(); 548 self.ext.1.push(b); 549 if b != 4 { 550 return Err(DecodingError::Format( 551 "control extension has wrong length" 552 )) 553 } 554 Ok(Byte(ByteValue::ControlFlags)) 555 } 556 add_frame(&mut self)557 fn add_frame(&mut self) { 558 if self.current.is_none() { 559 self.current = Some(Frame::default()) 560 } 561 } 562 } 563