0001: 
0002: #include <GL/glut.h>
0003: #include "CBitmap.h"
0004: 
0005: 
0006: // ---------------------------------------------------------------------------
0007: // Bitmapヘッダチェック
0008: // ---------------------------------------------------------------------------
0009: int CBitmap::_CheckHeaders (const BitmapHeader *pBH, const BitmapInfoHeader *pBIH)
0010: {
0011:     //ヘッダのBMの文字
0012:     if( pBH->distinct1!='B' || pBH->distinct2!='M' )return 0;
0013:     //レイヤー1
0014:     if( pBIH->plane !=1 )return 0;
0015:     //圧縮なし
0016:     if( pBIH->compression !=0 ) return 0;
0017:     //色数を返す
0018:     if( pBIH->bits ==24 || pBIH->bits ==8 ) return pBIH->bits;
0019:     
0020:     return 0;
0021: }
0022: // ---------------------------------------------------------------------------
0023: // ビットマップファイルのサイズチェック
0024: // ---------------------------------------------------------------------------
0025: int CBitmap::_CheckSize(unsigned int pict_size)
0026: {
0027:     unsigned int i=2;
0028:     const unsigned int TEX_SIZE = 256;
0029:     unsigned int max_texture = TEX_SIZE*TEX_SIZE;
0030:     
0031:     //サイズチェック
0032:     for(i=2;i<=max_texture;i*=2){
0033:         if( i == pict_size){
0034:             return 1;
0035:         }
0036:     }
0037:     return 0;
0038: };
0039: // ---------------------------------------------------------------------------
0040: // Bitmapヘッダ読み込み
0041: // ---------------------------------------------------------------------------
0042: int CBitmap::_ReadHeader(BitmapHeader *header, FILE *fp)
0043: {
0044:     if( fread(&(header->distinct1), sizeof( char),1,fp)<1 ) return 1;
0045:     if( fread(&(header->distinct2), sizeof( char),1,fp)<1 ) return 2;
0046:     if( fread(&(header->filesize),  sizeof( int ),1,fp)<1 ) return 3;
0047:     if( fread(&(header->reserve1),  sizeof(short),1,fp)<1 ) return 4;
0048:     if( fread(&(header->reserve2),  sizeof(short),1,fp)<1 ) return 5;
0049:     if( fread(&(header->offset),    sizeof( int ),1,fp)<1 ) return 6;
0050:     
0051:     return 0;
0052: }
0053: // ---------------------------------------------------------------------------
0054: // BitmapInfoヘッダ読み込み
0055: // ---------------------------------------------------------------------------
0056: int CBitmap::_ReadInfoHeader(BitmapInfoHeader *info, FILE *fp)
0057: {
0058:     if( fread(&(info->header),              sizeof( int ),1,fp)<1) return 1;
0059:     if( fread(&(info->width),               sizeof( int ),1,fp)<1) return 2;
0060:     if( fread(&(info->height),              sizeof( int ),1,fp)<1) return 3;
0061:     if( fread(&(info->plane),               sizeof(short),1,fp)<1) return 4;
0062:     if( fread(&(info->bits),                sizeof(short),1,fp)<1) return 5;
0063:     if( fread(&(info->compression),         sizeof( int ),1,fp)<1) return 6;
0064:     if( fread(&(info->comp_image_size),     sizeof( int ),1,fp)<1) return 7;
0065:     if( fread(&(info->x_resolution),        sizeof( int ),1,fp)<1) return 8;
0066:     if( fread(&(info->y_resolution),        sizeof( int ),1,fp)<1) return 9;
0067:     if( fread(&(info->pallet_num),          sizeof( int ),1,fp)<1) return 10;
0068:     if( fread(&(info->important_pallet_num),sizeof( int ),1,fp)<1) return 11;
0069:     
0070:     return 0;
0071: }
0072: 
0073: // ---------------------------------------------------------------------------
0074: // 256色テクスチャの読み込み
0075: // ---------------------------------------------------------------------------
0076: unsigned int CBitmap::_Analize8bit( const BitmapInfoHeader *pBIH, FILE *fp )
0077: {
0078:     unsigned int tex_id = 0;
0079:     unsigned char pallete_num;
0080:     unsigned char *color_pallete_r;
0081:     unsigned char *color_pallete_g;
0082:     unsigned char *color_pallete_b;
0083:     unsigned char *color_pallete_v;
0084:     unsigned char *bitdata;
0085:     int i, j;
0086:     
0087:     //カラーパレット読み込み
0088:     //メモリ確保
0089:     color_pallete_r = (unsigned char*)malloc(256*sizeof(unsigned char));
0090:     color_pallete_g = (unsigned char*)malloc(256*sizeof(unsigned char));
0091:     color_pallete_b = (unsigned char*)malloc(256*sizeof(unsigned char));
0092:     color_pallete_v = (unsigned char*)malloc(256*sizeof(unsigned char));
0093:     //パレット読み込み
0094:     for( i=0 ; i<256 ; i++){
0095:         fread( (color_pallete_r+i), sizeof(unsigned char),1,fp);
0096:         fread( (color_pallete_g+i), sizeof(unsigned char),1,fp);
0097:         fread( (color_pallete_b+i), sizeof(unsigned char),1,fp);
0098:         fread( (color_pallete_v+i), sizeof(unsigned char),1,fp);
0099:     }
0100:     //ビットデータ読み込み
0101:     bitdata = (unsigned char*)malloc(3*pBIH->width*pBIH->height*sizeof(unsigned char));
0102:     for(j=(pBIH->height-1);j>=0;j--){
0103:         for(i=(pBIH->width-1);i>=0;i--){
0104:             fread( &pallete_num, sizeof(unsigned char),1,fp);
0105:             *(bitdata+3*i+3*j*pBIH->width)  = *(color_pallete_b+pallete_num); 
0106:             *(bitdata+3*i+3*j*pBIH->width+1)= *(color_pallete_g+pallete_num); 
0107:             *(bitdata+3*i+3*j*pBIH->width+2)= *(color_pallete_r+pallete_num); 
0108:         }
0109:     }
0110:     //カラーパレットメモリ開放
0111:     free(color_pallete_r);
0112:     free(color_pallete_g);
0113:     free(color_pallete_b);
0114:     free(color_pallete_v);
0115:     //テクスチャ作成
0116:     glGenTextures(1, &tex_id);
0117:     glBindTexture(GL_TEXTURE_2D, tex_id);
0118:     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pBIH->width, pBIH->height
0119:                 , 0, GL_RGB, GL_UNSIGNED_BYTE, bitdata);
0120:     free(bitdata);
0121:     
0122:     return tex_id;
0123: }
0124: // ---------------------------------------------------------------------------
0125: // 24bitsテクスチャの読み込み
0126: // ---------------------------------------------------------------------------
0127: unsigned int CBitmap::_Analize24bit( const BitmapInfoHeader *pBIH, FILE *fp )
0128: {
0129:     unsigned int tex_id = 0;
0130:     unsigned char *bitdata;
0131:     unsigned char red,green,blue;
0132:     int i, j;
0133:     
0134:     //メモリ確保
0135:     bitdata = (unsigned char*)malloc(3*pBIH->width*pBIH->height*sizeof(unsigned char));
0136:     //読み込み
0137:     for(j=(pBIH->height-1);j>=0;j--){
0138:         for(i=(pBIH->width-1);i>=0;i--){
0139:             fread( &red,   sizeof(unsigned char),1,fp);
0140:             fread( &green, sizeof(unsigned char),1,fp);
0141:             fread( &blue,  sizeof(unsigned char),1,fp);
0142:             *(bitdata+3*i+3*j*pBIH->width)  = blue;
0143:             *(bitdata+3*i+3*j*pBIH->width+1)= green; 
0144:             *(bitdata+3*i+3*j*pBIH->width+2)= red;
0145:         }
0146:     }
0147:     //テクスチャ作成
0148:     glGenTextures(1, &tex_id);
0149:     glBindTexture(GL_TEXTURE_2D, tex_id);
0150:     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pBIH->width, pBIH->height,
0151:                 0, GL_RGB, GL_UNSIGNED_BYTE, bitdata);
0152:     
0153:     //メモリ開放
0154:     free(bitdata);
0155:     
0156:     return tex_id;
0157: }
0158: // ---------------------------------------------------------------------------
0159: // テクスチャの読み込み
0160: // ---------------------------------------------------------------------------
0161: unsigned int CBitmap::Load(const char *filename)
0162: {
0163:     unsigned int tex_id = 0;
0164:     FILE *fp;
0165:     //ビットマップヘッダ
0166:     BitmapHeader header;
0167:     BitmapInfoHeader info;
0168:     //色数
0169:     unsigned int color_bit;
0170:     
0171:     // ファイルオープン
0172:     if( NULL==( fp = fopen(filename, "rb") ) ) return tex_id;
0173:     
0174:     //ヘッダ読み込み
0175:     if( _ReadHeader(&header, fp))   goto end;
0176:     if( _ReadInfoHeader(&info, fp)) goto end;
0177:     
0178:     //ヘッダチェック
0179:     if( !(color_bit = _CheckHeaders(&header, &info))) goto end;
0180:     
0181:     //ビットマップファイルサイズチェック
0182:     if( !_CheckSize(info.width*info.height) ) goto end;
0183:     
0184:     //カラービット数で処理を分ける
0185:     switch(color_bit){
0186:     case 8:
0187:         tex_id = _Analize8bit(&info, fp);
0188:         break;
0189:     case 24:
0190:         tex_id = _Analize24bit(&info, fp);
0191:         break;
0192:     }
0193:     
0194: end:
0195:     // ファイルクローズ
0196:     fclose(fp);
0197:     
0198:     return tex_id;
0199: }
0200: