1 use byteorder::{LittleEndian, ReadBytesExt}; 2 use std::io; 3 use std::io::{Read, Seek}; 4 5 use color::ColorType; 6 use image::DecodingResult; 7 use image::ImageDecoder; 8 use image::ImageError; 9 use image::ImageResult; 10 11 enum ImageType { 12 NoImageData = 0, 13 /// Uncompressed images 14 RawColorMap = 1, 15 RawTrueColor = 2, 16 RawGrayScale = 3, 17 /// Run length encoded images 18 RunColorMap = 9, 19 RunTrueColor = 10, 20 RunGrayScale = 11, 21 Unknown, 22 } 23 24 impl ImageType { 25 /// Create a new image type from a u8 new(img_type: u8) -> ImageType26 fn new(img_type: u8) -> ImageType { 27 match img_type { 28 0 => ImageType::NoImageData, 29 30 1 => ImageType::RawColorMap, 31 2 => ImageType::RawTrueColor, 32 3 => ImageType::RawGrayScale, 33 34 9 => ImageType::RunColorMap, 35 10 => ImageType::RunTrueColor, 36 11 => ImageType::RunGrayScale, 37 38 _ => ImageType::Unknown, 39 } 40 } 41 42 /// Check if the image format uses colors as opposed to gray scale is_color(&self) -> bool43 fn is_color(&self) -> bool { 44 match *self { 45 ImageType::RawColorMap 46 | ImageType::RawTrueColor 47 | ImageType::RunTrueColor 48 | ImageType::RunColorMap => true, 49 _ => false, 50 } 51 } 52 53 /// Does the image use a color map is_color_mapped(&self) -> bool54 fn is_color_mapped(&self) -> bool { 55 match *self { 56 ImageType::RawColorMap | ImageType::RunColorMap => true, 57 _ => false, 58 } 59 } 60 61 /// Is the image run length encoded is_encoded(&self) -> bool62 fn is_encoded(&self) -> bool { 63 match *self { 64 ImageType::RunColorMap | ImageType::RunTrueColor | ImageType::RunGrayScale => true, 65 _ => false, 66 } 67 } 68 } 69 70 /// Header used by TGA image files 71 #[derive(Debug)] 72 struct Header { 73 id_length: u8, // length of ID string 74 map_type: u8, // color map type 75 image_type: u8, // image type code 76 map_origin: u16, // starting index of map 77 map_length: u16, // length of map 78 map_entry_size: u8, // size of map entries in bits 79 x_origin: u16, // x-origin of image 80 y_origin: u16, // y-origin of image 81 image_width: u16, // width of image 82 image_height: u16, // height of image 83 pixel_depth: u8, // bits per pixel 84 image_desc: u8, // image descriptor 85 } 86 87 impl Header { 88 /// Create a header with all values set to zero new() -> Header89 fn new() -> Header { 90 Header { 91 id_length: 0, 92 map_type: 0, 93 image_type: 0, 94 map_origin: 0, 95 map_length: 0, 96 map_entry_size: 0, 97 x_origin: 0, 98 y_origin: 0, 99 image_width: 0, 100 image_height: 0, 101 pixel_depth: 0, 102 image_desc: 0, 103 } 104 } 105 106 /// Load the header with values from the reader from_reader(r: &mut Read) -> ImageResult<Header>107 fn from_reader(r: &mut Read) -> ImageResult<Header> { 108 Ok(Header { 109 id_length: try!(r.read_u8()), 110 map_type: try!(r.read_u8()), 111 image_type: try!(r.read_u8()), 112 map_origin: try!(r.read_u16::<LittleEndian>()), 113 map_length: try!(r.read_u16::<LittleEndian>()), 114 map_entry_size: try!(r.read_u8()), 115 x_origin: try!(r.read_u16::<LittleEndian>()), 116 y_origin: try!(r.read_u16::<LittleEndian>()), 117 image_width: try!(r.read_u16::<LittleEndian>()), 118 image_height: try!(r.read_u16::<LittleEndian>()), 119 pixel_depth: try!(r.read_u8()), 120 image_desc: try!(r.read_u8()), 121 }) 122 } 123 } 124 125 struct ColorMap { 126 /// sizes in bytes 127 start_offset: usize, 128 entry_size: usize, 129 bytes: Vec<u8>, 130 } 131 132 impl ColorMap { from_reader( r: &mut Read, start_offset: u16, num_entries: u16, bits_per_entry: u8, ) -> ImageResult<ColorMap>133 pub fn from_reader( 134 r: &mut Read, 135 start_offset: u16, 136 num_entries: u16, 137 bits_per_entry: u8, 138 ) -> ImageResult<ColorMap> { 139 let bytes_per_entry = (bits_per_entry as usize + 7) / 8; 140 141 let mut bytes = vec![0; bytes_per_entry * num_entries as usize]; 142 try!(r.read_exact(&mut bytes)); 143 144 Ok(ColorMap { 145 entry_size: bytes_per_entry, 146 start_offset: start_offset as usize, 147 bytes, 148 }) 149 } 150 151 /// Get one entry from the color map get(&self, index: usize) -> &[u8]152 pub fn get(&self, index: usize) -> &[u8] { 153 let entry = self.start_offset + self.entry_size * index; 154 &self.bytes[entry..entry + self.entry_size] 155 } 156 } 157 158 /// The representation of a TGA decoder 159 pub struct TGADecoder<R> { 160 r: R, 161 162 width: usize, 163 height: usize, 164 bytes_per_pixel: usize, 165 has_loaded_metadata: bool, 166 167 image_type: ImageType, 168 color_type: ColorType, 169 170 header: Header, 171 color_map: Option<ColorMap>, 172 173 // Used in read_scanline 174 line_read: Option<usize>, 175 line_remain_buff: Vec<u8>, 176 } 177 178 impl<R: Read + Seek> TGADecoder<R> { 179 /// Create a new decoder that decodes from the stream `r` new(r: R) -> TGADecoder<R>180 pub fn new(r: R) -> TGADecoder<R> { 181 TGADecoder { 182 r, 183 184 width: 0, 185 height: 0, 186 bytes_per_pixel: 0, 187 has_loaded_metadata: false, 188 189 image_type: ImageType::Unknown, 190 color_type: ColorType::Gray(1), 191 192 header: Header::new(), 193 color_map: None, 194 195 line_read: None, 196 line_remain_buff: Vec::new(), 197 } 198 } 199 read_header(&mut self) -> ImageResult<()>200 fn read_header(&mut self) -> ImageResult<()> { 201 self.header = try!(Header::from_reader(&mut self.r)); 202 self.image_type = ImageType::new(self.header.image_type); 203 self.width = self.header.image_width as usize; 204 self.height = self.header.image_height as usize; 205 self.bytes_per_pixel = (self.header.pixel_depth as usize + 7) / 8; 206 Ok(()) 207 } 208 read_metadata(&mut self) -> ImageResult<()>209 fn read_metadata(&mut self) -> ImageResult<()> { 210 if !self.has_loaded_metadata { 211 try!(self.read_header()); 212 try!(self.read_image_id()); 213 try!(self.read_color_map()); 214 try!(self.read_color_information()); 215 self.has_loaded_metadata = true; 216 } 217 Ok(()) 218 } 219 220 /// Loads the color information for the decoder 221 /// 222 /// To keep things simple, we won't handle bit depths that aren't divisible 223 /// by 8 and are less than 32. read_color_information(&mut self) -> ImageResult<()>224 fn read_color_information(&mut self) -> ImageResult<()> { 225 if self.header.pixel_depth % 8 != 0 { 226 return Err(ImageError::UnsupportedError( 227 "Bit depth must be divisible by 8".to_string(), 228 )); 229 } 230 if self.header.pixel_depth > 32 { 231 return Err(ImageError::UnsupportedError( 232 "Bit depth must be less than 32".to_string(), 233 )); 234 } 235 236 let num_alpha_bits = self.header.image_desc & 0b1111; 237 238 let other_channel_bits = if self.header.map_type != 0 { 239 self.header.map_entry_size 240 } else { 241 if num_alpha_bits > self.header.pixel_depth { 242 return Err(ImageError::UnsupportedError( 243 format!("Color format not supported. Alpha bits: {}", num_alpha_bits) 244 .to_string(), 245 )); 246 } 247 248 self.header.pixel_depth - num_alpha_bits 249 }; 250 let color = self.image_type.is_color(); 251 252 match (num_alpha_bits, other_channel_bits, color) { 253 // really, the encoding is BGR and BGRA, this is fixed 254 // up with `TGADecoder::reverse_encoding`. 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) -> ImageResult<Vec<u8>>346 fn read_encoded_data(&mut self, num_bytes: usize) -> ImageResult<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 self.read_encoded_data(num_bytes) 388 } 389 390 /// Reads a run length encoded line read_encoded_line(&mut self) -> ImageResult<Vec<u8>>391 fn read_encoded_line(&mut self) -> ImageResult<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 } 469 470 impl<R: Read + Seek> ImageDecoder for TGADecoder<R> { dimensions(&mut self) -> ImageResult<(u32, u32)>471 fn dimensions(&mut self) -> ImageResult<(u32, u32)> { 472 try!(self.read_metadata()); 473 474 Ok((self.width as u32, self.height as u32)) 475 } 476 colortype(&mut self) -> ImageResult<ColorType>477 fn colortype(&mut self) -> ImageResult<ColorType> { 478 try!(self.read_metadata()); 479 480 Ok(self.color_type) 481 } 482 row_len(&mut self) -> ImageResult<usize>483 fn row_len(&mut self) -> ImageResult<usize> { 484 try!(self.read_metadata()); 485 486 Ok(self.bytes_per_pixel * self.width) 487 } 488 read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32>489 fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32> { 490 try!(self.read_metadata()); 491 492 if let Some(line_read) = self.line_read { 493 if line_read == self.height { 494 return Err(ImageError::ImageEnd); 495 } 496 } 497 498 // read the pixels from the data region 499 let mut pixel_data = if self.image_type.is_encoded() { 500 try!(self.read_encoded_line()) 501 } else { 502 let num_raw_bytes = self.width * self.bytes_per_pixel; 503 let mut buf = vec![0; num_raw_bytes]; 504 try!(self.r.by_ref().read_exact(&mut buf)); 505 buf 506 }; 507 508 // expand the indices using the color map if necessary 509 if self.image_type.is_color_mapped() { 510 pixel_data = self.expand_color_map(&pixel_data) 511 } 512 self.reverse_encoding(&mut pixel_data); 513 514 // copy to the output buffer 515 buf[..pixel_data.len()].copy_from_slice(&pixel_data); 516 517 let mut row_index = self.line_read.unwrap_or(0) + 1; 518 self.line_read = Some(row_index); 519 520 if self.is_flipped_vertically() { 521 row_index = self.height - (row_index - 1); 522 } 523 524 Ok(row_index as u32) 525 } 526 read_image(&mut self) -> ImageResult<DecodingResult>527 fn read_image(&mut self) -> ImageResult<DecodingResult> { 528 try!(self.read_metadata()); 529 self.read_image_data().map(DecodingResult::U8) 530 } 531 } 532