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