Tips of VC++ > ビットマップ > RIFF標準パレットファイル(*.pal)の構造
前へ戻る次へ進む


このドキュメントにはサンプルプログラムが含まれています。
ワークスペース
ソースファイル(テキスト)


RIFF標準パレットファイル(*.pal)の構造

パレットの標準保存形式として、拡張子がPALのパレットファイルがあります。 VCのリソースエディタで使われているやつです。 以前はペイントで使えたような気がしますが、 今はサポートされていないようです。

PALファイルは、テキストエディタなどで開くと分かるように 先頭にRIFFと記述されています。 したがって、RIFF形式の一つということになります。 RIFFというのは"Microsoft Resource Interchange File Format"の略で、 汎用なファイルフォーマットです。 PALファイルのほかにもメジャーなものとして、WAV,AVIなどいろいろあります。 それを、4文字のIDで区別しています。

PALファイルの構造はやたら簡単で、ようするにLOGPALETTE構造体を 強引にRIFF形式に当てはめてるだけです。 以下に構造を示します。

PALファイルの構造

あとは、実際に読み込んでみればいいですね。
こんな感じです。
読み込むだけじゃ面白くないので、テキストファイルに列挙してみたり。(笑

bool LoadRIFFPalette(LPCTSTR in_PalFile,LPCTSTR in_ResultFile)
{
	// バイナリモードで開くのがミソ
	ifstream file(in_PalFile,ios::binary|ios::in);

	DWORD id= 0;
	file.read((char*)&id,4);
	if ( id!='FFIR' )
		return false;

	DWORD datsize= 0;
	file.read((char*)&datsize,4);
	if ( datsize==0 )
		return false;

	PBYTE pCore= new BYTE[datsize];
	if ( pCore==NULL )
		return false;

	file.read(pCore,datsize);
	file.close();

	PBYTE p= pCore;

	::memcpy((char*)&id,p,4);
	if ( id!=' LAP' )
		return false;
	else
		p+=4;

	::memcpy((char*)&id,p,4);
	if ( id!='atad' )
		return false;
	else
		p+=4;

	::memcpy((char*)&datsize,p,4);
	if ( datsize==0 )
		return false;
	else
		p+=4;

	PLOGPALETTE pPal= (PLOGPALETTE)(new BYTE[datsize]);
	if ( pPal==NULL )
		return false;

	::memcpy(pPal,p,datsize);

	delete [] pCore;

	int entries= (datsize-4)/sizeof(PALETTEENTRY);
	if ( pPal->palVersion   ==0x300 &&
		 pPal->palNumEntries==entries )
	{
		ofstream result(in_ResultFile);

		char buf[30];

		for ( int i=0 ; i<entries; ++i )
		{
			::wsprintf(buf,"[%3d]: (%03d,%03d,%03d)\r\n",i,
				pPal->palPalEntry[i].peRed,
				pPal->palPalEntry[i].peGreen,
				pPal->palPalEntry[i].peBlue);
			result << buf;
		}

		result.close();

		delete [] pPal;

		return true;
	}

	delete [] pPal;

	return false;
}

順番に読み込んでいけばいいだけです。 それと、RIFFを意識しなくてもできます。 値のチェックをしっかりやることだけ考えればいいでしょう。 次に保存です。 ストリームに文字列を出力するのが一番簡単でしょう。

void SaveRIFFPalette(PLOGPALETTE in_pPal,LPCTSTR in_NewPal)
{
	// バイナリモードで開くのがミソ
	DWORD datsize= 4+in_pPal->palNumEntries*
		sizeof(PALETTEENTRY);

	ofstream file(in_NewPal,ios::out|ios::binary);
	file << "RIFF";

	datsize+=12;
	file.write((char*)&datsize,4);

	file << "PAL data";

	datsize-=12;
	file.write((char*)&datsize,4);
	file.write((char*)in_pPal,datsize);

	file.close();
}

サンプルでは、この二つの関数をそのまま使って、 (0,0,0)〜(255,255,255)のエントリを含むグレイスケールのパレットを保存して それを再び読み込んで、テキストファイルに列挙する。 というようなことを行っています。

Aug.12, 2002