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|*・主な BITMAPFILEHEADER と BITMAPINFOHEADER のメンバ変数は次の通りです。
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|