+#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>
#include "icon_tools.h"
#include "plist.h"
#include "values.h"
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
enum
{
R_SECTION,
R_ICON,
R_PLIST,
+ R_STRING,
};
typedef struct
{"section", R_SECTION},
{"icon", R_ICON},
{"plist", R_PLIST},
+ {"string", R_STRING},
};
#define TAG_MAP_SZ (sizeof(tag_map)/sizeof(tag_map_t))
gboolean closed_top;
} parse_data_t;
+GList *inc_list = NULL;
+
+static gchar*
+find_file(GList *list, const gchar *name)
+{
+ gchar *str;
+ GList *link = list;
+
+ while (link != NULL)
+ {
+ gchar *inc;
+
+ inc = (gchar*)link->data;
+ str = g_strdup_printf("%s/%s", inc, name);
+ if (g_file_test(str, G_FILE_TEST_IS_REGULAR))
+ {
+ return str;
+ }
+ g_free(str);
+ link = g_list_next(link);
+ }
+ if (g_file_test(name, G_FILE_TEST_IS_REGULAR))
+ {
+ return g_strdup(name);
+ }
+ return NULL;
+}
+
static const gchar*
lookup_attr_value(
const gchar *name,
return NULL;
}
+static GValue*
+read_string_from_file(const gchar *filename)
+{
+ gchar *buffer;
+ size_t size;
+ GValue *gval;
+ FILE *fd;
+
+ fd = g_fopen(filename, "r");
+ if (fd == NULL)
+ return NULL;
+ fseek(fd, 0, SEEK_END);
+ size = ftell(fd);
+ fseek(fd, 0, SEEK_SET);
+ buffer = g_malloc(size+1);
+ size = fread(buffer, 1, size, fd);
+ buffer[size] = 0;
+ gval = ghb_value_new(G_TYPE_STRING);
+ g_value_take_string(gval, buffer);
+ fclose(fd);
+ return gval;
+}
+
static void
start_element(
GMarkupParseContext *ctx,
- const gchar *name,
+ const gchar *tag,
const gchar **attr_names,
const gchar **attr_values,
gpointer ud,
for (ii = 0; ii < TAG_MAP_SZ; ii++)
{
- if (strcmp(name, tag_map[ii].tag) == 0)
+ if (strcmp(tag, tag_map[ii].tag) == 0)
{
id.id = tag_map[ii].id;
break;
}
if (ii == TAG_MAP_SZ)
{
- g_warning("Unrecognized start tag (%s)", name);
+ g_warning("Unrecognized start tag (%s)", tag);
return;
}
g_queue_push_head(pd->tag_stack, id.pid);
{
case R_SECTION:
{
- const gchar *sect;
+ const gchar *name;
- sect = lookup_attr_value("name", attr_names, attr_values);
- if (sect && strcmp(sect, "icons") == 0)
+ name = lookup_attr_value("name", attr_names, attr_values);
+ if (name && strcmp(name, "icons") == 0)
{
gval = ghb_dict_value_new();
if (pd->key) g_free(pd->key);
- pd->key = g_strdup(sect);
+ pd->key = g_strdup(name);
g_queue_push_head(pd->stack, gval);
}
} break;
case R_ICON:
{
- const gchar *filename, *icon;
+ gchar *filename;
+ const gchar *name;
- filename = lookup_attr_value("file", attr_names, attr_values);
- icon = lookup_attr_value("name", attr_names, attr_values);
- if (filename && icon)
+ name = lookup_attr_value("file", attr_names, attr_values);
+ filename = find_file(inc_list, name);
+ name = lookup_attr_value("name", attr_names, attr_values);
+ if (filename && name)
{
ghb_rawdata_t *rd;
- guint size;
+ GdkPixbuf *pb;
+ GError *err = NULL;
+
+ pb = gdk_pixbuf_new_from_file(filename, &err);
+ if (pb == NULL)
+ {
+ g_warning("Failed to open icon file %s: %s", filename, err->message);
+ break;
+ }
+ gval = ghb_dict_value_new();
+ int colorspace = gdk_pixbuf_get_colorspace(pb);
+ gboolean alpha = gdk_pixbuf_get_has_alpha(pb);
+ int width = gdk_pixbuf_get_width(pb);
+ int height = gdk_pixbuf_get_height(pb);
+ int bps = gdk_pixbuf_get_bits_per_sample(pb);
+ int rowstride = gdk_pixbuf_get_rowstride(pb);
+
+ ghb_dict_insert(gval, g_strdup("colorspace"),
+ ghb_int_value_new(colorspace));
+ ghb_dict_insert(gval, g_strdup("alpha"),
+ ghb_boolean_value_new(alpha));
+ ghb_dict_insert(gval, g_strdup("width"),
+ ghb_int_value_new(width));
+ ghb_dict_insert(gval, g_strdup("height"),
+ ghb_int_value_new(height));
+ ghb_dict_insert(gval, g_strdup("bps"),
+ ghb_int_value_new(bps));
+ ghb_dict_insert(gval, g_strdup("rowstride"),
+ ghb_int_value_new(rowstride));
rd = g_malloc(sizeof(ghb_rawdata_t));
- rd->data = icon_file_serialize(filename, &size);
- rd->size = size;
- gval = ghb_rawdata_value_new(rd);
+ rd->data = gdk_pixbuf_get_pixels(pb);
+ rd->size = height * rowstride * bps / 8;
+ GValue *data = ghb_rawdata_value_new(rd);
+ ghb_dict_insert(gval, g_strdup("data"), data);
+
if (pd->key) g_free(pd->key);
- pd->key = g_strdup(icon);
+ pd->key = g_strdup(name);
+ g_free(filename);
}
else
{
g_warning("%s:missing a requried attribute", name);
+ exit(EXIT_FAILURE);
}
} break;
case R_PLIST:
{
- const gchar *filename, *plist;
+ gchar *filename;
+ const gchar *name;
- filename = lookup_attr_value("file", attr_names, attr_values);
- plist = lookup_attr_value("name", attr_names, attr_values);
- if (filename && plist)
+ name = lookup_attr_value("file", attr_names, attr_values);
+ filename = find_file(inc_list, name);
+ name = lookup_attr_value("name", attr_names, attr_values);
+ if (filename && name)
{
gval = ghb_plist_parse_file(filename);
if (pd->key) g_free(pd->key);
- pd->key = g_strdup(plist);
+ pd->key = g_strdup(name);
+ g_free(filename);
+ }
+ else
+ {
+ g_warning("%s:missing a requried attribute", name);
+ exit(EXIT_FAILURE);
+ }
+ } break;
+ case R_STRING:
+ {
+ gchar *filename;
+ const gchar *name;
+
+ name = lookup_attr_value("file", attr_names, attr_values);
+ filename = find_file(inc_list, name);
+ name = lookup_attr_value("name", attr_names, attr_values);
+ if (filename && name)
+ {
+ gval = read_string_from_file(filename);
+ if (pd->key) g_free(pd->key);
+ pd->key = g_strdup(name);
+ g_free(filename);
}
else
{
g_warning("%s:missing a requried attribute", name);
+ exit(EXIT_FAILURE);
}
} break;
}
return gval;
}
+static void
+usage(char *cmd)
+{
+ fprintf(stderr,
+"Usage: %s [-I <inc path>] <in resource list> <out resource plist>\n"
+"Summary:\n"
+" Creates a resource plist from a resource list\n"
+"Options:\n"
+" I - Include path to search for files\n"
+" <in resource list> Input resources file\n"
+" <out resource plist> Output resources plist file\n"
+, cmd);
+
+ exit(EXIT_FAILURE);
+}
+
+#define OPTS "I:"
gint
main(gint argc, gchar *argv[])
{
FILE *file;
GValue *gval;
-
- if (argc < 3)
+ int opt;
+ const gchar *src, *dst;
+
+ do
+ {
+ opt = getopt(argc, argv, OPTS);
+ switch (opt)
+ {
+ case -1: break;
+
+ case 'I':
+ inc_list = g_list_prepend(inc_list, g_strdup(optarg));
+ break;
+ }
+ } while (opt != -1);
+
+ if (optind != argc - 2)
{
- fprintf(stderr, "Usage: <in resource list> <out resource plist>\n");
- return 1;
+ usage(argv[0]);
+ return EXIT_FAILURE;
}
+ src = argv[optind++];
+ dst = argv[optind++];
+
g_type_init();
- file = g_fopen(argv[1], "r");
+ file = g_fopen(src, "r");
if (file == NULL)
- return 1;
+ {
+ fprintf(stderr, "Error: failed to open %s\n", src);
+ return EXIT_FAILURE;
+ }
gval = ghb_resource_parse_file(file);
- ghb_plist_write_file(argv[2], gval);
+ ghb_plist_write_file(dst, gval);
return 0;
}