1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <Imlib2.h>
/* macros */
#define ARRLEN(a) (sizeof(a) / sizeof((a)[0]))
/* globals */
static unsigned long palette[16] = {0};
static unsigned int palette_size = 0;
static unsigned int run_column = 0;
static unsigned int icon_sizes[16] = {0};
static unsigned int icon_sizes_size = 0;
/* functions */
static void error(int eval, int err, const char *fmt, ...)
{
va_list ap;
fflush(stdout);
va_start(ap, fmt);
if (fmt)
vfprintf(stderr, fmt, ap);
va_end(ap);
if (err)
fprintf(stderr, "%s%s", fmt ? ": " : "", strerror(err));
fputc('\n', stderr);
if (eval)
exit(eval);
}
static unsigned long color_to_ulong(Imlib_Color color)
{
return (color.alpha << 24 & 0xff000000) |
(color.red << 16 & 0x00ff0000) |
(color.green << 8 & 0x0000ff00) |
(color.blue & 0x000000ff);
}
static int to_palette(unsigned long color)
{
unsigned int i;
for (i = 0; i < palette_size; i++) {
if (palette[i] == color)
return i;
}
if (palette_size + 1 == 16)
error(EXIT_FAILURE, 0, "Error: More than 16 colors in palette");
palette[palette_size] = color;
return palette_size++;
}
static void print_run(int color, unsigned int run_length)
{
while (run_length > 0) {
int x = run_length / 16 >= 1 ? 16 : run_length;
printf("0x%02x, ", (x - 1) << 4 | color);
run_length -= x;
if (++run_column % 12 == 0)
printf("\n\t");
}
}
static void print_palette(void)
{
unsigned int i;
printf("static const unsigned long icon_colors[] = {\n\t");
for (i = 0; i < palette_size; i++) {
printf("0x%08lx, ", palette[i]);
if (i % 4 == 3)
printf("\n\t");
}
printf("\n};\n\n");
}
static void print_icon_array(void)
{
unsigned int i;
printf("static const icon_data_t icons[] = {\n");
for (i = 0; i < icon_sizes_size; i++)
printf("\tICON_(%d),\n", icon_sizes[i]);
printf("};\n\n");
}
static unsigned int print_encoded_image(const char *path)
{
Imlib_Image image;
Imlib_Color color;
unsigned int width, height, x, y;
unsigned int run_length = 1;
int currentcolor = 0;
int lastcolor = -1;
image = imlib_load_image(path);
if (image == NULL)
error(EXIT_FAILURE, 0, "Error loading image: %s", path);
imlib_context_set_image(image);
width = imlib_image_get_width();
height = imlib_image_get_height();
if (width != height)
error(EXIT_FAILURE, 0, "Image is not square: %s", path);
printf("static const unsigned char icon_data_%d[] = {\n\t", width);
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
imlib_image_query_pixel(x, y, &color);
currentcolor = to_palette(color_to_ulong(color));
if (currentcolor != lastcolor) {
if (lastcolor != -1)
print_run(lastcolor, run_length);
run_length = 1;
} else {
run_length++;
}
lastcolor = currentcolor;
}
}
print_run(lastcolor, run_length);
printf("\n};\n\n");
imlib_free_image();
return width;
}
int main(int argc, char **argv)
{
unsigned int img_size = 0;
unsigned int i;
if (argc < 2)
error(EXIT_FAILURE, 0, "No icons provided");
else if (argc-1 > ARRLEN(icon_sizes))
error(EXIT_FAILURE, 0, "Too many icons");
for (i = 1; i < argc; i++) {
img_size = print_encoded_image(argv[i]);
run_column = 0;
icon_sizes[icon_sizes_size++] = img_size;
}
print_palette();
print_icon_array();
return EXIT_SUCCESS;
}
|