Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fortran: How to store value 255 into one byte?

I would like to call a C api function from Fortran. The C function accepts an array of bytes:

void image(const void *bitmap, int w, int h);

where three successive bytes in *bitmap represent an RGB colour tripple and are interpreted as unsigned char in C. I want to initialize the bitmap in Fortran and take care of drawing inside C. Current definition in Fortran uses

integer*1 rgbImage(6,2)

to initialize an image of 2x2 for example, but compiler won't accept assignment

rgbImage(1,1) = 255

to get red colour. I've seen hints of using BYTE, UNSIGNED*1, LOGICAL*1 for unsigned single bytes, but gfortran (MacPort's gcc 4.4 or 4.6 under Mac OS X) isn't really happy with either of them. I could probably get away by cheating and assigning value -1 instead of 255, but that is very uncomfortable to use. The compiler flag -fno-range-check helped compile the code, but might not be available in other Fortran compilers and I consider it an ugly solution (I would still want to catch other warning). The values 'FF'X or '11111111'B are also recognized as 32-bit integers.

It is highly desirable for the code to be portable across different Fortran compilers.

like image 536
Mojca Avatar asked May 25 '12 14:05

Mojca


People also ask

What is a 4 byte integer?

4-byte values (word, int) If we combine 4 bytes, we get a value with 32 bits, which can store 65536*65536 distinct values. This gives a range of approximately 4 billion different values. In many languages, a data type referred to simply as an "int" (=integer) is assumed to be 4 bytes.

How many bytes is Fortran real?

REAL*16 (Quad Real) @ (SPARC only) The REAL*16 data type is a quadruple-precision real. The size for a REAL*16 item is 16 bytes.


1 Answers

My suggestion would be to use CHARACTER variables, and use ACHAR to set values (and ICHAR to convert back to integers as necessary). That should get you what you want and be completely portable. eg,

character, dimension(6,2) :: rgbImage

rgbImage(1,1) = achar(255)

Updated to add: if you're going to use the Fortran 2003 iso_c_binding stuff to interface to the C routines (highly recommended!) then you might as well make that rgbImage array characters of kind c_char, eg

character(kind=c_char), dimension(6,2) :: rgbImage
integer(kind=c_int) :: w, h

...
rgbImage(1,1) = achar(255)
...

call image(rgbImage, w, h)

where you've defined the interface for the routine

 interface
    subroutine image(img, w, h) bind(C)
       use, intrinsic :: iso_c_binding
       implicit none
       integer(kind=c_int), intent(in), value :: w, h
       character(kind=c_char) :: img(:,:)
    end subroutine image
 end interface
like image 175
Jonathan Dursi Avatar answered Jan 01 '23 07:01

Jonathan Dursi