list3.c

    1|/***********************************************************************
    2|*  <<< ビットマップ・ファイルをプログラムのデータにする >>> 
    3|*【補足】
    4|*・データ配列が書かれたソースファイルを出力します。
    5|*・現在 24bit ビットマップ・ファイルから 16bit のデータしか出力できません。
    6|*・コンパイルは、cl bmp2nvc.c とします。
    7|*・bmp2nvc.htm を参照
    8|*【内部補足】
    9|*・プログラムの際、word と byte*n の関係と、座標と byte*n の関係に注意
   10|*・V800 シリーズ, SDV の Word とエディアンの関係
   11|*    Type           Range  Value              WordPack
   12|* -------------------------------------------------------------
   13|*  4bpp D5xVRAM        0xF  palet          [7|6|5|4|3|2|1|0]
   14|*  8bpp D5xVRAM       0xFF  palet          [ 3 | 2 | 1 | 0 ]
   15|* 16bpp D5xVRAM     0xFFFF  R5G6B5         [ 1L| 1H| 0L| 0H]
   16|* 12bpp D51Palet     0xFFF  X4R4G4B4       [ 1L| 1H| 0L| 0H]
   17|* 16bpp D52Palet    0xFFFF  R1G2B1R4G4B4   [   1   |   0   ]
   18|* 18bpp D54Palet  0xFFFFFF  X8R6X2G6X2B6X2 [ 0B| 0G| 0R| 0X]
   19|*  4bpp BMP            0xF  palet          [7|6|5|4|3|2|1|0]
   20|*  8bpp BMP           0xFF  palet          [ 3 | 2 | 1 | 0 ]
   21|* 24bpp BMP       0xFFFFFF  R8G8B8         [ 1B| 0R| 0G| 0B] [ 2G| 2B| 1R| 1G] [ 3R| 3G| 3B| 2R]
   22|* 24bpp BMPPalet  0xFFFFFF  X8R8G8B8       [ 0X| 0R| 0G| 0B]
   23|*
   24|* 0〜7: X座標
   25|* H:High byte, L=Low byte, R=Red, G=Green, B=Blue, X=Blank
   26|* BMP: Windows Bitmap
   27|************************************************************************/
   28|
   29|#include <windows.h>
   30|#include <string.h>
   31|#include <stdio.h>
   32|#include <stdlib.h>
   33|#include <compone.h>
   34|
   35|typedef struct _BmpFile  BmpFile;
   36|typedef struct _BmpSrc   BmpSrc;
   37|typedef struct _LineBuf  LineBuf;
   38|
   39| 
   40|/***********************************************************************
   41|*  <<< [BmpFile] ビットマップ・ファイル >>> 
   42|*【補足】
   43|*  <<< [BITMAPFILEHEADER, BITMAPINFOHEADER] >>>
   44|*・この2つの構造体は、Microsoft が提供する BMP ファイルの構造に対応しておます。
   45|*・主な BITMAPFILEHEADERBITMAPINFOHEADER のメンバ変数は次の通りです。
   46|*  (BITMAPFILEHEADER)
   47|*   ・bfOffBits;   ビットマップ・データのファイルオフセット
   48|*  (BITMAPINFOHEADER)
   49|*   ・biWidth, biHeight, biBitCount(bpp)
   50|************************************************************************/
   51|struct _BmpFile {
   52|  FILE*  file;
   53|  const char*  fname;
   54|  BITMAPFILEHEADER  head;  /* 画像情報 1 */
   55|  BITMAPINFOHEADER  info;  /* 画像情報 2 */
   56|  int   nPalet;            /* パレット数、パレットが無いとき=0 */
   57|  long  paletAdr;          /* パレットの先頭のファイル・アドレス */
   58|  long  pixelSize;         /* ピクセルパターン部のファイルサイズ */
   59|  int   lineSize;          /* 1ライン(水平線)のファイルサイズ */
   60|};
   61|
   62|void  BmpFile_init( BmpFile*, const char* fname );
   63|void  BmpFile_printInfo( BmpFile* );
   64|void  BmpFile_readLine( BmpFile* bmp, LineBuf* buf );
   65|void  BmpFile_finish( BmpFile* );
   66|
   67| 
   68|/***********************************************************************
   69|*  <<< [BmpSrc] ソース・ファイル >>> 
   70|*【役割】
   71|*・NvcBmp2_File 型のデータをソース・ファイル形式で出力します。
   72|************************************************************************/
   73|struct _BmpSrc {
   74|  FILE*  file;
   75|  char  fname[256];
   76|  char  dataName[256];    /* データ名(変数名の接頭辞)*/
   77|};
   78|
   79|void  BmpSrc_init( BmpSrc*, const char* fname, const char* dataName );
   80|void  BmpSrc_writeInfo( BmpSrc* src, BmpFile* bmp );
   81|void  BmpSrc_writeLineHead( BmpSrc* );
   82|void  BmpSrc_writeLine( BmpSrc*, LineBuf* buf );
   83|void  BmpSrc_writeLineFoot( BmpSrc* );
   84|void  BmpSrc_finish( BmpSrc* );
   85|
   86| 
   87|/***********************************************************************
   88|*  <<< [LineBuf] ラインバッファ >>> 
   89|*【補足】
   90|*・バッファは、内部に持っています。
   91|*【内部補足】
   92|*・バッファには、パディングのための行末のダミーデータが入っています。
   93|************************************************************************/
   94|struct _LineBuf {
   95|  char*  adr;   /* バッファの先頭アドレス */
   96|  int  size;    /* バッファに格納されて入るデータのサイズ */
   97|  int  maxsize; /* バッファに格納できる最大のデータのサイズ */
   98|};
   99|
  100|void  LineBuf_init( LineBuf*, int size );
  101|void  LineBuf_chg24to16( LineBuf* );
  102| 
  103|/***********************************************************************
  104|*  <<< [main] メイン ★>>> 
  105|************************************************************************/
  106|void  main( int argc, char* argv[] )
  107|{
  108|  int  y;
  109|  BmpFile  bmp;  /* ビットマップファイル・オブジェクト */
  110|  BmpSrc  src;   /* ビットマップソース・オブジェクト */
  111|  char  path[_MAX_PATH];
  112|  char  dataName[_MAX_PATH];
  113|
  114|  try {
  115|
  116|    /* dataName を作る */
  117|    strcpy( path, argv[1] );
  118|    StrX_chgExt( path, "c" );
  119|    strcpy( dataName, argv[1] );
  120|    ASSERT( strrchr( dataName, '.' ) != NULL );
  121|    *strrchr( dataName, '.' ) = '\0';
  122|
  123|    /* bmp, src を初期化する */
  124|    BmpFile_init( &bmp, argv[1] );
  125|    BmpSrc_init( &src, path, dataName );
  126|
  127|    /* 情報を出力する */
  128|    BmpFile_printInfo( &bmp );
  129|    BmpSrc_writeInfo( &src, &bmp );
  130|
  131|    /* ピクセルパターンを出力する */
  132|    {
  133|      LineBuf  buf;   /* ラインバッファ・オブジェクト */
  134|
  135|      LineBuf_init( &buf, bmp.lineSize );
  136|      BmpSrc_writeLineHead( &src );
  137|      for ( y = 0; y < (int)bmp.info.biHeight; y++ ) {  /* 水平線の集合 */
  138|        BmpFile_readLine( &bmp, &buf );
  139|        LineBuf_chg24to16( &buf );
  140|        BmpSrc_writeLine( &src, &buf );
  141|      }
  142|      BmpSrc_writeLineFoot( &src );
  143|    }
  144|
  145|    BmpFile_finish( &bmp );
  146|    BmpSrc_finish( &src );
  147|
  148|  }
  149|  catch_xxx() {
  150|
  151|    /* ヘルプ表示する */
  152|    printf( " usage: bmp2nvc (bmp file name) \n" );
  153|    Except2_Sys_print();
  154|
  155|  } end_catch;
  156|Errors_printf_flush();
  157|}
  158| 
  159|/***********************************************************************
  160|*  <<< [BmpFile_init] ビットマップ・ファイルと結合する >>> 
  161|************************************************************************/
  162|void  BmpFile_init( BmpFile* this, const char* fname )
  163|{
  164|  int  a;
  165|
  166|  this->fname = fname;
  167|  this->file = FileX_open( fname, "rb" );
  168|
  169|  fread( &this->head, sizeof(this->head), 1, this->file );
  170|  fread( &this->info, sizeof(this->info), 1, this->file );
  171|
  172|  /* ファイル形式が正しいか、サポートしているかチェックする */
  173|  if ( this->head.bfType != 0x4D42 )
  174|    throw( Except2_Str_newExcept2( "This is not BMP file." ) );
  175|  if ( this->info.biCompression != 0 )
  176|    throw( Except2_Str_newExcept2( "The Compression file can't support" ) );
  177|
  178|  /* パレットの数 nPalettes を得る */
  179|  if ( this->info.biBitCount != 24 )
  180|    throw( Except2_Str_newExcept2( "This program is for 24bpp BMP file." ) );
  181|  this->nPalet = 0;
  182|
  183|  /* パレットの先頭のファイル・アドレスを取得する */
  184|  this->paletAdr = ftell( this->file );
  185|
  186|  /* ピクセル部のファイルサイズを取得する */
  187|  this->pixelSize = this->info.biWidth * this->info.biHeight * 3;
  188|
  189|  /* lineSize 取得する(行末のパディングもサイズに含む)*/
  190|  a = (int)(this->info.biWidth) * 3;
  191|  while ( (a & 3) > 0 )  a ++;    /* ... if (a % 3 > 0) */
  192|  this->lineSize = a;
  193|}
  194| 
  195|/***********************************************************************
  196|*  <<< [BmpFile_printInfo] ビットマップの情報を画面に表示する >>> 
  197|************************************************************************/
  198|void  BmpFile_printInfo( BmpFile* this )
  199|{
  200|  printf( "%s\n", this->fname );
  201|  printf( " colors    : %dbit\n", this->info.biBitCount );
  202|  printf( " size      : %ld x %ld\n",
  203|    this->info.biWidth, this->info.biHeight );
  204|}
  205|
  206| 
  207|/***********************************************************************
  208|*  <<< [BmpFile_readLine] ファイルからピクセル・データ1行分を読み込む >>> 
  209|*【補足】
  210|*・ビットマップの幅と bpp を考慮しています。
  211|************************************************************************/
  212|void  BmpFile_readLine( BmpFile* bmp, LineBuf* buf )
  213|{
  214|  ASSERT( bmp->info.biBitCount == 24 );
  215|  ASSERT( bmp->lineSize <= buf->maxsize );
  216|
  217|  buf->size = fread( buf->adr, 1, bmp->lineSize, bmp->file );
  218|}
  219| 
  220|/***********************************************************************
  221|*  <<< [BmpFile_finish] 後始末する >>> 
  222|************************************************************************/
  223|void  BmpFile_finish( BmpFile* this )
  224|{
  225|  fclose( this->file );
  226|}
  227| 
  228|/***********************************************************************
  229|*  <<< [BmpSrc_init] ソース・ファイルを開く >>> 
  230|*【引数】
  231|*  ・char*  fname;     ソース・ファイル名
  232|*  ・char*  dataName;  テクスチャ・データ名(変数の前半部分)
  233|************************************************************************/
  234|void  BmpSrc_init( BmpSrc* this, const char* fname, const char* dataName )
  235|{
  236|  this->file = FileX_open( fname, "wt" );
  237|  strcpy( this->fname, fname );
  238|  strcpy( this->dataName, dataName );
  239|}
  240|
  241| 
  242|/***********************************************************************
  243|*  <<< [BmpSrc_writeInfo] ヘッダコメントを出力する >>> 
  244|************************************************************************/
  245|void  BmpSrc_writeInfo( BmpSrc* src, BmpFile* bmp )
  246|{
  247|  /* ヘッダ(変数宣言部)を出力する */
  248|  fprintf( src->file,
  249|    "/***********************************************************************\n" );
  250|  fprintf( src->file,
  251|    "*  <<%c NVC Bitmap Data from %s %c>>\n", '<', src->fname, '>' );
  252|  fprintf( src->file,
  253|    "************************************************************************/\n" );
  254|  fprintf( src->file, "#include <compone.h>\n\n" );
  255|
  256|  fprintf( src->file, "NvcBmp2_File  %s;\n", src->dataName );
  257|  fprintf( src->file, "extern long  %s_palet[];\n", src->dataName );
  258|  fprintf( src->file, "extern int   %s_bmp[];\n\n\n", src->dataName );
  259|
  260|
  261|  /* ビットマップの情報を出力する */
  262|  fprintf( src->file,
  263|    "/***********************************************************************\n" );
  264|  fprintf( src->file,
  265|    "*  <<%c [%s_get] get NVC Bitmap Data %c>>\n", '<', src->dataName, '>' );
  266|  fprintf( src->file, "*【補足】\n" );
  267|  fprintf( src->file, "*・nvcbmp2.h ファイル内の NvcBmp2_File を参照してください。\n" );
  268|  fprintf( src->file,
  269|    "************************************************************************/\n" );
  270|  fprintf( src->file, "NvcBmp2_File*  %s_get()\n", src->dataName );
  271|  fprintf( src->file, "{\n" );
  272|  fprintf( src->file, "  %s.width = %d;\n", src->dataName,
  273|    bmp->info.biWidth );
  274|  fprintf( src->file, "  %s.height = %d;\n", src->dataName,
  275|    bmp->info.biHeight );
  276|  fprintf( src->file, "  %s.bpp = %d;\n", src->dataName,
  277|    bmp->info.biBitCount );
  278|  fprintf( src->file, "  %s.bmp = %s_bmp;\n\n", src->dataName,
  279|    src->dataName );
  280|
  281|  fprintf( src->file, "  %s.palet_n = 0;\n", src->dataName );
  282|  fprintf( src->file, "  %s.palet_bpp = 0;\n", src->dataName );
  283|  fprintf( src->file, "  %s.palet_type = NvcBmp2_Long;\n", src->dataName );
  284|  fprintf( src->file, "  %s.palet = NULL;\n\n", src->dataName );
  285|
  286|  fprintf( src->file, "  return  &%s;\n", src->dataName );
  287|  fprintf( src->file, "}\n\n\n" );
  288|}
  289| 
  290|/***********************************************************************
  291|*  <<< [BmpSrc_writeLineHead] ビットマップ・データのヘッダを出力する >>> 
  292|************************************************************************/
  293|void  BmpSrc_writeLineHead( BmpSrc* this )
  294|{
  295|  fprintf( this->file,
  296|    "/***********************************************************************\n" );
  297|  fprintf( this->file, "*  <<%c [%s_bmp] Bitmap Data %c>>\n", '<', this->dataName, '>' );
  298|  fprintf( this->file, "*【補足】\n" );
  299|  fprintf( this->file, "*・ビットマップの行がワード単位になるように、行末にダミーを埋め込んでいます。\n" );
  300|  fprintf( this->file, "*・エディアンは、bmp2nvc をコンパイルしたコンパイラに従っています。\n" );
  301|  fprintf( this->file,
  302|    "************************************************************************/\n" );
  303|  fprintf( this->file, "int  %s_bmp[] = {\n", this->dataName );
  304|}
  305| 
  306|/***********************************************************************
  307|*  <<< [BmpSrc_writeLine] ビットマップ・データ1行分を出力する >>> 
  308|*【補足】
  309|*・ビットマップ・データ1行分は、ソースコードの1行分ではなく、
  310|*  画像の水平線のことをさします。
  311|************************************************************************/
  312|void  BmpSrc_writeLine( BmpSrc* this, LineBuf* buf )
  313|{
  314|  #ifndef FOR_32BIT
  315|    #error
  316|  #endif
  317|
  318|  int  i;
  319|  int  ofs;  /* (i / 4) % 4 */
  320|
  321|  for ( i = 0; i < buf->size; i+=4 ) {  /* ワード・データの集合 */
  322|    ofs = (i >> 2) & 0x03;
  323|
  324|    /* 行頭を出力する */
  325|    if ( ofs == 0 ) {
  326|      fprintf( this->file, "  " );
  327|    }
  328|
  329|    /* 値を出力する */
  330|    fprintf( this->file, "0x%08lX", *(long*)(buf->adr + i) );
  331|
  332|    /* コンマ、または4列ごとの改行 */
  333|    if ( ofs == 3 )
  334|      fprintf( this->file, ",\n" );
  335|    else
  336|      fprintf( this->file, ", " );
  337|  }
  338|  if ( ofs != 3 )
  339|    fprintf( this->file, "\n" );
  340|}
  341| 
  342|/***********************************************************************
  343|*  <<< [BmpSrc_writeLineFoot] ビットマップ・データのフッタを出力する >>> 
  344|************************************************************************/
  345|void  BmpSrc_writeLineFoot( BmpSrc* this )
  346|{
  347|  fprintf( this->file, "};\n\n\n" );
  348|}
  349|
  350| 
  351|/***********************************************************************
  352|*  <<< [BmpSrc_finish] 後始末する >>> 
  353|************************************************************************/
  354|void  BmpSrc_finish( BmpSrc* this )
  355|{
  356|  fclose( this->file );
  357|}
  358| 
  359|/***********************************************************************
  360|*  <<< [LineBuf_init] 初期化する >>> 
  361|*【引数】
  362|*  ・int  maxsize;   バッファの最大サイズ
  363|************************************************************************/
  364|void  LineBuf_init( LineBuf* this, int maxsize )
  365|{
  366|  static char  lineBuf[32768];
  367|
  368|  ASSERT( maxsize <= sizeof(lineBuf) );
  369|  ASSERT( maxsize % 4 == 0 );
  370|
  371|  this->adr = lineBuf;
  372|  this->size = 0;
  373|  this->maxsize = sizeof(lineBuf);
  374|}
  375| 
  376|/***********************************************************************
  377|*  <<< [LineBuf_chg24to16] 24bpp から 16bpp に減色する >>> 
  378|*【補足】
  379|*・バッファ中のデータサイズも変化します。
  380|*・リトルエディアンのコンパイラで使用してください。
  381|************************************************************************/
  382|void  LineBuf_chg24to16( LineBuf* this )
  383|{
  384|  int  i;
  385|  int  r,g,b;
  386|  unsigned char*  p = (unsigned char*)this->adr;
  387|  short*  p2 = (short*)this->adr;
  388|
  389|  for ( i = 0; i <= this->size - 3; i += 3 ) { /* ピクセルの集合 */
  390|    b = *p >> 3;  p++;
  391|    g = *p >> 2;  p++;
  392|    r = *p >> 3;  p++;
  393|    *p2 = (short)Color_RGB16_init( r, g, b );  p2++;
  394|  }
  395|Errors_printf( "size = %d", this->size );
  396|  this->size = this->size * 2 / 3;
  397|Errors_printf( "size2 = %d", this->size );
  398|}
  399|
  400| 
  401|