diff -Naur linux-2.5.61-fbdev/drivers/video/cfbimgblt.c linux-2.5.61-ad/drivers/video/cfbimgblt.c --- linux-2.5.61-fbdev/drivers/video/cfbimgblt.c 2003-02-16 00:55:52.000000000 +0000 +++ linux-2.5.61-ad/drivers/video/cfbimgblt.c 2003-02-16 03:53:39.000000000 +0000 @@ -113,7 +113,7 @@ int i, n, bpp = p->var.bits_per_pixel; unsigned long null_bits = BITS_PER_LONG - bpp; u32 *palette = (u32 *) p->pseudo_palette; - u8 *src = image->data; + u8 *src = (u8 *) image->data; dst2 = (unsigned long *) dst1; for (i = image->height; i--; ) { @@ -173,7 +173,7 @@ unsigned long *dst, *dst2, val, pitch = p->fix.line_length; unsigned long null_bits = BITS_PER_LONG - bpp; unsigned long spitch = (image->width+7)/8; - u8 *src = image->data, *s; + const char *src = image->data, *s; unsigned long i, j, l; dst2 = (unsigned long *) dst1; @@ -246,7 +246,7 @@ u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 ppw = BITS_PER_LONG/bpp, spitch = (image->width + 7)/8; u32 bit_mask, end_mask, eorx, shift; - char *s = image->data, *src; + const char *s = image->data, *src; unsigned long *dst; u32 *tab = NULL; int i, j, k; @@ -328,7 +328,7 @@ if (p->fbops->fb_sync) p->fbops->fb_sync(p); - if (image->depth == 1) { + if (image->depth == 0) { if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR) { fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.c linux-2.5.61-ad/drivers/video/console/fbcon.c --- linux-2.5.61-fbdev/drivers/video/console/fbcon.c 2003-02-16 00:55:52.000000000 +0000 +++ linux-2.5.61-ad/drivers/video/console/fbcon.c 2003-02-16 03:53:21.000000000 +0000 @@ -555,7 +555,7 @@ cursor.image.height = height; cursor.image.dx = xx * width; cursor.image.dy = yy * height; - cursor.image.depth = 1; + cursor.image.depth = 0; cursor.image.data = image; cursor.image.bg_color = bgcolor; cursor.image.fg_color = fgcolor; @@ -945,6 +945,7 @@ int cnt; int step; + logo_height = fb_prepare_logo(info); logo_lines = (logo_height + vc->vc_font.height - 1) / vc->vc_font.height; q = (unsigned short *) (vc->vc_origin + @@ -1942,7 +1943,7 @@ if (logo_shown == -2) { logo_shown = fg_console; /* This is protected above by initmem_freed */ - logo_height = fb_show_logo(info); + fb_show_logo(info); update_region(fg_console, vc->vc_origin + vc->vc_size_row * vc->vc_top, vc->vc_size_row * (vc->vc_bottom - diff -Naur linux-2.5.61-fbdev/drivers/video/fbmem.c linux-2.5.61-ad/drivers/video/fbmem.c --- linux-2.5.61-fbdev/drivers/video/fbmem.c 2003-02-16 00:55:52.000000000 +0000 +++ linux-2.5.61-ad/drivers/video/fbmem.c 2003-02-16 03:53:21.000000000 +0000 @@ -511,101 +511,121 @@ * We isolate each bit and expand each into a byte. The "needs_logo" flag will * be set to 1. */ -int fb_show_logo(struct fb_info *info) -{ - unsigned char *fb = info->screen_base, *logo_new = NULL; - u32 *palette = NULL, *saved_pseudo_palette = NULL; - int needs_directpalette = 0; - int needs_truepalette = 0; - int needs_cmapreset = 0; - struct fb_image image; - const struct linux_logo *logo = 0; +static struct logo_data { + int depth; + int needs_logo; + int needs_directpalette; + int needs_truepalette; + int needs_cmapreset; int type; - int needs_logo = 0; - int done = 0, x; - - /* Return if the frame buffer is not mapped */ - if (!fb || !info->fbops->fb_imageblit) - return 0; - - image.depth = info->var.bits_per_pixel; + const struct linux_logo *logo; +} fb_logo; - /* reasonable default */ - if (image.depth >= 8) - type = LINUX_LOGO_CLUT224; - else if (image.depth >= 4) - type = LINUX_LOGO_VGA16; - else - type = LINUX_LOGO_MONO; - - /* Return if no suitable logo was found */ - logo = fb_find_logo(type); - if (!logo || logo->height > info->var.yres) - return 0; +int fb_prepare_logo(struct fb_info *info) +{ + memset(&fb_logo, 0, sizeof(struct logo_data)); - image.data = logo->data; + fb_logo.depth = info->var.bits_per_pixel; switch (info->fix.visual) { case FB_VISUAL_TRUECOLOR: - needs_truepalette = 1; - if (image.depth >= 4 && image.depth <= 8) - needs_logo = 4; - else if (image.depth < 4) - needs_logo = 1; + if (fb_logo.depth >= 8) { + fb_logo.needs_truepalette = 1; + fb_logo.needs_logo = 8; + } else if (fb_logo.depth >= 4) + fb_logo.needs_logo = 4; + else + fb_logo.needs_logo = 1; break; case FB_VISUAL_DIRECTCOLOR: - if (image.depth >= 24) { - needs_directpalette = 1; - needs_cmapreset = 1; + if (fb_logo.depth >= 24) { + fb_logo.needs_directpalette = 1; + fb_logo.needs_cmapreset = 1; + fb_logo.needs_logo = 8; } /* 16 colors */ - else if (image.depth >= 16) - needs_logo = 4; + else if (fb_logo.depth >= 16) + fb_logo.needs_logo = 4; /* 2 colors */ else - needs_logo = 1; + fb_logo.needs_logo = 1; break; case FB_VISUAL_MONO01: /* reversed 0 = fg, 1 = bg */ - needs_logo = ~1; + fb_logo.needs_logo = ~1; break; case FB_VISUAL_MONO10: - needs_logo = 1; + fb_logo.needs_logo = 1; break; case FB_VISUAL_PSEUDOCOLOR: default: - if (image.depth >= 8) - needs_cmapreset = 1; + if (fb_logo.depth >= 8) { + fb_logo.needs_cmapreset = 1; + fb_logo.needs_logo = 8; + } /* fall through */ case FB_VISUAL_STATIC_PSEUDOCOLOR: /* 16 colors */ - if (image.depth >= 4 && image.depth < 8) - needs_logo = 4; + if (fb_logo.depth >= 4 && fb_logo.depth < 8) + fb_logo.needs_logo = 4; /* 2 colors */ - else if (image.depth < 4) - needs_logo = 1; + else if (fb_logo.depth < 4) + fb_logo.needs_logo = 1; break; } - if (needs_cmapreset) - fb_set_logocmap(info, logo); + if (fb_logo.needs_logo >= 8) + fb_logo.type = LINUX_LOGO_CLUT224; + else if (fb_logo.needs_logo >= 4) + fb_logo.type = LINUX_LOGO_VGA16; + else + fb_logo.type = LINUX_LOGO_MONO; + + /* Return if no suitable logo was found */ + fb_logo.logo = fb_find_logo(fb_logo.type); + if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { + fb_logo.logo = NULL; + return 0; + } + return fb_logo.logo->height; +} + +int fb_show_logo(struct fb_info *info) +{ + unsigned char *fb = info->screen_base, *logo_new = NULL; + u32 *palette = NULL, *saved_pseudo_palette = NULL; + struct fb_image image; + int x; + + /* Return if the frame buffer is not mapped */ + if (!fb || !info->fbops->fb_imageblit || + fb_logo.logo == NULL) + return 0; - if (needs_truepalette || needs_directpalette) { + image.depth = fb_logo.depth; + image.data = fb_logo.logo->data; + + if (fb_logo.needs_cmapreset) + fb_set_logocmap(info, fb_logo.logo); + + if (fb_logo.needs_truepalette || + fb_logo.needs_directpalette) { palette = kmalloc(256 * 4, GFP_KERNEL); if (palette == NULL) return 0; - if (needs_truepalette) - fb_set_logo_truepalette(info, logo, palette); + if (fb_logo.needs_truepalette) + fb_set_logo_truepalette(info, fb_logo.logo, palette); else - fb_set_logo_directpalette(info, logo, palette); + fb_set_logo_directpalette(info, fb_logo.logo, palette); saved_pseudo_palette = info->pseudo_palette; info->pseudo_palette = palette; } - if (needs_logo) { - logo_new = kmalloc(logo->width * logo->height, GFP_KERNEL); + if (fb_logo.needs_logo != 8) { + logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height, + GFP_KERNEL); if (logo_new == NULL) { if (palette) kfree(palette); @@ -615,27 +635,26 @@ } image.data = logo_new; - fb_set_logo(info, logo, logo_new, needs_logo); + fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.needs_logo); } - image.width = logo->width; - image.height = logo->height; + image.width = fb_logo.logo->width; + image.height = fb_logo.logo->height; image.dy = 0; - for (x = 0; x < num_online_cpus() * (logo->width + 8) && - x <= info->var.xres-logo->width; x += (logo->width + 8)) { + for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && + x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { image.dx = x; info->fbops->fb_imageblit(info, &image); - done = 1; } - + if (palette != NULL) kfree(palette); if (saved_pseudo_palette != NULL) info->pseudo_palette = saved_pseudo_palette; if (logo_new != NULL) kfree(logo_new); - return logo->height; + return fb_logo.logo->height; } static int fbmem_read_proc(char *buf, char **start, off_t offset, @@ -1212,6 +1231,7 @@ EXPORT_SYMBOL(unregister_framebuffer); EXPORT_SYMBOL(num_registered_fb); EXPORT_SYMBOL(registered_fb); +EXPORT_SYMBOL(fb_prepare_logo); EXPORT_SYMBOL(fb_show_logo); EXPORT_SYMBOL(fb_set_var); EXPORT_SYMBOL(fb_blank); diff -Naur linux-2.5.61-fbdev/drivers/video/tdfxfb.c linux-2.5.61-ad/drivers/video/tdfxfb.c --- linux-2.5.61-fbdev/drivers/video/tdfxfb.c 2003-02-16 00:55:53.000000000 +0000 +++ linux-2.5.61-ad/drivers/video/tdfxfb.c 2003-02-16 03:53:50.000000000 +0000 @@ -939,7 +939,7 @@ u8 *chardata = (u8 *) pixmap->data; u32 srcfmt; - if (pixmap->depth != 1) { + if (pixmap->depth != 0) { //banshee_make_room(par, 6 + ((size + 3) >> 2)); //srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000; cfb_imageblit(info, pixmap); diff -Naur linux-2.5.61-fbdev/drivers/video/tgafb.c linux-2.5.61-ad/drivers/video/tgafb.c --- linux-2.5.61-fbdev/drivers/video/tgafb.c 2003-02-16 00:48:32.000000000 +0000 +++ linux-2.5.61-ad/drivers/video/tgafb.c 2003-02-16 03:53:45.000000000 +0000 @@ -585,7 +585,7 @@ can do better than the generic code. */ /* ??? There is a DMA write mode; I wonder if that could be made to pull the data from the image buffer... */ - if (image->depth > 1) { + if (image->depth > 0) { cfb_imageblit(info, image); return; } diff -Naur linux-2.5.61-fbdev/include/linux/fb.h linux-2.5.61-ad/include/linux/fb.h --- linux-2.5.61-fbdev/include/linux/fb.h 2003-02-16 00:55:53.000000000 +0000 +++ linux-2.5.61-ad/include/linux/fb.h 2003-02-16 03:53:21.000000000 +0000 @@ -462,6 +462,7 @@ /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); +extern int fb_prepare_logo(struct fb_info *fb_info); extern int fb_show_logo(struct fb_info *fb_info); extern struct fb_info *registered_fb[FB_MAX]; extern int num_registered_fb; diff -Naur linux-2.5.61-fbdev/scripts/Makefile linux-2.5.61-ad/scripts/Makefile --- linux-2.5.61-fbdev/scripts/Makefile 2003-02-16 02:10:09.000000000 +0000 +++ linux-2.5.61-ad/scripts/Makefile 2003-02-16 03:53:21.000000000 +0000 @@ -8,7 +8,7 @@ # docproc: Preprocess .tmpl file in order to generate .sgml documentation # conmakehash: Create arrays for initializing the kernel console tables -host-progs := fixdep split-include conmakehash docproc kallsyms +host-progs := fixdep split-include conmakehash docproc kallsyms pnmtologo build-targets := $(host-progs) # Let clean descend into subdirs diff -Naur linux-2.5.61-fbdev/scripts/pnmtologo.c linux-2.5.61-ad/scripts/pnmtologo.c --- linux-2.5.61-fbdev/scripts/pnmtologo.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.5.61-ad/scripts/pnmtologo.c 2003-02-16 03:53:21.000000000 +0000 @@ -0,0 +1,498 @@ + +/* + * Convert a logo in ASCII PNM format to C source suitable for inclusion in + * the Linux kernel + * + * (C) Copyright 2001-2003 by Geert Uytterhoeven + * + * -------------------------------------------------------------------------- + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of the Linux + * distribution for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + +static const char *programname; +static const char *filename; +static const char *logoname = "linux_logo"; +static const char *outputname; +static FILE *out; + + +#define LINUX_LOGO_MONO 1 /* monochrome black/white */ +#define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */ +#define LINUX_LOGO_CLUT224 3 /* 224 colors */ +#define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */ + +static const char *logo_types[LINUX_LOGO_GRAY256+1] = { + [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO", + [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16", + [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224", + [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256" +}; + +#define MAX_LINUX_LOGO_COLORS 224 + +struct color { + unsigned char red; + unsigned char green; + unsigned char blue; +}; + +static const struct color clut_vga16[16] = { + { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0xaa }, + { 0x00, 0xaa, 0x00 }, + { 0x00, 0xaa, 0xaa }, + { 0xaa, 0x00, 0x00 }, + { 0xaa, 0x00, 0xaa }, + { 0xaa, 0x55, 0x00 }, + { 0xaa, 0xaa, 0xaa }, + { 0x55, 0x55, 0x55 }, + { 0x55, 0x55, 0xff }, + { 0x55, 0xff, 0x55 }, + { 0x55, 0xff, 0xff }, + { 0xff, 0x55, 0x55 }, + { 0xff, 0x55, 0xff }, + { 0xff, 0xff, 0x55 }, + { 0xff, 0xff, 0xff }, +}; + + +static int logo_type = LINUX_LOGO_CLUT224; +static unsigned int logo_width; +static unsigned int logo_height; +static struct color **logo_data; +static struct color logo_clut[MAX_LINUX_LOGO_COLORS]; +static unsigned int logo_clutsize = 0; + +static void die(const char *fmt, ...) + __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2))); +static void usage(void) __attribute ((noreturn)); + + +static unsigned int 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'; + c = fgetc(fp); + if (c == EOF) + die("%s: end of file\n", filename); + } + return val; +} + +static void read_image(void) +{ + FILE *fp; + int i, j, magic; + unsigned int 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.\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 */ + 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 = 255*get_number(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 = 255*get_number(fp)/maxval; + logo_data[i][j].green = 255*get_number(fp)/maxval; + logo_data[i][j].blue = 255*get_number(fp)/maxval; + } + break; + } + + /* close file */ + fclose(fp); +} + +static inline int is_black(struct color c) +{ + return c.red == 0 && c.green == 0 && c.blue == 0; +} + +static inline int is_white(struct color c) +{ + return c.red == 255 && c.green == 255 && c.blue == 255; +} + +static inline int is_gray(struct color c) +{ + return c.red == c.green && c.red == c.blue; +} + +static inline int is_equal(struct color c1, struct color c2) +{ + return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue; +} + +static void write_header(void) +{ + /* open logo file */ + if (outputname) { + out = fopen(outputname, "w"); + if (!out) + die("Cannot create file %s: %s\n", outputname, strerror(errno)); + } else { + out = stdout; + } + + fputs("/*\n", out); + fputs(" * DO NOT EDIT THIS FILE!\n", out); + fputs(" *\n", out); + fprintf(out, " * It was automatically generated from %s\n", filename); + fputs(" *\n", out); + fprintf(out, " * Linux logo %s\n", logoname); + fputs(" */\n\n", out); + fputs("#include \n\n", out); + fprintf(out, "static const unsigned char %s_data[] __initdata = {\n", + logoname); +} + +static void write_footer(void) +{ + fputs("\n};\n\n", out); + fprintf(out, "const struct linux_logo %s __initdata = {\n", logoname); + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]); + fprintf(out, " .width\t= %d,\n", logo_width); + fprintf(out, " .height\t= %d,\n", logo_height); + if (logo_type == LINUX_LOGO_CLUT224) { + fprintf(out, " .clutsize\t= %d,\n", logo_clutsize); + fprintf(out, " .clut\t= %s_clut,\n", logoname); + } + fprintf(out, " .data\t= %s_data\n", logoname); + fputs("};\n\n", out); + + /* close logo file */ + if (outputname) + fclose(out); +} + +static int write_hex_cnt = 0; + +static void write_hex(unsigned char byte) +{ + if (write_hex_cnt % 12) + fprintf(out, ", 0x%02x", byte); + else if (write_hex_cnt) + fprintf(out, ",\n\t0x%02x", byte); + else + fprintf(out, "\t0x%02x", byte); + write_hex_cnt++; +} + +static void write_logo_mono(void) +{ + int i, j; + unsigned char 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(); +} + +static void write_logo_vga16(void) +{ + int i, j, k; + unsigned char 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"); + } + + /* 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(); +} + +static void write_logo_clut224(void) +{ + int 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", + 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[] __initdata = {\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(); +} + +static void write_logo_gray256(void) +{ + int 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(); +} + +static void die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + exit(1); +} + +static void usage(void) +{ + die("\n" + "Usage: %s [options] \n" + "\n" + "Valid options:\n" + " -h : display this usage information\n" + " -n : specify logo name (default: linux_logo)\n" + " -o : output to file instead of stdout\n" + " -t : specify logo type, one of\n" + " mono : monochrome black/white\n" + " vga16 : 16 colors VGA text palette\n" + " clut224 : 224 colors (default)\n" + " gray256 : 256 levels grayscale\n" + "\n", programname); +} + +int main(int argc, char *argv[]) +{ + int opt; + + programname = argv[0]; + + opterr = 0; + while (1) { + opt = getopt(argc, argv, "hn:o:t:"); + if (opt == -1) + break; + + switch (opt) { + case 'h': + usage(); + break; + + case 'n': + logoname = optarg; + break; + + case 'o': + outputname = optarg; + break; + + case 't': + if (!strcmp(optarg, "mono")) + logo_type = LINUX_LOGO_MONO; + else if (!strcmp(optarg, "vga16")) + logo_type = LINUX_LOGO_VGA16; + else if (!strcmp(optarg, "clut224")) + logo_type = LINUX_LOGO_CLUT224; + else if (!strcmp(optarg, "gray256")) + logo_type = LINUX_LOGO_GRAY256; + else + usage(); + break; + + default: + usage(); + break; + } + } + if (optind != argc-1) + usage(); + + filename = argv[optind]; + + read_image(); + switch (logo_type) { + case LINUX_LOGO_MONO: + write_logo_mono(); + break; + + case LINUX_LOGO_VGA16: + write_logo_vga16(); + break; + + case LINUX_LOGO_CLUT224: + write_logo_clut224(); + break; + + case LINUX_LOGO_GRAY256: + write_logo_gray256(); + break; + } + exit(0); +} +