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