program demo_ppm
use forimage, only: format_pnm, rk, ik
implicit none
! Declare format_pnm object and parameters for image dimensions
type(format_pnm) :: image, copy_image
integer, parameter :: height = 400
integer, parameter :: width = 400
integer(ik) :: px(height, 3*width)
! Generate Mandelbrot fractal and assign pixel values
px = mandelbrot(height, width)
! Set the properties of the format_pnm object (encoding, file format, width, height, max_color, comment and pixels)
call image%set_pnm(&
encoding = 'binary', &
file_format = 'ppm', &
width = width, &
height = height, &
max_color = 255, &
comment = 'demo: mandelbrot', &
pixels = px &
)
! Print information about the image
call image%print_info()
! Export the image to a PPM file
call image%export_pnm('pnm_files/mandelbrot_binary')
! Export the image to a PPM file with ascii encoding
call image%export_pnm('pnm_files/mandelbrot_ascii', 'ascii')
! Export the image to a PPM file with a different encoding
copy_image = image ! Copy the format_pnm object
call copy_image%negative()
call copy_image%export_pnm('pnm_files/mandelbrot_binary_negative', 'binary')
call copy_image%finalize()
! Brighten the image
copy_image = image ! Copy the format_pnm object
call copy_image%brighten(100)
call copy_image%export_pnm('pnm_files/mandelbrot_binary_brighten', 'binary')
call copy_image%finalize()
! Swap the red and blue channels
copy_image = image ! Copy the format_pnm object
call copy_image%swap_channels('rb')
call copy_image%export_pnm('pnm_files/mandelbrot_binary_swap', 'binary')
call copy_image%finalize()
! Remove the blue channel
copy_image = image ! Copy the format_pnm object
call copy_image%remove_channels(remove_b=.true.)
call copy_image%export_pnm('pnm_files/mandelbrot_binary_remove', 'binary')
call copy_image%finalize()
! Convert the image to greyscale
copy_image = image ! Copy the format_pnm object
call copy_image%greyscale()
call copy_image%export_pnm('pnm_files/mandelbrot_binary_greyscale', 'binary')
call copy_image%finalize()
! Rotate the image 90 degrees clockwise
copy_image = image ! Copy the format_pnm object
call copy_image%rotate(-90)
call copy_image%export_pnm('pnm_files/mandelbrot_binary_rotate', 'binary')
call copy_image%finalize()
! Flip the image horizontally
copy_image = image ! Copy the format_pnm object
call copy_image%flip_horizontal()
call copy_image%export_pnm('pnm_files/mandelbrot_binary_flip_horizontal', 'binary')
call copy_image%finalize()
! Flip the image vertically
copy_image = image ! Copy the format_pnm object
call copy_image%flip_vertical()
call copy_image%export_pnm('pnm_files/mandelbrot_binary_flip_vertical', 'binary')
call copy_image%finalize()
! Crop the image
copy_image = image ! Copy the format_pnm object
call copy_image%crop(100,200, 50, 300)
call copy_image%export_pnm('pnm_files/mandelbrot_binary_crop', 'binary')
call copy_image%finalize()
! Resize the image
copy_image = image ! Copy the format_pnm object
call copy_image%resize(800,200)
call copy_image%export_pnm('pnm_files/mandelbrot_binary_resize', 'binary')
call copy_image%finalize()
! Finalize the format_pnm object to release resources
call image%finalize()
! Import a PPM file with binary encoding and export it with ascii encoding
call image%import_pnm('pnm_files/mandelbrot_binary', 'ppm', 'binary')
call image%export_pnm('pnm_files/mandelbrot_ascii_ex', 'ascii')
call image%finalize()
! Import a PPM file with ascii encoding and export it with binary encoding
call image%import_pnm('pnm_files/mandelbrot_ascii', 'ppm', 'ascii')
call image%export_pnm('pnm_files/mandelbrot_binary_ex', 'binary')
call image%finalize()
contains
! Function to generate Mandelbrot fractal
pure function mandelbrot(h, w) result(pixels)
integer, intent(in) :: w, h
integer(ik) :: pixels(h, 3*w)
integer(ik), parameter :: max_iter = 256_ik
real(rk), parameter :: x_min = -2.0_rk
real(rk), parameter :: x_max = 1.0_rk
real(rk), parameter :: y_min = -1.5_rk
real(rk), parameter :: y_max = 1.5_rk
real(rk) :: x, y, x_temp, zx, zy, scale_x, scale_y
integer(ik) :: iter
integer :: i, j
! Calculate scale factors for mapping pixel coordinates to Mandelbrot coordinates
scale_x = (x_max - x_min) / real(w, kind=rk)
scale_y = (y_max - y_min) / real(h, kind=rk)
! Generate Mandelbrot fractal
do i = 1, h
do j = 1, w
x = x_min + real(j - 1, kind=rk) * scale_x
y = y_max - real(i - 1, kind=rk) * scale_y
zx = 0.0_rk
zy = 0.0_rk
iter = 0_ik
do while (iter < max_iter .and. zx * zx + zy * zy < 4.0_rk)
x_temp = zx * zx - zy * zy + x
zy = 2.0_rk * zx * zy + y
zx = x_temp
iter = iter + 1_ik
end do
! Assign colors
pixels(i, 3*j-2) = int(mod(iter*7_ik, 256_ik), kind=ik) ! Red channel
pixels(i, 3*j-1) = int(mod(iter*4_ik, 256_ik), kind=ik) ! Green channel
pixels(i, 3*j) = int(mod(iter*10_ik, 256_ik), kind=ik) ! Blue channel
end do
end do
end function
end program demo_ppm