18f0e0560SNikita Romanyuk // SPDX-License-Identifier: GPL-2.0-only
278a20a01SMasahiro Yamada /*
378a20a01SMasahiro Yamada * Convert a logo in ASCII PNM format to C source suitable for inclusion in
478a20a01SMasahiro Yamada * the Linux kernel
578a20a01SMasahiro Yamada *
678a20a01SMasahiro Yamada * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
778a20a01SMasahiro Yamada */
878a20a01SMasahiro Yamada
978a20a01SMasahiro Yamada #include <ctype.h>
1078a20a01SMasahiro Yamada #include <errno.h>
1178a20a01SMasahiro Yamada #include <stdarg.h>
1278a20a01SMasahiro Yamada #include <stdio.h>
1378a20a01SMasahiro Yamada #include <stdlib.h>
1478a20a01SMasahiro Yamada #include <string.h>
1578a20a01SMasahiro Yamada #include <unistd.h>
1678a20a01SMasahiro Yamada
1778a20a01SMasahiro Yamada
1878a20a01SMasahiro Yamada static const char *programname;
1978a20a01SMasahiro Yamada static const char *filename;
2078a20a01SMasahiro Yamada static const char *logoname = "linux_logo";
2178a20a01SMasahiro Yamada static const char *outputname;
2278a20a01SMasahiro Yamada static FILE *out;
2378a20a01SMasahiro Yamada
2478a20a01SMasahiro Yamada
2578a20a01SMasahiro Yamada #define LINUX_LOGO_MONO 1 /* monochrome black/white */
2678a20a01SMasahiro Yamada #define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */
2778a20a01SMasahiro Yamada #define LINUX_LOGO_CLUT224 3 /* 224 colors */
2878a20a01SMasahiro Yamada #define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */
2978a20a01SMasahiro Yamada
3078a20a01SMasahiro Yamada static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
3178a20a01SMasahiro Yamada [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
3278a20a01SMasahiro Yamada [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
3378a20a01SMasahiro Yamada [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
3478a20a01SMasahiro Yamada [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
3578a20a01SMasahiro Yamada };
3678a20a01SMasahiro Yamada
3778a20a01SMasahiro Yamada #define MAX_LINUX_LOGO_COLORS 224
3878a20a01SMasahiro Yamada
3978a20a01SMasahiro Yamada struct color {
4078a20a01SMasahiro Yamada unsigned char red;
4178a20a01SMasahiro Yamada unsigned char green;
4278a20a01SMasahiro Yamada unsigned char blue;
4378a20a01SMasahiro Yamada };
4478a20a01SMasahiro Yamada
4578a20a01SMasahiro Yamada static const struct color clut_vga16[16] = {
4678a20a01SMasahiro Yamada { 0x00, 0x00, 0x00 },
4778a20a01SMasahiro Yamada { 0x00, 0x00, 0xaa },
4878a20a01SMasahiro Yamada { 0x00, 0xaa, 0x00 },
4978a20a01SMasahiro Yamada { 0x00, 0xaa, 0xaa },
5078a20a01SMasahiro Yamada { 0xaa, 0x00, 0x00 },
5178a20a01SMasahiro Yamada { 0xaa, 0x00, 0xaa },
5278a20a01SMasahiro Yamada { 0xaa, 0x55, 0x00 },
5378a20a01SMasahiro Yamada { 0xaa, 0xaa, 0xaa },
5478a20a01SMasahiro Yamada { 0x55, 0x55, 0x55 },
5578a20a01SMasahiro Yamada { 0x55, 0x55, 0xff },
5678a20a01SMasahiro Yamada { 0x55, 0xff, 0x55 },
5778a20a01SMasahiro Yamada { 0x55, 0xff, 0xff },
5878a20a01SMasahiro Yamada { 0xff, 0x55, 0x55 },
5978a20a01SMasahiro Yamada { 0xff, 0x55, 0xff },
6078a20a01SMasahiro Yamada { 0xff, 0xff, 0x55 },
6178a20a01SMasahiro Yamada { 0xff, 0xff, 0xff },
6278a20a01SMasahiro Yamada };
6378a20a01SMasahiro Yamada
6478a20a01SMasahiro Yamada
6578a20a01SMasahiro Yamada static int logo_type = LINUX_LOGO_CLUT224;
6678a20a01SMasahiro Yamada static unsigned int logo_width;
6778a20a01SMasahiro Yamada static unsigned int logo_height;
6878a20a01SMasahiro Yamada static struct color **logo_data;
6978a20a01SMasahiro Yamada static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
7078a20a01SMasahiro Yamada static unsigned int logo_clutsize;
7178a20a01SMasahiro Yamada static int is_plain_pbm = 0;
7278a20a01SMasahiro Yamada
7378a20a01SMasahiro Yamada static void die(const char *fmt, ...)
7478a20a01SMasahiro Yamada __attribute__((noreturn)) __attribute((format (printf, 1, 2)));
7578a20a01SMasahiro Yamada static void usage(void) __attribute((noreturn));
7678a20a01SMasahiro Yamada
7778a20a01SMasahiro Yamada
get_number(FILE * fp)7878a20a01SMasahiro Yamada static unsigned int get_number(FILE *fp)
7978a20a01SMasahiro Yamada {
8078a20a01SMasahiro Yamada int c, val;
8178a20a01SMasahiro Yamada
8278a20a01SMasahiro Yamada /* Skip leading whitespace */
8378a20a01SMasahiro Yamada do {
8478a20a01SMasahiro Yamada c = fgetc(fp);
8578a20a01SMasahiro Yamada if (c == EOF)
8678a20a01SMasahiro Yamada die("%s: end of file\n", filename);
8778a20a01SMasahiro Yamada if (c == '#') {
8878a20a01SMasahiro Yamada /* Ignore comments 'till end of line */
8978a20a01SMasahiro Yamada do {
9078a20a01SMasahiro Yamada c = fgetc(fp);
9178a20a01SMasahiro Yamada if (c == EOF)
9278a20a01SMasahiro Yamada die("%s: end of file\n", filename);
9378a20a01SMasahiro Yamada } while (c != '\n');
9478a20a01SMasahiro Yamada }
9578a20a01SMasahiro Yamada } while (isspace(c));
9678a20a01SMasahiro Yamada
9778a20a01SMasahiro Yamada /* Parse decimal number */
9878a20a01SMasahiro Yamada val = 0;
9978a20a01SMasahiro Yamada while (isdigit(c)) {
10078a20a01SMasahiro Yamada val = 10*val+c-'0';
10178a20a01SMasahiro Yamada /* some PBM are 'broken'; GiMP for example exports a PBM without space
10278a20a01SMasahiro Yamada * between the digits. This is Ok cause we know a PBM can only have a '1'
103044b14b5SNikita Romanyuk * or a '0' for the digit.
104044b14b5SNikita Romanyuk */
10578a20a01SMasahiro Yamada if (is_plain_pbm)
10678a20a01SMasahiro Yamada break;
10778a20a01SMasahiro Yamada c = fgetc(fp);
10878a20a01SMasahiro Yamada if (c == EOF)
10978a20a01SMasahiro Yamada die("%s: end of file\n", filename);
11078a20a01SMasahiro Yamada }
11178a20a01SMasahiro Yamada return val;
11278a20a01SMasahiro Yamada }
11378a20a01SMasahiro Yamada
get_number255(FILE * fp,unsigned int maxval)11478a20a01SMasahiro Yamada static unsigned int get_number255(FILE *fp, unsigned int maxval)
11578a20a01SMasahiro Yamada {
11678a20a01SMasahiro Yamada unsigned int val = get_number(fp);
117044b14b5SNikita Romanyuk
11878a20a01SMasahiro Yamada return (255*val+maxval/2)/maxval;
11978a20a01SMasahiro Yamada }
12078a20a01SMasahiro Yamada
read_image(void)12178a20a01SMasahiro Yamada static void read_image(void)
12278a20a01SMasahiro Yamada {
12378a20a01SMasahiro Yamada FILE *fp;
12478a20a01SMasahiro Yamada unsigned int i, j;
12578a20a01SMasahiro Yamada int magic;
12678a20a01SMasahiro Yamada unsigned int maxval;
12778a20a01SMasahiro Yamada
12878a20a01SMasahiro Yamada /* open image file */
12978a20a01SMasahiro Yamada fp = fopen(filename, "r");
13078a20a01SMasahiro Yamada if (!fp)
13178a20a01SMasahiro Yamada die("Cannot open file %s: %s\n", filename, strerror(errno));
13278a20a01SMasahiro Yamada
13378a20a01SMasahiro Yamada /* check file type and read file header */
13478a20a01SMasahiro Yamada magic = fgetc(fp);
13578a20a01SMasahiro Yamada if (magic != 'P')
13678a20a01SMasahiro Yamada die("%s is not a PNM file\n", filename);
13778a20a01SMasahiro Yamada magic = fgetc(fp);
13878a20a01SMasahiro Yamada switch (magic) {
13978a20a01SMasahiro Yamada case '1':
14078a20a01SMasahiro Yamada case '2':
14178a20a01SMasahiro Yamada case '3':
14278a20a01SMasahiro Yamada /* Plain PBM/PGM/PPM */
14378a20a01SMasahiro Yamada break;
14478a20a01SMasahiro Yamada
14578a20a01SMasahiro Yamada case '4':
14678a20a01SMasahiro Yamada case '5':
14778a20a01SMasahiro Yamada case '6':
14878a20a01SMasahiro Yamada /* Binary PBM/PGM/PPM */
14978a20a01SMasahiro Yamada die("%s: Binary PNM is not supported\n"
15078a20a01SMasahiro Yamada "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
15178a20a01SMasahiro Yamada
15278a20a01SMasahiro Yamada default:
15378a20a01SMasahiro Yamada die("%s is not a PNM file\n", filename);
15478a20a01SMasahiro Yamada }
15578a20a01SMasahiro Yamada logo_width = get_number(fp);
15678a20a01SMasahiro Yamada logo_height = get_number(fp);
15778a20a01SMasahiro Yamada
15878a20a01SMasahiro Yamada /* allocate image data */
15978a20a01SMasahiro Yamada logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
16078a20a01SMasahiro Yamada if (!logo_data)
16178a20a01SMasahiro Yamada die("%s\n", strerror(errno));
16278a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++) {
16378a20a01SMasahiro Yamada logo_data[i] = malloc(logo_width*sizeof(struct color));
16478a20a01SMasahiro Yamada if (!logo_data[i])
16578a20a01SMasahiro Yamada die("%s\n", strerror(errno));
16678a20a01SMasahiro Yamada }
16778a20a01SMasahiro Yamada
16878a20a01SMasahiro Yamada /* read image data */
16978a20a01SMasahiro Yamada switch (magic) {
17078a20a01SMasahiro Yamada case '1':
17178a20a01SMasahiro Yamada /* Plain PBM */
17278a20a01SMasahiro Yamada is_plain_pbm = 1;
17378a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
17478a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++)
17578a20a01SMasahiro Yamada logo_data[i][j].red = logo_data[i][j].green =
17678a20a01SMasahiro Yamada logo_data[i][j].blue = 255*(1-get_number(fp));
17778a20a01SMasahiro Yamada break;
17878a20a01SMasahiro Yamada
17978a20a01SMasahiro Yamada case '2':
18078a20a01SMasahiro Yamada /* Plain PGM */
18178a20a01SMasahiro Yamada maxval = get_number(fp);
18278a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
18378a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++)
18478a20a01SMasahiro Yamada logo_data[i][j].red = logo_data[i][j].green =
18578a20a01SMasahiro Yamada logo_data[i][j].blue = get_number255(fp, maxval);
18678a20a01SMasahiro Yamada break;
18778a20a01SMasahiro Yamada
18878a20a01SMasahiro Yamada case '3':
18978a20a01SMasahiro Yamada /* Plain PPM */
19078a20a01SMasahiro Yamada maxval = get_number(fp);
19178a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
19278a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++) {
19378a20a01SMasahiro Yamada logo_data[i][j].red = get_number255(fp, maxval);
19478a20a01SMasahiro Yamada logo_data[i][j].green = get_number255(fp, maxval);
19578a20a01SMasahiro Yamada logo_data[i][j].blue = get_number255(fp, maxval);
19678a20a01SMasahiro Yamada }
19778a20a01SMasahiro Yamada break;
19878a20a01SMasahiro Yamada }
19978a20a01SMasahiro Yamada
20078a20a01SMasahiro Yamada /* close file */
20178a20a01SMasahiro Yamada fclose(fp);
20278a20a01SMasahiro Yamada }
20378a20a01SMasahiro Yamada
is_black(struct color c)20478a20a01SMasahiro Yamada static inline int is_black(struct color c)
20578a20a01SMasahiro Yamada {
20678a20a01SMasahiro Yamada return c.red == 0 && c.green == 0 && c.blue == 0;
20778a20a01SMasahiro Yamada }
20878a20a01SMasahiro Yamada
is_white(struct color c)20978a20a01SMasahiro Yamada static inline int is_white(struct color c)
21078a20a01SMasahiro Yamada {
21178a20a01SMasahiro Yamada return c.red == 255 && c.green == 255 && c.blue == 255;
21278a20a01SMasahiro Yamada }
21378a20a01SMasahiro Yamada
is_gray(struct color c)21478a20a01SMasahiro Yamada static inline int is_gray(struct color c)
21578a20a01SMasahiro Yamada {
21678a20a01SMasahiro Yamada return c.red == c.green && c.red == c.blue;
21778a20a01SMasahiro Yamada }
21878a20a01SMasahiro Yamada
is_equal(struct color c1,struct color c2)21978a20a01SMasahiro Yamada static inline int is_equal(struct color c1, struct color c2)
22078a20a01SMasahiro Yamada {
22178a20a01SMasahiro Yamada return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
22278a20a01SMasahiro Yamada }
22378a20a01SMasahiro Yamada
write_header(void)22478a20a01SMasahiro Yamada static void write_header(void)
22578a20a01SMasahiro Yamada {
22678a20a01SMasahiro Yamada /* open logo file */
22778a20a01SMasahiro Yamada if (outputname) {
22878a20a01SMasahiro Yamada out = fopen(outputname, "w");
22978a20a01SMasahiro Yamada if (!out)
23078a20a01SMasahiro Yamada die("Cannot create file %s: %s\n", outputname, strerror(errno));
23178a20a01SMasahiro Yamada } else {
23278a20a01SMasahiro Yamada out = stdout;
23378a20a01SMasahiro Yamada }
23478a20a01SMasahiro Yamada
23578a20a01SMasahiro Yamada fputs("/*\n", out);
23678a20a01SMasahiro Yamada fputs(" * DO NOT EDIT THIS FILE!\n", out);
23778a20a01SMasahiro Yamada fputs(" *\n", out);
23878a20a01SMasahiro Yamada fprintf(out, " * Linux logo %s\n", logoname);
23978a20a01SMasahiro Yamada fputs(" */\n\n", out);
24078a20a01SMasahiro Yamada fputs("#include <linux/linux_logo.h>\n\n", out);
241*3dc59489SGeert Uytterhoeven fprintf(out, "static const unsigned char %s_data[] __initconst = {\n",
24278a20a01SMasahiro Yamada logoname);
24378a20a01SMasahiro Yamada }
24478a20a01SMasahiro Yamada
write_footer(void)24578a20a01SMasahiro Yamada static void write_footer(void)
24678a20a01SMasahiro Yamada {
24778a20a01SMasahiro Yamada fputs("\n};\n\n", out);
24878a20a01SMasahiro Yamada fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
24978a20a01SMasahiro Yamada fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
25029328fb0SColin Ian King fprintf(out, "\t.width\t\t= %u,\n", logo_width);
25129328fb0SColin Ian King fprintf(out, "\t.height\t\t= %u,\n", logo_height);
25278a20a01SMasahiro Yamada if (logo_type == LINUX_LOGO_CLUT224) {
25329328fb0SColin Ian King fprintf(out, "\t.clutsize\t= %u,\n", logo_clutsize);
25478a20a01SMasahiro Yamada fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname);
25578a20a01SMasahiro Yamada }
25678a20a01SMasahiro Yamada fprintf(out, "\t.data\t\t= %s_data\n", logoname);
25778a20a01SMasahiro Yamada fputs("};\n\n", out);
25878a20a01SMasahiro Yamada
25978a20a01SMasahiro Yamada /* close logo file */
26078a20a01SMasahiro Yamada if (outputname)
26178a20a01SMasahiro Yamada fclose(out);
26278a20a01SMasahiro Yamada }
26378a20a01SMasahiro Yamada
26478a20a01SMasahiro Yamada static int write_hex_cnt;
26578a20a01SMasahiro Yamada
write_hex(unsigned char byte)26678a20a01SMasahiro Yamada static void write_hex(unsigned char byte)
26778a20a01SMasahiro Yamada {
26878a20a01SMasahiro Yamada if (write_hex_cnt % 12)
26978a20a01SMasahiro Yamada fprintf(out, ", 0x%02x", byte);
27078a20a01SMasahiro Yamada else if (write_hex_cnt)
27178a20a01SMasahiro Yamada fprintf(out, ",\n\t0x%02x", byte);
27278a20a01SMasahiro Yamada else
27378a20a01SMasahiro Yamada fprintf(out, "\t0x%02x", byte);
27478a20a01SMasahiro Yamada write_hex_cnt++;
27578a20a01SMasahiro Yamada }
27678a20a01SMasahiro Yamada
write_logo_mono(void)27778a20a01SMasahiro Yamada static void write_logo_mono(void)
27878a20a01SMasahiro Yamada {
27978a20a01SMasahiro Yamada unsigned int i, j;
28078a20a01SMasahiro Yamada unsigned char val, bit;
28178a20a01SMasahiro Yamada
28278a20a01SMasahiro Yamada /* validate image */
28378a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
28478a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++)
28578a20a01SMasahiro Yamada if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
28678a20a01SMasahiro Yamada die("Image must be monochrome\n");
28778a20a01SMasahiro Yamada
28878a20a01SMasahiro Yamada /* write file header */
28978a20a01SMasahiro Yamada write_header();
29078a20a01SMasahiro Yamada
29178a20a01SMasahiro Yamada /* write logo data */
29278a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++) {
29378a20a01SMasahiro Yamada for (j = 0; j < logo_width;) {
29478a20a01SMasahiro Yamada for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
29578a20a01SMasahiro Yamada if (logo_data[i][j].red)
29678a20a01SMasahiro Yamada val |= bit;
29778a20a01SMasahiro Yamada write_hex(val);
29878a20a01SMasahiro Yamada }
29978a20a01SMasahiro Yamada }
30078a20a01SMasahiro Yamada
30178a20a01SMasahiro Yamada /* write logo structure and file footer */
30278a20a01SMasahiro Yamada write_footer();
30378a20a01SMasahiro Yamada }
30478a20a01SMasahiro Yamada
write_logo_vga16(void)30578a20a01SMasahiro Yamada static void write_logo_vga16(void)
30678a20a01SMasahiro Yamada {
30778a20a01SMasahiro Yamada unsigned int i, j, k;
30878a20a01SMasahiro Yamada unsigned char val;
30978a20a01SMasahiro Yamada
31078a20a01SMasahiro Yamada /* validate image */
31178a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
31278a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++) {
31378a20a01SMasahiro Yamada for (k = 0; k < 16; k++)
31478a20a01SMasahiro Yamada if (is_equal(logo_data[i][j], clut_vga16[k]))
31578a20a01SMasahiro Yamada break;
31678a20a01SMasahiro Yamada if (k == 16)
31778a20a01SMasahiro Yamada die("Image must use the 16 console colors only\n"
31878a20a01SMasahiro Yamada "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
31978a20a01SMasahiro Yamada "of colors\n");
32078a20a01SMasahiro Yamada }
32178a20a01SMasahiro Yamada
32278a20a01SMasahiro Yamada /* write file header */
32378a20a01SMasahiro Yamada write_header();
32478a20a01SMasahiro Yamada
32578a20a01SMasahiro Yamada /* write logo data */
32678a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
32778a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++) {
32878a20a01SMasahiro Yamada for (k = 0; k < 16; k++)
32978a20a01SMasahiro Yamada if (is_equal(logo_data[i][j], clut_vga16[k]))
33078a20a01SMasahiro Yamada break;
33178a20a01SMasahiro Yamada val = k<<4;
33278a20a01SMasahiro Yamada if (++j < logo_width) {
33378a20a01SMasahiro Yamada for (k = 0; k < 16; k++)
33478a20a01SMasahiro Yamada if (is_equal(logo_data[i][j], clut_vga16[k]))
33578a20a01SMasahiro Yamada break;
33678a20a01SMasahiro Yamada val |= k;
33778a20a01SMasahiro Yamada }
33878a20a01SMasahiro Yamada write_hex(val);
33978a20a01SMasahiro Yamada }
34078a20a01SMasahiro Yamada
34178a20a01SMasahiro Yamada /* write logo structure and file footer */
34278a20a01SMasahiro Yamada write_footer();
34378a20a01SMasahiro Yamada }
34478a20a01SMasahiro Yamada
write_logo_clut224(void)34578a20a01SMasahiro Yamada static void write_logo_clut224(void)
34678a20a01SMasahiro Yamada {
34778a20a01SMasahiro Yamada unsigned int i, j, k;
34878a20a01SMasahiro Yamada
34978a20a01SMasahiro Yamada /* validate image */
35078a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
35178a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++) {
35278a20a01SMasahiro Yamada for (k = 0; k < logo_clutsize; k++)
35378a20a01SMasahiro Yamada if (is_equal(logo_data[i][j], logo_clut[k]))
35478a20a01SMasahiro Yamada break;
35578a20a01SMasahiro Yamada if (k == logo_clutsize) {
35678a20a01SMasahiro Yamada if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
35778a20a01SMasahiro Yamada die("Image has more than %d colors\n"
35878a20a01SMasahiro Yamada "Use ppmquant(1) to reduce the number of colors\n",
35978a20a01SMasahiro Yamada MAX_LINUX_LOGO_COLORS);
36078a20a01SMasahiro Yamada logo_clut[logo_clutsize++] = logo_data[i][j];
36178a20a01SMasahiro Yamada }
36278a20a01SMasahiro Yamada }
36378a20a01SMasahiro Yamada
36478a20a01SMasahiro Yamada /* write file header */
36578a20a01SMasahiro Yamada write_header();
36678a20a01SMasahiro Yamada
36778a20a01SMasahiro Yamada /* write logo data */
36878a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
36978a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++) {
37078a20a01SMasahiro Yamada for (k = 0; k < logo_clutsize; k++)
37178a20a01SMasahiro Yamada if (is_equal(logo_data[i][j], logo_clut[k]))
37278a20a01SMasahiro Yamada break;
37378a20a01SMasahiro Yamada write_hex(k+32);
37478a20a01SMasahiro Yamada }
37578a20a01SMasahiro Yamada fputs("\n};\n\n", out);
37678a20a01SMasahiro Yamada
37778a20a01SMasahiro Yamada /* write logo clut */
378*3dc59489SGeert Uytterhoeven fprintf(out, "static const unsigned char %s_clut[] __initconst = {\n",
37978a20a01SMasahiro Yamada logoname);
38078a20a01SMasahiro Yamada write_hex_cnt = 0;
38178a20a01SMasahiro Yamada for (i = 0; i < logo_clutsize; i++) {
38278a20a01SMasahiro Yamada write_hex(logo_clut[i].red);
38378a20a01SMasahiro Yamada write_hex(logo_clut[i].green);
38478a20a01SMasahiro Yamada write_hex(logo_clut[i].blue);
38578a20a01SMasahiro Yamada }
38678a20a01SMasahiro Yamada
38778a20a01SMasahiro Yamada /* write logo structure and file footer */
38878a20a01SMasahiro Yamada write_footer();
38978a20a01SMasahiro Yamada }
39078a20a01SMasahiro Yamada
write_logo_gray256(void)39178a20a01SMasahiro Yamada static void write_logo_gray256(void)
39278a20a01SMasahiro Yamada {
39378a20a01SMasahiro Yamada unsigned int i, j;
39478a20a01SMasahiro Yamada
39578a20a01SMasahiro Yamada /* validate image */
39678a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
39778a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++)
39878a20a01SMasahiro Yamada if (!is_gray(logo_data[i][j]))
39978a20a01SMasahiro Yamada die("Image must be grayscale\n");
40078a20a01SMasahiro Yamada
40178a20a01SMasahiro Yamada /* write file header */
40278a20a01SMasahiro Yamada write_header();
40378a20a01SMasahiro Yamada
40478a20a01SMasahiro Yamada /* write logo data */
40578a20a01SMasahiro Yamada for (i = 0; i < logo_height; i++)
40678a20a01SMasahiro Yamada for (j = 0; j < logo_width; j++)
40778a20a01SMasahiro Yamada write_hex(logo_data[i][j].red);
40878a20a01SMasahiro Yamada
40978a20a01SMasahiro Yamada /* write logo structure and file footer */
41078a20a01SMasahiro Yamada write_footer();
41178a20a01SMasahiro Yamada }
41278a20a01SMasahiro Yamada
die(const char * fmt,...)41378a20a01SMasahiro Yamada static void die(const char *fmt, ...)
41478a20a01SMasahiro Yamada {
41578a20a01SMasahiro Yamada va_list ap;
41678a20a01SMasahiro Yamada
41778a20a01SMasahiro Yamada va_start(ap, fmt);
41878a20a01SMasahiro Yamada vfprintf(stderr, fmt, ap);
41978a20a01SMasahiro Yamada va_end(ap);
42078a20a01SMasahiro Yamada
42178a20a01SMasahiro Yamada exit(1);
42278a20a01SMasahiro Yamada }
42378a20a01SMasahiro Yamada
usage(void)42478a20a01SMasahiro Yamada static void usage(void)
42578a20a01SMasahiro Yamada {
42678a20a01SMasahiro Yamada die("\n"
42778a20a01SMasahiro Yamada "Usage: %s [options] <filename>\n"
42878a20a01SMasahiro Yamada "\n"
42978a20a01SMasahiro Yamada "Valid options:\n"
43078a20a01SMasahiro Yamada " -h : display this usage information\n"
43178a20a01SMasahiro Yamada " -n <name> : specify logo name (default: linux_logo)\n"
43278a20a01SMasahiro Yamada " -o <output> : output to file <output> instead of stdout\n"
43378a20a01SMasahiro Yamada " -t <type> : specify logo type, one of\n"
43478a20a01SMasahiro Yamada " mono : monochrome black/white\n"
43578a20a01SMasahiro Yamada " vga16 : 16 colors VGA text palette\n"
43678a20a01SMasahiro Yamada " clut224 : 224 colors (default)\n"
43778a20a01SMasahiro Yamada " gray256 : 256 levels grayscale\n"
43878a20a01SMasahiro Yamada "\n", programname);
43978a20a01SMasahiro Yamada }
44078a20a01SMasahiro Yamada
main(int argc,char * argv[])44178a20a01SMasahiro Yamada int main(int argc, char *argv[])
44278a20a01SMasahiro Yamada {
44378a20a01SMasahiro Yamada int opt;
44478a20a01SMasahiro Yamada
44578a20a01SMasahiro Yamada programname = argv[0];
44678a20a01SMasahiro Yamada
44778a20a01SMasahiro Yamada opterr = 0;
44878a20a01SMasahiro Yamada while (1) {
44978a20a01SMasahiro Yamada opt = getopt(argc, argv, "hn:o:t:");
45078a20a01SMasahiro Yamada if (opt == -1)
45178a20a01SMasahiro Yamada break;
45278a20a01SMasahiro Yamada
45378a20a01SMasahiro Yamada switch (opt) {
45478a20a01SMasahiro Yamada case 'h':
45578a20a01SMasahiro Yamada usage();
45678a20a01SMasahiro Yamada break;
45778a20a01SMasahiro Yamada
45878a20a01SMasahiro Yamada case 'n':
45978a20a01SMasahiro Yamada logoname = optarg;
46078a20a01SMasahiro Yamada break;
46178a20a01SMasahiro Yamada
46278a20a01SMasahiro Yamada case 'o':
46378a20a01SMasahiro Yamada outputname = optarg;
46478a20a01SMasahiro Yamada break;
46578a20a01SMasahiro Yamada
46678a20a01SMasahiro Yamada case 't':
46778a20a01SMasahiro Yamada if (!strcmp(optarg, "mono"))
46878a20a01SMasahiro Yamada logo_type = LINUX_LOGO_MONO;
46978a20a01SMasahiro Yamada else if (!strcmp(optarg, "vga16"))
47078a20a01SMasahiro Yamada logo_type = LINUX_LOGO_VGA16;
47178a20a01SMasahiro Yamada else if (!strcmp(optarg, "clut224"))
47278a20a01SMasahiro Yamada logo_type = LINUX_LOGO_CLUT224;
47378a20a01SMasahiro Yamada else if (!strcmp(optarg, "gray256"))
47478a20a01SMasahiro Yamada logo_type = LINUX_LOGO_GRAY256;
47578a20a01SMasahiro Yamada else
47678a20a01SMasahiro Yamada usage();
47778a20a01SMasahiro Yamada break;
47878a20a01SMasahiro Yamada
47978a20a01SMasahiro Yamada default:
48078a20a01SMasahiro Yamada usage();
48178a20a01SMasahiro Yamada break;
48278a20a01SMasahiro Yamada }
48378a20a01SMasahiro Yamada }
48478a20a01SMasahiro Yamada if (optind != argc-1)
48578a20a01SMasahiro Yamada usage();
48678a20a01SMasahiro Yamada
48778a20a01SMasahiro Yamada filename = argv[optind];
48878a20a01SMasahiro Yamada
48978a20a01SMasahiro Yamada read_image();
49078a20a01SMasahiro Yamada switch (logo_type) {
49178a20a01SMasahiro Yamada case LINUX_LOGO_MONO:
49278a20a01SMasahiro Yamada write_logo_mono();
49378a20a01SMasahiro Yamada break;
49478a20a01SMasahiro Yamada
49578a20a01SMasahiro Yamada case LINUX_LOGO_VGA16:
49678a20a01SMasahiro Yamada write_logo_vga16();
49778a20a01SMasahiro Yamada break;
49878a20a01SMasahiro Yamada
49978a20a01SMasahiro Yamada case LINUX_LOGO_CLUT224:
50078a20a01SMasahiro Yamada write_logo_clut224();
50178a20a01SMasahiro Yamada break;
50278a20a01SMasahiro Yamada
50378a20a01SMasahiro Yamada case LINUX_LOGO_GRAY256:
50478a20a01SMasahiro Yamada write_logo_gray256();
50578a20a01SMasahiro Yamada break;
50678a20a01SMasahiro Yamada }
50778a20a01SMasahiro Yamada exit(0);
50878a20a01SMasahiro Yamada }
509