diff options
Diffstat (limited to 'ivi-layermanagement-api/ilmControl/src/bitmap.c')
-rw-r--r-- | ivi-layermanagement-api/ilmControl/src/bitmap.c | 103 |
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; } |