summaryrefslogtreecommitdiff
path: root/ivi-layermanagement-api/ilmControl/src/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'ivi-layermanagement-api/ilmControl/src/bitmap.c')
-rw-r--r--ivi-layermanagement-api/ilmControl/src/bitmap.c103
1 files changed, 88 insertions, 15 deletions
diff --git a/ivi-layermanagement-api/ilmControl/src/bitmap.c b/ivi-layermanagement-api/ilmControl/src/bitmap.c
index 2c7fdb5..79d2a5d 100644
--- a/ivi-layermanagement-api/ilmControl/src/bitmap.c
+++ b/ivi-layermanagement-api/ilmControl/src/bitmap.c
@@ -21,6 +21,11 @@
*/
#include "bitmap.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <arpa/inet.h>
+#include "ivi-wm-client-protocol.h"
struct __attribute__ ((__packed__)) BITMAPFILEHEADER {
char bfType[2];
@@ -49,22 +54,22 @@ create_file_header(struct BITMAPFILEHEADER *file_header, int32_t image_size)
{
file_header->bfType[0] = 'B';
file_header->bfType[1] = 'M';
- file_header->bfSize = sizeof(struct BITMAPFILEHEADER)
- + sizeof(struct BITMAPINFOHEADER)
- + image_size;
- file_header->bfOffBits = sizeof(struct BITMAPFILEHEADER)
- + sizeof(struct BITMAPINFOHEADER);
+ file_header->bfSize = htole32(sizeof(struct BITMAPFILEHEADER) +
+ sizeof(struct BITMAPINFOHEADER) +
+ image_size);
+ file_header->bfOffBits = htole32(sizeof(struct BITMAPFILEHEADER) +
+ sizeof(struct BITMAPINFOHEADER));
}
static void
create_info_header(struct BITMAPINFOHEADER *info_header, int32_t image_size, int32_t width, int32_t height, int16_t bpp)
{
- info_header->biSize = sizeof(struct BITMAPINFOHEADER);
- info_header->biWidth = width;
- info_header->biHeight = height;
- info_header->biPlanes = 1;
- info_header->biBitCount = bpp;
- info_header->biSizeImage = image_size;
+ info_header->biSize = htole32(sizeof(struct BITMAPINFOHEADER));
+ info_header->biWidth = htole32(width);
+ info_header->biHeight = htole32(height);
+ info_header->biPlanes = htole16(1);
+ info_header->biBitCount = htole16(bpp);
+ info_header->biSizeImage = htole32(image_size);
}
static int
@@ -89,19 +94,87 @@ write_bitmap(const char *filename,
int
save_as_bitmap(const char *filename,
const char *buffer,
- int32_t image_size,
int32_t width,
int32_t height,
- int16_t bpp)
+ uint32_t format)
{
+ int32_t image_stride = 0;
+ int32_t image_size = 0;
+ char *image_buffer = NULL;
+ int32_t row = 0;
+ int32_t col = 0;
+ int32_t image_offset = 0;
+ int32_t offset = 0;
+ int32_t i = 0;
+ int32_t j = 0;
+ int bytes_per_pixel;
+ bool flip_order;
+ bool has_alpha;
+
if ((filename == NULL) || (buffer == NULL)) {
return -1;
}
+ switch (format) {
+ case WL_SHM_FORMAT_ARGB8888:
+ flip_order = true;
+ has_alpha = true;
+ break;
+ case WL_SHM_FORMAT_XRGB8888:
+ flip_order = true;
+ has_alpha = false;
+ break;
+ case WL_SHM_FORMAT_ABGR8888:
+ flip_order = false;
+ has_alpha = true;
+ break;
+ case WL_SHM_FORMAT_XBGR8888:
+ flip_order = false;
+ has_alpha = false;
+ break;
+ default:
+ fprintf(stderr, "unsupported pixelformat 0x%x\n", format);
+ return -1;
+ }
+
+ bytes_per_pixel = has_alpha ? 4 : 3;
+ image_stride = (((width * bytes_per_pixel) + 3) & ~3);
+ image_size = image_stride * height;
+
+ image_buffer = malloc(image_size);
+ if (image_buffer == NULL) {
+ fprintf(stderr, "failed to allocate %d bytes for image buffer: %m\n",
+ image_size);
+ return -1;
+ }
+
+ // Store the image in image_buffer in the follwing order B, G, R, [A](B at the lowest address)
+ for (row = 0; row < height; ++row) {
+ for (col = 0; col < width; ++col) {
+ offset = (height - row - 1) * width + col;
+ uint32_t pixel = htonl(((uint32_t*)buffer)[offset]);
+ char * pixel_p = (char*) &pixel;
+ image_offset = row * image_stride + col * bytes_per_pixel;
+ for (i = 0; i < 3; ++i) {
+ j = flip_order ? 2 - i : i;
+ image_buffer[image_offset + i] = pixel_p[1 + j];
+ }
+ if (has_alpha) {
+ image_buffer[image_offset + 3] = pixel_p[0];
+ }
+ }
+ }
+
struct BITMAPFILEHEADER file_header = {};
struct BITMAPINFOHEADER info_header = {};
create_file_header(&file_header, image_size);
- create_info_header(&info_header, image_size, width, height, bpp);
- return write_bitmap(filename, &file_header, &info_header, buffer);
+ create_info_header(&info_header, image_size, width, height, bytes_per_pixel * 8);
+ if (write_bitmap(filename, &file_header, &info_header, image_buffer) != 0) {
+ free(image_buffer);
+ return -1;
+ }
+
+ free(image_buffer);
+ return 0;
}