image.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // ╻┏┳┓┏━┓┏━╸┏━╸ ╻┏━┓
  2. // ┃┃┃┃┣━┫┃╺┓┣╸ ┃┃ ┃
  3. // ╹╹ ╹╹ ╹┗━┛┗━╸ ╹┗━┛
  4. use std::fs::File;
  5. use std::io::BufReader;
  6. use std::io::Read;
  7. use std::convert::From;
  8. use std::io::BufWriter;
  9. use std::io::Write;
  10. use std::path::Path;
  11. use crate::geometry::Vec3;
  12. pub struct Image {
  13. width: u16,
  14. height: u16,
  15. data: Vec<Vec3>,
  16. }
  17. impl Image {
  18. pub fn get_pixel(&self, x: usize, y: usize) -> &Vec3 {
  19. &self.data[y * self.width as usize + x]
  20. }
  21. pub fn mod_pixel(&mut self, x: usize, y: usize) -> &mut Vec3 {
  22. &mut self.data[y * self.width as usize + x]
  23. }
  24. pub fn new(width: u16, height: u16) -> Image {
  25. let mut data: Vec<Vec3> = Vec::new();
  26. data.resize(
  27. usize::from(width) * usize::from(height),
  28. Vec3 {
  29. x: 0.0,
  30. y: 0.0,
  31. z: 0.0,
  32. },
  33. );
  34. Image {
  35. width: width,
  36. height: height,
  37. data: data,
  38. }
  39. }
  40. pub fn save_bmp(self: &Image, p: &Path) -> std::io::Result<()> {
  41. let f: File = File::create(p)?;
  42. let mut w = BufWriter::new(f);
  43. // File header
  44. w.write_all(&['B' as u8, 'M' as u8])?;
  45. write_int(&mut w, 0)?; // size, left blank for now
  46. write_int(&mut w, 0)?; // reserved bytes
  47. write_int(&mut w, 54)?; // offset
  48. // Bitmap info header
  49. write_int(&mut w, 40)?; // header size in bytes
  50. write_int(&mut w, self.width as u32)?;
  51. write_int(&mut w, self.height as u32)?;
  52. write_int16(&mut w, 1)?; // number of color planes
  53. write_int16(&mut w, 24)?; // bits per pixel
  54. write_int(&mut w, 0)?; // no compression
  55. write_int(&mut w, 0)?; // image size
  56. write_int(&mut w, 1000)?; // horizontal resolution in pixels per metre
  57. write_int(&mut w, 1000)?; // vertical resolution
  58. write_int(&mut w, 0)?; // number of colors
  59. write_int(&mut w, 0)?; // number of important colors
  60. // Pixel data
  61. for y in (0..self.height).rev() {
  62. for x in 0..self.width {
  63. write_vec3(&mut w, self.get_pixel(x.into(), y.into()))?;
  64. }
  65. }
  66. Ok(())
  67. }
  68. }
  69. fn read_int(v: &[u8]) -> u32 {
  70. let mut result = 0;
  71. for i in 0..3 {
  72. result |= (v[i] as u32) << (i * 8);
  73. }
  74. result
  75. }
  76. fn read_int16(v: &[u8]) -> u16 {
  77. v[1] as u16 >> 8 | v[0] as u16
  78. }
  79. fn read_vec3(v: &[u8]) -> Vec3 {
  80. Vec3 {
  81. x: v[2] as f32,
  82. y: v[1] as f32,
  83. z: v[0] as f32,
  84. }
  85. }
  86. fn round_row_size(width: u32) -> u32 {
  87. ((24 * width + 31) / 32) * 4
  88. }
  89. pub fn load_bmp(path: &Path) -> Image {
  90. // See https://en.wikipedia.org/wiki/BMP_file_format for more information.
  91. // BMP is little-endian (least-significant bytes first)
  92. // Some limitations here:
  93. // - we only support bottom-up bitmaps
  94. // - without compression
  95. // - and a depth of 24 bits per pixel
  96. let mut buf = Vec::new();
  97. let mut f = BufReader::new(File::open(path).expect("Could not find image file"));
  98. f.read_to_end(&mut buf).expect("Could not read image file");
  99. assert!(
  100. buf[0] == 'B' as u8 && buf[1] == 'M' as u8,
  101. "File is not a bitmap file"
  102. );
  103. let width = read_int(&buf[18..22]);
  104. let height = read_int(&buf[22..26]);
  105. let compression = read_int(&buf[30..34]);
  106. assert!(compression == 0, "Only uncompressed BMPs are supported");
  107. let depth = read_int16(&buf[28..30]);
  108. assert!(depth == 24, "Only 24 bits per pixel are supported");
  109. let offset = read_int(&buf[10..14]);
  110. let row_size = round_row_size(width);
  111. let mut image_data = Vec::new();
  112. for row in 0..height {
  113. for col in 0..width {
  114. let y = height - row - 1;
  115. let x = 3 * col;
  116. let idx = (offset + y * row_size + x) as usize;
  117. let pixel = read_vec3(&buf[idx..(idx + 3)]);
  118. image_data.push(pixel);
  119. }
  120. }
  121. assert!(image_data.len() == (width * height) as usize);
  122. Image {
  123. width: width as u16,
  124. height: height as u16,
  125. data: image_data,
  126. }
  127. }
  128. fn write_int(f: &mut dyn Write, v: u32) -> std::io::Result<()> {
  129. let bytes = [v as u8, (v >> 8) as u8, (v >> 16) as u8, (v >> 24) as u8];
  130. f.write_all(&bytes)?;
  131. Ok(())
  132. }
  133. fn write_int16(f: &mut dyn Write, v: u16) -> std::io::Result<()> {
  134. let bytes = [v as u8, (v >> 8) as u8];
  135. f.write_all(&bytes)?;
  136. Ok(())
  137. }
  138. fn write_vec3(f: &mut dyn Write, v: &Vec3) -> std::io::Result<()> {
  139. let bytes = [v.z as u8, v.y as u8, v.x as u8];
  140. f.write_all(&bytes)?;
  141. Ok(())
  142. }