summaryrefslogtreecommitdiff
path: root/Source/DirectFB/tools/directfb-csource.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/tools/directfb-csource.c')
-rwxr-xr-xSource/DirectFB/tools/directfb-csource.c894
1 files changed, 894 insertions, 0 deletions
diff --git a/Source/DirectFB/tools/directfb-csource.c b/Source/DirectFB/tools/directfb-csource.c
new file mode 100755
index 0000000..027bd83
--- /dev/null
+++ b/Source/DirectFB/tools/directfb-csource.c
@@ -0,0 +1,894 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ directfb-csource is based on gdk-pixbuf-csource, a GdkPixbuf
+ based image CSource generator Copyright (C) 1999, 2001 Tim Janik
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <png.h>
+
+#include <directfb.h>
+
+#include <direct/types.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+
+#define DFB_DITHER565 DFB_DITHER_ADVANCED
+#include <misc/dither565.h>
+
+
+static struct {
+ DFBSurfacePixelFormat format;
+ const char *name;
+} pixelformats[] = {
+ { DSPF_ARGB, "ARGB" },
+ { DSPF_ARGB1555, "ARGB1555" },
+ { DSPF_ARGB2554, "ARGB2554" },
+ { DSPF_ARGB4444, "ARGB4444" },
+ { DSPF_RGB32, "RGB32" },
+ { DSPF_RGB24, "RGB24" },
+ { DSPF_RGB16, "RGB16" },
+ { DSPF_RGB332, "RGB332" },
+ { DSPF_A8, "A8" },
+ { DSPF_LUT8, "LUT8" }
+};
+static int n_pixelformats = D_ARRAY_SIZE( pixelformats );
+
+
+static void print_usage (const char *prg_name);
+static DFBResult load_image (const char *filename,
+ DFBSurfaceDescription *desc,
+ DFBColor *palette,
+ int *palette_size,
+ DFBSurfacePixelFormat rgbformat,
+ bool dither565);
+static void dither_rgb16 (const u32 *src,
+ u16 *dest,
+ int y,
+ int width);
+static DFBResult merge_images (DFBSurfaceDescription *images,
+ int num_images,
+ DFBSurfaceDescription *dest,
+ DFBRectangle *rectangles);
+static DFBResult dump_raw_data (const char *name,
+ const unsigned char *data,
+ unsigned int len);
+static DFBResult dump_image (const char *name,
+ DFBSurfaceDescription *desc,
+ DFBColor *palette,
+ int palette_size);
+static DFBResult dump_rectangles (const char *name,
+ DFBRectangle *rectangles,
+ const char **names,
+ int num_rects);
+static char * variable_name (const char *name);
+static char * base_name (const char *name);
+
+
+int main (int argc,
+ const char *argv[])
+{
+ DFBSurfaceDescription desc = { flags: 0 };
+ DFBSurfacePixelFormat format = DSPF_UNKNOWN;
+ DFBSurfacePixelFormat rgbformat = DSPF_UNKNOWN;
+ DFBColor palette[256];
+
+ const char *filename[argc];
+ const char *name = NULL;
+ int palette_size = 0;
+ int num_images = 0;
+ int i, n;
+ bool rawmode = 0;
+ bool dither565 = 0;
+
+ /* parse command line */
+
+ for (n = 1; n < argc; n++) {
+ if (strncmp (argv[n], "--", 2) == 0) {
+
+ const char *arg = argv[n] + 2;
+
+ if (strcmp (arg, "help") == 0) {
+ print_usage (argv[0]);
+ return EXIT_SUCCESS;
+ }
+ if (strcmp (arg, "version") == 0) {
+ fprintf (stderr, "directfb-csource version %s\n",
+ DIRECTFB_VERSION);
+ return EXIT_SUCCESS;
+ }
+ if (strcmp (arg, "raw") == 0) {
+ rawmode = 1;
+ continue;
+ }
+ if (strcmp (arg, "dither-rgb16") == 0) {
+ dither565 = 1;
+ continue;
+ }
+ if (strncmp (arg, "format=", 7) == 0 && !format) {
+ for (i = 0; i < n_pixelformats && !format; i++)
+ if (!strcasecmp (pixelformats[i].name, arg + 7))
+ format = pixelformats[i].format;
+ if (format)
+ continue;
+ }
+ if (strncmp (arg, "rgbformat=", 10) == 0 && !rgbformat) {
+ for (i = 0; i < n_pixelformats && !rgbformat; i++)
+ if (!strcasecmp (pixelformats[i].name, arg + 10))
+ rgbformat = pixelformats[i].format;
+ if (rgbformat)
+ continue;
+ }
+ if (strncmp (arg, "name=", 5) == 0 && !name) {
+ name = arg + 5;
+ if (*name)
+ continue;
+ }
+
+ print_usage (argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ filename[num_images++] = argv[n];
+ }
+
+ /* check parameters */
+
+ if (! num_images) {
+ print_usage (argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (num_images > 1 && rawmode) {
+ fprintf (stderr,
+ "Multiple input files not allowed in raw mode.\n");
+ return EXIT_FAILURE;
+ }
+
+ if (num_images > 1 && !name) {
+ fprintf (stderr,
+ "You must specify a variable name when using multiple images.\n");
+ return EXIT_FAILURE;
+ }
+
+ /* load the first image */
+
+ if (rawmode) {
+
+ struct stat statbuf;
+ if (0 == stat(filename[0], &statbuf))
+ {
+ FILE *f;
+ unsigned char *data = alloca(statbuf.st_size);
+ memset(data, 0, statbuf.st_size);
+
+ f = fopen(filename[0], "r");
+ if (f)
+ {
+ fread(data, statbuf.st_size, 1, f);
+ fclose(f);
+ }
+
+ return dump_raw_data(name ? : strrchr (filename[0], '/') ? : filename[0],
+ data, statbuf.st_size);
+ }
+
+ }
+ else {
+ if (format) {
+ desc.flags = DSDESC_PIXELFORMAT;
+ desc.pixelformat = format;
+ }
+
+ if (load_image (filename[0],
+ &desc, palette, &palette_size,
+ rgbformat, dither565) != DFB_OK)
+ return EXIT_FAILURE;
+
+ /* dump it and quit if this is the only image on the command line */
+
+ if (num_images == 1)
+ return dump_image (name ? : strrchr (filename[0], '/') ? : filename[0],
+ &desc, palette, palette_size);
+ }
+
+ /* merge multiple images into one surface */
+ {
+ DFBSurfaceDescription image[num_images];
+ DFBRectangle rect[num_images];
+ DFBColor foo[256];
+ int foo_size;
+
+ image[0] = desc;
+
+ for (i = 1; i < num_images; i++) {
+ image[i].flags = DSDESC_PIXELFORMAT;
+ image[i].pixelformat = desc.pixelformat;
+
+ if (load_image (filename[i],
+ image + i, foo, &foo_size, rgbformat,
+ dither565) != DFB_OK)
+ return EXIT_FAILURE;
+ }
+
+ if (merge_images (image, num_images, &desc, rect) != DFB_OK)
+ return EXIT_FAILURE;
+
+ /* dump the rectangles, then the surface */
+
+ if (dump_rectangles (name, rect, filename, num_images) != DFB_OK)
+ return EXIT_FAILURE;
+
+ return dump_image (name, &desc, palette, palette_size);
+ }
+}
+
+static void print_usage (const char *prg_name)
+{
+ fprintf (stderr, "directfb-csource version %s\n\n", DIRECTFB_VERSION);
+ fprintf (stderr, "Usage: %s [options] <imagefile>\n", prg_name);
+ fprintf (stderr, " --name=<identifer> specifies variable name\n");
+ fprintf (stderr, " --format=<identifer> specifies surface format\n");
+ fprintf (stderr, " --rgbformat=<identifer> specifies format for non-alpha images\n");
+ fprintf (stderr, " --multi multiple images\n");
+ fprintf (stderr, " --raw dump a single file directly to header\n");
+ fprintf (stderr, " --dither-rgb16 dither images rendered to RGB16 surfaces\n");
+ fprintf (stderr, " --help show this help message\n");
+ fprintf (stderr, " --version print version information\n");
+ fprintf (stderr, "\n");
+ fprintf (stderr, "See the directfb-csource(1) man-page for more information.\n");
+ fprintf (stderr, "\n");
+}
+
+static DFBResult load_image (const char *filename,
+ DFBSurfaceDescription *desc,
+ DFBColor *palette,
+ int *palette_size,
+ DFBSurfacePixelFormat rgbformat,
+ bool dither565)
+{
+ DFBSurfacePixelFormat dest_format;
+ DFBSurfacePixelFormat src_format;
+ FILE *fp;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ unsigned char *data = NULL;
+ int type;
+ char header[8];
+ int bytes, pitch;
+
+ dest_format =
+ (desc->flags & DSDESC_PIXELFORMAT) ? desc->pixelformat : DSPF_UNKNOWN;
+
+ desc->flags = 0;
+ desc->preallocated[0].data = NULL;
+
+ if (!(fp = fopen (filename, "rb"))) {
+ fprintf (stderr, "Failed to open file '%s': %s.\n",
+ filename, strerror (errno));
+ goto cleanup;
+ }
+
+ bytes = fread (header, 1, sizeof(header), fp);
+ if (png_sig_cmp ((unsigned char*) header, 0, bytes)) {
+ fprintf (stderr, "File '%s' doesn't seem to be a PNG image file.\n",
+ filename);
+ goto cleanup;
+ }
+
+ png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
+ NULL, NULL, NULL);
+ if (!png_ptr)
+ goto cleanup;
+
+ if (setjmp (png_ptr->jmpbuf)) {
+ if (desc->preallocated[0].data) {
+ free (desc->preallocated[0].data);
+ desc->preallocated[0].data = NULL;
+ }
+
+ /* data might have been clobbered,
+ set it to NULL and leak instead of crashing */
+ data = NULL;
+
+ goto cleanup;
+ }
+
+ info_ptr = png_create_info_struct (png_ptr);
+ if (!info_ptr)
+ goto cleanup;
+
+ png_init_io (png_ptr, fp);
+ png_set_sig_bytes (png_ptr, bytes);
+
+ png_read_info (png_ptr, info_ptr);
+
+ png_get_IHDR (png_ptr, info_ptr,
+ &width, &height, &bytes, &type, NULL, NULL, NULL);
+
+ if (bytes == 16)
+ png_set_strip_16 (png_ptr);
+
+#ifdef WORDS_BIGENDIAN
+ png_set_swap_alpha (png_ptr);
+#else
+ png_set_bgr (png_ptr);
+#endif
+
+ src_format = (type & PNG_COLOR_MASK_ALPHA) ? DSPF_ARGB : DSPF_RGB32;
+ switch (type) {
+ case PNG_COLOR_TYPE_GRAY:
+ if (dest_format == DSPF_A8) {
+ src_format = DSPF_A8;
+ break;
+ }
+ /* fallthru */
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_set_gray_to_rgb (png_ptr);
+ if (rgbformat)
+ dest_format = rgbformat;
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ if (dest_format == DSPF_LUT8) {
+ src_format = DSPF_LUT8;
+ break;
+ }
+ png_set_palette_to_rgb (png_ptr);
+ /* fallthru */
+ case PNG_COLOR_TYPE_RGB:
+ if (rgbformat)
+ dest_format = rgbformat;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if (dest_format == DSPF_RGB24) {
+ png_set_strip_alpha (png_ptr);
+ src_format = DSPF_RGB24;
+ }
+ break;
+ }
+
+ switch (src_format) {
+ case DSPF_LUT8:
+ if (info_ptr->num_palette) {
+ png_byte *alpha;
+ int i, num;
+
+ *palette_size = MIN (info_ptr->num_palette, 256);
+ for (i = 0; i < *palette_size; i++) {
+ palette[i].a = 0xFF;
+ palette[i].r = info_ptr->palette[i].red;
+ palette[i].g = info_ptr->palette[i].green;
+ palette[i].b = info_ptr->palette[i].blue;
+ }
+ if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_get_tRNS (png_ptr, info_ptr, &alpha, &num, NULL);
+ for (i = 0; i < MIN (num, *palette_size); i++)
+ palette[i].a = alpha[i];
+ }
+ }
+ break;
+ case DSPF_RGB32:
+ png_set_filler (png_ptr, 0xFF,
+#ifdef WORDS_BIGENDIAN
+ PNG_FILLER_BEFORE
+#else
+ PNG_FILLER_AFTER
+#endif
+ );
+ break;
+ case DSPF_ARGB:
+ case DSPF_A8:
+ if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha (png_ptr);
+ break;
+ default:
+ break;
+ }
+
+ pitch = width * DFB_BYTES_PER_PIXEL (src_format);
+ if (pitch & 3)
+ pitch += 4 - (pitch & 3);
+
+ data = malloc (height * pitch);
+ if (!data) {
+ fprintf (stderr, "Failed to allocate %ld bytes.\n", height * pitch);
+ goto cleanup;
+ }
+
+ {
+ unsigned int i;
+ png_bytep bptrs[height];
+
+ for (i = 0; i < height; i++)
+ bptrs[i] = data + i * pitch;
+
+ png_read_image (png_ptr, bptrs);
+ }
+
+ if (!dest_format)
+ dest_format = src_format;
+
+ if (DFB_BYTES_PER_PIXEL(src_format) != DFB_BYTES_PER_PIXEL(dest_format)) {
+ unsigned char *s, *d, *dest;
+ int d_pitch, h;
+
+ assert (DFB_BYTES_PER_PIXEL (src_format) == 4);
+
+ d_pitch = width * DFB_BYTES_PER_PIXEL (dest_format);
+ if (d_pitch & 3)
+ d_pitch += 4 - (d_pitch & 3);
+
+ dest = malloc (height * d_pitch);
+ if (!dest) {
+ fprintf (stderr, "Failed to allocate %ld bytes.\n",
+ height * d_pitch);
+ goto cleanup;
+ }
+
+ h = height;
+ switch (dest_format) {
+ case DSPF_RGB16:
+ for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
+ if (dither565)
+ dither_rgb16 ((u32 *) s, (u16 *) d, height - h, width);
+ else
+ dfb_argb_to_rgb16 ((u32 *) s, (u16 *) d, width);
+ break;
+ case DSPF_ARGB1555:
+ for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
+ dfb_argb_to_argb1555 ((u32 *) s, (u16 *) d, width);
+ break;
+ case DSPF_ARGB2554:
+ for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
+ dfb_argb_to_argb2554 ((u32 *) s, (u16 *) d, width);
+ break;
+ case DSPF_ARGB4444:
+ for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
+ dfb_argb_to_argb4444 ((u32 *) s, (u16 *) d, width);
+ break;
+ case DSPF_RGB332:
+ for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
+ dfb_argb_to_rgb332 ((u32 *) s, (u8 *) d, width);
+ break;
+ case DSPF_A8:
+ for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
+ dfb_argb_to_a8 ((u32 *) s, (u8 *) d, width);
+ break;
+ default:
+ fprintf (stderr,
+ "Sorry, unsupported format conversion.\n");
+ goto cleanup;
+ }
+
+ free (data);
+ data = dest;
+ pitch = d_pitch;
+ }
+
+ desc->flags = (DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
+ DSDESC_PREALLOCATED);
+ desc->width = width;
+ desc->height = height;
+ desc->pixelformat = dest_format;
+ desc->preallocated[0].pitch = pitch;
+ desc->preallocated[0].data = data;
+
+ data = NULL;
+
+ cleanup:
+ if (fp)
+ fclose (fp);
+
+ if (png_ptr)
+ png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+
+ if (data)
+ free (data);
+
+ return ((desc->flags) ? DFB_OK : DFB_FAILURE);
+}
+
+static DFBResult merge_images (DFBSurfaceDescription *images,
+ int num_images,
+ DFBSurfaceDescription *dest,
+ DFBRectangle *rectangles)
+{
+ DFBSurfaceDescription *image = images;
+ DFBRectangle *rect = rectangles;
+ unsigned char *data;
+ int bpp;
+ int pitch, i;
+
+ rect->x = 0;
+ rect->y = 0;
+ rect->w = image->width;
+ rect->h = image->height;
+
+ dest->flags = (DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
+ DSDESC_PREALLOCATED);
+ dest->pixelformat = image->pixelformat;
+
+ bpp = DFB_BYTES_PER_PIXEL (dest->pixelformat);
+
+ if (bpp == 1)
+ dest->width = (rect->w + 3) & ~3;
+ else
+ dest->width = rect->w;
+
+ dest->height = rect->h;
+
+ for (i = 1; i < num_images; i++) {
+ image++;
+ rect++;
+
+ if (image->pixelformat != dest->pixelformat)
+ return DFB_INVARG;
+
+ rect->x = dest->width;
+ rect->y = 0;
+ rect->w = image->width;
+ rect->h = image->height;
+
+ if (bpp == 1)
+ dest->width += (rect->w + 3) & ~3;
+ else
+ dest->width += rect->w;
+
+ if (dest->height < rect->h)
+ dest->height = rect->h;
+ }
+
+ pitch = (dest->width * bpp + 3) &~ 3;
+ data = malloc (dest->height * pitch);
+ if (!data) {
+ fprintf (stderr, "Failed to allocate %ld bytes.\n",
+ (long) dest->height * pitch);
+ return DFB_FAILURE;
+ }
+
+
+ for (i = 0, image = images, rect = rectangles;
+ i < num_images;
+ i++, image++, rect++) {
+
+ unsigned char *dest = data + rect->x * bpp;
+ unsigned char *src = image->preallocated[0].data;
+ int height = rect->h;
+
+ do {
+ memcpy (dest, src, rect->w * bpp);
+ src += image->preallocated[0].pitch;
+ dest += pitch;
+ }
+ while (--height);
+ }
+
+ dest->preallocated[0].pitch = pitch;
+ dest->preallocated[0].data = data;
+
+ return DFB_OK;
+}
+
+static void
+dither_rgb16 (const u32 *src, u16 *dest, int y, int width)
+{
+ const u32 *dm = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT);
+ int x;
+
+ for (x = 0; x < width; x++) {
+ u32 rgb = ((src[x] & 0xFF) |
+ (src[x] & 0xFF00) << 2 |
+ (src[x] & 0xFF0000) << 4);
+
+ rgb += dm[x & (DM_WIDTH - 1)];
+ rgb += (0x10040100
+ - ((rgb & 0x1e0001e0) >> 5)
+ - ((rgb & 0x00070000) >> 6));
+
+ dest[x] = (((rgb & 0x0f800000) >> 12) |
+ ((rgb & 0x0003f000) >> 7) |
+ ((rgb & 0x000000f8) >> 3));
+ }
+}
+
+
+typedef struct {
+ FILE *fp;
+ int pos;
+ bool pad;
+} CSourceData;
+
+static inline void save_uchar (CSourceData *csource,
+ unsigned char d)
+{
+ if (csource->pos > 70) {
+ fprintf (csource->fp, "\"\n \"");
+
+ csource->pos = 3;
+ csource->pad = false;
+ }
+ if (d < 33 || d > 126) {
+ fprintf (csource->fp, "\\%o", d);
+ csource->pos += 1 + 1 + (d > 7) + (d > 63);
+ csource->pad = d < 64;
+ return;
+ }
+ if (d == '\\') {
+ fprintf (csource->fp, "\\\\");
+ csource->pos += 2;
+ }
+ else if (d == '"') {
+ fprintf (csource->fp, "\\\"");
+ csource->pos += 2;
+ }
+ else if (csource->pad && d >= '0' && d <= '9') {
+ fprintf (csource->fp, "\"\"%c", d);
+ csource->pos += 3;
+ }
+ else {
+ fputc (d, csource->fp);
+ csource->pos += 1;
+ }
+ csource->pad = false;
+
+ return;
+}
+
+static void dump_data(CSourceData *csource,
+ const char *name,
+ const unsigned char *data,
+ unsigned int len)
+{
+ fprintf (csource->fp,
+ "static const unsigned char %s_data[] =\n", name);
+ fprintf (csource->fp, " \"");
+
+ csource->pos = 3;
+ do
+ save_uchar (csource, *data++);
+ while (--len);
+
+ fprintf (csource->fp, "\";\n\n");
+}
+
+static DFBResult dump_raw_data(const char *name,
+ const unsigned char *data,
+ unsigned int len)
+{
+ CSourceData csource = { stdout, 0, 0 };
+ char *vname = variable_name (name);
+
+ if (!data || !len)
+ return DFB_INVARG;
+
+ fprintf (csource.fp,
+ "/* DirectFB raw data dump created by directfb-csource %s */\n\n",
+ DIRECTFB_VERSION);
+
+ dump_data(&csource, vname, data, len);
+
+ free (vname);
+
+ return DFB_OK;
+}
+
+
+static DFBResult dump_image (const char *name,
+ DFBSurfaceDescription *desc,
+ DFBColor *palette,
+ int palette_size)
+{
+ CSourceData csource = { stdout, 0, 0 };
+ const char *format = NULL;
+ char *vname = variable_name (name);
+ unsigned char *data;
+ unsigned long len;
+ int i;
+
+ if (desc &&
+ desc->flags != (DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
+ DSDESC_PREALLOCATED))
+ return DFB_INVARG;
+
+ for (i = 0; i < n_pixelformats && !format; i++)
+ if (pixelformats[i].format == desc->pixelformat)
+ format = pixelformats[i].name;
+
+ if (!format)
+ return DFB_INVARG;
+
+ data = (unsigned char *) desc->preallocated[0].data;
+ len = desc->height * desc->preallocated[0].pitch;
+
+ if (!len)
+ return DFB_INVARG;
+
+ /* dump comment */
+ fprintf (csource.fp,
+ "/* DirectFB surface dump created by directfb-csource %s */\n\n",
+ DIRECTFB_VERSION);
+
+ /* dump data */
+ dump_data(&csource, vname, data, len);
+
+ /* dump palette */
+ if (palette_size > 0) {
+ fprintf (csource.fp,
+ "static const DFBColor %s_palette[%d] = {\n", vname, palette_size);
+ for (i = 0; i < palette_size; i++)
+ fprintf (csource.fp,
+ " { 0x%02x, 0x%02x, 0x%02x, 0x%02x }%c\n",
+ palette[i].a, palette[i].r, palette[i].g, palette[i].b,
+ i+1 < palette_size ? ',' : ' ');
+ fprintf (csource.fp, "};\n\n");
+ }
+
+ /* dump description */
+ fprintf (csource.fp,
+ "static const DFBSurfaceDescription %s_desc = {\n", vname);
+ fprintf (csource.fp,
+ " flags : DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |\n"
+ " DSDESC_PREALLOCATED");
+ if (palette_size > 0)
+ fprintf (csource.fp, " | DSDESC_PALETTE");
+ fprintf (csource.fp, ",\n");
+ fprintf (csource.fp,
+ " width : %d,\n", desc->width);
+ fprintf (csource.fp,
+ " height : %d,\n", desc->height);
+ fprintf (csource.fp,
+ " pixelformat : DSPF_%s,\n", format);
+ fprintf (csource.fp,
+ " preallocated : {{ data : (void *) %s_data,\n", vname);
+ fprintf (csource.fp,
+ " pitch : %d }}", desc->preallocated[0].pitch);
+ if (palette_size > 0) {
+ fprintf (csource.fp, ",\n");
+ fprintf (csource.fp,
+ " palette : { entries : %s_palette,\n", vname);
+ fprintf (csource.fp,
+ " size : %d }", palette_size);
+ }
+ fprintf (csource.fp, "\n};\n\n");
+
+ free (vname);
+
+ return DFB_OK;
+}
+
+static DFBResult dump_rectangles (const char *name,
+ DFBRectangle *rectangles,
+ const char **names,
+ int num_rects)
+{
+ DFBRectangle *rect;
+ const char *blanks = " ";
+ char *vname = variable_name (name);
+ FILE *fp = stdout;
+ int len, i;
+
+ if (num_rects < 1)
+ return DFB_INVARG;
+
+ fprintf (fp,
+ "/* DirectFB multi-surface dump created by directfb-csource %s */\n\n",
+ DIRECTFB_VERSION);
+
+ fprintf (fp,
+ "static const struct {\n"
+ " const char *name;\n"
+ " DFBRectangle rect;\n"
+ "} %s[] = {\n", vname);
+
+ for (i = 0, len = 0; i < num_rects; i++)
+ len = MAX (len, strlen (names[i]));
+
+ len = len + 4 - strlen (blanks);
+
+ for (i = 0, rect = rectangles; i < num_rects; i++, rect++) {
+
+ char *v = base_name (names[i]);
+
+ if (i)
+ fprintf (fp, ",\n");
+
+ if (len < 0) {
+ int l = fprintf (fp, " { \"%s\", ", v);
+
+ fprintf (fp, blanks - len + l);
+ fprintf (fp, "{ x : %4d, y : %4d, w : %4d, h : %4d } }",
+ rect->x, rect->y, rect->w, rect->h);
+ }
+ else {
+ fprintf (fp,
+ " { \"%s\",\n"
+ " { x : %4d, y : %4d, w : %4d, h : %4d } }",
+ v, rect->x, rect->y, rect->w, rect->h);
+ }
+
+ free (v);
+ }
+ fprintf (fp, "\n};\n\n");
+
+ free (vname);
+
+ return DFB_OK;
+}
+
+static char *
+variable_name (const char *name)
+{
+ char *vname = strdup (name);
+ char *v = vname;
+
+ while (DFB_TRUE) {
+ switch (*v) {
+ case 0:
+ return vname;
+ case 'a'...'z':
+ case 'A'...'Z':
+ case '0'...'9':
+ case '_':
+ break;
+ default:
+ *v = '_';
+ }
+ v++;
+ }
+}
+
+static char *
+base_name (const char *name)
+{
+ char *vname = strdup (name);
+ char *v = vname;
+
+ while (DFB_TRUE) {
+ switch (*v) {
+ case '.':
+ *v = 0;
+ case 0:
+ return vname;
+ default:
+ break;
+ }
+ v++;
+ }
+}