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