因此,作为学习Fortran的练习,我决定从我的并行编程类中重新实现一个分配,该分配的目的是加载,水平模糊然后保存PPM(P3)图像文件。我的code可以读取(具有适当的深度和尺寸),但是当我保存数据时,图像显示为乱码,几乎一半的数据丢失。
subroutine loadppm( this, filename )
class( ppmfile ) :: this
character( len = * ), intent( in ) :: filename
integer :: funit, cdepth, cwidth, cheight, x, y, cr, cg, cb, reason
character( 2 ) :: header
open( newunit = funit, file = filename, status = 'old', action = 'read', access = 'stream', form = 'formatted' )
read( funit, '(a2)' ) header
if ( header /= 'P3' ) then
print *, "Invalid file type detected."
stop
end if
read( funit, * ) cwidth, cheight
read( funit, * ) cdepth
if ( cdepth /= 255 ) then
print *, "Invalid colour depth detected."
stop
end if
this%width = cwidth
this%height = cheight
this%depth = cdepth
allocate( this%data( 3, this%width, this%height ) )
do y = 1, this%width
do x = 1, this%height
read( funit, *, IOSTAT = reason ) cr, cg, cb
if ( reason < 0 ) then
! EOF reached
exit
exit
end if
this%data( 1, y, x ) = cr
this%data( 2, y, x ) = cg
this%data( 3, y, x ) = cb
end do
end do
close( funit )
end subroutine loadppm
我将其范围缩小到loadppm()方法。由于某种原因,它会正确读取第一个像素。由于某种原因,每隔一个读入的像素是错误的。我尝试读取的格式可以归结为:
P3
2 2
255
232 112 255 255 255 255
112 212 2 97 12 112
第一行是标题,第二行是尺寸,第三行是颜色深度(始终为255)。之后的所有行都是像素数据,每个三元组都是给定像素的RGB值。当我输出读取的内容时,第一个三元组是正确的(例如,它匹配文件中的内容),但是之后的所有内容都是错误的;例如,它与文件中的内容不匹配。文件中会忽略换行符,但任何给定值之间都只有一个空格。
答案 0 :(得分:1)
Erik,
您遇到的问题是您使用read语句。在fortran中,即使该行上仍有数据,读语句也会在完成后始终前进到下一行。这就是为什么您正确读取某些数据的原因,它是该行开头的数据。
如果PPM中的所有整数正好是3个字符,则可以使用advance='no'
来解决此问题:
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cr
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cg
READ( funit, '(I3)', IOSTAT = reason, advance='no' ) cb
但是对于更一般的情况,您需要将整个行作为字符串读取,然后手动将其拆分为数组。