Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1419781
  • 博文数量: 430
  • 博客积分: 9995
  • 博客等级: 中将
  • 技术积分: 4388
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-24 18:04
文章存档

2013年(1)

2008年(2)

2007年(14)

2006年(413)

分类:

2006-08-23 22:07:23

/*
  fblogo.c
  Generate linux_logo.h header file for use with the framebuffer boot logo
  Daniel Ved鴜 <> 1999
  Gordon Fraser <> 2001/2002/2003
  This software comes with ABSOLUTELY NO WARRANTY
  This software is free software, and you are welcome to redistribute it
  under certain conditions
  See the COPYING file for details.
*/
#include "fblogo.h"
/*--------------------------------------------------------------------*/
int main(int argc, char** argv)
{
  char* input_filename  = NULL;
  char* output_filename = NULL;
  version_    = LINUX_24;
  verbose_    = FALSE;
  palette_    = NULL;
  image_data_ = NULL;
  parseArguments(argc, argv, &input_filename, &output_filename);
 
  if(openFiles(input_filename, output_filename) != SUCCESS)
    {
      cleanup();
      return ERROR;
    }
 
  if(readInputFile() != SUCCESS)
    {
      cleanup();
      exit(EXIT_FAILURE);
    }
 
  writeOutputFile();
  displayNotice();
  cleanup();
  if(input_filename  != NULL)
    free(input_filename);
  if(output_filename != NULL)
    free(output_filename);
 
  return SUCCESS;
}
/*--------------------------------------------------------------------*/
void cleanup()
{
  if(input_file_ != NULL)
    fclose(input_file_);
  if(output_file_ != NULL)
    fclose(output_file_);
  if(image_data_ != NULL)
    free(image_data_);
 
  if(palette_ != NULL)
    free(palette_);
}
/*--------------------------------------------------------------------*/
void displayUsage(char* program_name)
{
    printf("Usage:\n");
    printf("%s [-2|-4] [-d] [-v] [-h] [inputfile [outputfile]]\n", program_name);
    printf("  -h,  --help                    display this help screen\n");
    printf("  -v,  --version                 display program version\n");
    printf("  -d,  --verbose                 display helpful messages\n");
    printf("  -2,  --linux-2.2               Create for 2.2.x kernels\n");
    printf("  -4,  --linux-2.4               Create for 2.4.x kernels (default)\n");
    printf("  inputfile                      name of image file\n");
    printf("  outputfile                     name of output file\n");
    printf("If outputfile is omitted, results will be sent to stdout.\nIf inputfile is omitted too, input will be read from stdin.\n");
}
/*--------------------------------------------------------------------*/
void displayNotice()
{
  if(!verbose_)
    return;
  fprintf(stderr, "Logo generated successfully\n\n");
  fprintf(stderr, "Remember to modify linux/drivers/video/fbcon.c:\n");
  fprintf(stderr, " Change \"#define LOGO_H 80\" to \"#define LOGO_H %li\"\n", height_);
  fprintf(stderr, " Change \"#define LOGO_W 80\" to \"#define LOGO_W %li\"\n\n", width_);
  if(version_ == LINUX_22)
    {
      fprintf(stderr, "As you are going to use it for Linux 2.2,\nmodify linux/include/asm-/linux_logo.h:\n");
      fprintf(stderr, " Change \"#define LINUX_LOGO_COLORS 214\" to \"#define LINUX_LOGO_COLORS %i\"\n\n", num_palette_);
    }
  fprintf(stderr, "Then copy your new header to linux/include/linux/linux_logo.h,\n");
  fprintf(stderr, "and recompile the kernel.\n");
}

/*--------------------------------------------------------------------*/
void displayVersion(void)
{
    printf("fblogo version %s\n", PROGRAM_VERSION);
}
/*--------------------------------------------------------------------*/
int parseArguments(int argc, char** argv, char** input_filename, char** output_filename)
{
  static struct option long_opts[] = {
    {"help",       0, NULL, 'h'},
    {"version",    0, NULL, 'v'},
    {"linux-2.4",  0, NULL, '4'},
    {"linux-2.2",  0, NULL, '2'},
    {"verbose",    0, NULL, 'd'},
    {NULL,         0, NULL, 0  }};
  int counter;
  int filename_position;
  if(argc > MAX_ARGUMENTS)
    {
      displayUsage(argv[0]);
      exit(EXIT_FAILURE);
    }
   
  while ((counter = getopt_long(argc, argv, "hvd24", long_opts, NULL)) != -1)
    {
      switch (counter)
 {
 case 'h':
 case ':':
 case '?':
   displayUsage(argv[0]);
   exit(0);
   break;
 case 'v':
   displayVersion();
   exit(0);
   break;
 case 'd':
   verbose_ = TRUE;
   break;
 case '2':
   version_ = LINUX_22;
   break;
 case '4':
   version_ = LINUX_24;
   break;
 }
    }
 
  filename_position = optind;
 
  if(filename_position < argc)
    {
      *input_filename = (char*)malloc(strlen(argv[filename_position])+1);
      strcpy(*input_filename, argv[filename_position]);
    }
  if(++filename_position < argc)
    {
      *output_filename = (char*)malloc(strlen(argv[filename_position])+1);
      strcpy(*output_filename, argv[filename_position]);
    }
  return optind;
}
/*--------------------------------------------------------------------*/
int openFiles(char* input_filename, char* output_filename)
{
  if(input_filename == NULL)
    {
      if ((input_file_ = fdopen(0, "rb")) == (FILE *)NULL)
 {
   fprintf(stderr, "fblogo error: cannot open stdin\n");
   return ERROR;
 }
    }
  else
    {
      if ((input_file_ = fopen(input_filename, "rb")) == (FILE *)NULL)
 {
   fprintf(stderr, "fblogo error: cannot open input file %s\n", input_filename);
   return ERROR;
 }
    }
   
  if(output_filename == NULL)
    {
      if ((output_file_ = fdopen(1, "w")) == (FILE *)NULL)
 {
   fprintf(stderr, "fblogo error: cannot open stdout\n");
   return ERROR;
 }
    }
  else
    {
      if ((output_file_ = fopen(output_filename, "w")) == (FILE *)NULL)
 {
   fprintf(stderr, "fblogo error: cannot open output file %s\n", output_filename);
   return ERROR;
 }
    }
  return SUCCESS;
}
/*--------------------------------------------------------------------*/
int pngCheck()
{
  unsigned char buf[PNG_SIG_BYTES];
  if (fread(buf, 1, PNG_SIG_BYTES, input_file_) != PNG_SIG_BYTES)
    {
      fprintf(stderr, "fblogo error: image is not a png\n");
      return ERROR;
    }
 
  if(png_sig_cmp(buf, 0, PNG_SIG_BYTES))
    {
      fprintf(stderr, "fblogo error: image is not a png\n");
      return ERROR;
    }
  return SUCCESS;
}
/*--------------------------------------------------------------------*/
int pngInit(png_structp *png_ptr, png_infop *info_ptr)
{
  /* Now create png_struct and png_info */
  *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
  if (!*png_ptr)
    {
      fprintf(stderr, "fblogo error reading png\n");
      return ERROR;
    }
 
  *info_ptr = png_create_info_struct(*png_ptr);
  if (!*info_ptr)
    {
      fprintf(stderr, "fblogo error reading png\n");
      png_destroy_read_struct(&*png_ptr, (png_infopp)NULL, (png_infopp)NULL);
      return ERROR;
    }
 
 
  png_init_io(*png_ptr, input_file_);
  png_set_sig_bytes(*png_ptr, PNG_SIG_BYTES);
  png_read_info(*png_ptr, *info_ptr);
  return SUCCESS;
}

/*--------------------------------------------------------------------*/int pngGetPalette(png_structp png_ptr, png_infop info_ptr, int bit_depth, int color_type)
{
  int num_colours = 0;
  png_colorp png_palette;
 
  if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth > 8) {
    fprintf(stderr, "fblogo error: only palette PNGs supported\n");
    return ERROR;
  }
 
  if (bit_depth < 8)
    png_set_packing(png_ptr);   /* expand to 1 byte per pixel */
 
  png_get_PLTE(png_ptr, info_ptr, &png_palette, &num_colours);
 
  if (num_colours > 223)
    {
      fprintf(stderr, "fblogo error: too many colors (%d); must be less than 224\n", num_colours);
      return ERROR;
    }
 
  palette_ = malloc(sizeof(png_color) * num_colours);
  memcpy(palette_, png_palette, sizeof(png_color) * num_colours);
  num_palette_ = num_colours;
  return SUCCESS;
}
/*--------------------------------------------------------------------*/
int pngReadImage(png_structp png_ptr,  png_infop info_ptr)
{
  png_uint_32 rowbytes;
  png_bytepp row_pointers = NULL;
  unsigned counter;
 
  /* allocate space for the PNG image data */
  rowbytes = png_get_rowbytes(png_ptr, info_ptr);
  if ((image_data_ = (png_bytep)malloc(width_*height_)) == NULL)
    {
      fprintf(stderr, "fblogo error: can't allocate image data\n");
      return ERROR;
    }
  if ((row_pointers = (png_bytepp)malloc(height_*sizeof(png_bytep))) == NULL)
    {
      fprintf(stderr, "fblogo error: can't allocate row pointers\n");
      free(row_pointers);
      return ERROR;
    }
 
  /* set the individual row_pointers to point at the correct offsets */
 
  for (counter = 0; counter < height_; counter++)
    row_pointers[counter] = image_data_ + counter * rowbytes;
 
  png_read_image(png_ptr, row_pointers);
 
  png_read_end(png_ptr, info_ptr);
  free(row_pointers);
  return SUCCESS;
}

/*--------------------------------------------------------------------
 Based on libpng example.c and
          png2linuxlogo by Greg Roelofs <>
*/
int readInputFile()
{
   int bit_depth, color_type;
   png_structp png_ptr;
   png_infop info_ptr;
   if(pngCheck())
     {
       return ERR_NOPNG;
     }
   if(pngInit(&png_ptr, &info_ptr))
     {
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
       return ERR_PNGPTR;
     }
   png_get_IHDR(png_ptr, info_ptr, &width_, &height_, &bit_depth, &color_type, NULL, NULL, NULL);
   if(pngGetPalette(png_ptr, info_ptr, bit_depth, color_type))
     {
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
       return ERR_NOPNG;
     }
   if(pngReadImage(png_ptr, info_ptr))
     {
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
       return ERR_PNGPTR;
     }
   
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    return SUCCESS;
}

/*--------------------------------------------------------------------*/
void writeOutputFileHeader()
{
  time_t timestamp;
  char datestr[32];
  timestamp = time((time_t *)NULL);
  strftime(datestr, 32, "%Y/%m/%d %H:%M:%S", localtime(×tamp));
 
  fprintf(output_file_, "/* linux_logo.h created with fblogo, %s\n"
" * include/linux/linux_logo.h: This is a linux logo\n"
" *                             to be displayed on boot.\n"
" *\n"
" * Copyright (C) 1996 Larry Ewing ("
" * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)\n"
" *\n"
" * You can put anything here, but:\n"
" * LINUX_LOGO_COLORS has to be less than 224\n", datestr);
   
  fprintf(output_file_, " * Generated by fblogo version %s\n *\n", PROGRAM_VERSION);
  if(version_ == LINUX_22)
    {
      fprintf(output_file_, " *\n * As you are going to use it for Linux 2.2,\n * modify include/asm-/linux_logo.h:\n");
      fprintf(output_file_, " * Change \"#define LINUX_LOGO_COLORS 214\" to \"#define LINUX_LOGO_COLORS %i\"\n", num_palette_);
    }
  fprintf(output_file_, " *\n * Remember to modify drivers/video/fbcon.c:\n");
  fprintf(output_file_, " * Change \"#define LOGO_H 80\" to \"#define LOGO_H %li\"\n", height_);
  fprintf(output_file_, " * Change \"#define LOGO_W 80\" to \"#define LOGO_W %li\"\n */\n\n", width_);
 
 
  if(version_ == LINUX_24)
    {
      fprintf(output_file_, "#ifndef __HAVE_ARCH_LINUX_LOGO\n");
      /*      fprintf(output_file_, "#define LINUX_LOGO_COLORS %d\n", num_palette_); */
      fprintf(output_file_, "#define LINUX_LOGO_COLORS %d\n", 223);
      fprintf(output_file_, "#endif\n");
     
      fprintf(output_file_, "#ifdef INCLUDE_LINUX_LOGO_DATA\n");
      fprintf(output_file_, "#ifndef __HAVE_ARCH_LINUX_LOGO\n");
     
    }
  else
    {
      fprintf(output_file_, "#if LINUX_LOGO_COLORS == %d\n", num_palette_);
    }
}
/*--------------------------------------------------------------------*/
void writeOutputFile()
{
  png_bytep pixel;
  unsigned counter;
 
  if(version_ == LINUX_22 && verbose_)
    printf("Creating for Linux kernel version 2.2.x\n");
 
  else if(version_ == LINUX_24 && verbose_)
    printf("Creating for Linux kernel version 2.4.x/2.5.x\n");
 
  writeOutputFileHeader();
 
  /* red palette */
  fprintf(output_file_, "unsigned char linux_logo_red[] __initdata = {");
  for(counter=0; counter    {
      if(counter % 8 == 0)
 fprintf(output_file_, "\n  ");
      fprintf(output_file_, "0x%2.2X",palette_[counter].red);
      if(counter != num_palette_-1)
 fprintf(output_file_, ", ");
    }
  fprintf(output_file_,"\n};\n\n");
 
  /* green palette */
  fprintf(output_file_, "unsigned char linux_logo_green[] __initdata = {");
  for(counter=0; counter    {
      if(counter % 8 == 0)
 fprintf(output_file_, "\n  ");
      fprintf(output_file_, "0x%2.2X",palette_[counter].green);
      if(counter != num_palette_-1)
 fprintf(output_file_, ", ");
    }
  fprintf(output_file_,"\n};\n\n");
 
  /* blue palette */
  fprintf(output_file_, "unsigned char linux_logo_blue[] __initdata = {");
  for(counter=0; counter    {
      if(counter % 8 == 0)
 fprintf(output_file_, "\n ");
      fprintf(output_file_, "0x%2.2X",palette_[counter].blue);
      if(counter!=num_palette_-1)
 fprintf(output_file_, ", ");
    }
  fprintf(output_file_,"\n};\n\n");
 
  /* image data */
  fprintf(output_file_, "unsigned char linux_logo[] __initdata = {");
  pixel = image_data_;
  for (counter = 0; counter < width_*height_; counter++)
    {
      if (counter > 0)
 fprintf(output_file_, ",");
      if (counter % 8 == 0)
 fprintf(output_file_, "\n ");
      fprintf(output_file_, " 0x%2.2X", (*pixel++) + 0x20);
    }
  /* footer */
  if(version_ == LINUX_22)
    {
      fprintf(output_file_,"\n};\n\n#endif\n\n");
      fprintf(output_file_, low_color_logo_22);
    }
  else
    {
      fprintf(output_file_,"\n};\n\n#endif /* !__HAVE_ARCH_LINUX_LOGO */\n");
      fprintf(output_file_, low_color_logo_24);
    } 
}
 
阅读(891) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~