--- /dev/null
+/***************************************************************************
+ *
+ * Copyright 2010,2011 BMW Car IT GmbH
+ * Copyright (C) 2012 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include "bmpaccessor.h"
+
+typedef struct _BITMAPFILEHEADER {
+ unsigned short bfType;
+ unsigned int bfSize;
+ unsigned short bfReserved1;
+ unsigned short bfReserved2;
+ unsigned int bfOffBits;
+} BITMAPFILEHEADER;
+
+typedef struct _BITMAPINFOHEADER {
+ unsigned int biSize;
+ int biWidth;
+ int biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned int biCompression;
+ unsigned int biSizeImage;
+ int biXPixPerMeter;
+ int biYPixPerMeter;
+ unsigned int biClrUsed;
+ unsigned int biClrImporant;
+} BITMAPINFOHEADER;
+
+/**
+ * \brief Open windows bitmap file
+ * \param[in] bitmap file path
+ * \return context of bmpaccessor
+*/
+ctx_bmpaccessor* bmpaccessor_open(unsigned char* path)
+{
+ FILE* fp;
+ ctx_bmpaccessor* ctx = NULL;
+ BITMAPFILEHEADER file_head;
+ BITMAPINFOHEADER info_head;
+ size_t read_num = 0;
+ unsigned char* p_in = NULL;
+ unsigned char* p_in_pnt = NULL;
+ unsigned char* p_out_pnt = NULL;
+ int cntX = 0;
+ int cntY = 0;
+
+ do
+ {
+ fp = fopen(path, "rb");
+ if (fp == NULL)
+ {
+ printf("failed to open %s\n", path);
+ break;
+ }
+
+ ctx = (ctx_bmpaccessor*)malloc(sizeof(ctx_bmpaccessor));
+ if (NULL == ctx)
+ {
+ printf("failed to allocate context\n");
+ break;
+ }
+
+ read_num = fread(&file_head.bfType, sizeof(unsigned short), 1, fp);
+ if (read_num != 1)
+ {
+ printf("failed to read bfType\n");
+ break;
+ }
+ read_num = fread(&file_head.bfSize, sizeof(unsigned int), 2, fp);
+ if (read_num != 2)
+ {
+ printf("failed to read bfSize\n");
+ break;
+ }
+ read_num = fread(&file_head.bfOffBits, sizeof(unsigned int), 1, fp);
+ if (read_num != 1)
+ {
+ printf("failed to read bfOffBits\n");
+ break;
+ }
+ printf("bfSize : %d(0x%x)\n", file_head.bfSize, file_head.bfSize);
+ printf("bfOffBits: %d(0x%x)\n", file_head.bfOffBits, file_head.bfOffBits);
+
+ read_num = fread(&info_head.biSize, sizeof(unsigned int), 1, fp);
+ if (read_num != 1)
+ {
+ printf("failed to read biSize\n");
+ break;
+ }
+ read_num = fread(&info_head.biWidth, sizeof(unsigned int), 2, fp);
+ if (read_num != 2)
+ {
+ printf("failed to read image size\n");
+ break;
+ }
+ read_num = fread(&info_head.biPlanes, sizeof(unsigned short), 2, fp);
+ if (read_num != 2)
+ {
+ printf("failed to read biBitCount\n");
+ break;
+ }
+
+ printf("biSize : %d(0x%x)\n", info_head.biSize, info_head.biSize);
+ printf("biWidth : %d(0x%x)\n", info_head.biWidth, info_head.biWidth);
+ printf("biHeight : %d(0x%x)\n", info_head.biHeight, info_head.biHeight);
+ printf("bitCount : %d(0x%x)\n", info_head.biBitCount, info_head.biBitCount);
+
+ ctx->bitCountOrg = (info_head.biBitCount>>3);
+ ctx->bitCount = 4;
+ if (0 >= ctx->bitCountOrg)
+ {
+ printf("support bitCounts is only 24BPP with non-compression\n");
+ break;
+ }
+ ctx->width = info_head.biWidth;
+ if (0 > info_head.biHeight)
+ {
+ ctx->height = -info_head.biHeight;
+ }
+ else
+ {
+ ctx->height = info_head.biHeight;
+ }
+ ctx->strideOrg = ctx->width * ctx->bitCountOrg;
+ ctx->stride = (ctx->width<<2);
+ p_in = (void*)malloc(ctx->strideOrg * ctx->height);
+ if (NULL == p_in)
+ {
+ printf("failed to allocate work memory\n");
+ break;
+ }
+ ctx->data = (void*)malloc(ctx->stride * ctx->height);
+ if (NULL == ctx->data)
+ {
+ printf("failed to allocate image memory\n");
+ break;
+ }
+ fseek(fp, file_head.bfOffBits, SEEK_SET);
+ read_num = fread(p_in, ctx->strideOrg * ctx->height, 1, fp);
+ if (read_num != 1)
+ {
+ printf("failed to read header\n");
+ break;
+ }
+ p_in_pnt = p_in;
+ p_out_pnt = ctx->data;
+ for (cntY = 0; cntY < ctx->height; cntY++)
+ {
+ p_out_pnt = (unsigned char*)ctx->data + (ctx->height - cntY - 1) * ctx->stride;
+ for (cntX = 0; cntX < ctx->width; cntX++)
+ {
+ *(p_out_pnt + 0) = *(p_in_pnt + 0);
+ *(p_out_pnt + 1) = *(p_in_pnt + 1);
+ *(p_out_pnt + 2) = *(p_in_pnt + 2);
+ //*(p_out_pnt + 3) = 0;
+ *(p_out_pnt + 3) = 0xFF;
+ p_out_pnt += 4;
+ p_in_pnt += 3;
+ }
+ }
+
+ free(p_in);
+ fclose(fp);
+
+ printf("%s is %d x %d\n", path, ctx->width, ctx->height);
+
+ return ctx;
+
+ } while(0);
+
+ if (NULL != ctx)
+ {
+ free(ctx);
+ }
+ if (NULL != p_in)
+ {
+ free(p_in);
+ }
+ if (NULL != fp)
+ {
+ fclose(fp);
+ }
+
+ return NULL;
+}
+
+/**
+ * \brief Close windows bitmap file
+ * \param[in] context of bmpaccessor_open
+*/
+void bmpaccessor_close(ctx_bmpaccessor* ctx)
+{
+ if (NULL == ctx)
+ {
+ return;
+ }
+ if (NULL != ctx->data)
+ {
+ free(ctx->data);
+ }
+ free(ctx);
+}
+
+/* End of File */
--- /dev/null
+/***************************************************************************
+ *
+ * Copyright 2010,2011 BMW Car IT GmbH
+ * Copyright (C) 2012 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+#include "wayland-client.h"
+#include "wayland-client-protocol.h"
+#include "ilm/ilm_client.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <getopt.h>
+
+#include "serverinfo-client-protocol.h"
+#include "serverinfo-protocol.c"
+
+#include "bmpaccessor.h"
+
+/*****************************************************************************
+ * local defines
+ ****************************************************************************/
+#define LAYER_CHROMAKEY 3500
+#define SURFACE_CHROMAKEY 6789
+
+#define CHECK_ILM_ERROR(S) \
+ if ((S) != ILM_SUCCESS){ \
+ printf("%s (%d): ilm command failed.\n", __FILE__, __LINE__); \
+ break; \
+ } \
+
+/*****************************************************************************
+ * structure
+ ****************************************************************************/
+typedef struct t_wlContextStruct {
+ struct wl_display* wlDisplay;
+ struct wl_compositor* wlCompositor;
+ struct wl_surface* wlSurface;
+ struct wl_shm* wlShm;
+ uint32_t formats;
+ uint32_t mask;
+ struct serverinfo* wlExtServerinfo;
+ uint32_t connect_id;
+ ctx_bmpaccessor* ctx_bmp;
+ void* data;
+ struct wl_buffer* wlBuffer;
+} WLContextStruct;
+
+/*****************************************************************************
+ * globals
+ ****************************************************************************/
+WLContextStruct g_wlContextStruct;
+int gRun = 0;
+
+static void serverinfoListener(void *data, struct serverinfo *pServerinfo, uint32_t client_handle)
+{
+ WLContextStruct* p_wlCtx = (WLContextStruct*)data;
+ p_wlCtx->connect_id = client_handle;
+}
+
+struct serverinfo_listener serverinfo_listener_list = {
+ serverinfoListener
+};
+
+static void shm_format(void* data, struct wl_shm* pWlShm, uint32_t format)
+{
+ WLContextStruct* pDsp = data;
+ pDsp->formats |= (1 << format);
+}
+
+struct wl_shm_listener shm_listenter = {
+ shm_format
+};
+
+static void display_handle_global(struct wl_display* display, uint32_t id, const char* interface, uint32_t version, void* data)
+{
+ WLContextStruct* p_wlCtx = (WLContextStruct*)data;
+ int ans_strcmp = 0;
+
+ do
+ {
+ ans_strcmp = strcmp(interface, "wl_compositor");
+ if (0 == ans_strcmp)
+ {
+ p_wlCtx->wlCompositor = (struct wl_compositor*)wl_display_bind(display, id, &wl_compositor_interface);
+ break;
+ }
+
+ ans_strcmp = strcmp(interface, "wl_shm");
+ if (0 == ans_strcmp)
+ {
+ p_wlCtx->wlShm = wl_display_bind(display, id, &wl_shm_interface);
+ wl_shm_add_listener(p_wlCtx->wlShm, &shm_listenter, p_wlCtx);
+ break;
+ }
+
+ ans_strcmp = strcmp(interface, "serverinfo");
+ if (0 == ans_strcmp)
+ {
+ p_wlCtx->wlExtServerinfo = (struct serverinfo*)wl_display_bind(display, id, &serverinfo_interface);
+ serverinfo_add_listener(p_wlCtx->wlExtServerinfo, &serverinfo_listener_list, data);
+ serverinfo_get_connection_id(p_wlCtx->wlExtServerinfo);
+ }
+ } while(0);
+}
+
+static int
+event_mask_update(uint32_t mask, void* data)
+{
+ WLContextStruct* p_wlCtx = (WLContextStruct*)data;
+ p_wlCtx->mask = mask;
+ return 0;
+}
+
+/*****************************************************************************
+ * local functions
+ ****************************************************************************/
+static void createShmBuffer()
+{
+ char filename[] = "/tmp/wayland-shm-XXXXXX";
+ int fd = -1;
+ int size = 0;
+
+ fd = mkstemp(filename);
+ if (fd < 0){
+ fprintf(stderr, "open %s failed: %m\n", filename);
+ return;
+ }
+ size = g_wlContextStruct.ctx_bmp->stride * g_wlContextStruct.ctx_bmp->height;
+ if (ftruncate(fd, size) < 0){
+ fprintf(stderr, "ftruncate failed: %m\n");
+ close(fd);
+ return;
+ }
+
+ g_wlContextStruct.data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if (MAP_FAILED == g_wlContextStruct.data)
+ {
+ fprintf(stderr, "mmap failed: %m\n");
+ close(fd);
+ return;
+ }
+
+ g_wlContextStruct.wlBuffer = wl_shm_create_buffer(g_wlContextStruct.wlShm,
+ fd,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height,
+ g_wlContextStruct.ctx_bmp->stride,
+ WL_SHM_FORMAT_XRGB8888);
+ if (NULL == g_wlContextStruct.wlBuffer)
+ {
+ fprintf(stderr, "wl_shm_create_buffer failed: %m\n");
+ close(fd);
+ return;
+ }
+ wl_surface_attach(g_wlContextStruct.wlSurface, g_wlContextStruct.wlBuffer, 0, 0);
+
+ close(fd);
+
+ return;
+}
+
+static void destroyWLContext()
+{
+ if (g_wlContextStruct.wlSurface)
+ {
+ wl_surface_destroy(g_wlContextStruct.wlSurface);
+ }
+ if (g_wlContextStruct.wlCompositor)
+ {
+ wl_compositor_destroy(g_wlContextStruct.wlCompositor);
+ }
+}
+
+static int createWLContext()
+{
+ t_ilm_bool result = ILM_TRUE;
+
+ g_wlContextStruct.wlDisplay = wl_display_connect(NULL);
+ if (NULL == g_wlContextStruct.wlDisplay)
+ {
+ printf("Error: wl_display_connect() failed.\n");
+ }
+
+ wl_display_add_global_listener(g_wlContextStruct.wlDisplay, display_handle_global, &g_wlContextStruct);
+ wl_display_get_fd(g_wlContextStruct.wlDisplay, event_mask_update, &g_wlContextStruct);
+ wl_display_iterate(g_wlContextStruct.wlDisplay, WL_DISPLAY_READABLE);
+ wl_display_roundtrip(g_wlContextStruct.wlDisplay);
+
+ g_wlContextStruct.wlSurface = wl_compositor_create_surface(g_wlContextStruct.wlCompositor);
+ if (NULL == g_wlContextStruct.wlSurface)
+ {
+ printf("Error: wl_compositor_create_surface failed.\n");
+ destroyWLContext();
+ }
+
+ createShmBuffer();
+
+ return result;
+}
+
+static void frame_listener_func(void *data, struct wl_callback *callback, uint32_t time)
+{
+ if (callback)
+ {
+ wl_callback_destroy(callback);
+ }
+}
+
+static const struct wl_callback_listener frame_listener = {
+ frame_listener_func
+};
+
+static void drawImage(void)
+{
+ memcpy(g_wlContextStruct.data,
+ g_wlContextStruct.ctx_bmp->data,
+ g_wlContextStruct.ctx_bmp->stride * g_wlContextStruct.ctx_bmp->height);
+
+ wl_buffer_damage(g_wlContextStruct.wlBuffer,
+ 0, 0,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ wl_surface_attach(g_wlContextStruct.wlSurface,
+ g_wlContextStruct.wlBuffer,
+ 0, 0);
+ wl_surface_damage(g_wlContextStruct.wlSurface,
+ 0, 0,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ struct wl_callback* callback = wl_surface_frame(g_wlContextStruct.wlSurface);
+ wl_callback_add_listener(callback, &frame_listener, NULL);
+ //wl_display_flush(g_wlContextStruct.wlDisplay);
+ wl_display_roundtrip(g_wlContextStruct.wlDisplay);
+}
+
+static ilmErrorTypes createILMAttribute(t_ilm_layer *pLayerId, t_ilm_surface *pSurfaceId, unsigned int colorkey[])
+{
+ ilmErrorTypes error = ILM_FAILED;
+ t_ilm_layer layerid = *pLayerId;
+ t_ilm_surface surfaceid = *pSurfaceId;
+
+ do {
+ printf("Creating Layer... ");
+ error = ilm_layerCreateWithDimension(&layerid,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ CHECK_ILM_ERROR(error);
+
+ printf("Setting Layer destination rectangle(0, 0, %d, %d)... \n",
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ error = ilm_layerSetDestinationRectangle(layerid,
+ 0, 0,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ CHECK_ILM_ERROR(error);
+
+ printf("Setting Layer source rectangle(0, 0, %d, %d)... \n",
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ error = ilm_layerSetSourceRectangle(layerid,
+ 0, 0,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ CHECK_ILM_ERROR(error);
+
+ printf("Setting Layer visibility(%d)... \n", 1);
+ error = ilm_layerSetVisibility(layerid, ILM_TRUE);
+ CHECK_ILM_ERROR(error);
+
+ error = ilm_layerSetOpacity(layerid, 1.0f);
+ CHECK_ILM_ERROR(error);
+
+ struct wl_object* p_obj = (struct wl_object*)g_wlContextStruct.wlSurface;
+ t_ilm_nativehandle native_ilm_handle = (g_wlContextStruct.connect_id << 16) | (uint32_t)p_obj->id;
+ error = ilm_surfaceCreate(native_ilm_handle,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height,
+ ILM_PIXELFORMAT_RGBA_8888,
+ &surfaceid);
+ CHECK_ILM_ERROR(error);
+
+ printf("set surface dest region\n");
+ error = ilm_surfaceSetDestinationRectangle(surfaceid,
+ 0, 0,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ CHECK_ILM_ERROR(error);
+
+
+ printf("set surface src region\n");
+ error = ilm_surfaceSetSourceRectangle(surfaceid,
+ 0, 0,
+ g_wlContextStruct.ctx_bmp->width,
+ g_wlContextStruct.ctx_bmp->height);
+ CHECK_ILM_ERROR(error);
+
+
+ printf("add surface to layer\n");
+ error = ilm_layerAddSurface(layerid, surfaceid);
+ CHECK_ILM_ERROR(error);
+
+ printf("Set surface visible\n");
+ error = ilm_surfaceSetVisibility(surfaceid, ILM_TRUE);
+ CHECK_ILM_ERROR(error);
+
+ printf("Set surface opacity\n");
+ error = ilm_surfaceSetOpacity(surfaceid, 0.7f);
+ CHECK_ILM_ERROR(error);
+
+ printf("Set surface chromakey\n");
+ //unsigned int col[3] = {255, 242, 0};
+ error = ilm_surfaceSetChromaKey(surfaceid, colorkey);
+ CHECK_ILM_ERROR(error);
+
+ printf("commit\n");
+ error = ilm_commitChanges();
+ CHECK_ILM_ERROR(error);
+
+ } while (0);
+
+ *pLayerId = layerid;
+ *pSurfaceId = surfaceid;
+
+ return error;
+}
+
+static void sigFunc()
+{
+ printf("Catch signal\n");
+ gRun = 0;
+}
+
+static void print_usage()
+{
+ printf("Usage: WLChromakeyExample -f [BITMAP FILE] -c [R,G,B]\n");
+ printf("Chromakey for surface example (wayland backend).\n");
+ printf("\n");
+ printf("Option:\n");
+ printf("-f, --file=FILE bitmap file of uncompressed RGB888(24BPP) format\n");
+ printf("-c, --color=COLOR(R,G,B) color value which defines the transparency value\n");
+ printf(" default values are 255,255,255\n");
+}
+
+/*****************************************************************************
+ * exported functions
+ ****************************************************************************/
+
+int main(int argc, char *argv[])
+{
+ ilmErrorTypes result = ILM_FAILED;
+ t_ilm_layer layerid = (t_ilm_layer)LAYER_CHROMAKEY;
+ t_ilm_surface surfaceid = (t_ilm_surface)SURFACE_CHROMAKEY;
+ char* bitmapFile = NULL;
+ int o;
+ static const char opts[] = "f:c:h";
+ static const struct option longopts[] = {
+ { "file", 1, NULL, 'f' },
+ { "color", 1, NULL, 'c' },
+ { "help", 1, NULL, 'h' },
+ { NULL, }
+ };
+ unsigned int rgb[] = {255, 255, 255}; /* Default color key is 'White' */
+
+ while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) {
+ switch (o) {
+ case 'f':
+ bitmapFile = optarg;
+ break;
+ case 'c':
+ sscanf(optarg, "%d,%d,%d", &rgb[0], &rgb[1], &rgb[2]);
+ break;
+ case 'h':
+ print_usage();
+ return 0;
+ }
+ }
+
+ if (bitmapFile == NULL) {
+ print_usage();
+ return -1;
+ }
+
+ printf("[INFO] bitmap file = %s\n", bitmapFile);
+ printf("[INFO] color key = R(%d),G(%d),B(%d)\n", rgb[0], rgb[1], rgb[2]);
+
+ /* signal handling */
+ signal(SIGINT, sigFunc);
+ signal(SIGKILL, sigFunc);
+
+ gRun = 1;
+ memset(&g_wlContextStruct, 0x00, sizeof(g_wlContextStruct));
+
+ g_wlContextStruct.ctx_bmp = bmpaccessor_open(bitmapFile);
+ if (NULL == g_wlContextStruct.ctx_bmp)
+ {
+ printf("Failed to create bmp accessor\n");
+ return -1;
+ }
+
+ do {
+ createWLContext();
+
+ result = ilm_init();
+ if (ILM_SUCCESS == result)
+ {
+ printf("ilm_init success\n");
+ }
+ else
+ {
+ printf("ilm_init failed\n");
+ break;
+ }
+ result = createILMAttribute(&layerid, &surfaceid, rgb);
+ if (result != ILM_SUCCESS)
+ {
+ break;
+ }
+
+ t_ilm_layer layer[] = {1000, 2000, 3000, LAYER_CHROMAKEY};
+ ilm_displaySetRenderOrder(0, &layer[0], 4);
+
+ ilm_commitChanges();
+
+ while(gRun) {
+ drawImage();
+ }
+
+ ilm_surfaceRemove(surfaceid);
+ ilm_layerRemove(layerid);
+ } while(0);
+
+ ilm_destroy();
+ destroyWLContext();
+
+ bmpaccessor_close(g_wlContextStruct.ctx_bmp);
+
+ return 0;
+}