(&mut self, remapped_image: &RowBitmap<'_, PalIndexRemap>, palette: &PalF, uses_background: bool)
| 124 | } |
| 125 | |
| 126 | pub(crate) fn update_dither_map(&mut self, remapped_image: &RowBitmap<'_, PalIndexRemap>, palette: &PalF, uses_background: bool) -> Result<(), Error> { |
| 127 | if self.edges.is_none() { |
| 128 | self.contrast_maps()?; |
| 129 | } |
| 130 | let Some(mut edges) = self.edges.take() else { return Ok(()) }; |
| 131 | let colors = palette.as_slice(); |
| 132 | |
| 133 | let width = self.width(); |
| 134 | let mut prev_row: Option<&[_]> = None; |
| 135 | let mut rows = remapped_image.rows().zip(edges.chunks_exact_mut(width)).peekable(); |
| 136 | while let Some((this_row, edges)) = rows.next() { |
| 137 | let mut lastpixel = this_row[0]; |
| 138 | let mut lastcol = 0; |
| 139 | for (col, px) in this_row.iter().copied().enumerate().skip(1) { |
| 140 | if uses_background && (colors[px as usize]).a < MIN_OPAQUE_A { |
| 141 | // Transparency may or may not create an edge. When there's an explicit background set, assume no edge. |
| 142 | continue; |
| 143 | } |
| 144 | if px != lastpixel || col == width - 1 { |
| 145 | let mut neighbor_count = 10 * (col - lastcol); |
| 146 | let mut i = lastcol; |
| 147 | while i < col { |
| 148 | if let Some(prev_row) = prev_row { |
| 149 | let pixelabove = prev_row[i]; |
| 150 | if pixelabove == lastpixel { neighbor_count += 15; } |
| 151 | } |
| 152 | if let Some((next_row, _)) = rows.peek() { |
| 153 | let pixelbelow = next_row[i]; |
| 154 | if pixelbelow == lastpixel { neighbor_count += 15; } |
| 155 | } |
| 156 | i += 1; |
| 157 | } |
| 158 | while lastcol <= col { |
| 159 | edges[lastcol] = (f32::from(u16::from(edges[lastcol]) + 128) |
| 160 | * (255. / (255 + 128) as f32) |
| 161 | * (1. - 20. / (20 + neighbor_count) as f32)) |
| 162 | as u8; |
| 163 | lastcol += 1; |
| 164 | } |
| 165 | lastpixel = px; |
| 166 | } |
| 167 | } |
| 168 | prev_row = Some(this_row); |
| 169 | } |
| 170 | self.dither_map = Some(edges); |
| 171 | Ok(()) |
| 172 | } |
| 173 | |
| 174 | /// Set which pixels are more important (and more likely to get a palette entry) |
| 175 | /// |
no test coverage detected