掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
Photoshop 7 で作成したBitmapを読み込むには? (ID:11212)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
ようやくTBitmap のソースの該当部分を見終わりました。 しかし、EReadError 例外がなぜ起きるのか解りませんでした。 パレルさんより追加のサンプルを得ました。 試した結果は、次のとおりです。 X:EReadError; 0: nonError; red32x32.bmp 0 red63x63.bmp 0 red64x64.bmp X red65x65.bmp 0 red127x127.bmp 0 red127x128.bmp X red128x127.bmp 0 red128x128.bmp X red129x129.bmp 0 red256x256.bmp X 現象的には、次のことが確認できました。 1.BitmapInfoHeader.biSizeImage の値が不正で、 かつ、Height が64の倍数の場合のみ例外が発生する。 2. 性善説さんの指摘のようにGraphic.pasを修正し、 biSizeImageが常に正しくセットされるようにすると例外は発生しない。 3. BitmapInfoHeader.biSizeImage の値が不正のままであっても、 ファイルサイズがただしければ、エラーとならない。 3.については、パレルさんのサンプルから、ファイル末尾2バイトを削除して確認したことです。 今回の事例に限り有効です。 つまり、(1) BitmapFileHeader.bfOffBits の値が正しい。 (2) 実際のイメージデータも bfOffBits から始まっている。 (3) 不正部分は、ファイル末尾に存在している。 という条件です。 しかし、biSizeImage が不正であろうと、ファイルサイズが不正であろうと、 なぜ EReadError 例外が発生するの理由が解りません。 どなたか教えていただけないでしょうか。 尚、追加のサンプルも先の私のトピックのアドレスでダウンロードできるようにしました。私が作成し直した2バイト削除ファイルも同様です。 10.01のトピックで性善説さんが示された 5652://*** if biSizeImage = 0 then // top-down DIBs have negative height を基準(Delphi7 では 5912 にあたります)にソースを示してみます。 ---------------------------------------------------------------------- Delphi 7 では、56行くらいあとの Stream.ReadBuffer(BitsMem^, ImageSize); で例外が発生します。// <A> この手続きは、ImageSize に設定された値が0の場合か、 実際に読み込めた=存在していた読み込み対象のデータサイズと、 読み込みサイズを指定した ImageSize とが異なる場合に例外を起こします。 エラーとなるビットマップの場合に実際に読み込めたバイト数を調べたところ、ゼロでした。 すなわち、読み込みに失敗していたわけです。 この手続きは、最終的には ReadFile() API で読み込みを実行しています。 では、ReadFile() API はどういう場合に失敗するのでしょう。 (1) 読込先バッファへのポインタ BitsMem が nil の場合。 今回は、これはあり得ません。基準より 42行あとに if (BMHandle = 0) or (BitsMem = nil) then // <B> if GetLastError = 0 then InvalidBitmap else RaiseLastOSError; があり、そうであればここで例外が発生し <A> にまで到達できません。 (2) BitsMem が示す先にメモリが確保されていない メモリの確保は、<B>より1行前の BMHandle := CreateDIBSection(DC, BitmapInfo^, DIB_RGB_COLORS, BitsMem, 0, 0); で CreateDIBSection() API が行っているはずですが、どのようにしてくれているのか解りません。 (3) 確保されたメモリサイズが少なすぎる メモリの確保が正しいイメージサイズで行われていたとしても、 私の実験では、確保サイズより2バイトくらい多く読み込みを指定しても実行できてしまいます。 すなわち、書き込んではいけない領域にも連続して書き込んでしまう。 Windows も Delphi も管理してくれない。 (4) 読み込み対象のデータが存在しない これも今回はあり得ません。
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.