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