いつもお世話になっております。
Ver3.10cでパレットカラーの不具合らしき症状を見つけたので、ご報告いたします。
DirectX Ver:3.10c
OS:Windows7 32bit Ultimate
Visual Studio 2010使用
症状:画面サイズが縦長の時MakePAL8ColorSoftImage
を使用した時、正常動作しない場合がある。
画像読み出しのメモリアドレスがずれていくような画になる。
コード説明;
16bit 1CHグレースケール Raw画像データを読み込み表示させるプログラムです。動作確認用なので、同じ画像が表示され続け、静止画を出しているのと同じ状態です。
720x405,530X707,600x600,760x980の4種類の画像サイズを読み込み表示させてみました。
inheight,inwidthで描画ウィンドウの高さと幅を設定しています。描画ウィンドウと画像サイズは一致しさせています。
元から16bit 1CHのグレースケール画像なのでR,G,B,アルファブレンドの8bitx4CH分のデータを書き込む手間を省くため、MakePAL8ColorSoftImageでパレットを作り、見かけ上8bit1CH分のデータをimage0に書き込むようにしていたのですが、530x707の縦長画像のときに正常に画が出ません。(いくつか他のサイズの縦長画像でも試しましたが症状は再現しました。)
ただ、画像サイズが大きくなると、正常になります。760x1090の画像では正常に画が出ます。
横長の画像や、縦横が同じサイズの画像では、特に今のところ異常は出ていません。
コメントアウトしていますが、パレットカラーではなく、MakeARGB9ColorSoftImageを使用すると、縦長画像530x707の画像でもおかしな画は出なくなります。
コード上、何か問題があればご指摘ください。
パレットカラー使用で、縦長画像(それもある画サイズ以下)で起こるので、DXライブラリの不具合ではないかと思っているのですが。
ご助言を頂ければ幸いです。
以上、よろしくお願いいたします。
#include "DxLib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <omp.h>
int WindowWidth = 1920;
int WindowHeight = 1200;
//int inwidth = 720;
//int inheight = 405;
int inwidth = 530;
int inheight = 707;
//int inwidth = 600;
//int inheight = 600;
//int inwidth = 760;
//int inheight = 1090;
//垂直同期Wait数
int VsyncCount = 3;
int Color0,Color1,Color2;
int i;
//Key入力検出用
int Key[256];
char tmpKey[256];
int KeyWait = 0;
long long int StartTime0,EndTime0,EndTime1,EndTime2,EndTime3,EndTime4,EndTime5;
BYTE *image0;
//FILE NAME用
char ch1[512],ch2[512] ;
//画像メモリエリア
unsigned short* pSrc16u_all;
unsigned short* pSrc16u_1;
unsigned char* pSrc8u_1;
FILE *fp1;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int handle0, grhandle0 ;
//入力画像エリア確保
pSrc16u_all = (unsigned short*)malloc(sizeof(unsigned short)*inwidth*inheight);
//入力画像を8bitシフト後のエリア確保
pSrc16u_1= (unsigned short*)malloc(sizeof(unsigned short)*inwidth*inheight);
//出力8bitデータ画像
pSrc8u_1= (unsigned char*)malloc(sizeof(unsigned short)*inwidth*inheight);
//LCD表示初期設定
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1;
//描画Windowsのサイズ設定
SetGraphMode( WindowWidth , WindowHeight , 32 ) ;
ChangeWindowMode(FALSE); // ウィンドウモードに設定
SetDrawScreen( DX_SCREEN_BACK ); //描画先を表画面に設定
// 空のフルカラー画像を作成する
//ALFA Blend Handle
//handle0 = MakeARGB8ColorSoftImage(inwidth,inheight) ;
//Palette Color Handle
handle0 = MakePAL8ColorSoftImage(inwidth,inheight) ;
//パレットカラーNormal
for(i = 0;i < 256;i++){
SetPaletteSoftImage(handle0,i,i,i,i,0);
}
//作成した画像handleの先頭アドレスを検出する。
image0 = ( BYTE * )GetImageAddressSoftImage( handle0 ) ;
//画像データの読み込み
//image1 W530xH707
strcpy(ch1,"Test530x707.raw");
//image2 W720x405
//strcpy(ch1,"Test720x405.raw");
//image3 600x600
//strcpy(ch1,"Test600x600.raw");
//image4 760x1090
//strcpy(ch1,"Test760x1090.raw");
fp1 = fopen(ch1,"rb");
if(fp1 == NULL){
printf("Input FILE Error!!\n");
getchar();
return -1;
}
fread(pSrc16u_all,sizeof(unsigned short),inwidth*inheight,fp1);
fclose(fp1);
//DEBUG 全てのデータから1枚Saveする。
fp1 = fopen("testout_img.raw","wb");
if(fp1 == NULL){
printf("Output FILE Error!!\n");
getchar();
return -1;
}
fwrite(pSrc16u_all,sizeof(unsigned short),inwidth*inheight,fp1);
fclose(fp1);
// 赤色の値を取得
Color0 = GetColor( 255 , 0 , 0 ) ;
// 青色の値を取得
Color1 = GetColor( 0 , 0 , 255 ) ;
// 緑色の値を取得
Color2 = GetColor( 0 , 255 , 0 ) ;
//LCDのVsyncを待ってLOOPをSTARTさせる。
WaitVSync(1) ;
//動画像表示(無限LOOPにしている:抜け出しはキー割り込み)
while(ProcessMessage()==0){
//処理時間の測定START
StartTime0 = GetNowCount() ;
//全ての画像から、1Frameデータを読み出す。
for(i=0;i<inwidth*inheight;i++){
pSrc16u_1[i] = pSrc16u_all[i]
>>8;
pSrc8u_1[i] = (unsigned char)pSrc16u_1[i];
}
//画像データのコピー
//Palaette Color Handle時使用
memcpy(image0,pSrc8u_1,sizeof(char)*inwidth*inheight);
//ARGB Color Handle時使用
//for(i=0;i<inheight*inwidth;i++){
// image0[i*4 ] = pSrc8u_1[i];
// image0[i*4+1] = pSrc8u_1[i];
// image0[i*4+2] = pSrc8u_1[i];
// image0[i*4+3] = 255; //Alfa Data
//}
//グラフィックハンドルを作成
grhandle0 = CreateGraphFromSoftImage( handle0 ) ;
EndTime0 = GetNowCount() ;
ClearDrawScreen();//ScreenのClear
//描画命令
DrawGraph( 0, 0, grhandle0, FALSE ) ;
//Image Information
DrawFormatString( 0,20 , Color0, "Through Test" ) ;
DrawFormatString( 0,40 , Color0, "ProcessTime0:%d[msec]\n",EndTime0-StartTime0 ) ;
DrawFormatString( 0,60 , Color0, "VsyncCount:%d\n",VsyncCount ) ;
WaitVSync(VsyncCount) ;
ScreenFlip(); //裏画面を表画面に反映
//メモリ読み込んだ画像を消去する。
//これを入れないと、多数の静止画を読み込んだ時、メモリが更新されなくなる。
InitGraph() ;
//処理時間の測定END
//KeyWait時間調整
if(VsyncCount<=1)
{
KeyWait = 4;
}
else if(VsyncCount==2)
{
KeyWait = 3;
}
else
{
KeyWait = 2;
}
//key Sense
GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
for( int i=0; i<256; i++ ){
if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
Key[i]++; // 加算
} else { // 押されていなければ
Key[i] = 0; // 0にする
}
}
//Vsync Wait Time Cahnge
if( Key[KEY_INPUT_NUMPAD3] >= KeyWait){
VsyncCount = VsyncCount + 1;
if(VsyncCount >= 10) VsyncCount = 10;
}
if( Key[KEY_INPUT_NUMPAD1] >= KeyWait){
VsyncCount = VsyncCount - 1;
if(VsyncCount <= 1) VsyncCount = 1;
}
//Program終了
if( Key[ KEY_INPUT_END ] >= 1 ){ // Endキーが押されていたら
DeleteSoftImage( handle0 ) ;
DxLib_End(); //終了
return 0;
}
}//__while
// 使い終わっったメモリ解放
free(pSrc16u_all);
free( pSrc16u_1);
free(pSrc8u_1);
// 使い終わったら解放
DeleteSoftImage( handle0 ) ;
// キー入力待ち
WaitKey();
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}