| 103 | /// this function will fail with `LIQ_BUFFER_TOO_SMALL`. |
| 104 | #[inline(never)] |
| 105 | pub fn add_image(&mut self, attr: &Attributes, image: &mut Image) -> Result<(), Error> { |
| 106 | let width = image.width(); |
| 107 | let height = image.height(); |
| 108 | if image.importance_map.is_none() && attr.use_contrast_maps { |
| 109 | image.contrast_maps()?; |
| 110 | } |
| 111 | |
| 112 | self.gamma = image.gamma(); |
| 113 | |
| 114 | if !image.fixed_colors.is_empty() { |
| 115 | self.fixed_colors.extend(image.fixed_colors.iter().copied().enumerate().map(|(idx, rgba)| { |
| 116 | HashColor { rgba, index: idx as _ } |
| 117 | })); |
| 118 | } |
| 119 | |
| 120 | if attr.progress(f32::from(attr.progress_stage1) * 0.40) { |
| 121 | return Err(Aborted); // bow can free the RGBA source if copy has been made in f_pixels |
| 122 | } |
| 123 | |
| 124 | let posterize_bits = attr.posterize_bits(); |
| 125 | let surface_area = height * width; |
| 126 | let estimated_colors = (surface_area / (posterize_bits as usize + if surface_area > 512 * 512 { 7 } else { 5 })).min(250_000); |
| 127 | self.reserve(estimated_colors); |
| 128 | |
| 129 | self.add_pixel_rows(&image.px, image.importance_map.as_deref(), posterize_bits)?; |
| 130 | |
| 131 | Ok(()) |
| 132 | } |
| 133 | |
| 134 | /// Alternative to `add_image()`. Intead of counting colors in an image, it directly takes an array of colors and their counts. |
| 135 | /// |