みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

fortran g95を使ってBMPを処理したい

以前XP環境でVisual Fortran(VF)を使ってBMPファイルを読み込むプログラム使っていました.
PCがWin7になった為,FreeのFortran g95を使用して同様の処理を行いたいのですが,上手くできません.例えば”test.bmp”と言う8bitのファイルを読み込みたいとしたとき,
VFでは
character*1078 temp
integer*1 data
open(10,file='test.bmp',form='binary')
read(10)temp
read(10)data
このときwrite(*,*)dataは133とします.

g95では"binary"が使用できず,
character*1078 temp
chracter*1 data
open(10,file='test.bmp',form='formatted')
read(10,*)temp
read(10,*)data
data2=ichar(data)
write(*,*)data2は32となってしまいます.
画像の輝度は133で,VFで読み込んだ値となります.

上のプログラムで何を直せば g95でも正しい輝度情報を読めるのでしょうか?
どうぞ宜しくお願いします.

投稿日時 - 2011-06-27 18:46:42

QNo.6839020

すぐに回答ほしいです

質問者が選んだベストアンサー

じゃあ,こんな感じ。
character*4 t4
character*1078 temp
character*1 data
open(10,file='test.bmp',form='unformatted',access='direct',recl=1)
do i=1,1078
read(10,rec=i)temp(i:i)
enddo
read(10,rec=1079)data
data2=ichar(data)
write(*,*)data2
end


でもg95で
> access='stream'を代入するとエラーが出てしまいます.
というのはどうしてだろう?私の環境では

$ g95 -v
Using built-in specs.
Target:
Configured with: ../configure --prefix=/mingw --enable-languages=c --with-ld=/mi
ngw/bin/ld --with-as=/mingw/bin/as --host=i386-pc-mingw32 --enable-threads --dis
able-nls --disable-win32-registry --enable-sjlj-exceptions --enable-libgcj --wit
hout-x
Thread model: win32
gcc version 4.1.2 (g95 0.93!) Jun 16 2010

$ cat aa.f95
character*4 t4
character*1078 temp
character*1 data
!integer*1 data
open(10,file='test.bmp',form='unformatted',access='stream')
read(10)temp
read(10)data
!write(10)temp
!write(10)data
data2=ichar(data)
write(*,*)data2
end

$ g95 aa.f95

$ ./a
141.

$
こんな感じだったよ。
で,確かにtest.bmpの1079バイト目をバイナリエディタで確認してもZ'8D'です。

投稿日時 - 2011-06-28 19:43:26

お礼

たびたびコメントを頂きありがとうございます.

私の環境では,
read(10,rec=i)temp(i:i)
ではコンパイルを通りません.

ただ,
do i=1,1078
read(10,rec=i)
end do

read(10,rec=1079)data
data2=ichar(data2)
write(*,*)data2

とすると「133」が表示され,正しい値を返しているようです.

*********
教えて頂きましたプログラ中
character*4 t4
は何でしょうか?
また
read(10,rec=i)temp(i:i)
はどう言う意味になるのでしょうか?
普段使用しない書き方なので良く意味がとらえられません

*********
おそらく教えていただきましたコメントで,
私の行いたかったことができそうです.

上記に関するコメントは,お時間のある時で構いませんので
ご教授頂ければと思います.

本当に有難うございました.

投稿日時 - 2011-06-29 17:46:52

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

> 教えて頂きましたプログラ中
> character*4 t4
> は何でしょうか?

これはちょっと違うことを書いていたときに使った変数で,今となっては単なるゴミです。
消してもかまいません。

> また
> read(10,rec=i)temp(i:i)
> はどう言う意味になるのでしょうか?
> 普段使用しない書き方なので良く意味がとらえられません

文字部分列と言われるもので,文字列の連続する部分集合を表します。
string ([ starting-position ] : [ ending-position ])
こんな感じで使用して,文字列中での開始位置と終了位置を指定します。
だからtemp(i:i)は文字列tempのi文字目を表し,10番のファイルのi番目のレコードを文字列tempのi文字目に読み込むことになります。ファイルの1バイト目から1078バイト目が必要でなければ,doループ全体が必要ではなく
character*1 data
open(10,file='test.bmp',form='unformatted',access='direct',recl=1)
read(10,rec=1079)data
data2=ichar(data)
write(*,*)data2
end
これでも同じ結果を返すはず。

投稿日時 - 2011-06-29 18:30:55

ANo.1

わざわざg95で確かめることはしてないけど
character*1078 temp
character*1 data
open(10,file='test.bmp',form='unformatted',access='stream')
read(10)temp
read(10)data
data2=ichar(data)
write(*,*)data2
end
こんな感じ?

投稿日時 - 2011-06-27 21:02:20

お礼

コメント有難う御座います.早速試したところ,
open(10,file='test.bmp',form='unformatted',access='stream')
のaccess='stream'を代入するとエラーが出てしまいます.
access='stream'を削除した場合,
read(10)temp
read(10)data
でread(10)tempによりデータを読みに行った箇所でエラーが出てしまいます.

私もはじめ教えていただいたものと同等のプログラムで動くかと思ったのですが,unformatted,read(10)の記述でエラーが出てしまい,formatted, read(10,*)だと何とか動くのですが,帰ってくる値が以前のものと違い,何処に問題があるのかわからずにおります.

何かご存知でしたら教えていただければ大変助かります.

投稿日時 - 2011-06-28 09:23:14

あなたにオススメの質問