Krolyxon
Commit 88a480c

Branches

Refs →

nsxiviconimg2data.c

157 lines · 3.3 KB · C

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