From f27db5f80b074148aa9b8dd593dc2eefbc9e36ad Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 26 Mar 2022 14:21:18 +0000 Subject: Bitmap: Add format conversion routines. --- desktop/bitmap.c | 33 +++++++++++++++++++++++++++++++++ desktop/bitmap.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) (limited to 'desktop') diff --git a/desktop/bitmap.c b/desktop/bitmap.c index 48065d080..3e8529a54 100644 --- a/desktop/bitmap.c +++ b/desktop/bitmap.c @@ -44,3 +44,36 @@ void bitmap_set_format(const bitmap_fmt_t *bitmap_format) bitmap_fmt.layout = bitmap_sanitise_bitmap_layout(bitmap_fmt.layout); bitmap_layout = bitmap__get_colour_layout(&bitmap_fmt); } + +/* Exported function, documented in desktop/bitmap.h */ +void bitmap_format_convert(void *bitmap, + const bitmap_fmt_t *fmt_from, + const bitmap_fmt_t *fmt_to) +{ + int width = guit->bitmap->get_width(bitmap); + int height = guit->bitmap->get_height(bitmap); + uint8_t *buffer = guit->bitmap->get_buffer(bitmap); + size_t rowstride = guit->bitmap->get_rowstride(bitmap); + struct bitmap_colour_layout to = bitmap__get_colour_layout(fmt_to); + struct bitmap_colour_layout from = bitmap__get_colour_layout(fmt_from); + + NSLOG(netsurf, DEEPDEBUG, "Bitmap format conversion (%u --> %u)", + fmt_from->layout, fmt_to->layout); + + for (int y = 0; y < height; y++) { + uint8_t *row = buffer; + + for (int x = 0; x < width; x++) { + const uint32_t px = *((uint32_t *)(void *) row); + + row[to.r] = ((const uint8_t *) &px)[from.r]; + row[to.g] = ((const uint8_t *) &px)[from.g]; + row[to.b] = ((const uint8_t *) &px)[from.b]; + row[to.a] = ((const uint8_t *) &px)[from.a]; + + row += sizeof(uint32_t); + } + + buffer += rowstride; + } +} diff --git a/desktop/bitmap.h b/desktop/bitmap.h index 490928980..af7e9040f 100644 --- a/desktop/bitmap.h +++ b/desktop/bitmap.h @@ -121,4 +121,53 @@ static inline enum bitmap_layout bitmap_sanitise_bitmap_layout( return layout; } +/** + * Convert bitmap from one format to another. + * + * Note that both formats should be sanitised. + * + * \param[in] bitmap The bitmap to convert. + * \param[in] from The current bitmap format specifier. + * \param[in] to The bitmap format to convert to. + */ +void bitmap_format_convert(void *bitmap, + const bitmap_fmt_t *from, + const bitmap_fmt_t *to); + +/** + * Convert a bitmap to the client bitmap format. + * + * \param[in] bitmap The bitmap to convert. + * \param[in] current_fmt The current bitmap format specifier. + */ +static inline void bitmap_format_to_client( + void *bitmap, + const bitmap_fmt_t *current_fmt) +{ + bitmap_fmt_t from = *current_fmt; + + from.layout = bitmap_sanitise_bitmap_layout(from.layout); + if (from.layout != bitmap_fmt.layout) { + bitmap_format_convert(bitmap, &from, &bitmap_fmt); + } +} + +/** + * Convert a bitmap to the client bitmap format. + * + * \param[in] bitmap The bitmap to convert. + * \param[in] target_fmt The target bitmap format specifier. + */ +static inline void bitmap_format_from_client( + void *bitmap, + const bitmap_fmt_t *target_fmt) +{ + bitmap_fmt_t to = *target_fmt; + + to.layout = bitmap_sanitise_bitmap_layout(to.layout); + if (to.layout != bitmap_fmt.layout) { + bitmap_format_convert(bitmap, &bitmap_fmt, &to); + } +} + #endif -- cgit v1.2.3