new add bmp logo for factorytool
authorywj <ywj@rockchip.com>
Thu, 16 Aug 2012 06:33:38 +0000 (14:33 +0800)
committerywj <ywj@rockchip.com>
Thu, 16 Aug 2012 06:33:38 +0000 (14:33 +0800)
drivers/video/logo/Kconfig
drivers/video/logo/Makefile
drivers/video/logo/logo.c
drivers/video/rockchip/rk_fb.c
include/linux/linux_logo.h
scripts/Makefile
scripts/bmptologo.c [new file with mode: 0644]

index 3abc2bca9f8fb609e4396ee30a08c065693888d9..a783e87086c26deeba4c89f9109e51fb0fbdc5bc 100755 (executable)
@@ -27,6 +27,10 @@ config LOGO_LINUX_CLUT224
        bool "Standard 224-color Linux logo"
        default y
 
+config LOGO_LINUX_BMP
+       bool "bmp logo"
+       default y
+
 config LOGO_BLACKFIN_VGA16
        bool "16-colour Blackfin Processor Linux logo"
        depends on BLACKFIN
index 3f68c8bc72b2fbe15ccff02167aac0f56428b47c..86849cd3262e256d7683efbd8ab0916d855a7ed0 100755 (executable)
@@ -16,6 +16,7 @@ obj-$(CONFIG_LOGO_SUPERH_VGA16)               += logo_superh_vga16.o
 obj-$(CONFIG_LOGO_SUPERH_CLUT224)      += logo_superh_clut224.o
 obj-$(CONFIG_LOGO_M32R_CLUT224)                += logo_m32r_clut224.o
 obj-$(CONFIG_LOGO_G3_CLUT224)          += logo_g3_clut224.o
+obj-$(CONFIG_LOGO_LINUX_BMP)           += logo_bmp.o
 
 
 obj-$(CONFIG_LOGO_CHARGER_CLUT224)         += logo_charger00_clut224.o logo_charger01_clut224.o logo_charger02_clut224.o logo_charger03_clut224.o logo_charger04_clut224.o logo_charger05_clut224.o logo_charger06_clut224.o logo_charger07_clut224.o logo_charger08_clut224.o 
@@ -41,6 +42,9 @@ extra-y += $(call logo-cfiles,_clut224,ppm)
 # Gray 256
 extra-y += $(call logo-cfiles,_gray256,pgm)
 
+extra-y += $(call logo-cfiles,_bmp,bmp)
+
+bmptologo := scripts/bmptologo
 pnmtologo := scripts/pnmtologo
 
 # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..."
@@ -49,6 +53,11 @@ quiet_cmd_logo = LOGO    $@
                        -t $(patsubst $*_%,%,$(notdir $(basename $<))) \
                        -n $(notdir $(basename $<)) -o $@ $<
 
+quiet_cmd_bmplogo = LOGO    $@
+       cmd_bmplogo = $(bmptologo) \
+                       -t $(patsubst $*_%,%,$(notdir $(basename $<))) \
+                       -n $(notdir $(basename $<)) -o $@ $<
+
 $(obj)/%_mono.c: $(src)/%_mono.pbm $(pnmtologo) FORCE
        $(call if_changed,logo)
 
@@ -61,5 +70,8 @@ $(obj)/%_clut224.c: $(src)/%_clut224.ppm $(pnmtologo) FORCE
 $(obj)/%_gray256.c: $(src)/%_gray256.pgm $(pnmtologo) FORCE
        $(call if_changed,logo)
 
+$(obj)/%_bmp.c: $(src)/%_bmp.bmp $(bmptologo) FORCE
+       $(call if_changed,bmplogo)
+
 # Files generated that shall be removed upon make clean
-clean-files := *.o *_mono.c *_vga16.c *_clut224.c *_gray256.c
+clean-files := *.o *_mono.c *_vga16.c *_clut224.c *_gray256.c *_bmp.c
index 32e998ff609be82f15038e39be7548fd2c7e6840..284c96d0d23ee08176d66834be075b1fa642e6bb 100644 (file)
@@ -120,12 +120,20 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
 #ifdef CONFIG_LOGO_CRUZ_CLUT224
                 logo = &logo_cruz_clut224;
 #endif
-       logo->width = ((logo->data[0] << 8) + logo->data[1]);
-        logo->height = ((logo->data[2] << 8) + logo->data[3]);
-        logo->clutsize = logo->clut[0];
-        logo->data += 4;
-        logo->clut += 1;
-
+               if (depth >= 24)
+               {
+                       #ifdef  CONFIG_LOGO_LINUX_BMP
+                       logo = &logo_bmp;       
+                       #endif  
+               }
+               else
+               {
+                       logo->width = ((logo->data[0] << 8) + logo->data[1]);
+                       logo->height = ((logo->data[2] << 8) + logo->data[3]);
+                       logo->clutsize = logo->clut[0];
+                       logo->data += 4;
+                       logo->clut += 1;
+               }
        }
        m_logo = logo;
        return m_logo;
index d526cdba2cd920c8edc90ee4b5c47f07550fb005..9e70bca3f1c1b6e57387fb6fa6f9a73d12b40e51 100644 (file)
@@ -31,6 +31,7 @@
 #include<linux/rk_fb.h>
 #include <plat/ipp.h>
 #include "hdmi/rk_hdmi.h"
+#include <linux/linux_logo.h>
 
 
 
@@ -377,6 +378,8 @@ static int rk_fb_set_par(struct fb_info *info)
        u32 yvir = var->yres_virtual;
        u8 data_format = var->nonstd&0xff;
        var->pixclock = dev_drv->pixclock;
+       
+       printk("-----data_format=%d\n",data_format);
        #if defined(CONFIG_HDMI_RK30)
                #if defined(CONFIG_DUAL_DISP_IN_KERNEL)
                        if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
@@ -564,7 +567,11 @@ static struct fb_var_screeninfo def_var = {
     .green  = {5,6,0},
     .blue   = {0,5,0},
     .transp = {0,0,0}, 
+    #ifdef  CONFIG_LOGO_LINUX_BMP
+       .nonstd      = HAL_PIXEL_FORMAT_RGBA_8888,
+       #else
     .nonstd      = HAL_PIXEL_FORMAT_RGB_565,   //(ypos<<20+xpos<<8+format) format
+    #endif
     .grayscale   = 0,  //(ysize<<20+xsize<<8)
     .activate    = FB_ACTIVATE_NOW,
     .accel_flags = 0,
@@ -891,7 +898,21 @@ static int init_lcdc_device_driver(struct rk_lcdc_device_driver *dev_drv,
        
        return 0;
 }
+static  struct linux_logo *logo = NULL;
+char  fb_prepare_bmp_logo(struct fb_info *info, int rotate) 
+{
+       logo = fb_find_logo(24);
+       if (logo == NULL)
+               printk("%s....%s..error\n",__FILE__,__FUNCTION__);
+       return 1;
+}
 
+void fb_show_bmp_logo(struct fb_info *info, int rotate)
+{
+       char *framebase = info->screen_base;
+       memcpy(framebase,logo->data,(logo->width)*(logo->height)*4);
+
+}
 int rk_fb_register(struct rk_lcdc_device_driver *dev_drv,
        struct rk_lcdc_device_driver *def_drv,int id)
 {
@@ -961,7 +982,12 @@ int rk_fb_register(struct rk_lcdc_device_driver *dev_drv,
         fbi->var.xres = fb_inf->lcdc_dev_drv[lcdc_id]->screen->x_res;
         fbi->var.yres = fb_inf->lcdc_dev_drv[lcdc_id]->screen->y_res;
        fbi->var.grayscale |= (fbi->var.xres<<8) + (fbi->var.yres<<20);
-        fbi->var.bits_per_pixel = 16;
+        //fbi->var.bits_per_pixel = 16;
+        #ifdef  CONFIG_LOGO_LINUX_BMP
+               fbi->var.bits_per_pixel = 32; 
+               #else
+                       fbi->var.bits_per_pixel = 16; 
+               #endif
         fbi->var.xres_virtual = fb_inf->lcdc_dev_drv[lcdc_id]->screen->x_res;
         fbi->var.yres_virtual = fb_inf->lcdc_dev_drv[lcdc_id]->screen->y_res;
         fbi->var.width = fb_inf->lcdc_dev_drv[lcdc_id]->screen->width;
@@ -994,12 +1020,21 @@ int rk_fb_register(struct rk_lcdc_device_driver *dev_drv,
     {
            fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_open(fb_inf->fb[fb_inf->num_fb-2],1);
            fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_set_par(fb_inf->fb[fb_inf->num_fb-2]);
-           if(fb_prepare_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR)) {
+               #ifdef  CONFIG_LOGO_LINUX_BMP
+               if(fb_prepare_bmp_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR)) {
+               /* Start display and show logo on boot */
+               fb_set_cmap(&fb_inf->fb[fb_inf->num_fb-2]->cmap, fb_inf->fb[fb_inf->num_fb-2]);
+               fb_show_bmp_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR);
+                       fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_pan_display(&(fb_inf->fb[fb_inf->num_fb-2]->var), fb_inf->fb[fb_inf->num_fb-2]);
+           }
+               #else
+               if(fb_prepare_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR)) {
                /* Start display and show logo on boot */
                fb_set_cmap(&fb_inf->fb[fb_inf->num_fb-2]->cmap, fb_inf->fb[fb_inf->num_fb-2]);
                fb_show_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR);
-               fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_pan_display(&(fb_inf->fb[fb_inf->num_fb-2]->var), fb_inf->fb[fb_inf->num_fb-2]);
+                       fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_pan_display(&(fb_inf->fb[fb_inf->num_fb-2]->var), fb_inf->fb[fb_inf->num_fb-2]);
            }
+               #endif
     }
 #endif
        return 0;
index 0bc9cca1bbe95cdb94385072d5169189dd664af0..1ac3f1ebcf28dc293e72747ba64a4e169d1cce18 100644 (file)
@@ -21,6 +21,7 @@
 #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 */
+#define LINUX_LOGO_bmp      5  /* truecolours*/
 
 
 struct linux_logo {
@@ -48,6 +49,7 @@ extern const struct linux_logo logo_superh_clut224;
 extern const struct linux_logo logo_m32r_clut224;
 extern const struct linux_logo logo_spe_clut224;
 extern const struct linux_logo logo_g3_clut224;
+extern const struct linux_logo logo_bmp;
 
 
 extern const struct linux_logo *fb_find_logo(int depth);
index df7678febf277b119cbffc4d3b6f230974fb18f0..905d59e06bc8fd27b66c1d1ccdecb812efd93abd 100644 (file)
@@ -10,6 +10,7 @@
 
 hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
 hostprogs-$(CONFIG_LOGO)         += pnmtologo
+hostprogs-y        += bmptologo
 hostprogs-$(CONFIG_VT)           += conmakehash
 hostprogs-$(CONFIG_IKCONFIG)     += bin2c
 hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
diff --git a/scripts/bmptologo.c b/scripts/bmptologo.c
new file mode 100644 (file)
index 0000000..fdac7cf
--- /dev/null
@@ -0,0 +1,494 @@
+
+/*
+ *  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>
+ *
+ *  --------------------------------------------------------------------------
+ *
+ *  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 <ctype.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+static const char *programname;
+static const char *filename;
+static const char *logoname = "linux_logo";
+static const char *outputname;
+static FILE *out;
+
+//#define debug 0
+#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 */
+#define LINUX_LOGO_bmp         5       /* truecolours*/
+
+static const char *logo_types[LINUX_LOGO_bmp+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",
+    [LINUX_LOGO_bmp] = "LINUX_LOGO_bmp"
+};
+
+#define MAX_LINUX_LOGO_COLORS  224
+
+struct color {
+    char blue;
+    char green;
+    char red;
+};
+
+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 },
+};
+
+unsigned char data_name[] = {
+       0x6C, 0x6F, 0x67,
+       0x6F, 0x5F, 0x52,
+       0x4B, 0x6C, 0x6F,
+       0x67, 0x6F, 0x5F,
+       0x64, 0x61, 0x74,
+       0x61
+};
+
+unsigned char clut_name[] = {
+       0x62, 0x6D, 0x70,
+       0x6C, 0x6F, 0x67,
+       0x6F, 0x5F, 0x52,
+       0x4B, 0x6C, 0x6F,
+       0x67, 0x6F, 0x5F,
+       0x63, 0x6C, 0x75,
+       0x74, 0x00
+};
+
+static int logo_type = LINUX_LOGO_CLUT224;
+static unsigned long logo_width;
+static unsigned long logo_height;
+static unsigned long data_long;
+static unsigned long data_start;
+static unsigned char *logo_data;
+static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
+static unsigned int logo_clutsize;
+
+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 unsigned int get_number255(FILE *fp, unsigned int maxval)
+{
+    unsigned int val = get_number(fp);
+    return (255*val+maxval/2)/maxval;
+}
+
+static void read_image(void)
+{
+       FILE *fp;
+       unsigned long i;
+       struct stat s;
+       char j = 0;
+       int magic;
+       unsigned int maxval;
+       char read_buf[0x28];
+       long ret = 0;
+       unsigned char *data;
+       
+       /* open image file */
+       fp = open(filename, O_RDONLY);
+       if (!fp)
+               die("Cannot open file isll.. %s: %s\n", filename, strerror(errno));
+
+       if (fstat(fp, &s) < 0) {
+        die("Cannot stat file isll.. %s: %s\n", filename, strerror(errno));
+    }
+#if 0
+       ret = fread(read_buf,1,0x26,fp);
+       if (ret != 0x26)
+               die("read file %s: error read_buf=%ld\n", filename,ret);
+
+       logo_height = (read_buf[0x19]<<24) + (read_buf[0x18]<<16) +(read_buf[0x17]<<8) +(read_buf[0x16]);
+       logo_width  = (read_buf[0x15]<<24) + (read_buf[0x14]<<16) +(read_buf[0x13]<<8) +(read_buf[0x12]);
+       data_start = (read_buf[0x0d]<<24) + (read_buf[0x0c]<<16) +(read_buf[0x0b]<<8) +(read_buf[0x0a]);
+       data_long  = (read_buf[0x25]<<24) + (read_buf[0x24]<<16) +(read_buf[0x023]<<8) +(read_buf[0x22]);
+#endif 
+       /* allocate image data */
+       //logo_data = (char *)malloc(logo_height * logo_width * 3);
+       //data_long = logo_height * logo_width * 3;
+//#ifdef debug
+#if 0
+       die("%s..logo_height=%ld,logo_width=%ld,data_start=%ld,data_long=%ld,sizeof(struct color)=%d,  \
+               read_buf[0x17]=%d  read_buf[0x13]=%d\n\n",filename,logo_height,logo_width,data_start,  \
+               data_long,sizeof(struct color),read_buf[0x17],read_buf[0x13]);
+       if ((logo_width*logo_height*3) != data_long)
+               die("something is wront in scripts/bmptologo.c\n");
+
+#endif
+#if 0
+       fseek(fp,data_start,SEEK_SET);
+       ret = fread(logo_data,1,data_long,fp);
+       if (ret != data_long)
+               die("read file %s: error logo_data=%ld\n", filename,ret);
+#else
+    data = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fp, 0);
+    if (data == MAP_FAILED)
+        die("read file %s: error logo_data\n", filename);
+       logo_data = data + 54;
+       logo_height = (data[0x19]<<24) + (data[0x18]<<16) +(data[0x17]<<8) +(data[0x16]);
+       logo_width  = (data[0x15]<<24) + (data[0x14]<<16) +(data[0x13]<<8) +(data[0x12]);
+       data_start = (data[0x0d]<<24) + (data[0x0c]<<16) +(data[0x0b]<<8) +(data[0x0a]);
+       data_long  = (data[0x25]<<24) + (data[0x24]<<16) +(data[0x023]<<8) +(data[0x22]);
+       data_long = logo_height * logo_width * 3;
+#if 0
+       die("%s..logo_height=%ld,logo_width=%ld,data_start=%ld,data_long=%ld,sizeof(struct color)=%d,  \
+               read_buf[0x17]=%d  read_buf[0x13]=%d\n\n",filename,logo_height,logo_width,data_start,  \
+               data_long,sizeof(struct color),read_buf[0x17],read_buf[0x13]);
+       if ((logo_width*logo_height*3) != data_long)
+               die("something is wront in scripts/bmptologo.c\n");
+#endif 
+#endif
+#ifdef  debug
+       die("logo_data is:%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x:over\n", \
+               logo_data[0],logo_data[1],logo_data[2],logo_data[3],logo_data[4],logo_data[5],logo_data[6],logo_data[7],logo_data[8], \
+logo_data[9],logo_data[10],logo_data[11]);
+#endif
+    /* close file */
+    close(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 int write_hex_cnt;
+
+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_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 <linux/linux_logo.h>\n\n", out);
+       fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
+               logoname);
+}
+
+static void write_footer(void)
+{
+       fputs("\n};\n\n", out);
+       fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
+       fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
+
+       if (logo_type == LINUX_LOGO_bmp) {
+               fprintf(out, "\t.width\t\t= %ld,\n",  logo_width);
+               fprintf(out, "\t.height\t\t= %ld,\n",  logo_height);
+               //fprintf(out, "\t.data\t\t= %s_data,\n", logoname);
+               fprintf(out, "\t.data\t\t= &(%s_data[%ld]),\n", logoname,sizeof(data_name) + 8);
+               fprintf(out, "\t.clut\t\t= %s_clut\n", logoname);
+       }  
+
+       fputs("};\n\n", out);
+
+       /* close logo file */
+       if (outputname)
+               fclose(out);
+}
+
+
+static void write_logo_bmp(void)
+{
+       unsigned long  i=0, j=0;
+       unsigned char *position ;
+       
+       /* validate image */
+/*statistics how many colours ,and if have over 224
+       logo_clutsize = 0;
+       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_hex_cnt = 0;
+
+       
+       /* write file header */
+       write_header();
+#if 1
+       write_hex((unsigned char)(logo_width >> 8));
+       write_hex((unsigned char)logo_width);
+       write_hex((unsigned char)(logo_height >> 8));
+       write_hex((unsigned char)logo_height);
+
+       for (i = 0; i < sizeof(data_name); i++){
+               write_hex(data_name[i]);
+       }
+       write_hex((unsigned char)(logo_width >> 8));
+       write_hex((unsigned char)logo_width);
+       write_hex((unsigned char)(logo_height >> 8));
+       write_hex((unsigned char)logo_height);
+#endif
+       
+#if 0
+       /* 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 unsigned char %s_clut[] __initdata = {\n",
+               logoname);
+
+       write_hex_cnt = 0;
+
+       for (i = 0; i < sizeof(clut_name); i++){
+               write_hex(clut_name[i]);
+       }
+       write_hex(logo_clutsize);
+
+       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);
+       }
+
+       for (i = logo_clutsize; i < (MAX_LINUX_LOGO_COLORS * 3); i++)
+       {
+               write_hex(32);
+       }
+
+       /* write logo structure and file footer */
+#endif
+
+#if 1
+       for (i=logo_height; i>0; i--)
+       {
+               for (j=0; j<logo_width; j++)
+               {       
+                               position = logo_data + (i-1)* logo_width * 3 + 3 * j;
+#if 0
+                       write_hex(*(position));
+                       write_hex(*(position+1));
+                       write_hex(*(position+2));
+#else
+                       write_hex(*(position));
+                       write_hex(*(position+1));
+                       write_hex(*(position+2));               
+                       write_hex(0);
+#endif
+               }
+       }
+#endif
+
+       fputs("\n};\n\n", out);
+       /* write logo clut */
+       fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
+               logoname);
+
+       write_hex_cnt = 0;
+       for (i = 0; i < sizeof(clut_name); i++){
+               write_hex(clut_name[i]);
+       }
+       
+       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] <filename>\n"
+       "\n"
+       "Valid options:\n"
+       "    -h          : display this usage information\n"
+       "    -n <name>   : specify logo name (default: linux_logo)\n"
+       "    -o <output> : output to file <output> instead of stdout\n"
+       "    -t <type>   : specify logo type, one of\n"                       
+       "                      bmp : truecolour\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, "bmp"))
+                   logo_type = LINUX_LOGO_bmp;         
+               else
+                       die("logo_type is wrong without bmp\n");
+               break;
+
+           default:
+               usage();
+               break;
+       }
+    }
+    if (optind != argc-1)
+       usage();
+
+    filename = argv[optind];
+
+       read_image();
+    switch (logo_type) {
+       case LINUX_LOGO_bmp:
+               write_logo_bmp();
+           break;
+       default :
+               die("logo_type is wrong\n");
+    }
+    exit(0);
+}
+