alpha image, transforms
This commit is contained in:
		
							parent
							
								
									b647d95713
								
							
						
					
					
						commit
						2f7b20fde7
					
				
							
								
								
									
										69
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								src/main.rs
									
									
									
									
									
								
							|  | @ -617,22 +617,29 @@ fn main() { | ||||||
| 
 | 
 | ||||||
|             image_rect = rect_union(image_rect, rect); |             image_rect = rect_union(image_rect, rect); | ||||||
| 
 | 
 | ||||||
|             (info, offset, rect, output.frame.inverted_y) |             ( | ||||||
|  |                 info, | ||||||
|  |                 offset, | ||||||
|  |                 rect, | ||||||
|  |                 output.frame.inverted_y, | ||||||
|  |                 output.transform.unwrap_or(wl_output::Transform::Normal), | ||||||
|  |             ) | ||||||
|         }) |         }) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|     let mut image = image::RgbImage::new(image_rect.width, image_rect.height); |     let mut image = image::RgbaImage::new(image_rect.width, image_rect.height); | ||||||
| 
 | 
 | ||||||
|     let now = std::time::Instant::now(); |     let now = std::time::Instant::now(); | ||||||
|     for (info, offset, rect, inverted_y) in buffers { |     for (info, offset, rect, inverted_y, transform) in buffers { | ||||||
|         let size = info.stride * info.height; |         let size = info.stride * info.height; | ||||||
|         let view = BufferView { |         let view = BufferView { | ||||||
|             info, |             info, | ||||||
|             inverted_y, |             inverted_y, | ||||||
|  |             transform, | ||||||
|             bytes: &buffer[offset..][..size as usize], |             bytes: &buffer[offset..][..size as usize], | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         if rect.width != info.width || rect.height != info.height { |         if rect.width != view.width() || rect.height != view.height() { | ||||||
|             let sampled = SampledView { |             let sampled = SampledView { | ||||||
|                 view: &view, |                 view: &view, | ||||||
|                 dimensions: (rect.width, rect.height), |                 dimensions: (rect.width, rect.height), | ||||||
|  | @ -680,17 +687,52 @@ impl<'a, V: GenericImageView> GenericImageView for SampledView<'a, V> { | ||||||
| struct BufferView<'a> { | struct BufferView<'a> { | ||||||
|     info: BufferInfo, |     info: BufferInfo, | ||||||
|     inverted_y: bool, |     inverted_y: bool, | ||||||
|  |     transform: wl_output::Transform, | ||||||
|     bytes: &'a [u8], |     bytes: &'a [u8], | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl BufferView<'_> { | impl BufferView<'_> { | ||||||
|     fn pixel_offset(&self, x: u32, y: u32) -> usize { |     fn transformed_pixel_position(&self, x: u32, y: u32) -> (u32, u32) { | ||||||
|  |         let (width, height) = self.transformed_dimensions(); | ||||||
|  |         let width = width - 1; | ||||||
|  |         let height = height - 1; | ||||||
|  | 
 | ||||||
|  |         let (x, y) = match self.transform { | ||||||
|  |             Transform::Normal => (x, y), | ||||||
|  |             Transform::_90 => (y, x), | ||||||
|  |             Transform::_180 => (width - x, height - y), | ||||||
|  |             Transform::_270 => (height - y, x), | ||||||
|  |             Transform::Flipped => (width - x, y), | ||||||
|  |             Transform::Flipped90 => (y, width - x), | ||||||
|  |             Transform::Flipped180 => (x, height - y), | ||||||
|  |             Transform::Flipped270 => (height - y, width - x), | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         // apply buffer-local y flip
 | ||||||
|         let y = if self.inverted_y { |         let y = if self.inverted_y { | ||||||
|             self.info.height - y |             self.info.height - y | ||||||
|         } else { |         } else { | ||||||
|             y |             y | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         (x, y) | ||||||
|  |     } | ||||||
|  |     fn transformed_dimensions(&self) -> (u32, u32) { | ||||||
|  |         match self.transform { | ||||||
|  |             Transform::Flipped180 | Transform::_180 | Transform::Flipped | Transform::Normal => { | ||||||
|  |                 (self.info.width, self.info.height) | ||||||
|  |             } | ||||||
|  |             Transform::_90 | Transform::_270 | Transform::Flipped90 | Transform::Flipped270 => { | ||||||
|  |                 (self.info.height, self.info.width) | ||||||
|  |             } | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     fn pixel_offset(&self, x: u32, y: u32) -> usize { | ||||||
|  |         // apply transform
 | ||||||
|  |         let (x, y) = self.transformed_pixel_position(x, y); | ||||||
|  | 
 | ||||||
|         self.info.stride as usize * y as usize + (x as usize * self.pixel_stride() as usize) |         self.info.stride as usize * y as usize + (x as usize * self.pixel_stride() as usize) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -918,22 +960,27 @@ impl BufferView<'_> { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl GenericImageView for BufferView<'_> { | impl GenericImageView for BufferView<'_> { | ||||||
|     type Pixel = image::Rgb<u8>; |     type Pixel = image::Rgba<u8>; | ||||||
| 
 | 
 | ||||||
|     fn dimensions(&self) -> (u32, u32) { |     fn dimensions(&self) -> (u32, u32) { | ||||||
|         (self.info.width, self.info.height) |         self.transformed_dimensions() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel { |     fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel { | ||||||
|         match self.info.format { |         match self.info.format { | ||||||
|             wl_shm::Format::Xbgr8888 => Self::Pixel::from( |             wl_shm::Format::Xbgr8888 => { | ||||||
|                 <[u8; 3] as TryFrom<&[u8]>>::try_from(&self.bytes[self.pixel_offset(x, y)..][..3]) |                 let [r, g, b] = <[u8; 3] as TryFrom<&[u8]>>::try_from( | ||||||
|                     .unwrap(), |                     &self.bytes[self.pixel_offset(x, y)..][..3], | ||||||
|             ), |                 ) | ||||||
|  |                 .unwrap(); | ||||||
|  | 
 | ||||||
|  |                 Self::Pixel::from([r, g, b, 255]) | ||||||
|  |             } | ||||||
|             _ => Self::Pixel::from([ |             _ => Self::Pixel::from([ | ||||||
|                 self.sample_r(x, y), |                 self.sample_r(x, y), | ||||||
|                 self.sample_g(x, y), |                 self.sample_g(x, y), | ||||||
|                 self.sample_b(x, y), |                 self.sample_b(x, y), | ||||||
|  |                 255, | ||||||
|             ]), |             ]), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue