1 use byteorder::{LittleEndian, ReadBytesExt};
2 use std::io;
3 use std::io::{Read, Seek};
4 
5 use color::ColorType;
6 use image::{ImageDecoder, ImageError, ImageReadBuffer, ImageResult};
7 
8 enum ImageType {
9     NoImageData = 0,
10     /// Uncompressed images
11     RawColorMap = 1,
12     RawTrueColor = 2,
13     RawGrayScale = 3,
14     /// Run length encoded images
15     RunColorMap = 9,
16     RunTrueColor = 10,
17     RunGrayScale = 11,
18     Unknown,
19 }
20 
21 impl ImageType {
22     /// Create a new image type from a u8
new(img_type: u8) -> ImageType23     fn new(img_type: u8) -> ImageType {
24         match img_type {
25             0 => ImageType::NoImageData,
26 
27             1 => ImageType::RawColorMap,
28             2 => ImageType::RawTrueColor,
29             3 => ImageType::RawGrayScale,
30 
31             9 => ImageType::RunColorMap,
32             10 => ImageType::RunTrueColor,
33             11 => ImageType::RunGrayScale,
34 
35             _ => ImageType::Unknown,
36         }
37     }
38 
39     /// Check if the image format uses colors as opposed to gray scale
is_color(&self) -> bool40     fn is_color(&self) -> bool {
41         match *self {
42             ImageType::RawColorMap
43             | ImageType::RawTrueColor
44             | ImageType::RunTrueColor
45             | ImageType::RunColorMap => true,
46             _ => false,
47         }
48     }
49 
50     /// Does the image use a color map
is_color_mapped(&self) -> bool51     fn is_color_mapped(&self) -> bool {
52         match *self {
53             ImageType::RawColorMap | ImageType::RunColorMap => true,
54             _ => false,
55         }
56     }
57 
58     /// Is the image run length encoded
is_encoded(&self) -> bool59     fn is_encoded(&self) -> bool {
60         match *self {
61             ImageType::RunColorMap | ImageType::RunTrueColor | ImageType::RunGrayScale => true,
62             _ => false,
63         }
64     }
65 }
66 
67 /// Header used by TGA image files
68 #[derive(Debug)]
69 struct Header {
70     id_length: u8,      // length of ID string
71     map_type: u8,       // color map type
72     image_type: u8,     // image type code
73     map_origin: u16,    // starting index of map
74     map_length: u16,    // length of map
75     map_entry_size: u8, // size of map entries in bits
76     x_origin: u16,      // x-origin of image
77     y_origin: u16,      // y-origin of image
78     image_width: u16,   // width of image
79     image_height: u16,  // height of image
80     pixel_depth: u8,    // bits per pixel
81     image_desc: u8,     // image descriptor
82 }
83 
84 impl Header {
85     /// Create a header with all values set to zero
new() -> Header86     fn new() -> Header {
87         Header {
88             id_length: 0,
89             map_type: 0,
90             image_type: 0,
91             map_origin: 0,
92             map_length: 0,
93             map_entry_size: 0,
94             x_origin: 0,
95             y_origin: 0,
96             image_width: 0,
97             image_height: 0,
98             pixel_depth: 0,
99             image_desc: 0,
100         }
101     }
102 
103     /// Load the header with values from the reader
from_reader(r: &mut dyn Read) -> ImageResult<Header>104     fn from_reader(r: &mut dyn Read) -> ImageResult<Header> {
105         Ok(Header {
106             id_length: r.read_u8()?,
107             map_type: r.read_u8()?,
108             image_type: r.read_u8()?,
109             map_origin: r.read_u16::<LittleEndian>()?,
110             map_length: r.read_u16::<LittleEndian>()?,
111             map_entry_size: r.read_u8()?,
112             x_origin: r.read_u16::<LittleEndian>()?,
113             y_origin: r.read_u16::<LittleEndian>()?,
114             image_width: r.read_u16::<LittleEndian>()?,
115             image_height: r.read_u16::<LittleEndian>()?,
116             pixel_depth: r.read_u8()?,
117             image_desc: r.read_u8()?,
118         })
119     }
120 }
121 
122 struct ColorMap {
123     /// sizes in bytes
124     start_offset: usize,
125     entry_size: usize,
126     bytes: Vec<u8>,
127 }
128 
129 impl ColorMap {
from_reader( r: &mut dyn Read, start_offset: u16, num_entries: u16, bits_per_entry: u8, ) -> ImageResult<ColorMap>130     pub fn from_reader(
131         r: &mut dyn Read,
132         start_offset: u16,
133         num_entries: u16,
134         bits_per_entry: u8,
135     ) -> ImageResult<ColorMap> {
136         let bytes_per_entry = (bits_per_entry as usize + 7) / 8;
137 
138         let mut bytes = vec![0; bytes_per_entry * num_entries as usize];
139         r.read_exact(&mut bytes)?;
140 
141         Ok(ColorMap {
142             entry_size: bytes_per_entry,
143             start_offset: start_offset as usize,
144             bytes,
145         })
146     }
147 
148     /// Get one entry from the color map
get(&self, index: usize) -> &[u8]149     pub fn get(&self, index: usize) -> &[u8] {
150         let entry = self.start_offset + self.entry_size * index;
151         &self.bytes[entry..entry + self.entry_size]
152     }
153 }
154 
155 /// The representation of a TGA decoder
156 pub struct TGADecoder<R> {
157     r: R,
158 
159     width: usize,
160     height: usize,
161     bytes_per_pixel: usize,
162     has_loaded_metadata: bool,
163 
164     image_type: ImageType,
165     color_type: ColorType,
166 
167     header: Header,
168     color_map: Option<ColorMap>,
169 
170     // Used in read_scanline
171     line_read: Option<usize>,
172     line_remain_buff: Vec<u8>,
173 }
174 
175 impl<R: Read + Seek> TGADecoder<R> {
176     /// Create a new decoder that decodes from the stream `r`
new(r: R) -> ImageResult<TGADecoder<R>>177     pub fn new(r: R) -> ImageResult<TGADecoder<R>> {
178         let mut decoder = TGADecoder {
179             r,
180 
181             width: 0,
182             height: 0,
183             bytes_per_pixel: 0,
184             has_loaded_metadata: false,
185 
186             image_type: ImageType::Unknown,
187             color_type: ColorType::Gray(1),
188 
189             header: Header::new(),
190             color_map: None,
191 
192             line_read: None,
193             line_remain_buff: Vec::new(),
194         };
195         decoder.read_metadata()?;
196         Ok(decoder)
197     }
198 
read_header(&mut self) -> ImageResult<()>199     fn read_header(&mut self) -> ImageResult<()> {
200         self.header = Header::from_reader(&mut self.r)?;
201         self.image_type = ImageType::new(self.header.image_type);
202         self.width = self.header.image_width as usize;
203         self.height = self.header.image_height as usize;
204         self.bytes_per_pixel = (self.header.pixel_depth as usize + 7) / 8;
205         Ok(())
206     }
207 
read_metadata(&mut self) -> ImageResult<()>208     fn read_metadata(&mut self) -> ImageResult<()> {
209         if !self.has_loaded_metadata {
210             self.read_header()?;
211             self.read_image_id()?;
212             self.read_color_map()?;
213             self.read_color_information()?;
214             self.has_loaded_metadata = true;
215         }
216         Ok(())
217     }
218 
219     /// Loads the color information for the decoder
220     ///
221     /// To keep things simple, we won't handle bit depths that aren't divisible
222     /// by 8 and are less than 32.
read_color_information(&mut self) -> ImageResult<()>223     fn read_color_information(&mut self) -> ImageResult<()> {
224         if self.header.pixel_depth % 8 != 0 {
225             return Err(ImageError::UnsupportedError(
226                 "Bit depth must be divisible by 8".to_string(),
227             ));
228         }
229         if self.header.pixel_depth > 32 {
230             return Err(ImageError::UnsupportedError(
231                 "Bit depth must be less than 32".to_string(),
232             ));
233         }
234 
235         let num_alpha_bits = self.header.image_desc & 0b1111;
236 
237         let other_channel_bits = if self.header.map_type != 0 {
238             self.header.map_entry_size
239         } else {
240             if num_alpha_bits > self.header.pixel_depth {
241                 return Err(ImageError::UnsupportedError(
242                     format!("Color format not supported. Alpha bits: {}", num_alpha_bits)
243                         .to_string(),
244                 ));
245             }
246 
247             self.header.pixel_depth - num_alpha_bits
248         };
249         let color = self.image_type.is_color();
250 
251         match (num_alpha_bits, other_channel_bits, color) {
252             // really, the encoding is BGR and BGRA, this is fixed
253             // up with `TGADecoder::reverse_encoding`.
254             (0, 32, true) => self.color_type = ColorType::RGBA(8),
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             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) -> io::Result<Vec<u8>>346     fn read_encoded_data(&mut self, num_bytes: usize) -> io::Result<Vec<u8>> {
347         let mut pixel_data = Vec::with_capacity(num_bytes);
348 
349         while pixel_data.len() < num_bytes {
350             let run_packet = 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         Ok(self.read_encoded_data(num_bytes)?)
388     }
389 
390     /// Reads a run length encoded line
read_encoded_line(&mut self) -> io::Result<Vec<u8>>391     fn read_encoded_line(&mut self) -> io::Result<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 
read_scanline(&mut self, buf: &mut [u8]) -> io::Result<usize>469     fn read_scanline(&mut self, buf: &mut [u8]) -> io::Result<usize> {
470         if let Some(line_read) = self.line_read {
471             if line_read == self.height {
472                 return Ok(0);
473             }
474         }
475 
476         // read the pixels from the data region
477         let mut pixel_data = if self.image_type.is_encoded() {
478             self.read_encoded_line()?
479         } else {
480             let num_raw_bytes = self.width * self.bytes_per_pixel;
481             let mut buf = vec![0; num_raw_bytes];
482             self.r.by_ref().read_exact(&mut buf)?;
483             buf
484         };
485 
486         // expand the indices using the color map if necessary
487         if self.image_type.is_color_mapped() {
488             pixel_data = self.expand_color_map(&pixel_data)
489         }
490         self.reverse_encoding(&mut pixel_data);
491 
492         // copy to the output buffer
493         buf[..pixel_data.len()].copy_from_slice(&pixel_data);
494 
495         self.line_read = Some(self.line_read.unwrap_or(0) + 1);
496 
497         Ok(pixel_data.len())
498     }
499 }
500 
501 impl<'a, R: 'a + Read + Seek> ImageDecoder<'a> for TGADecoder<R> {
502     type Reader = TGAReader<R>;
503 
dimensions(&self) -> (u64, u64)504     fn dimensions(&self) -> (u64, u64) {
505         (self.width as u64, self.height as u64)
506     }
507 
colortype(&self) -> ColorType508     fn colortype(&self) -> ColorType {
509         self.color_type
510     }
511 
scanline_bytes(&self) -> u64512     fn scanline_bytes(&self) -> u64 {
513         self.row_bytes()
514     }
515 
into_reader(self) -> ImageResult<Self::Reader>516     fn into_reader(self) -> ImageResult<Self::Reader> {
517         if self.total_bytes() > usize::max_value() as u64 {
518             return Err(ImageError::InsufficientMemory);
519         }
520 
521         Ok(TGAReader {
522             buffer: ImageReadBuffer::new(self.scanline_bytes() as usize, self.total_bytes() as usize),
523             decoder: self,
524         })
525     }
526 
read_image(mut self) -> ImageResult<Vec<u8>>527     fn read_image(mut self) -> ImageResult<Vec<u8>> {
528         self.read_image_data()
529     }
530 }
531 
532 pub struct TGAReader<R> {
533     buffer: ImageReadBuffer,
534     decoder: TGADecoder<R>,
535 }
536 impl<R: Read + Seek> Read for TGAReader<R> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>537     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
538         let ref mut decoder = &mut self.decoder;
539         self.buffer.read(buf, |buf| decoder.read_scanline(buf))
540     }
541 }
542 
543