Allow alpha palettes in grayscale mode.

This commit is contained in:
Matt Dawson 2020-05-09 17:15:33 -07:00
parent 7e83dbb92e
commit c45ab418d4
2 changed files with 20 additions and 11 deletions

View File

@ -579,7 +579,7 @@ inline bool pixel_to_binary(int bpp, uint32_t pixel) {
* @param other_x_end End x pixel (exclusive) location in source/mask image. * @param other_x_end End x pixel (exclusive) location in source/mask image.
* @param over_x_scale Scale from other scale to image scale. * @param over_x_scale Scale from other scale to image scale.
*/ */
static void int_generate_cache_line_grayscale(uint16_t *cache_line, int alpha, uint8_t *other_row_ptr, int other_bpp, void *mask_row_ptr, int mask_bpp, int other_x_start, int other_x_end, float over_xscale) static void int_generate_cache_line_grayscale(uint16_t *cache_line, int alpha, uint8_t *other_row_ptr, int other_bpp, void *mask_row_ptr, int mask_bpp, int other_x_start, int other_x_end, float over_xscale, const uint8_t *alpha_palette)
{ {
for (int i = 0, x = other_x_start; x < other_x_end; x++, i++) { for (int i = 0, x = other_x_start; x < other_x_end; x++, i++) {
float other_x_float = (x + 0.5) * over_xscale; float other_x_float = (x + 0.5) * over_xscale;
@ -594,8 +594,16 @@ static void int_generate_cache_line_grayscale(uint16_t *cache_line, int alpha, u
uint32_t alpha1 = mask1 ? (alpha - weight_x) : 0; uint32_t alpha1 = mask1 ? (alpha - weight_x) : 0;
uint32_t alpha2 = mask2 ? weight_x : 0; uint32_t alpha2 = mask2 ? weight_x : 0;
uint32_t other_pixel1 = safe_map_pixel(IMAGE_BPP_GRAYSCALE, other_bpp, imlib_get_pixel_fast(other_bpp, other_row_ptr, other_x)) * alpha1; uint32_t other_pixel1 = safe_map_pixel(IMAGE_BPP_GRAYSCALE, other_bpp, imlib_get_pixel_fast(other_bpp, other_row_ptr, other_x));
uint32_t other_pixel2 = safe_map_pixel(IMAGE_BPP_GRAYSCALE, other_bpp, imlib_get_pixel_fast(other_bpp, other_row_ptr, other_x + 1)) * alpha2; uint32_t other_pixel2 = safe_map_pixel(IMAGE_BPP_GRAYSCALE, other_bpp, imlib_get_pixel_fast(other_bpp, other_row_ptr, other_x + 1));
if (alpha_palette) {
alpha1 = alpha1 * alpha_palette[other_pixel1] >> 8;
alpha2 = alpha2 * alpha_palette[other_pixel2] >> 8;
}
other_pixel1 *= alpha1;
other_pixel2 *= alpha2;
// Image alpha is the remaining alpha after applying other alpha // Image alpha is the remaining alpha after applying other alpha
uint32_t img_alpha = 256 - (alpha1 + alpha2); uint32_t img_alpha = 256 - (alpha1 + alpha2);
@ -755,7 +763,7 @@ void imlib_draw_image(image_t *img, image_t *other, int x_off, int y_off, float
uint8_t *other_row_ptr = imlib_compute_row_ptr(other, temp_other_y); uint8_t *other_row_ptr = imlib_compute_row_ptr(other, temp_other_y);
void *mask_row_ptr = mask ? imlib_compute_row_ptr(mask, temp_other_y) : NULL; void *mask_row_ptr = mask ? imlib_compute_row_ptr(mask, temp_other_y) : NULL;
int_generate_cache_line_grayscale(cache_line_bottom, alpha, other_row_ptr, other_bpp, mask_row_ptr, mask_bpp, other_x_start, other_x_end, over_xscale); int_generate_cache_line_grayscale(cache_line_bottom, alpha, other_row_ptr, other_bpp, mask_row_ptr, mask_bpp, other_x_start, other_x_end, over_xscale, alpha_palette);
// Used to detect when other starts rendering from the next line // Used to detect when other starts rendering from the next line
int last_other_y = -1; int last_other_y = -1;
@ -785,7 +793,7 @@ void imlib_draw_image(image_t *img, image_t *other, int x_off, int y_off, float
// And generate a new y+1 // And generate a new y+1
other_row_ptr = imlib_compute_row_ptr(other, other_y + 1); other_row_ptr = imlib_compute_row_ptr(other, other_y + 1);
mask_row_ptr = mask ? imlib_compute_row_ptr(mask, other_y + 1) : NULL; mask_row_ptr = mask ? imlib_compute_row_ptr(mask, other_y + 1) : NULL;
int_generate_cache_line_grayscale(cache_line_bottom, alpha, other_row_ptr, other_bpp, mask_row_ptr, mask_bpp, other_x_start, other_x_end, over_xscale); int_generate_cache_line_grayscale(cache_line_bottom, alpha, other_row_ptr, other_bpp, mask_row_ptr, mask_bpp, other_x_start, other_x_end, over_xscale, alpha_palette);
} }
// Draw the line to img // Draw the line to img

View File

@ -1964,6 +1964,10 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t
} }
} }
if (color_palette && arg_img->bpp != IMAGE_BPP_RGB565) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Color palettes must be used with color images!"));
}
const uint8_t *alpha_palette = NULL; const uint8_t *alpha_palette = NULL;
{ {
image_t *arg_alpha_palette = py_helper_keyword_to_image_mutable_alpha_palette(n_args, args, offset + 5, kw_args); image_t *arg_alpha_palette = py_helper_keyword_to_image_mutable_alpha_palette(n_args, args, offset + 5, kw_args);
@ -1972,15 +1976,12 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t
if (arg_other->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Can only specify an alpha palette when passing a grayscale image!")); if (arg_other->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Can only specify an alpha palette when passing a grayscale image!"));
if (arg_alpha_palette->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Alpha palette must be an grayscale format image!")); if (arg_alpha_palette->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Alpha palette must be an grayscale format image!"));
if ((arg_alpha_palette->w * arg_alpha_palette->h) != 256) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Alpha palette image must have 256 pixels!")); if ((arg_alpha_palette->w * arg_alpha_palette->h) != 256) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Alpha palette image must have 256 pixels!"));
if (arg_img->bpp != IMAGE_BPP_GRAYSCALE && arg_img->bpp != IMAGE_BPP_RGB565) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Alpha palettes must be used with color images!"));
alpha_palette = (uint8_t*)arg_alpha_palette->data; alpha_palette = (uint8_t*)arg_alpha_palette->data;
} }
} }
if ((color_palette || alpha_palette) && arg_img->bpp != IMAGE_BPP_RGB565) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Palettes must be used with color images!"));
}
image_hint_t hint = image_hint_t hint =
py_helper_keyword_int(n_args, args, offset + 6, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hint), 0); py_helper_keyword_int(n_args, args, offset + 6, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hint), 0);