summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-03-26 14:21:18 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2022-03-26 15:45:00 +0000
commitf27db5f80b074148aa9b8dd593dc2eefbc9e36ad (patch)
tree732d1f0f95efd800600ba47a6dd18e44c5bad30f /desktop
parente9d1a1fa9d698c0f6507f1b2ab719ce0fc5a0550 (diff)
downloadnetsurf-f27db5f80b074148aa9b8dd593dc2eefbc9e36ad.tar.gz
netsurf-f27db5f80b074148aa9b8dd593dc2eefbc9e36ad.tar.bz2
Bitmap: Add format conversion routines.
Diffstat (limited to 'desktop')
-rw-r--r--desktop/bitmap.c33
-rw-r--r--desktop/bitmap.h49
2 files changed, 82 insertions, 0 deletions
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