Сохранение PPM в Фортране - PullRequest
0 голосов
/ 31 октября 2018

Итак, в качестве упражнения по изучению Фортрана я решил переопределить задание из моего класса параллельного программирования, целью которого является загрузка, размытие по горизонтали, а затем сохранение файла изображения PPM (P3). Мой код работает для чтения (он имеет правильную глубину и размеры), но когда я сохраняю данные, изображение получается искаженным и почти половина данных отсутствует.

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 данного пикселя. Когда мне нужно вывести то, что прочитано, первая тройка верна (как, например, она совпадает с тем, что находится в файле), но потом все неправильно; как в, это не соответствует тому, что находится в файле. Новые строки в файле игнорируются, но между данными значениями всегда есть только один пробел.

1 Ответ

0 голосов
/ 09 ноября 2018

Эрик

Проблема, с которой вы столкнулись, заключается в использовании вами оператора read. В Фортране оператор чтения всегда будет переходить на следующую строку после его завершения, даже если в строке остаются данные. Вот почему некоторые из ваших данных были прочитаны правильно, это были данные в начале строки.

Если бы все целые числа в вашем 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

Но для более общего случая вам нужно прочитать всю строку в виде строки и вручную разбить ее на массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...