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