1 use byteorder::{LittleEndian, ReadBytesExt};
2 use std::io;
3 use std::io::{Read, Seek};
4 
5 use color::ColorType;
6 use image::DecodingResult;
7 use image::ImageDecoder;
8 use image::ImageError;
9 use image::ImageResult;
10 
11 enum ImageType {
12     NoImageData = 0,
13     /// Uncompressed images
14     RawColorMap = 1,
15     RawTrueColor = 2,
16     RawGrayScale = 3,
17     /// Run length encoded images
18     RunColorMap = 9,
19     RunTrueColor = 10,
20     RunGrayScale = 11,
21     Unknown,
22 }
23 
24 impl ImageType {
25     /// Create a new image type from a u8
new(img_type: u8) -> ImageType26     fn new(img_type: u8) -> ImageType {
27         match img_type {
28             0 => ImageType::NoImageData,
29 
30             1 => ImageType::RawColorMap,
31             2 => ImageType::RawTrueColor,
32             3 => ImageType::RawGrayScale,
33 
34             9 => ImageType::RunColorMap,
35             10 => ImageType::RunTrueColor,
36             11 => ImageType::RunGrayScale,
37 
38             _ => ImageType::Unknown,
39         }
40     }
41 
42     /// Check if the image format uses colors as opposed to gray scale
is_color(&self) -> bool43     fn is_color(&self) -> bool {
44         match *self {
45             ImageType::RawColorMap
46             | ImageType::RawTrueColor
47             | ImageType::RunTrueColor
48             | ImageType::RunColorMap => true,
49             _ => false,
50         }
51     }
52 
53     /// Does the image use a color map
is_color_mapped(&self) -> bool54     fn is_color_mapped(&self) -> bool {
55         match *self {
56             ImageType::RawColorMap | ImageType::RunColorMap => true,
57             _ => false,
58         }
59     }
60 
61     /// Is the image run length encoded
is_encoded(&self) -> bool62     fn is_encoded(&self) -> bool {
63         match *self {
64             ImageType::RunColorMap | ImageType::RunTrueColor | ImageType::RunGrayScale => true,
65             _ => false,
66         }
67     }
68 }
69 
70 /// Header used by TGA image files
71 #[derive(Debug)]
72 struct Header {
73     id_length: u8,      // length of ID string
74     map_type: u8,       // color map type
75     image_type: u8,     // image type code
76     map_origin: u16,    // starting index of map
77     map_length: u16,    // length of map
78     map_entry_size: u8, // size of map entries in bits
79     x_origin: u16,      // x-origin of image
80     y_origin: u16,      // y-origin of image
81     image_width: u16,   // width of image
82     image_height: u16,  // height of image
83     pixel_depth: u8,    // bits per pixel
84     image_desc: u8,     // image descriptor
85 }
86 
87 impl Header {
88     /// Create a header with all values set to zero
new() -> Header89     fn new() -> Header {
90         Header {
91             id_length: 0,
92             map_type: 0,
93             image_type: 0,
94             map_origin: 0,
95             map_length: 0,
96             map_entry_size: 0,
97             x_origin: 0,
98             y_origin: 0,
99             image_width: 0,
100             image_height: 0,
101             pixel_depth: 0,
102             image_desc: 0,
103         }
104     }
105 
106     /// Load the header with values from the reader
from_reader(r: &mut Read) -> ImageResult<Header>107     fn from_reader(r: &mut Read) -> ImageResult<Header> {
108         Ok(Header {
109             id_length: try!(r.read_u8()),
110             map_type: try!(r.read_u8()),
111             image_type: try!(r.read_u8()),
112             map_origin: try!(r.read_u16::<LittleEndian>()),
113             map_length: try!(r.read_u16::<LittleEndian>()),
114             map_entry_size: try!(r.read_u8()),
115             x_origin: try!(r.read_u16::<LittleEndian>()),
116             y_origin: try!(r.read_u16::<LittleEndian>()),
117             image_width: try!(r.read_u16::<LittleEndian>()),
118             image_height: try!(r.read_u16::<LittleEndian>()),
119             pixel_depth: try!(r.read_u8()),
120             image_desc: try!(r.read_u8()),
121         })
122     }
123 }
124 
125 struct ColorMap {
126     /// sizes in bytes
127     start_offset: usize,
128     entry_size: usize,
129     bytes: Vec<u8>,
130 }
131 
132 impl ColorMap {
from_reader( r: &mut Read, start_offset: u16, num_entries: u16, bits_per_entry: u8, ) -> ImageResult<ColorMap>133     pub fn from_reader(
134         r: &mut Read,
135         start_offset: u16,
136         num_entries: u16,
137         bits_per_entry: u8,
138     ) -> ImageResult<ColorMap> {
139         let bytes_per_entry = (bits_per_entry as usize + 7) / 8;
140 
141         let mut bytes = vec![0; bytes_per_entry * num_entries as usize];
142         try!(r.read_exact(&mut bytes));
143 
144         Ok(ColorMap {
145             entry_size: bytes_per_entry,
146             start_offset: start_offset as usize,
147             bytes,
148         })
149     }
150 
151     /// Get one entry from the color map
get(&self, index: usize) -> &[u8]152     pub fn get(&self, index: usize) -> &[u8] {
153         let entry = self.start_offset + self.entry_size * index;
154         &self.bytes[entry..entry + self.entry_size]
155     }
156 }
157 
158 /// The representation of a TGA decoder
159 pub struct TGADecoder<R> {
160     r: R,
161 
162     width: usize,
163     height: usize,
164     bytes_per_pixel: usize,
165     has_loaded_metadata: bool,
166 
167     image_type: ImageType,
168     color_type: ColorType,
169 
170     header: Header,
171     color_map: Option<ColorMap>,
172 
173     // Used in read_scanline
174     line_read: Option<usize>,
175     line_remain_buff: Vec<u8>,
176 }
177 
178 impl<R: Read + Seek> TGADecoder<R> {
179     /// Create a new decoder that decodes from the stream `r`
new(r: R) -> TGADecoder<R>180     pub fn new(r: R) -> TGADecoder<R> {
181         TGADecoder {
182             r,
183 
184             width: 0,
185             height: 0,
186             bytes_per_pixel: 0,
187             has_loaded_metadata: false,
188 
189             image_type: ImageType::Unknown,
190             color_type: ColorType::Gray(1),
191 
192             header: Header::new(),
193             color_map: None,
194 
195             line_read: None,
196             line_remain_buff: Vec::new(),
197         }
198     }
199 
read_header(&mut self) -> ImageResult<()>200     fn read_header(&mut self) -> ImageResult<()> {
201         self.header = try!(Header::from_reader(&mut self.r));
202         self.image_type = ImageType::new(self.header.image_type);
203         self.width = self.header.image_width as usize;
204         self.height = self.header.image_height as usize;
205         self.bytes_per_pixel = (self.header.pixel_depth as usize + 7) / 8;
206         Ok(())
207     }
208 
read_metadata(&mut self) -> ImageResult<()>209     fn read_metadata(&mut self) -> ImageResult<()> {
210         if !self.has_loaded_metadata {
211             try!(self.read_header());
212             try!(self.read_image_id());
213             try!(self.read_color_map());
214             try!(self.read_color_information());
215             self.has_loaded_metadata = true;
216         }
217         Ok(())
218     }
219 
220     /// Loads the color information for the decoder
221     ///
222     /// To keep things simple, we won't handle bit depths that aren't divisible
223     /// by 8 and are less than 32.
read_color_information(&mut self) -> ImageResult<()>224     fn read_color_information(&mut self) -> ImageResult<()> {
225         if self.header.pixel_depth % 8 != 0 {
226             return Err(ImageError::UnsupportedError(
227                 "Bit depth must be divisible by 8".to_string(),
228             ));
229         }
230         if self.header.pixel_depth > 32 {
231             return Err(ImageError::UnsupportedError(
232                 "Bit depth must be less than 32".to_string(),
233             ));
234         }
235 
236         let num_alpha_bits = self.header.image_desc & 0b1111;
237 
238         let other_channel_bits = if self.header.map_type != 0 {
239             self.header.map_entry_size
240         } else {
241             if num_alpha_bits > self.header.pixel_depth {
242                 return Err(ImageError::UnsupportedError(
243                     format!("Color format not supported. Alpha bits: {}", num_alpha_bits)
244                         .to_string(),
245                 ));
246             }
247 
248             self.header.pixel_depth - num_alpha_bits
249         };
250         let color = self.image_type.is_color();
251 
252         match (num_alpha_bits, other_channel_bits, color) {
253             // really, the encoding is BGR and BGRA, this is fixed
254             // up with `TGADecoder::reverse_encoding`.
255             (8, 24, true) => self.color_type = ColorType::RGBA(8),
256             (0, 24, true) => self.color_type = ColorType::RGB(8),
257             (8, 8, false) => self.color_type = ColorType::GrayA(8),
258             (0, 8, false) => self.color_type = ColorType::Gray(8),
259             _ => {
260                 return Err(ImageError::UnsupportedError(
261                     format!(
262                         "Color format not supported. Bit depth: {}, Alpha bits: {}",
263                         other_channel_bits, num_alpha_bits
264                     ).to_string(),
265                 ))
266             }
267         }
268         Ok(())
269     }
270 
271     /// Read the image id field
272     ///
273     /// We're not interested in this field, so this function skips it if it
274     /// is present
read_image_id(&mut self) -> ImageResult<()>275     fn read_image_id(&mut self) -> ImageResult<()> {
276         try!(
277             self.r
278                 .seek(io::SeekFrom::Current(i64::from(self.header.id_length)))
279         );
280         Ok(())
281     }
282 
read_color_map(&mut self) -> ImageResult<()>283     fn read_color_map(&mut self) -> ImageResult<()> {
284         if self.header.map_type == 1 {
285             self.color_map = Some(try!(ColorMap::from_reader(
286                 &mut self.r,
287                 self.header.map_origin,
288                 self.header.map_length,
289                 self.header.map_entry_size
290             )));
291         }
292         Ok(())
293     }
294 
295     /// Expands indices into its mapped color
expand_color_map(&self, pixel_data: &[u8]) -> Vec<u8>296     fn expand_color_map(&self, pixel_data: &[u8]) -> Vec<u8> {
297         #[inline]
298         fn bytes_to_index(bytes: &[u8]) -> usize {
299             let mut result = 0usize;
300             for byte in bytes.iter() {
301                 result = result << 8 | *byte as usize;
302             }
303             result
304         }
305 
306         let bytes_per_entry = (self.header.map_entry_size as usize + 7) / 8;
307         let mut result = Vec::with_capacity(self.width * self.height * bytes_per_entry);
308 
309         let color_map = match self.color_map {
310             Some(ref color_map) => color_map,
311             None => unreachable!(),
312         };
313 
314         for chunk in pixel_data.chunks(self.bytes_per_pixel) {
315             let index = bytes_to_index(chunk);
316             result.extend(color_map.get(index).iter().cloned());
317         }
318 
319         result
320     }
321 
read_image_data(&mut self) -> ImageResult<Vec<u8>>322     fn read_image_data(&mut self) -> ImageResult<Vec<u8>> {
323         // read the pixels from the data region
324         let mut pixel_data = if self.image_type.is_encoded() {
325             try!(self.read_all_encoded_data())
326         } else {
327             let num_raw_bytes = self.width * self.height * self.bytes_per_pixel;
328             let mut buf = vec![0; num_raw_bytes];
329             try!(self.r.by_ref().read_exact(&mut buf));
330             buf
331         };
332 
333         // expand the indices using the color map if necessary
334         if self.image_type.is_color_mapped() {
335             pixel_data = self.expand_color_map(&pixel_data)
336         }
337 
338         self.reverse_encoding(&mut pixel_data);
339 
340         self.flip_vertically(&mut pixel_data);
341 
342         Ok(pixel_data)
343     }
344 
345     /// Reads a run length encoded data for given number of bytes
read_encoded_data(&mut self, num_bytes: usize) -> ImageResult<Vec<u8>>346     fn read_encoded_data(&mut self, num_bytes: usize) -> ImageResult<Vec<u8>> {
347         let mut pixel_data = Vec::with_capacity(num_bytes);
348 
349         while pixel_data.len() < num_bytes {
350             let run_packet = try!(self.r.read_u8());
351             // If the highest bit in `run_packet` is set, then we repeat pixels
352             //
353             // Note: the TGA format adds 1 to both counts because having a count
354             // of 0 would be pointless.
355             if (run_packet & 0x80) != 0 {
356                 // high bit set, so we will repeat the data
357                 let repeat_count = ((run_packet & !0x80) + 1) as usize;
358                 let mut data = Vec::with_capacity(self.bytes_per_pixel);
359                 try!(
360                     self.r
361                         .by_ref()
362                         .take(self.bytes_per_pixel as u64)
363                         .read_to_end(&mut data)
364                 );
365                 for _ in 0usize..repeat_count {
366                     pixel_data.extend(data.iter().cloned());
367                 }
368             } else {
369                 // not set, so `run_packet+1` is the number of non-encoded pixels
370                 let num_raw_bytes = (run_packet + 1) as usize * self.bytes_per_pixel;
371                 try!(
372                     self.r
373                         .by_ref()
374                         .take(num_raw_bytes as u64)
375                         .read_to_end(&mut pixel_data)
376                 );
377             }
378         }
379 
380         Ok(pixel_data)
381     }
382 
383     /// Reads a run length encoded packet
read_all_encoded_data(&mut self) -> ImageResult<Vec<u8>>384     fn read_all_encoded_data(&mut self) -> ImageResult<Vec<u8>> {
385         let num_bytes = self.width * self.height * self.bytes_per_pixel;
386 
387         self.read_encoded_data(num_bytes)
388     }
389 
390     /// Reads a run length encoded line
read_encoded_line(&mut self) -> ImageResult<Vec<u8>>391     fn read_encoded_line(&mut self) -> ImageResult<Vec<u8>> {
392         let line_num_bytes = self.width * self.bytes_per_pixel;
393         let remain_len = self.line_remain_buff.len();
394 
395         if remain_len >= line_num_bytes {
396             let remain_buf = self.line_remain_buff.clone();
397 
398             self.line_remain_buff = remain_buf[line_num_bytes..].to_vec();
399             return Ok(remain_buf[0..line_num_bytes].to_vec());
400         }
401 
402         let num_bytes = line_num_bytes - remain_len;
403 
404         let line_data = self.read_encoded_data(num_bytes)?;
405 
406         let mut pixel_data = Vec::with_capacity(line_num_bytes);
407         pixel_data.append(&mut self.line_remain_buff);
408         pixel_data.extend_from_slice(&line_data[..num_bytes]);
409 
410         // put the remain data to line_remain_buff
411         self.line_remain_buff = line_data[num_bytes..].to_vec();
412 
413         Ok(pixel_data)
414     }
415 
416     /// Reverse from BGR encoding to RGB encoding
417     ///
418     /// TGA files are stored in the BGRA encoding. This function swaps
419     /// the blue and red bytes in the `pixels` array.
reverse_encoding(&mut self, pixels: &mut [u8])420     fn reverse_encoding(&mut self, pixels: &mut [u8]) {
421         // We only need to reverse the encoding of color images
422         match self.color_type {
423             ColorType::RGB(8) | ColorType::RGBA(8) => {
424                 for chunk in pixels.chunks_mut(self.bytes_per_pixel) {
425                     chunk.swap(0, 2);
426                 }
427             }
428             _ => {}
429         }
430     }
431 
432     /// Flip the image vertically depending on the screen origin bit
433     ///
434     /// The bit in position 5 of the image descriptor byte is the screen origin bit.
435     /// If it's 1, the origin is in the top left corner.
436     /// If it's 0, the origin is in the bottom left corner.
437     /// This function checks the bit, and if it's 0, flips the image vertically.
flip_vertically(&mut self, pixels: &mut [u8])438     fn flip_vertically(&mut self, pixels: &mut [u8]) {
439         if self.is_flipped_vertically() {
440             let num_bytes = pixels.len();
441 
442             let width_bytes = num_bytes / self.height;
443 
444             // Flip the image vertically.
445             for vertical_index in 0..(self.height / 2) {
446                 let vertical_target = (self.height - vertical_index) * width_bytes - width_bytes;
447 
448                 for horizontal_index in 0..width_bytes {
449                     let source = vertical_index * width_bytes + horizontal_index;
450                     let target = vertical_target + horizontal_index;
451 
452                     pixels.swap(target, source);
453                 }
454             }
455         }
456     }
457 
458     /// Check whether the image is vertically flipped
459     ///
460     /// The bit in position 5 of the image descriptor byte is the screen origin bit.
461     /// If it's 1, the origin is in the top left corner.
462     /// If it's 0, the origin is in the bottom left corner.
463     /// This function checks the bit, and if it's 0, flips the image vertically.
is_flipped_vertically(&self) -> bool464     fn is_flipped_vertically(&self) -> bool {
465         let screen_origin_bit = 0b10_0000 & self.header.image_desc != 0;
466         !screen_origin_bit
467     }
468 }
469 
470 impl<R: Read + Seek> ImageDecoder for TGADecoder<R> {
dimensions(&mut self) -> ImageResult<(u32, u32)>471     fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
472         try!(self.read_metadata());
473 
474         Ok((self.width as u32, self.height as u32))
475     }
476 
colortype(&mut self) -> ImageResult<ColorType>477     fn colortype(&mut self) -> ImageResult<ColorType> {
478         try!(self.read_metadata());
479 
480         Ok(self.color_type)
481     }
482 
row_len(&mut self) -> ImageResult<usize>483     fn row_len(&mut self) -> ImageResult<usize> {
484         try!(self.read_metadata());
485 
486         Ok(self.bytes_per_pixel * self.width)
487     }
488 
read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>489     fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32> {
490         try!(self.read_metadata());
491 
492         if let Some(line_read) = self.line_read {
493             if line_read == self.height {
494                 return Err(ImageError::ImageEnd);
495             }
496         }
497 
498         // read the pixels from the data region
499         let mut pixel_data = if self.image_type.is_encoded() {
500             try!(self.read_encoded_line())
501         } else {
502             let num_raw_bytes = self.width * self.bytes_per_pixel;
503             let mut buf = vec![0; num_raw_bytes];
504             try!(self.r.by_ref().read_exact(&mut buf));
505             buf
506         };
507 
508         // expand the indices using the color map if necessary
509         if self.image_type.is_color_mapped() {
510             pixel_data = self.expand_color_map(&pixel_data)
511         }
512         self.reverse_encoding(&mut pixel_data);
513 
514         // copy to the output buffer
515         buf[..pixel_data.len()].copy_from_slice(&pixel_data);
516 
517         let mut row_index = self.line_read.unwrap_or(0) + 1;
518         self.line_read = Some(row_index);
519 
520         if self.is_flipped_vertically() {
521             row_index = self.height - (row_index - 1);
522         }
523 
524         Ok(row_index as u32)
525     }
526 
read_image(&mut self) -> ImageResult<DecodingResult>527     fn read_image(&mut self) -> ImageResult<DecodingResult> {
528         try!(self.read_metadata());
529         self.read_image_data().map(DecodingResult::U8)
530     }
531 }
532