From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/tools/directfb-csource.c | 894 +++++++++++++++++++++++++++++++ 1 file changed, 894 insertions(+) create mode 100755 Source/DirectFB/tools/directfb-csource.c (limited to 'Source/DirectFB/tools/directfb-csource.c') 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 , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + 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 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include + +#include + +#define DFB_DITHER565 DFB_DITHER_ADVANCED +#include + + +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] \n", prg_name); + fprintf (stderr, " --name= specifies variable name\n"); + fprintf (stderr, " --format= specifies surface format\n"); + fprintf (stderr, " --rgbformat= 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++; + } +} -- cgit