// SPDX-License-Identifier: GPL-2.0-only /* * Convert a logo in ASCII PNM format to C source suitable for inclusion in * the Linux kernel * * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
*/
staticunsignedint get_number(FILE *fp)
{ int c, val;
/* Skip leading whitespace */ do {
c = fgetc(fp); if (c == EOF)
die("%s: end of file\n", filename); if (c == '#') { /* Ignore comments 'till end of line */ do {
c = fgetc(fp); if (c == EOF)
die("%s: end of file\n", filename);
} while (c != '\n');
}
} while (isspace(c));
/* Parse decimal number */
val = 0; while (isdigit(c)) {
val = 10*val+c-'0'; /* some PBM are 'broken'; GiMP for example exports a PBM without space * between the digits. This is Ok cause we know a PBM can only have a '1' * or a '0' for the digit.
*/ if (is_plain_pbm) break;
c = fgetc(fp); if (c == EOF)
die("%s: end of file\n", filename);
} return val;
}
staticunsignedint get_number255(FILE *fp, unsignedint maxval)
{ unsignedint val = get_number(fp);
return (255*val+maxval/2)/maxval;
}
staticvoid read_image(void)
{
FILE *fp; unsignedint i, j; int magic; unsignedint maxval;
/* open image file */
fp = fopen(filename, "r"); if (!fp)
die("Cannot open file %s: %s\n", filename, strerror(errno));
/* check file type and read file header */
magic = fgetc(fp); if (magic != 'P')
die("%s is not a PNM file\n", filename);
magic = fgetc(fp); switch (magic) { case'1': case'2': case'3': /* Plain PBM/PGM/PPM */ break;
case'4': case'5': case'6': /* Binary PBM/PGM/PPM */
die("%s: Binary PNM is not supported\n" "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
default:
die("%s is not a PNM file\n", filename);
}
logo_width = get_number(fp);
logo_height = get_number(fp);
/* allocate image data */
logo_data = (struct color **)malloc(logo_height*sizeof(struct color *)); if (!logo_data)
die("%s\n", strerror(errno)); for (i = 0; i < logo_height; i++) {
logo_data[i] = malloc(logo_width*sizeof(struct color)); if (!logo_data[i])
die("%s\n", strerror(errno));
}
/* read image data */ switch (magic) { case'1': /* Plain PBM */
is_plain_pbm = 1; for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++)
logo_data[i][j].red = logo_data[i][j].green =
logo_data[i][j].blue = 255*(1-get_number(fp)); break;
case'2': /* Plain PGM */
maxval = get_number(fp); for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++)
logo_data[i][j].red = logo_data[i][j].green =
logo_data[i][j].blue = get_number255(fp, maxval); break;
case'3': /* Plain PPM */
maxval = get_number(fp); for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) {
logo_data[i][j].red = get_number255(fp, maxval);
logo_data[i][j].green = get_number255(fp, maxval);
logo_data[i][j].blue = get_number255(fp, maxval);
} break;
}
/* close file */
fclose(fp);
}
staticinlineint is_black(struct color c)
{ return c.red == 0 && c.green == 0 && c.blue == 0;
}
staticinlineint is_white(struct color c)
{ return c.red == 255 && c.green == 255 && c.blue == 255;
}
staticinlineint is_gray(struct color c)
{ return c.red == c.green && c.red == c.blue;
}
staticvoid write_logo_mono(void)
{ unsignedint i, j; unsignedchar val, bit;
/* validate image */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
die("Image must be monochrome\n");
/* write file header */
write_header();
/* write logo data */ for (i = 0; i < logo_height; i++) { for (j = 0; j < logo_width;) { for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1) if (logo_data[i][j].red)
val |= bit;
write_hex(val);
}
}
/* write logo structure and file footer */
write_footer();
}
staticvoid write_logo_vga16(void)
{ unsignedint i, j, k; unsignedchar val;
/* validate image */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) { for (k = 0; k < 16; k++) if (is_equal(logo_data[i][j], clut_vga16[k])) break; if (k == 16)
die("Image must use the 16 console colors only\n" "Use ppmquant(1) -map clut_vga16.ppm to reduce the number " "of colors\n");
}
/* write file header */
write_header();
/* write logo data */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) { for (k = 0; k < 16; k++) if (is_equal(logo_data[i][j], clut_vga16[k])) break;
val = k<<4; if (++j < logo_width) { for (k = 0; k < 16; k++) if (is_equal(logo_data[i][j], clut_vga16[k])) break;
val |= k;
}
write_hex(val);
}
/* write logo structure and file footer */
write_footer();
}
staticvoid write_logo_clut224(void)
{ unsignedint i, j, k;
/* validate image */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) { for (k = 0; k < logo_clutsize; k++) if (is_equal(logo_data[i][j], logo_clut[k])) break; if (k == logo_clutsize) { if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
die("Image has more than %d colors\n" "Use ppmquant(1) to reduce the number of colors\n",
MAX_LINUX_LOGO_COLORS);
logo_clut[logo_clutsize++] = logo_data[i][j];
}
}
/* write file header */
write_header();
/* write logo data */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) { for (k = 0; k < logo_clutsize; k++) if (is_equal(logo_data[i][j], logo_clut[k])) break;
write_hex(k+32);
}
fputs("\n};\n\n", out);
/* write logo clut */
fprintf(out, "static const unsigned char %s_clut[] __initconst = {\n",
logoname);
write_hex_cnt = 0; for (i = 0; i < logo_clutsize; i++) {
write_hex(logo_clut[i].red);
write_hex(logo_clut[i].green);
write_hex(logo_clut[i].blue);
}
/* write logo structure and file footer */
write_footer();
}
staticvoid write_logo_gray256(void)
{ unsignedint i, j;
/* validate image */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++) if (!is_gray(logo_data[i][j]))
die("Image must be grayscale\n");
/* write file header */
write_header();
/* write logo data */ for (i = 0; i < logo_height; i++) for (j = 0; j < logo_width; j++)
write_hex(logo_data[i][j].red);
/* write logo structure and file footer */
write_footer();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.