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 Read) -> ImageResult<Header>104 fn from_reader(r: &mut Read) -> ImageResult<Header> { 105 Ok(Header { 106 id_length: try!(r.read_u8()), 107 map_type: try!(r.read_u8()), 108 image_type: try!(r.read_u8()), 109 map_origin: try!(r.read_u16::<LittleEndian>()), 110 map_length: try!(r.read_u16::<LittleEndian>()), 111 map_entry_size: try!(r.read_u8()), 112 x_origin: try!(r.read_u16::<LittleEndian>()), 113 y_origin: try!(r.read_u16::<LittleEndian>()), 114 image_width: try!(r.read_u16::<LittleEndian>()), 115 image_height: try!(r.read_u16::<LittleEndian>()), 116 pixel_depth: try!(r.read_u8()), 117 image_desc: try!(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 Read, start_offset: u16, num_entries: u16, bits_per_entry: u8, ) -> ImageResult<ColorMap>130 pub fn from_reader( 131 r: &mut 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 try!(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 = try!(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 try!(self.read_header()); 211 try!(self.read_image_id()); 212 try!(self.read_color_map()); 213 try!(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 try!(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 = try!(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<R: Read + Seek> ImageDecoder 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