Bitmap/Write a PPM file: Difference between revisions

From Rosetta Code
Content added Content deleted
(Vedit macro language added)
No edit summary
Line 6: Line 6:


=={{header|Ada}}==
=={{header|Ada}}==
<ada>
<lang ada>
with Ada.Characters.Latin_1;
with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
Line 33: Line 33:
Character'Write (Stream (File), LF);
Character'Write (Stream (File), LF);
end Put_PPM;
end Put_PPM;
</ada>
</lang>
The solution writes the image into an opened file. The file format might fail to work on certain [[OS]]es, because output might mangle control characters like LF, CR, FF, HT, VT etc. The OS might also limit the line length of a text file. In general it is a bad idea to mix binary and text output in one file. This solution uses ''stream I/O'', which should be as portable as possible.
The solution writes the image into an opened file. The file format might fail to work on certain [[OS]]es, because output might mangle control characters like LF, CR, FF, HT, VT etc. The OS might also limit the line length of a text file. In general it is a bad idea to mix binary and text output in one file. This solution uses ''stream I/O'', which should be as portable as possible.


Line 67: Line 67:
== {{Header|OCaml}} ==
== {{Header|OCaml}} ==


<ocaml>let output_ppm ~oc ~img:(_, r_channel, g_channel, b_channel) =
<lang ocaml>let output_ppm ~oc ~img:(_, r_channel, g_channel, b_channel) =
let width = Bigarray.Array2.dim1 r_channel
let width = Bigarray.Array2.dim1 r_channel
and height = Bigarray.Array2.dim2 r_channel in
and height = Bigarray.Array2.dim2 r_channel in
Line 80: Line 80:
output_char oc '\n';
output_char oc '\n';
flush oc;
flush oc;
;;</ocaml>
;;</lang>


=={{header|Vedit macro language}}==
=={{header|Vedit macro language}}==

Revision as of 15:57, 3 February 2009

Task
Bitmap/Write a PPM file
You are encouraged to solve this task according to the task description, using any language you may know.

Using the data storage type defined on this page for raster images, write the image to a PPM file (binary P6 prefered).
(Read the definition of PPM file on Wikipedia.)

Ada

<lang ada> with Ada.Characters.Latin_1; with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;

procedure Put_PPM (File : File_Type; Picture : Image) is

  use Ada.Characters.Latin_1;
  Size   : constant String := Integer'Image (Picture'Length (2)) & Integer'Image (Picture'Length (1));
  Buffer : String (1..Picture'Length (2) * 3);
  Color  : Pixel;
  Index  : Positive;

begin

  String'Write (Stream (File), "P6" & LF);
  String'Write (Stream (File), Size (2..Size'Last) & LF);
  String'Write (Stream (File), "255" & LF);
  for I in Picture'Range (1) loop
     Index := Buffer'First;
     for J in Picture'Range (2) loop
        Color := Picture (I, J);
        Buffer (Index)     := Character'Val (Color.R);
        Buffer (Index + 1) := Character'Val (Color.G);
        Buffer (Index + 2) := Character'Val (Color.B);
        Index := Index + 3;
     end loop;
     String'Write (Stream (File), Buffer);
  end loop;
  Character'Write (Stream (File), LF);

end Put_PPM; </lang> The solution writes the image into an opened file. The file format might fail to work on certain OSes, because output might mangle control characters like LF, CR, FF, HT, VT etc. The OS might also limit the line length of a text file. In general it is a bad idea to mix binary and text output in one file. This solution uses stream I/O, which should be as portable as possible.

C

<C>#include <stdio.h>

void output_ppm(FILE *fd, image img) {

   unsigned int n;
   fprintf(fd, "P6\n%d %d\n255\n", img->width, img->height);
   n = img->width * img->height;
   fwrite(img->buf, sizeof(pixel), n, fd);
   fflush(fd);

}</C>

Forth

: write-ppm { bmp fid -- }
  s" P6"             fid write-line throw
  bmp bdim swap
  0 <# bl hold #s #> fid write-file throw
  0 <#         #s #> fid write-line throw
  s" 255"            fid write-line throw
  bmp bdata  bmp bdim * pixels
  bounds do
    i 3              fid write-file throw
  pixel +loop ;
s" red.ppm" w/o create-file throw
test over write-ppm
close-file throw

OCaml

<lang ocaml>let output_ppm ~oc ~img:(_, r_channel, g_channel, b_channel) =

 let width = Bigarray.Array2.dim1 r_channel
 and height = Bigarray.Array2.dim2 r_channel in
 Printf.fprintf oc "P6\n%d %d\n255\n" width height;
 for y = 0 to pred height do
   for x = 0 to pred width do
     output_char oc (char_of_int r_channel.{x,y});
     output_char oc (char_of_int g_channel.{x,y});
     output_char oc (char_of_int b_channel.{x,y});
   done;
 done;
 output_char oc '\n';
 flush oc;
</lang>

Vedit macro language

This routine creates a RAW PPM file (binary). Pixel data must be stored in edit buffer pointed by numeric register #10. The data in the buffer is assumed to be in R,G,B order, which is the order used by PPM file.

/////////////////////////////////////////////////////////////////////
//
//  Save image as PPM file.
//  @10 = filename.  Buffer #10 contains the Pixel data.
//
:SAVE_PPM:
Buf_Switch(#10)
BOF
IT("P6") IN
Num_Ins(#11, LEFT)	  // width of image
Num_Ins(#12, LEFT)	  // height of image
Num_Ins(255, LEFT+NOCR)	  // maxval
IC(10)
File_Save_As(@10, OK)
Return