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