Bitmap/Write a PPM file: Difference between revisions

→‎Ada: Fixed tipo an better reference
mNo edit summary
(→‎Ada: Fixed tipo an better reference)
Tags: Mobile edit Mobile web edit
(8 intermediate revisions by 4 users not shown)
Line 76:
print(bitmap.writeppmp3())
 
File(‘tmp.ppm’, ‘w’WRITE).write_bytes(bitmap.writeppmp6())</syntaxhighlight>
 
{{out}}
Line 89:
0 0 0 255 255 255 0 0 0 0 0 0
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Bitmap tools}}
Line 203 ⟶ 204:
<syntaxhighlight lang="ada">with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
 
with Bitmap_Store; use Bitmap_Store;
-- This package is defined in the Bitmap task.
 
procedure Put_PPM (File : File_Type; Picture : Image) is
Line 228 ⟶ 232:
end Put_PPM;</syntaxhighlight>
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.
 
=={{header|Aime}}==
<syntaxhighlight lang="aime">integer i, h, j, w;
Line 265 ⟶ 270:
500 R = C - INT (C / 256) * 256:B = INT (C / 65536):G = INT (C / 256) - B * 256:A = BB + X * 3 + Y * W * 3: POKE A,R: POKE A + 1,G: POKE A + 2,B: RETURN
600 FOR Y = 0 TO H - 1: FOR X = 0 TO W - 1: GOSUB 500: NEXT X,Y: RETURN</syntaxhighlight>
=={{header|ATS}}==
For this code you will also need <code>bitmap_task.sats</code> and <code>bitmap_task.dats</code> from [[Bitmap#ATS]].
 
The static file provides templates for writing a PPM in either raw or plain format, regardless of what type you use to represent a pixel. The dynamic file, however, provides implementations ''only'' for the <code>rgb24</code> type defined in <code>bitmap_task.sats</code>.
 
===The ATS static file===
The following interface file should be named <code>bitmap_write_ppm_task.sats</code>.
<syntaxhighlight lang="ats">
#define ATS_PACKNAME "Rosetta_Code.bitmap_write_ppm_task"
 
staload "bitmap_task.sats"
 
(* Only pixmaps with positive width and height (pixmap1) are accepted
for writing a PPM. *)
 
fn {a : t@ype}
pixmap_write_ppm_raw_or_plain
(outf : FILEref,
pix : !pixmap1 a,
plain : bool)
: bool (* success *)
 
fn {a : t@ype}
pixmap_write_ppm_raw
(outf : FILEref,
pix : !pixmap1 a)
: bool (* success *)
 
overload pixmap_write_ppm with pixmap_write_ppm_raw_or_plain
overload pixmap_write_ppm with pixmap_write_ppm_raw
</syntaxhighlight>
 
===The ATS dynamic file===
The following file of implementations should be named <code>bitmap_write_ppm_task.dats</code>.
<syntaxhighlight lang="ats">
(*------------------------------------------------------------------*)
 
#define ATS_DYNLOADFLAG 0
#define ATS_PACKNAME "Rosetta_Code.bitmap_write_ppm_task"
 
#include "share/atspre_staload.hats"
 
staload "bitmap_task.sats"
 
(* You need to staload bitmap_task.dats, so the ATS compiler will have
access to its implementations of templates. But we staload it
anonymously, so the programmer will not have access. *)
staload _ = "bitmap_task.dats"
 
staload "bitmap_write_ppm_task.sats"
 
(*------------------------------------------------------------------*)
 
(* Realizing that MAXVAL, and how to represent depend on the
pixel type, we implement the template functions ONLY for pixels of
type rgb24. *)
 
(* We will implement raw PPM using "dump", and plain PPM using the
"get a pixel" square brackets. The latter method is simpler than
writing a different implementation of pixmap$pixels_dump<rgb24>,
and also helps us satisfy the stated requirements of the task.
("Dump" goes beyond what was asked for.) *)
 
implement
pixmap_write_ppm_raw_or_plain<rgb24> (outf, pix, plain) =
begin
fprintln! (outf, (if plain then "P3" else "P6") : string);
fprintln! (outf, width pix, " ", height pix);
fprintln! (outf, "255");
if ~plain then
dump<rgb24> (outf, pix)
else
let
val w = width pix and h = height pix
prval [w : int] EQINT () = eqint_make_guint w
prval [h : int] EQINT () = eqint_make_guint h
 
fun
loop {x, y : nat | x <= w; y <= h}
.<h - y, w - x>.
(pix : !pixmap (rgb24, w, h),
x : size_t x,
y : size_t y)
: void =
if y = h then
()
else if x = w then
loop (pix, i2sz 0, succ y)
else
let
val @(r, g, b) = rgb24_values pix[x, y]
in
fprintln! (outf, r, " ", g, " ", b);
loop (pix, succ x, y)
end
in
loop (pix, i2sz 0, i2sz 0);
true
end
end
 
implement
pixmap_write_ppm_raw<rgb24> (outf, pix) =
pixmap_write_ppm_raw_or_plain<rgb24> (outf, pix, false)
 
(*------------------------------------------------------------------*)
 
#ifdef BITMAP_WRITE_PPM_TASK_TEST #then
 
implement
main0 () =
let
val bgcolor = rgb24_make (217u, 217u, 214u)
and fgcolor1 = rgb24_make (210, 0, 0)
and fgcolor2 = rgb24_make (0, 150, 0)
and fgcolor3 = rgb24_make (0, 0, 220)
 
stadef w = 300
stadef h = 200
val w : size_t w = i2sz 300
and h : size_t h = i2sz 200
 
val @(pfgc | pix) = pixmap_make<rgb24> (w, h, bgcolor)
val () =
let
var x : Size_t
in
for* {x : nat | x <= w}
.<w - x>.
(x : size_t x) =>
(x := i2sz 0; x <> w; x := succ x)
begin
pix[x, i2sz 50] := fgcolor1;
pix[x, i2sz 100] := fgcolor2;
pix[x, i2sz 150] := fgcolor3
end
end
 
val outf_raw = fileref_open_exn ("image-raw.ppm", file_mode_w)
and outf_plain = fileref_open_exn ("image-plain.ppm", file_mode_w)
 
val success = pixmap_write_ppm<rgb24> (outf_raw, pix)
val () = assertloc success
val success = pixmap_write_ppm<rgb24> (outf_plain, pix, true)
val () = assertloc success
in
fileref_close outf_raw;
fileref_close outf_plain;
free (pfgc | pix)
end
 
#endif
 
(*------------------------------------------------------------------*)
</syntaxhighlight>
 
There is a test program that you can compile and run thus:
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC -DATS BITMAP_WRITE_PPM_TASK_TEST bitmap_{,write_ppm_}task.{s,d}ats
$ ./a.out
</pre>
If everything worked, you should end up with two image files, <code>image-raw.ppm</code> and <code>image-plain.ppm</code>. The former will have been made with the "dump" functionality that outputs the raw pixel data in one call to <code>fwrite(3)</code>. The latter will have been written more in the way the task assumes: reading pixels individually, left-to-right and top-to-bottom.
 
The images should appear thus:
 
[[File:Bitmap write ppm task ATS.png|alt=A gray background with red, green, and blue horizontal stripes, one pixel thick each, evenly placed, top to bottom.]]
 
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L|45}}
Line 300 ⟶ 471:
}
</syntaxhighlight>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">#!/usr/bin/awk -f
Line 2,360 ⟶ 2,532:
=={{header|Wren}}==
{{libheader|DOME}}
{{libheader|Wren-str}}
This takes a while to run as DOME needs to build up the file contents in string form before saving them to a PPM file. It is not currently possible to write files a line at a time.
<syntaxhighlight lang="ecmascriptwren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window, Process
import "io" for FileSystem
import "./str" for Strs
 
class Bitmap {
Line 2,384 ⟶ 2,557:
init() {
// write bitmap to a PPM file
var ppm = ["P6\n%(_w) %(_h)\n255\n"]
for (y in 0..._h) {
for (x in 0..._w) {
var c = pget(x, y)
ppm = ppm + .add(String.fromByte(c.r))
ppm = ppm + .add(String.fromByte(c.g))
ppm = ppm + .add(String.fromByte(c.b))
}
}
FileSystem.save("output.ppm", Strs.concat(ppm))
Process.exit(0)
}
Line 2,407 ⟶ 2,580:
 
var Game = Bitmap.new("Bitmap - write to PPM file", 320, 320)</syntaxhighlight>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
3

edits