1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:47:44 +00:00

PixelPaint: Optimize color masking performance

This patch adds a small performance tweak when accsessing pixels for
color-masking. Despite of that the most time is spent in
Color::to_hsv()
This commit is contained in:
Torstennator 2023-08-20 13:54:23 +02:00 committed by Sam Atkins
parent 60b72b8033
commit b3a6ccc45b

View file

@ -226,39 +226,38 @@ void ImageMasking::generate_new_mask()
Gfx::HSV content_pixel_hsv; Gfx::HSV content_pixel_hsv;
for (int y = 0; y < m_reference_mask->height(); y++) { for (int y = 0; y < m_reference_mask->height(); y++) {
auto reference_scanline = m_reference_mask->scanline(y);
auto content_scanline = m_editor->active_layer()->content_bitmap().scanline(y);
auto mask_scanline = m_editor->active_layer()->mask_bitmap()->scanline(y);
fast_u32_fill(mask_scanline, 0, m_reference_mask->physical_width());
for (int x = 0; x < m_reference_mask->width(); x++) { for (int x = 0; x < m_reference_mask->width(); x++) {
reference_mask_pixel = m_reference_mask->get_pixel(x, y); reference_mask_pixel = Color::from_argb(reference_scanline[x]);
if (!reference_mask_pixel.alpha()) if (!reference_mask_pixel.alpha())
continue; continue;
content_pixel_hsv = m_editor->active_layer()->content_bitmap().get_pixel(x, y).to_hsv(); content_pixel_hsv = Color::from_argb(content_scanline[x]).to_hsv();
// check against saturation // check against saturation
if (!(lower_saturation <= content_pixel_hsv.saturation && upper_saturation >= content_pixel_hsv.saturation)) { if (!(lower_saturation <= content_pixel_hsv.saturation && upper_saturation >= content_pixel_hsv.saturation))
m_editor->active_layer()->mask_bitmap()->set_pixel(x, y, reference_mask_pixel.with_alpha(0));
continue; continue;
}
// check against value // check against value
if (!(lower_value <= content_pixel_hsv.value && upper_value >= content_pixel_hsv.value)) { if (!(lower_value <= content_pixel_hsv.value && upper_value >= content_pixel_hsv.value))
m_editor->active_layer()->mask_bitmap()->set_pixel(x, y, reference_mask_pixel.with_alpha(0));
continue; continue;
}
// check against hue // check against hue
corrected_current_hue = content_pixel_hsv.hue - m_color_wheel_widget->hue(); corrected_current_hue = content_pixel_hsv.hue - m_color_wheel_widget->hue();
distance_to_selected_color = AK::min(AK::abs(corrected_current_hue), AK::min(AK::abs(corrected_current_hue - 360), AK::abs(corrected_current_hue + 360))); distance_to_selected_color = AK::min(AK::abs(corrected_current_hue), AK::min(AK::abs(corrected_current_hue - 360), AK::abs(corrected_current_hue + 360)));
if (distance_to_selected_color > m_color_wheel_widget->color_range()) { if (distance_to_selected_color > m_color_wheel_widget->color_range())
m_editor->active_layer()->mask_bitmap()->set_pixel(x, y, reference_mask_pixel.with_alpha(0));
continue; continue;
}
if (distance_to_selected_color < full_masking_edge) { if (distance_to_selected_color < full_masking_edge) {
m_editor->active_layer()->mask_bitmap()->set_pixel(x, y, reference_mask_pixel); mask_scanline[x] = reference_mask_pixel.value();
continue; continue;
} }
m_editor->active_layer()->mask_bitmap()->set_pixel(x, y, reference_mask_pixel.with_alpha(reference_mask_pixel.alpha() - (((distance_to_selected_color - full_masking_edge) * reference_mask_pixel.alpha()) / gradient_masking_length))); mask_scanline[x] = reference_mask_pixel.with_alpha(reference_mask_pixel.alpha() - (((distance_to_selected_color - full_masking_edge) * reference_mask_pixel.alpha()) / gradient_masking_length)).value();
} }
} }
} }