Writing binary output

  • Follow


Hello,

I've spent at least a couple of hours trying to figure out how to output 
binary data with Fortran. Specifically, I want to write a PPM file 
because it is a very simple image format. The simplest PPM file is an 
ASCII file that looks like this:

P3
# The P3 means colors are in ASCII, then 3 columns and 2 rows,
# then 255 for max color, then RGB triplets
3 2
255
255   0   0     0 255   0     0   0 255
255 255   0   255 255 255     0   0   0



This makes larger files than I'd like. There is a binary version where 
the pixel colours are just bytes... or at least, that's what I think it is:

P6
# The P6 means colors are in binary, then 3 columns and 2 rows,
# then 255 for max color, then RGB triplets
3 2
255
<byte><byte><byte><byte><byte><byte><byte><byte><byte>
<byte><byte><byte><byte><byte><byte><byte><byte><byte>
<byte><byte><byte><byte><byte><byte><byte><byte><byte>



I cannot figure out how to print some bytes directly. I have tried 
borrowing code from these pages:

http://ferret.pmel.noaa.gov/Ferret/documentation/users-guide/data-set-basics/BINARY-DATA

http://idlastro.gsfc.nasa.gov/idl_html_help/Reading_and_Writing_FORTRAN_Data.html


Nothing has worked so far. I have tried 'form="unformatted"' but that 
seems to insert garbage bytes into the binary file. I have tried 
'access="direct"' and I just can't get it to work. I'm feeling quite 
frustrated. It seems to me that printing bytes should be extremely easy 
and I don't understand why I can't find a simple and reliable way to do it.

Btw, the full specification of PPM is here:


http://netpbm.sourceforge.net/doc/ppm.html


Any help would be appreciated.

Daniel.
0
Reply daniel8127 (276) 12/19/2011 4:34:47 PM

On 2011-12-19 12:34:47 -0400, Daniel Carrera said:

> Hello,
> 
> I've spent at least a couple of hours trying to figure out how to 
> output binary data with Fortran. Specifically, I want to write a PPM 
> file because it is a very simple image format. The simplest PPM file is 
> an ASCII file that looks like this:
> 
> P3
> # The P3 means colors are in ASCII, then 3 columns and 2 rows,
> # then 255 for max color, then RGB triplets
> 3 2
> 255
> 255   0   0     0 255   0     0   0 255
> 255 255   0   255 255 255     0   0   0
> 
> 
> 
> This makes larger files than I'd like. There is a binary version where 
> the pixel colours are just bytes... or at least, that's what I think it 
> is:
> 
> P6
> # The P6 means colors are in binary, then 3 columns and 2 rows,
> # then 255 for max color, then RGB triplets
> 3 2
> 255
> <byte><byte><byte><byte><byte><byte><byte><byte><byte>
> <byte><byte><byte><byte><byte><byte><byte><byte><byte>
> <byte><byte><byte><byte><byte><byte><byte><byte><byte>

Instead of byte think character. There is no need for the character to 
correspond
to a printing character in most implementations. Beware that the ASCII control
characters might cause troubles in formatted output. The whole issue of end of
line can also be a problem in formatted files, particulkarly if you accidently
generate one.

So you end up with characters in a stream file. If it is not a 
formatted file there
is even less need for thr artifice of a character. Many fortrans have a 
one byte integer.

> I cannot figure out how to print some bytes directly. I have tried 
> borrowing code from these pages:
> 
> http://ferret.pmel.noaa.gov/Ferret/documentation/users-guide/data-set-basics/BINARY-DATA 
> 
> 
> http://idlastro.gsfc.nasa.gov/idl_html_help/Reading_and_Writing_FORTRAN_Data.html 
> 
> 
> 
> Nothing has worked so far. I have tried 'form="unformatted"' but that 
> seems to insert garbage bytes into the binary file. I have tried 
> 'access="direct"' and I just can't get it to work. I'm feeling quite 
> frustrated. It seems to me that printing bytes should be extremely easy 
> and I don't understand why I can't find a simple and reliable way to do 
> it.
> 
> Btw, the full specification of PPM is here:
> 
> 
> http://netpbm.sourceforge.net/doc/ppm.html
> 
> 
> Any help would be appreciated.
> 
> Daniel.


0
Reply Gordon.Sande1 (250) 12/19/2011 4:56:44 PM


Daniel Carrera <daniel@gmail.com> wrote:

> I've spent at least a couple of hours trying to figure out how to output
> binary data with Fortran.

Before giving a more constructive answer, I'll first insert my usual
knee-jerk reaction to this use of the term "binary". "Binary" means
"base 2", which has little to do with what you are looking for. Pretty
much everything on your computer is binary (base 2) at some level,
though sometimes you can have decimal coded in binary. Yes, I know it is
a very common use of the term these days - not something you invented.
But it is still a use I dislike. Terms like "transparent", "raw", or
"unformatted" are a lot closer.

In fact, the problem that is vexing you has mostly to do with record
structure. (So the solution is to get rid of the records).

> Nothing has worked so far. I have tried 'form="unformatted"' but that
> seems to insert garbage bytes into the binary file.

That's the right direction. Those "garbage bytes" are part of the record
structure. That's not so much a function of it being unformatted as of
it being sequential and record-oriented. Sequential formatted files also
have simillar "garbage bytes" to delineate the records (most commonly
some combination of carriage return and line feed, though systems do
exist that use other schemes). Direct access files avoid the "garbage"
by being constant length and thus not needing delineation (in most
implementations).

> I have tried 'access="direct"' and I just can't get it to work.

Unformatted direct access can work, but indeed it gets messy. I've done
that, but it isn't what I'd recommend for new code today.

> I'm feeling quite 
> frustrated. It seems to me that printing bytes should be extremely easy
> and I don't understand why I can't find a simple and reliable way to do it.

Understandable. The complications involved are exactly why I pushed for
stream I/O to be added to f2003. I wrote the paper that first formally
proposed it, and I had some trepidation about how it would be recieved
because it was after what was supposed to be the deadline for new
features. Turns out that the only negative reactions to the paper were
that a majority wanted it to go further (my initial paper had only
unformatted stream).

Anyway, unformatted stream is exactly what you want. Though it is an
f2003 feature, most f95 compilers support it. If you happen to need to
use a compiler that doesn't support the exact syntax of the f2003
feature, it is bound to support comparable functionality with a
different nonstandard spelling. I recommend starting with the f2003
standard form and only going the nonstandard route if your compiler
doesn't support the standard one.
 
You want form='unformatted', access='stream'.

I note that the first url you cited does talk about stream files as a
structure, but it then goes into how to access them using direct access,
which is not what I'd recommend today. There was a time when that was
the most portable way, but it gets messy.

The "stream" basically means that the file doesn't have a record
structure. (Well, formatted stream is more complicated, but that's not
what you want).

-- 
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain
0
Reply nospam47 (9742) 12/19/2011 5:07:07 PM

On 12/19/2011 06:07 PM, Richard Maine wrote:
> Yes, I know it is
> a very common use of the term these days - not something you invented.
> But it is still a use I dislike. Terms like "transparent", "raw", or
> "unformatted" are a lot closer.

I see your point about "binary" but to me "transparent", "raw" and 
"unformatted" don't mean anything.


> Anyway, unformatted stream is exactly what you want. Though it is an
> f2003 feature, most f95 compilers support it. If you happen to need to
> use a compiler that doesn't support the exact syntax of the f2003
> feature, it is bound to support comparable functionality with a
> different nonstandard spelling. I recommend starting with the f2003
> standard form and only going the nonstandard route if your compiler
> doesn't support the standard one.
>
> You want form='unformatted', access='stream'.


Thanks. That seems to work a lot better. I'm still struggling a bit, but 
I think it has to do with the PPM format itself rather than Fortran.

Cheers,
Daniel.
0
Reply daniel8127 (276) 12/19/2011 8:48:15 PM

Daniel Carrera <daniel@gmail.com> wrote:
> On 12/19/2011 06:07 PM, Richard Maine wrote:
>> Yes, I know it is
>> a very common use of the term these days - not something you invented.
>> But it is still a use I dislike. Terms like "transparent", "raw", or
>> "unformatted" are a lot closer.

> I see your point about "binary" but to me "transparent", "raw" and 
> "unformatted" don't mean anything.

Note that for unix terminal I/O, the alternative to "raw" is "cooked."

When decimal machines, with decimal addressing and a storage system
that didn't allow for a power of two different values per word, were
popular, the distinction was a little different.

To me, "binary" only makes sense if all bit patterns are allowed.

If only 255 values per byte are allowed, then it is base 255, and
not binary, even if the underlying representation uses bits.

I probably like "transparent" or "raw", maybe a little better
than binary.  

Another example, IBM OS/360 and descendants allow for 256 different
values punched in a card column (no more than one punch in rows 1-7),
but card readers have a mode called "column binary" which will read
one column into two bytes in memory.  The direct map between punched
holes and bits in memory is an important difference.

-- glen
0
Reply gah (12254) 12/19/2011 10:34:19 PM

On 12/19/2011 11:34 PM, glen herrmannsfeldt wrote:
> To me, "binary" only makes sense if all bit patterns are allowed.
>
> If only 255 values per byte are allowed, then it is base 255, and
> not binary, even if the underlying representation uses bits.

That makes sense to me too. Are you saying that there is a bit pattern 
that is not allowed?


> Another example, IBM OS/360 and descendants allow for 256 different
> values punched in a card column (no more than one punch in rows 1-7),
> but card readers have a mode called "column binary" which will read
> one column into two bytes in memory.  The direct map between punched
> holes and bits in memory is an important difference.

Interesting.
0
Reply daniel8127 (276) 12/19/2011 11:28:25 PM

On 12/19/11 5:28 PM, Daniel Carrera wrote:
> On 12/19/2011 11:34 PM, glen herrmannsfeldt wrote:
>> To me, "binary" only makes sense if all bit patterns are allowed.
>>
>> If only 255 values per byte are allowed, then it is base 255, and
>> not binary, even if the underlying representation uses bits.
>
> That makes sense to me too. Are you saying that there is a bit pattern
> that is not allowed?
>
Technically, yes.  From chapter 3 "The processor character set is 
processor dependent."  Processors aren't required to provide anything 
more than the Fortran character set (letters, numbers, some special 
characters).  But, as a practical matter, processors do not put limits 
on the bit patterns that can be stored into character variables as a 
result of expressions evaluation.  Literal constants are more limited. 
Things like
char_var = "backspace or carriage return or bell or nonprintable ... "
are restricted.

Dick Hendrickson
>
>> Another example, IBM OS/360 and descendants allow for 256 different
>> values punched in a card column (no more than one punch in rows 1-7),
>> but card readers have a mode called "column binary" which will read
>> one column into two bytes in memory. The direct map between punched
>> holes and bits in memory is an important difference.
>
> Interesting.

0
Reply dick.hendrickson (1286) 12/20/2011 3:01:21 AM

Daniel, I sent a sample for writing .bmp-files (in FORTRAN ;-) )to
your e-mail address. You may want to convert these .bmp-files to .jpg
directly after production, since .jpg's are smaller (but I didn't know
how to generate them...).

Arjan
0
Reply arjan.van.dijk (248) 12/20/2011 10:43:05 AM

Hi Arjan,

Thanks for the help. I'll have a look at your sample right away.

Btw, ImageMagick should convvert BMP to jpg:

convert foo.bmp foo.pg

Cheers,
Daniel.

On 12/20/2011 11:43 AM, Arjan wrote:
> Daniel, I sent a sample for writing .bmp-files (in FORTRAN ;-) )to
> your e-mail address. You may want to convert these .bmp-files to .jpg
> directly after production, since .jpg's are smaller (but I didn't know
> how to generate them...).
>
> Arjan

0
Reply daniel8127 (276) 12/20/2011 10:50:23 AM

Daniel

As others have noted, you want stream I/O.   Some notes I wrote on it 
are here:
http://www.star.le.ac.uk/~cgp/streamIO.html

-- 
Clive Page
0
Reply usenet1820 (74) 12/20/2011 11:03:16 PM

9 Replies
105 Views

(page loaded in 0.227 seconds)

Similiar Articles:













7/14/2012 11:28:40 AM


Reply: