Bitmap: Add format conversion routines.

This commit is contained in:
Michael Drake 2022-03-26 14:21:18 +00:00
parent e9d1a1fa9d
commit f27db5f80b
2 changed files with 82 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -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