From 8e56cc3b1a0d9d18e35811a015cf42b57ede1025 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 29 Mar 2022 15:25:33 +0100 Subject: [PATCH] Bitmap: Implement test_opaque in core instead of in every frontend. --- content/handlers/image/gif.c | 2 +- content/handlers/image/png.c | 4 +-- desktop/bitmap.c | 25 +++++++++++++++++ desktop/gui_factory.c | 4 --- frontends/amiga/bitmap.c | 22 +-------------- frontends/amiga/bitmap.h | 8 ------ frontends/amiga/dt_picture.c | 2 +- frontends/atari/bitmap.c | 35 ------------------------ frontends/beos/bitmap.cpp | 16 ----------- frontends/framebuffer/bitmap.c | 34 ----------------------- frontends/gtk/bitmap.c | 31 --------------------- frontends/monkey/bitmap.c | 6 ---- frontends/riscos/bitmap.c | 50 ---------------------------------- frontends/windows/bitmap.c | 30 -------------------- include/netsurf/bitmap.h | 16 +++++------ 15 files changed, 38 insertions(+), 247 deletions(-) diff --git a/content/handlers/image/gif.c b/content/handlers/image/gif.c index 0dc7cb3bf..deabd0adc 100644 --- a/content/handlers/image/gif.c +++ b/content/handlers/image/gif.c @@ -119,7 +119,7 @@ static nserror gif_create_gif_data(gif_content *c) .destroy = guit->bitmap->destroy, .get_buffer = guit->bitmap->get_buffer, .set_opaque = guit->bitmap->set_opaque, - .test_opaque = guit->bitmap->test_opaque, + .test_opaque = bitmap_test_opaque, .modified = guit->bitmap->modified, }; diff --git a/content/handlers/image/png.c b/content/handlers/image/png.c index 520b72834..97a5795b3 100644 --- a/content/handlers/image/png.c +++ b/content/handlers/image/png.c @@ -538,7 +538,7 @@ png_cache_convert_error: } if (bitmap != NULL) { - bool opaque = guit->bitmap->test_opaque((void *)bitmap); + bool opaque = bitmap_test_opaque((void *)bitmap); guit->bitmap->set_opaque((void *)bitmap, opaque); bitmap_format_to_client((void *)bitmap, &(bitmap_fmt_t) { .layout = bitmap_fmt.layout, @@ -571,7 +571,7 @@ static bool nspng_convert(struct content *c) } if (png_c->bitmap != NULL) { - bool opaque = guit->bitmap->test_opaque(png_c->bitmap); + bool opaque = bitmap_test_opaque(png_c->bitmap); guit->bitmap->set_opaque(png_c->bitmap, opaque); bitmap_format_to_client(png_c->bitmap, &(bitmap_fmt_t) { .layout = bitmap_fmt.layout, diff --git a/desktop/bitmap.c b/desktop/bitmap.c index acbd22e41..0602773ca 100644 --- a/desktop/bitmap.c +++ b/desktop/bitmap.c @@ -311,3 +311,28 @@ void bitmap_format_convert(void *bitmap, } } } + +/* Exported function, documented in desktop/bitmap.h */ +bool bitmap_test_opaque(void *bitmap) +{ + int width = guit->bitmap->get_width(bitmap); + int height = guit->bitmap->get_height(bitmap); + size_t rowstride = guit->bitmap->get_rowstride(bitmap); + const uint8_t *buffer = guit->bitmap->get_buffer(bitmap); + + width *= sizeof(uint32_t); + + for (int y = 0; y < height; y++) { + const uint8_t *row = buffer; + + for (int x = bitmap_layout.a; x < width; x += 4) { + if (row[x] != 0xff) { + return false; + } + } + + buffer += rowstride; + } + + return true; +} diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c index cddafa09d..89f2e373f 100644 --- a/desktop/gui_factory.c +++ b/desktop/gui_factory.c @@ -560,10 +560,6 @@ static nserror verify_bitmap_register(struct gui_bitmap_table *gbt) return NSERROR_BAD_PARAMETER; } - if (gbt->test_opaque == NULL) { - return NSERROR_BAD_PARAMETER; - } - if (gbt->get_buffer == NULL) { return NSERROR_BAD_PARAMETER; } diff --git a/frontends/amiga/bitmap.c b/frontends/amiga/bitmap.c index c39f3842c..cd2667bdd 100644 --- a/frontends/amiga/bitmap.c +++ b/frontends/amiga/bitmap.c @@ -305,25 +305,6 @@ void amiga_bitmap_set_opaque(void *bitmap, bool opaque) } -/* exported function documented in amiga/bitmap.h */ -bool amiga_bitmap_test_opaque(void *bitmap) -{ - struct bitmap *bm = bitmap; - uint32 p = bm->width * bm->height; - uint32 a = 0; - uint32 *bmi = (uint32 *)amiga_bitmap_get_buffer(bm); - - assert(bitmap); - - for(a=0;abmh_Width, bmh->bmh_Height); - amiga_bitmap_set_opaque(bm, amiga_bitmap_test_opaque(bm)); + amiga_bitmap_set_opaque(bm, bitmap_test_opaque(bm)); } DisposeDTObject(dto); } @@ -809,7 +790,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = amiga_bitmap_destroy, .set_opaque = amiga_bitmap_set_opaque, .get_opaque = amiga_bitmap_get_opaque, - .test_opaque = amiga_bitmap_test_opaque, .get_buffer = amiga_bitmap_get_buffer, .get_rowstride = amiga_bitmap_get_rowstride, .get_width = bitmap_get_width, diff --git a/frontends/amiga/bitmap.h b/frontends/amiga/bitmap.h index ae072c0cd..8e7bcbc70 100755 --- a/frontends/amiga/bitmap.h +++ b/frontends/amiga/bitmap.h @@ -175,14 +175,6 @@ void amiga_bitmap_modified(void *bitmap); */ void amiga_bitmap_set_opaque(void *bitmap, bool opaque); -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -bool amiga_bitmap_test_opaque(void *bitmap); - /** * Gets whether a bitmap should be plotted opaque * diff --git a/frontends/amiga/dt_picture.c b/frontends/amiga/dt_picture.c index f84e0e016..e13790d5c 100644 --- a/frontends/amiga/dt_picture.c +++ b/frontends/amiga/dt_picture.c @@ -202,7 +202,7 @@ static struct bitmap *amiga_dt_picture_cache_convert(struct content *c) amiga_bitmap_get_rowstride(bitmap), 0, 0, c->width, c->height); - amiga_bitmap_set_opaque(bitmap, amiga_bitmap_test_opaque(bitmap)); + amiga_bitmap_set_opaque(bitmap, bitmap_test_opaque(bitmap)); DisposeDTObject(dto); adt->dto = NULL; diff --git a/frontends/atari/bitmap.c b/frontends/atari/bitmap.c index 8c467c7d6..9b5a016a5 100644 --- a/frontends/atari/bitmap.c +++ b/frontends/atari/bitmap.c @@ -269,40 +269,6 @@ static void bitmap_set_opaque(void *bitmap, bool opaque) } -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *bitmap) -{ - int tst; - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - NSLOG(netsurf, INFO, "NULL bitmap!"); - return false; - } - - if( nsoption_int(atari_transparency) == 0 ){ - return( true ); - } - - tst = bm->width * bm->height; - - while (tst-- > 0) { - if (bm->pixdata[(tst << 2) + 3] != 0xff) { - NSLOG(netsurf, INFO, - "bitmap %p has transparency", bm); - return false; - } - } - NSLOG(netsurf, INFO, "bitmap %p is opaque", bm); - return true; -} - - /* exported interface documented in atari/bitmap.h */ bool atari_bitmap_get_opaque(void *bitmap) { @@ -414,7 +380,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = atari_bitmap_destroy, .set_opaque = bitmap_set_opaque, .get_opaque = atari_bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, .get_buffer = bitmap_get_buffer, .get_rowstride = atari_bitmap_get_rowstride, .get_width = atari_bitmap_get_width, diff --git a/frontends/beos/bitmap.cpp b/frontends/beos/bitmap.cpp index 83e69fce5..f7e8fa032 100644 --- a/frontends/beos/bitmap.cpp +++ b/frontends/beos/bitmap.cpp @@ -155,21 +155,6 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque) } -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param vbitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - /* todo: test if bitmap is opaque */ - return false; -} - - /** * Gets whether a bitmap should be plotted opaque * @@ -503,7 +488,6 @@ static struct gui_bitmap_table bitmap_table = { /*.destroy =*/ bitmap_destroy, /*.set_opaque =*/ bitmap_set_opaque, /*.get_opaque =*/ bitmap_get_opaque, - /*.test_opaque =*/ bitmap_test_opaque, /*.get_buffer =*/ bitmap_get_buffer, /*.get_rowstride =*/ bitmap_get_rowstride, /*.get_width =*/ bitmap_get_width, diff --git a/frontends/framebuffer/bitmap.c b/frontends/framebuffer/bitmap.c index 9fb5db159..c9b58541e 100644 --- a/frontends/framebuffer/bitmap.c +++ b/frontends/framebuffer/bitmap.c @@ -155,39 +155,6 @@ static void bitmap_set_opaque(void *bitmap, bool opaque) } -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *bitmap) -{ - int tst; - nsfb_t *bm = bitmap; - unsigned char *bmpptr; - int width; - int height; - - assert(bm != NULL); - - nsfb_get_buffer(bm, &bmpptr, NULL); - - nsfb_get_geometry(bm, &width, &height, NULL); - - tst = width * height; - - while (tst-- > 0) { - if (bmpptr[(tst << 2) + 3] != 0xff) { - NSLOG(netsurf, INFO, "bitmap %p has transparency", bm); - return false; - } - } - NSLOG(netsurf, INFO, "bitmap %p is opaque", bm); - return true; -} - - /** * Gets weather a bitmap should be plotted opaque * @@ -307,7 +274,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = bitmap_destroy, .set_opaque = bitmap_set_opaque, .get_opaque = framebuffer_bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, .get_buffer = bitmap_get_buffer, .get_rowstride = bitmap_get_rowstride, .get_width = bitmap_get_width, diff --git a/frontends/gtk/bitmap.c b/frontends/gtk/bitmap.c index ace507333..595d5eae5 100644 --- a/frontends/gtk/bitmap.c +++ b/frontends/gtk/bitmap.c @@ -124,36 +124,6 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque) } -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param vbitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *vbitmap) -{ - struct bitmap *gbitmap = (struct bitmap *)vbitmap; - unsigned char *pixels; - int pcount; - int ploop; - - assert(gbitmap); - - pixels = cairo_image_surface_get_data(gbitmap->surface); - - pcount = cairo_image_surface_get_stride(gbitmap->surface) * - cairo_image_surface_get_height(gbitmap->surface); - - for (ploop = 3; ploop < pcount; ploop += 4) { - if (pixels[ploop] != 0xff) { - return false; - } - } - - return true; -} - - /** * Gets whether a bitmap should be plotted opaque * @@ -356,7 +326,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = bitmap_destroy, .set_opaque = bitmap_set_opaque, .get_opaque = bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, .get_buffer = bitmap_get_buffer, .get_rowstride = bitmap_get_rowstride, .get_width = nsgtk_bitmap_get_width, diff --git a/frontends/monkey/bitmap.c b/frontends/monkey/bitmap.c index 36016988c..900dbca72 100644 --- a/frontends/monkey/bitmap.c +++ b/frontends/monkey/bitmap.c @@ -68,11 +68,6 @@ static void bitmap_set_opaque(void *bitmap, bool opaque) bmap->opaque = opaque; } -static bool bitmap_test_opaque(void *bitmap) -{ - return false; -} - static bool bitmap_get_opaque(void *bitmap) { struct bitmap *bmap = bitmap; @@ -122,7 +117,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = bitmap_destroy, .set_opaque = bitmap_set_opaque, .get_opaque = bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, .get_buffer = bitmap_get_buffer, .get_rowstride = bitmap_get_rowstride, .get_width = bitmap_get_width, diff --git a/frontends/riscos/bitmap.c b/frontends/riscos/bitmap.c index d76f51d7e..97dce6acc 100644 --- a/frontends/riscos/bitmap.c +++ b/frontends/riscos/bitmap.c @@ -189,55 +189,6 @@ static size_t bitmap_get_rowstride(void *vbitmap) } -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param vbitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *vbitmap) -{ - struct bitmap *bitmap = (struct bitmap *) vbitmap; - unsigned char *sprite; - unsigned int width, height, size; - osspriteop_header *sprite_header; - unsigned *p, *ep; - - assert(bitmap); - - sprite = riscos_bitmap_get_buffer(bitmap); - if (!sprite) - return false; - - width = bitmap_get_rowstride(bitmap); - - sprite_header = (osspriteop_header *) (bitmap->sprite_area + 1); - - height = (sprite_header->height + 1); - - size = width * height; - - p = (void *) sprite; - - ep = (void *) (sprite + (size & ~31)); - while (p < ep) { - /* \todo prefetch(p, 128)? */ - if (((p[0] & p[1] & p[2] & p[3] & p[4] & p[5] & p[6] & p[7]) - & 0xff000000U) != 0xff000000U) - return false; - p += 8; - } - - ep = (void *) (sprite + size); - while (p < ep) { - if ((*p & 0xff000000U) != 0xff000000U) return false; - p++; - } - - return true; -} - - /* exported interface documented in riscos/bitmap.h */ bool riscos_bitmap_get_opaque(void *vbitmap) { @@ -856,7 +807,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = riscos_bitmap_destroy, .set_opaque = bitmap_set_opaque, .get_opaque = riscos_bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, .get_buffer = riscos_bitmap_get_buffer, .get_rowstride = bitmap_get_rowstride, .get_width = bitmap_get_width, diff --git a/frontends/windows/bitmap.c b/frontends/windows/bitmap.c index 26bc807ce..a52f29ad9 100644 --- a/frontends/windows/bitmap.c +++ b/frontends/windows/bitmap.c @@ -192,35 +192,6 @@ static void bitmap_set_opaque(void *bitmap, bool opaque) } -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -static bool bitmap_test_opaque(void *bitmap) -{ - int tst; - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - NSLOG(netsurf, INFO, "NULL bitmap!"); - return false; - } - - tst = bm->width * bm->height; - - while (tst-- > 0) { - if (bm->pixdata[(tst << 2) + 3] != 0xff) { - NSLOG(netsurf, INFO, "bitmap %p has transparency", bm); - return false; - } - } - NSLOG(netsurf, INFO, "bitmap %p is opaque", bm); - return true; -} - - /** * Gets whether a bitmap should be plotted opaque * @@ -356,7 +327,6 @@ static struct gui_bitmap_table bitmap_table = { .destroy = win32_bitmap_destroy, .set_opaque = bitmap_set_opaque, .get_opaque = bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, .get_buffer = bitmap_get_buffer, .get_rowstride = bitmap_get_rowstride, .get_width = bitmap_get_width, diff --git a/include/netsurf/bitmap.h b/include/netsurf/bitmap.h index eb26810a9..25923da5c 100644 --- a/include/netsurf/bitmap.h +++ b/include/netsurf/bitmap.h @@ -133,6 +133,14 @@ struct hlcache_handle; */ void bitmap_set_format(const bitmap_fmt_t *bitmap_format); +/** + * Test whether a bitmap is completely opaque (no transparency). + * + * \param[in] bitmap The bitmap to test. + * \return Returns true if the bitmap is opaque, false otherwise. + */ +bool bitmap_test_opaque(void *bitmap); + /** * Bitmap operations. */ @@ -172,14 +180,6 @@ struct gui_bitmap_table { */ bool (*get_opaque)(void *bitmap); - /** - * Test if a bitmap is opaque. - * - * \param bitmap The bitmap to examine. - * \return The bitmap opacity. - */ - bool (*test_opaque)(void *bitmap); - /** * Get the image buffer from a bitmap *