スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

某掲示板の話(ビットマップ)

どうにかして楽にソースコード載せることできないかな。
<を&lt;にかえたり、タブを変えたりとか面倒だよ。
しかもミスを見つけて治すにも狭い書きこみらんじゃ何か分からないし。

SyntaxHighlighterを使用してみたけどなぜか効果が無い。

水平線を引くのにputPixelを使うなど、このソースはあえて最適化してない。
あ~タブ幅があってないよ~ん

動作確認に使用した元画像の1bppビットマップ
test1bpp1.gif
あえて幅33にしてHorizonBytesの確認

実行結果
test4bpp1.gif
RGBQUADが元画像と違うので色が変わってしまう


 
void* cnv_2to16(void* src) {
    BITMAPINFOHEADER *src_bih, *dst_bih;
    RGBQUAD          *src_pal, *dst_pal;
    char *src_bits,  *dst_bits;
    int              src_rowbyte, dst_rowbyte;
    void             *dst;
    int              pal, x, y, src_pos, dst_pos;

    src_bih = (BITMAPINFOHEADER*)src;
    //assert(src_bih->biBitCount == 1);

    src_rowbyte = ((1 * src_bih->biWidth + 31) / 32) * 4;
    dst_rowbyte = ((4 * src_bih->biWidth + 31) / 32) * 4;
    dst = malloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 16 + dst_rowbyte * src_bih->biHeight);
    if (dst == NULL) {
        return NULL;
    }

    dst_bih = (BITMAPINFOHEADER*)dst;
    memcpy(dst_bih, src_bih, sizeof(BITMAPINFOHEADER));
    dst_bih->biSize = sizeof(BITMAPINFOHEADER);
    dst_bih->biBitCount = 4;
    dst_bih->biSizeImage = dst_bih->biClrUsed = dst_bih->biClrImportant = 0;

    src_pal = (RGBQUAD*)((char*)src_bih + src_bih->biSize);
    dst_pal = (RGBQUAD*)((char*)dst_bih + dst_bih->biSize);
    for (pal=0; pal < 2; ++pal) {
        dst_pal[pal] = src_pal[pal];
    }

    /* palette の空き領域に適当な色をセット */
        dst_pal[ 0].rgbBlue    =0x00;  /* 0:黒 */
        dst_pal[ 0].rgbGreen   =0x00;
        dst_pal[ 0].rgbRed     =0x00;
        dst_pal[ 0].rgbReserved=0x00;
        dst_pal[ 1].rgbBlue    =0x00;   /* 1:茶  */
        dst_pal[ 1].rgbGreen   =0x00;
        dst_pal[ 1].rgbRed     =0x80;
        dst_pal[ 1].rgbReserved=0x00;
        dst_pal[ 2].rgbBlue    =0x00;   /* 2:緑  */
        dst_pal[ 2].rgbGreen   =0x80;
        dst_pal[ 2].rgbRed     =0x00;
        dst_pal[ 2].rgbReserved=0x00;
        dst_pal[ 3].rgbBlue    =0x00;   /* 3:ウグイス ? */
        dst_pal[ 3].rgbGreen   =0x80;
        dst_pal[ 3].rgbRed     =0x80;
        dst_pal[ 3].rgbReserved=0x00;
        dst_pal[ 4].rgbBlue    =0x80;   /* 4:青  */
        dst_pal[ 4].rgbGreen   =0x00;
        dst_pal[ 4].rgbRed     =0x00;
        dst_pal[ 4].rgbReserved=0x00;
        dst_pal[ 5].rgbBlue    =0x80;   /* 5:紫  */
        dst_pal[ 5].rgbGreen   =0x00;
        dst_pal[ 5].rgbRed     =0x80;
        dst_pal[ 5].rgbReserved=0x00;
        dst_pal[ 6].rgbBlue    =0x80;   /* 6:水色  */
        dst_pal[ 6].rgbGreen   =0x80;
        dst_pal[ 6].rgbRed     =0x00;
        dst_pal[ 6].rgbReserved=0x00;
        dst_pal[ 7].rgbBlue    =0xC0;   /* 7:薄グレー  */
        dst_pal[ 7].rgbGreen   =0xC0;
        dst_pal[ 7].rgbRed     =0xC0;
        dst_pal[ 7].rgbReserved=0x00;
        dst_pal[ 8].rgbBlue    =0x80;   /* 8:グレー  */
        dst_pal[ 8].rgbGreen   =0x80;
        dst_pal[ 8].rgbRed     =0x80;
        dst_pal[ 8].rgbReserved=0x00;
        dst_pal[ 9].rgbBlue    =0x00;   /* 9:赤  */
        dst_pal[ 9].rgbGreen   =0x00;
        dst_pal[ 9].rgbRed     =0xFF;
        dst_pal[ 9].rgbReserved=0x00;
        dst_pal[10].rgbBlue    =0x00;   /* 10:黄緑  */
        dst_pal[10].rgbGreen   =0xFF;
        dst_pal[10].rgbRed     =0x00;
        dst_pal[10].rgbReserved=0x00;
        dst_pal[11].rgbBlue    =0x00;   /* 11:黄  */
        dst_pal[11].rgbGreen   =0xFF;
        dst_pal[11].rgbRed     =0xFF;
        dst_pal[11].rgbReserved=0x00;
        dst_pal[12].rgbBlue    =0xFF;   /* 12:青  */
        dst_pal[12].rgbGreen   =0x00;
        dst_pal[12].rgbRed     =0x00;
        dst_pal[12].rgbReserved=0x00;
        dst_pal[13].rgbBlue    =0xFF;   /* 13:ピンク  */
        dst_pal[13].rgbGreen   =0x00;
        dst_pal[13].rgbRed     =0xFF;
        dst_pal[13].rgbReserved=0x00;
        dst_pal[14].rgbBlue    =0xFF;   /* 14:水色2  */
        dst_pal[14].rgbGreen   =0xFF;
        dst_pal[14].rgbRed     =0x00;
        dst_pal[14].rgbReserved=0x00;
        dst_pal[15].rgbBlue    =0xFF;   /* 15:白(透明)  */
        dst_pal[15].rgbGreen   =0xFF;
        dst_pal[15].rgbRed     =0xFF;
        dst_pal[15].rgbReserved=0x00;

    src_bits = (char*)src_pal + sizeof(RGBQUAD) * 2;
    dst_bits = (char*)dst_pal + sizeof(RGBQUAD) * 16;
    memset(dst_bits, 0, dst_rowbyte * src_bih->biHeight);
    for (y=0; y < dst_bih->biHeight; ++y) {
        for (x=0; x < dst_bih->biWidth; ++x) {
            src_pos = src_rowbyte * y + (x / 8);
            dst_pos = dst_rowbyte * y + (x / 2);
            dst_bits[dst_pos] |= ((src_bits[src_pos] >> (7 - (x % 8))) & 0x01) << (4 * (1 - (x % 2)));
        }
    }
    return dst;
}

int putPixel(BITMAPINFOHEADER const * pInfo, BYTE * pFigureBuff, int x, int y, int colorIndex)
{
    int HorizonBytes;
    BYTE * pData;

    /* エラーチェック */
    if(pInfo == NULL) return -1;
    if(x < 0 || x >= pInfo->biWidth) return -1;
        if(y < 0 || y >= pInfo->biHeight) return -1;
    if(colorIndex< 0 || colorIndex>= 16) return -1;
    if(pInfo->biBitCount != 4) return -1;

        //上下逆さにする
        y = pInfo->biHeight - y - 1;

    HorizonBytes = ((4 * pInfo->biWidth + 31) / 32) * 4;
        pData = pFigureBuff + HorizonBytes * y + x/2;
        if(x&1) {
                *pData = (*pData & 0xf0) | colorIndex;
        }
        else {
                *pData = (*pData & 0x0f) | (colorIndex << 4);
        }
        return 0;
}

/*----- 水平線を引く -----*/
void drawHorizon(BITMAPINFOHEADER const * pInfo, BYTE * pFigureBuff, int sx, int sy, int ex, int colorIndex)
{
        if(sx <= ex)
        {
                for( ; sx <= ex; ++sx)
                {
                        putPixel(pInfo, pFigureBuff, sx, sy, colorIndex);
                }
        }
        else
        {
                for( ; sx >= ex; --sx)
                {
                        putPixel(pInfo, pFigureBuff, sx, sy, colorIndex);
                }
        }
}

//面倒なので省略
unsigned char BitMapFont8x8[][8]={
  {0x00, 0x7C, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0x7C}, /*-- 0  --*/
  {0x00, 0x7E, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18}, /*-- 1  --*/
  {0x00, 0xFE, 0xC0, 0x70, 0x1C, 0x06, 0xC6, 0x7C}, /*-- 2  --*/
  {0x00, 0x7C, 0xC6, 0x06, 0x1C, 0x06, 0xC6, 0x7C}, /*-- 3  --*/
  {0x00, 0x0C, 0xFE, 0xCC, 0x6C, 0x3C, 0x1C, 0x0C}, /*-- 4  --*/
  {0x00, 0x78, 0xCC, 0x06, 0x0C, 0xF8, 0xC0, 0xFE}, /*-- 5  --*/
  {0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0x60, 0x30, 0x1C}, /*-- 6  --*/
  {0x00, 0x30, 0x30, 0x30, 0x18, 0x0C, 0xC6, 0xFE}, /*-- 7  --*/
  {0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C}, /*-- 8  --*/
  {0x00, 0x78, 0x0C, 0x06, 0x7E, 0xC6, 0xC6, 0x7C}, /*-- 9  --*/
};

void drawNum(BITMAPINFOHEADER const * pInfo, BYTE * pFigureBuff, int x, int y, int num, int colorIndex)
{
    /* エラーチェック */
    if(pInfo == NULL) return;
    if(colorIndex< 0 || colorIndex>= 16) return;
    if(num< 0 || num> 9) return;

        for(int iy = 0; iy < 8; ++iy)
        {
                for(int ix = 0; ix < 8; ++ix)
                {
                        /* [7-iy]
                        putPixelに上下逆さにする機能があるので
                        BitMapFont8x8を上下逆さにする必要ないから
                        逆さにすることで戻す
                        */
                        int color = (BitMapFont8x8[num][7-iy] >> (7-ix)) & 1;
                        color = color * colorIndex;

                        putPixel(pInfo, pFigureBuff, x+ix, y+iy, color);
                }
        }
}

void test()
{
        //◆avlファイルの代わりに1bppビットマップを読み込む
        //本来はちゃんとサイズを計算すべき
        unsigned char * bitmap1_buffer = new unsigned char[5000];
        FILE * file;
        //本来はフルパスにしたりエラーチェックすべき
        file = fopen("test1bpp1.bmp","rb");
        int bitmap1_size = fread(bitmap1_buffer,1,5000,file);
        fclose(file);
        //本来は確認すべきだが絶対1bppとする
        BITMAPFILEHEADER * bitmap1_bmpfile = (BITMAPFILEHEADER*)bitmap1_buffer;
        BITMAPINFOHEADER * bitmap1_bmpinfo = (BITMAPINFOHEADER*)(bitmap1_buffer + sizeof(BITMAPFILEHEADER));
        RGBQUAD * bitmap1_rgbquad = (RGBQUAD*)(bitmap1_buffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
        unsigned char * bitmap1_image = bitmap1_buffer + bitmap1_bmpfile->bfOffBits;

        //◆4bpp変換
        unsigned char * bitmap4_buffer = (unsigned char *)cnv_2to16(bitmap1_bmpinfo);
        BITMAPINFOHEADER * bitmap4_bmpinfo = (BITMAPINFOHEADER*)(bitmap4_buffer);
        RGBQUAD * bitmap4_rgbquad = (RGBQUAD*)(bitmap4_buffer + sizeof(BITMAPINFOHEADER));
        unsigned char * bitmap4_image = bitmap4_buffer + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*16;

        //◆描画テスト
        drawHorizon(bitmap4_bmpinfo, bitmap4_image, 10,10,20, 15);
        drawHorizon(bitmap4_bmpinfo, bitmap4_image, 11,11,21, 14);
        drawNum(bitmap4_bmpinfo, bitmap4_image,  0,20, 1, 13);
        drawNum(bitmap4_bmpinfo, bitmap4_image, 11,20, 2, 13);
        drawNum(bitmap4_bmpinfo, bitmap4_image, 24,20, 3, 13);
        drawNum(bitmap4_bmpinfo, bitmap4_image, 28,25, 4, 12);

        //◆確認のためファイル保存
        //本来はフルパスにしたりエラーチェックすべき
        int HorizonBytes = ((4 * bitmap4_bmpinfo->biWidth + 31) / 32) * 4;
        int bitmap4_size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*16 + HorizonBytes * bitmap4_bmpinfo->biHeight;
        BITMAPFILEHEADER bitmap4_bmpfile;
        bitmap4_bmpfile.bfType = 'B' | ('M' << 8);
        bitmap4_bmpfile.bfSize = bitmap4_size + sizeof(BITMAPFILEHEADER);
        bitmap4_bmpfile.bfReserved1 = 0;
        bitmap4_bmpfile.bfReserved2 = 0;
        bitmap4_bmpfile.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*16;
        bitmap4_bmpinfo;
        file = fopen("test4bpp1.bmp","wb");
        fwrite(&bitmap4_bmpfile,1,sizeof(BITMAPFILEHEADER),file);
        fwrite(bitmap4_bmpinfo,1,bitmap4_size,file);
        fclose(file);

        delete[] bitmap1_buffer;
        free(bitmap4_bmpinfo);
}
  1. 2009/01/28(水) 23:35:20|
  2. Win/C++
  3. | コメント:1
<<ハードディスクがうるせー | ホーム | ソースコードに色を付けてHTMLってのをWYSIWYGで>>

コメント

承認待ちコメント

このコメントは管理者の承認待ちです
  1. 2009/01/30(金) 01:47:05 |
  2. |
  3. #
  4. [ 編集]

コメントの投稿


管理者にだけ表示を許可する

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。