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