Bitmap/Read a PPM file: Difference between revisions

Added FreeBASIC
(Added Wren)
(Added FreeBASIC)
 
(14 intermediate revisions by 5 users not shown)
Line 1:
[[Category:Input Output]]
[[Category:E examples needing attention]]
{{task|Raster graphics operations}}
[[Category:Input Output]]
 
Using the data storage type defined [[Basic_bitmap_storage|on this page]] for raster images, read an image from a PPM file (binary P6 prefered).
Line 6 ⟶ 7:
 
'''Task''': Use [[write ppm file]] solution and [[grayscale image]] solution with this one in order to convert a color image to grayscale one.
 
=={{header|11l}}==
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">T Colour
Byte r, g, b
 
Line 107:
print(‘Grey PPM:’)
bitmap.togreyscale()
print(bitmap.writeppmp3())</langsyntaxhighlight>
 
{{out}}
Line 121:
4 4 4 0 0 0 0 0 0 0 0 0
</pre>
=={{header|Action!}}==
Part of the task responsible for conversion from RGB color image into a grayscale image can be found in the module [http://www.rosettacode.org/wiki/Category:Action!_Bitmap_tools#RGB2GRAY.ACT RGB2GRAY.ACT]. File D:PPM6.PPM can be generated by task [http://www.rosettacode.org/wiki/Bitmap/Write_a_PPM_file#Action.21 Bitmap/Write a PPM file].
{{libheader|Action! Bitmap tools}}
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang="action!">INCLUDE "H6:RGB2GRAY.ACT" ;from task Grayscale image
 
PROC DecodeSize(CHAR ARRAY s BYTE POINTER width,height)
BYTE i
 
width^=ValB(s)
i=1
WHILE i<=s(0) AND s(i)#32
DO
s(i)=32
i==+1
OD
height^=ValB(s)
RETURN
 
PROC LoadHeader(RgbImage POINTER img
CHAR ARRAY format BYTE dev)
CHAR ARRAY line(255)
BYTE header,size,max,width,height
 
header=0 size=0 max=0
WHILE max=0
DO
InputSD(dev,line)
IF line(0)>0 AND line(1)#'# THEN
IF header=0 THEN
IF SCompare(format,format)#0 THEN
Break()
FI
header=1
ELSEIF size=0 THEN
DecodeSize(line,@width,@height)
IF width=0 OR height=0 THEN
Break()
FI
img.w=width img.h=height
size=1
ELSEIF max=0 THEN
max=ValB(line)
IF max#255 THEN
Break()
FI
FI
FI
OD
RETURN
 
PROC LoadPPM6(RgbImage POINTER img CHAR ARRAY path)
BYTE dev=[1],x,y
RGB c
 
Close(dev)
Open(dev,path,4)
LoadHeader(img,"P6",dev)
FOR y=0 TO img.h-1
DO
FOR x=0 TO img.w-1
DO
c.r=GetD(dev)
c.g=GetD(dev)
c.b=GetD(dev)
SetRgbPixel(img,x,y,c)
OD
OD
Close(dev)
RETURN
 
PROC SaveHeader(GrayImage POINTER img
CHAR ARRAY format BYTE dev)
 
PrintDE(dev,format)
PrintBD(dev,img.w)
PutD(dev,32)
PrintBDE(dev,img.h)
PrintBDE(dev,255)
RETURN
 
PROC SavePPM2(RgbImage POINTER img CHAR ARRAY path)
BYTE dev=[1],x,y,c
 
Close(dev)
Open(dev,path,8)
SaveHeader(img,"P2",dev)
FOR y=0 TO img.h-1
DO
FOR x=0 TO img.w-1
DO
c=GetGrayPixel(img,x,y)
PrintBD(dev,c)
IF x=img.w-1 THEN
PutDE(dev)
ELSE
PutD(dev,32)
FI
OD
OD
Close(dev)
RETURN
 
PROC Load(CHAR ARRAY path)
CHAR ARRAY line(255)
BYTE dev=[1]
 
Close(dev)
Open(dev,path,4)
WHILE Eof(dev)=0
DO
InputSD(dev,line)
PrintE(line)
OD
Close(dev)
RETURN
 
PROC Main()
BYTE ARRAY rgbdata(300),graydata(100)
RgbImage rgbimg
GrayImage grayimg
CHAR ARRAY path2="D:PPM2.PPM"
CHAR ARRAY path6="D:PPM6.PPM"
 
Put(125) PutE() ;clear the screen
InitRgbImage(rgbimg,0,0,rgbdata)
InitRgbToGray()
PrintF("Loading %S...%E%E",path6)
LoadPPM6(rgbimg,path6)
 
PrintF("Converting RGB to grayscale...%E%E")
InitGrayImage(grayimg,rgbimg.w,rgbimg.h,graydata)
RgbToGray(rgbimg,grayimg)
 
PrintF("Saving %S...%E%E",path2)
SavePPM2(grayimg,path2)
PrintF("Loading %S...%E%E",path2)
Load(path2)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Read_a_PPM_file.png Screenshot from Atari 8-bit computer]
<pre>
Loading D:PPM6.PPM...
 
Converting RGB to grayscale...
 
Saving D:PPM2.PPM...
 
Loading D:PPM2.PPM...
 
P2
3 4
255
0 18 182
54 201 73
237 255 61
45 54 74
</pre>
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
Line 192 ⟶ 350:
return Result;
end;
end Get_PPM;</langsyntaxhighlight>
The implementation propagates Data_Error when the file format is incorrect. End_Error is propagated when the file end is prematurely met. The following example illustrates conversion of a color file to grayscale.
<langsyntaxhighlight lang="ada">declare
F1, F2 : File_Type;
begin
Line 202 ⟶ 360:
Close (F1);
Close (F2);
end;</langsyntaxhighlight>
=={{header|ATS}}==
For this you will need the static and dynamic ATS source files of [[Bitmap#ATS]], [[Grayscale_image#ATS]], and [[Bitmap/Write_a_PPM_file#ATS]]. (You do ''not'' need libnetpbm, although one could easily use it with ATS.)
 
There are three files here: a static file for the interface to <code>pixmap_read_ppm</code>, a dynamic file for the implementation of <code>pixmap_read_ppm</code>, and a file for the program that converts an image to grayscale. (The last is a dynamic file, but we will call it the program file.)
 
With <code>pixmap_read_ppm<rgb24></code> you should be able to read any valid PPM, whether raw or plain, and with any valid Maxval. The result is a <code>pixmap1(rgb24)</code> with implicit Maxval of 255. The reader tries to be ''very'' permissive, although there seems not much I can do about the strange way comments work in PPM.
 
===The ATS static file===
This file should be called <code>bitmap_read_ppm_task.sats</code>.
<syntaxhighlight lang="ats">
#define ATS_PACKNAME "Rosetta_Code.bitmap_read_ppm_task"
 
staload "bitmap_task.sats"
 
fn {a : t@ype}
pixmap_read_ppm :
(* On failure to read, the return is None_vt(). I do not currently
provide any indication of why the attempt failed, although in
practice you probably would wish to add that. *)
FILEref ->
Option_vt ([w, h : pos] [p : addr | null < p]
@(mfree_gc_v p | pixmap (a, w, h, p)))
</syntaxhighlight>
 
===The ATS dynamic file===
This file should be called <code>bitmap_read_ppm_task.dats</code>.
<syntaxhighlight lang="ats">
(*------------------------------------------------------------------*)
 
#define ATS_DYNLOADFLAG 0
#define ATS_PACKNAME "Rosetta_Code.bitmap_read_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_read_ppm_task.sats"
 
(*------------------------------------------------------------------*)
 
datavtype magic_number_vt =
| Netpbm_magic_number of int
| Unknown_magic_number of ()
 
fn {}
read_magic_number (inpf : FILEref) : magic_number_vt =
let
val i = fileref_getc inpf
in
if i <> char2int0 'P' then
Unknown_magic_number ()
else
let
val i = fileref_getc inpf
in
if i < char2int0 '1' && char2int0 '7' < i then
Unknown_magic_number ()
else
Netpbm_magic_number (i - char2int0 '0')
end
end
 
fn {}
get_next_char (inpf : FILEref) : int =
let
fnx
get_next () : int =
let
val i = fileref_getc inpf
in
if i = char2int0 '#' then
skip_through_newline ()
else
i
end
and
skip_through_newline () : int =
let
val i = fileref_getc inpf
in
if i < 0 then
i
else if i = char2int0 '\n' then
get_next ()
else
skip_through_newline ()
end
in
get_next ()
end
 
(* The only tokens we need to scan for, in P1 through P6, are unsigned
integers. P7 headers (Portable Arbitrary Map) have a completely
different arrangement, but we are not handling that. *)
fn {}
get_next_integer (inpf : FILEref)
(* A negative return value means we have reached the end. We do
not distinguish whitespace characters from anything else that
is not a digit or '#'. (Really I want to use intmax_t here,
rather than llint, but there is no intmax_t support in the
prelude. The ats2-xprelude package has support, but I am
avoiding the dependency. *)
: llint =
let
fnx
look_for_digit () : llint =
let
val i = get_next_char inpf
in
if i < char2int0 '0' || char2int0 '9' < i then
look_for_digit ()
else
read_digits (g0i2i (i - char2int0 '0'))
end
and
read_digits (x : llint) : llint =
let
val i = get_next_char inpf
in
if i < char2int0 '0' || char2int0 '9' < i then
(* I cannot find an "ungetc" in prelude/SATS/filebas.sats,
so I will use the foreign function interface directly. *)
let
typedef FILEstar = $extype"FILE *"
extern castfn FILEref2star : FILEref -<> FILEstar
in
ignoret ($extfcall (int, "ungetc", i, FILEref2star inpf));
x
end
else
let
val digit : llint = g0i2i (i - char2int0 '0')
in
read_digits ((10LL * x) + digit)
end
end
in
look_for_digit ()
end
 
fn {}
read_ppm_header (inpf : FILEref)
: Option_vt @(ullint, ullint, ullint) =
let
val width = get_next_integer inpf
in
if width < 0LL then
None_vt ()
else
let
val height = get_next_integer inpf
in
if height < 0LL then
None_vt ()
else
let
val maxval = get_next_integer inpf
in
if maxval < 0LL then
None_vt ()
else
begin
(* There is supposed to be a whitespace character (or
comments and whitespace character) after the
MAXVAL. We will accept anything, whitespace or
not. *)
ignoret (fileref_getc inpf);
 
Some_vt @(g0i2u width, g0i2u height, g0i2u maxval)
end
end
end
end
 
fn {}
get_next_single_byte (inpf : FILEref) : llint =
let
val i = fileref_getc inpf
in
if i < 0 then
~1LL
else
g0i2i i
end
 
fn {}
get_next_double_byte (inpf : FILEref) : llint =
let
val i1 = fileref_getc inpf
in
if i1 < 0 then
~1LL
else
let
val i0 = fileref_getc inpf
in
if i0 < 0 then
~1LL
else
let
val i1 : llint = g0i2i i1
and i0 : llint = g0i2i i0
in
(i1 * 256LL) + i0
end
end
end
 
(*------------------------------------------------------------------*)
(* Implementation is provided only for rgb24. *)
 
extern castfn ull2sz : {i : int} ullint i -<> size_t i
extern castfn ull2u : {i : int} ullint i -<> uint i
extern castfn ull2u8 : ullint -<> uint8
 
extern fn {}
read_raw_ppm_rgb24 : $d2ctype (pixmap_read_ppm<rgb24>)
 
extern fn {}
read_plain_ppm_rgb24 : $d2ctype (pixmap_read_ppm<rgb24>)
 
extern fn {}
read_general_ppm_rgb24 : $d2ctype (pixmap_read_ppm<rgb24>)
 
extern fn {}
read_general$width () : [i : pos] size_t i
 
extern fn {}
read_general$height () : [i : pos] size_t i
 
extern fn {}
read_general$maxval () : [i : pos | i <= 65535] uint i
 
extern fn {}
read_general$next_value : FILEref -> llint
 
implement
pixmap_read_ppm<rgb24> inpf =
case+ read_magic_number inpf of
| ~ Unknown_magic_number () => None_vt ()
| ~ Netpbm_magic_number num =>
begin
case+ num of
| 6 => read_raw_ppm_rgb24 inpf
| 3 => read_plain_ppm_rgb24 inpf
| _ => None_vt
end
 
implement {}
read_raw_ppm_rgb24 inpf =
case+ read_ppm_header inpf of
| ~ None_vt () => None_vt ()
| ~ Some_vt @(width, height, maxval) =>
let
val width = g1ofg0 width
and height = g1ofg0 height
and maxval = g1ofg0 maxval
in
if (width < 1LLU) + (height < 1LLU) +
(maxval < 1LLU) + (65535LLU < maxval) then
None_vt ()
else
let
val w : Size_t = ull2sz width
val h : Size_t = ull2sz height
val maxval : uInt = ull2u maxval
in
if maxval = 255u then
let
val @(pfgc | pix) = pixmap_make<rgb24> (w, h)
val success =
load<rgb24> (inpf, pix, rgb24_make (255, 0, 0))
in
if ~success then
begin
free (pfgc | pix);
None_vt ()
end
else
Some_vt @(pfgc | pix)
end
else if maxval < 256u then
let
implement read_general$width<> () = w
implement read_general$height<> () = h
implement read_general$maxval<> () = maxval
implement
read_general$next_value<> inpf =
get_next_single_byte inpf
in
read_general_ppm_rgb24<> inpf
end
else
let
implement read_general$width<> () = w
implement read_general$height<> () = h
implement read_general$maxval<> () = maxval
implement
read_general$next_value<> inpf =
get_next_double_byte inpf
in
read_general_ppm_rgb24<> inpf
end
end
end
 
implement {}
read_plain_ppm_rgb24 inpf =
case+ read_ppm_header inpf of
| ~ None_vt () => None_vt ()
| ~ Some_vt @(width, height, maxval) =>
let
val width = g1ofg0 width
and height = g1ofg0 height
and maxval = g1ofg0 maxval
in
if (width < 1LLU) + (height < 1LLU) +
(maxval < 1LLU) + (65535LLU < maxval) then
None_vt ()
else
let
val w : Size_t = ull2sz width
val h : Size_t = ull2sz height
val maxval : uInt = ull2u maxval
implement read_general$width<> () = w
implement read_general$height<> () = h
implement read_general$maxval<> () = maxval
implement
read_general$next_value<> inpf =
get_next_integer inpf
in
read_general_ppm_rgb24<> inpf
end
end
 
implement {}
read_general_ppm_rgb24 inpf =
let
val [w : int] w = read_general$width<> ()
and [h : int] h = read_general$height<> ()
and maxval = read_general$maxval<> ()
 
fn
scale_value (v : ullint) : uint8 =
if maxval = 255u then
ull2u8 v
else
let
val maxval : ullint = g0u2u maxval
val v = 255LLU * v
val v1 = v / maxval
and v0 = v mod maxval
in
if v0 + v0 < maxval then
ull2u8 v1
else if maxval < v0 + v0 then
ull2u8 (succ v1)
else if v1 mod 2LLU = 0LLU then
ull2u8 v1
else
ull2u8 (succ v1)
end
 
(* For easier programming, start with a fully initialized
pixmap. The routine probably is I/O-bound, anyway. *)
val @(pfgc | pix) =
pixmap_make<rgb24> (w, h, rgb24_make (255, 0, 0))
 
macdef between (i, j, v) =
let
val v = ,(v)
in
(,(i) <= v) * (v <= ,(j))
end
 
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)
: bool (* success *) =
if y = h then
true
else if x = w then
loop (pix, i2sz 0, succ y)
else
let
val maxv : llint = g0u2i maxval
val vr = read_general$next_value<> inpf
in
if ~between (0LL, maxv, vr) then
false
else
let
val vg = read_general$next_value<> inpf
in
if ~between (0LL, maxv, vg) then
false
else
let
val vb = read_general$next_value<> inpf
in
if ~between (0LL, maxv, vb) then
false
else
let
val r = scale_value (g0i2u vr)
and g = scale_value (g0i2u vg)
and b = scale_value (g0i2u vb)
in
pix[x, y] := rgb24_make @(r, g, b);
loop (pix, succ x, y)
end
end
end
end
 
val success = loop (pix, i2sz 0, i2sz 0)
in
if ~success then
begin
free (pfgc | pix);
None_vt ()
end
else
Some_vt @(pfgc | pix)
end
 
(*------------------------------------------------------------------*)
 
#ifdef BITMAP_READ_PPM_TASK_TEST #then
 
staload "bitmap_write_ppm_task.sats"
staload _ = "bitmap_write_ppm_task.dats"
 
(* The test program converts a PPM at standard input to a raw PPM with
MAXVAL 255. *)
implement
main0 () =
let
val pix_opt = pixmap_read_ppm<rgb24> stdin_ref
in
case+ pix_opt of
| ~ None_vt () => ()
| ~ Some_vt @(pfgc | pix) =>
begin
ignoret (pixmap_write_ppm (stdout_ref, pix));
free (pfgc | pix)
end
end
 
#endif
 
(*------------------------------------------------------------------*)
</syntaxhighlight>
 
===The ATS program file===
This file should be called <code>bitmap_read_ppm_task_program.dats</code> (though it actually could be called by another name).
[[File:Bitmap read ppm task ATS color.jpg|thumb|alt=A gnarly tree on a rise by the sea, in color.]][[File:Bitmap read ppm task ATS gray.jpg|thumb|alt=A gnarly tree on a rise by the sea, in grayscale.]]
<syntaxhighlight lang="ats">
(* The program should be able to read a PPM in raw or plain format,
with any valid Maxval. The output will be a grayscale raw PPM with
Maxval=255.
 
Compile with "myatscc bitmap_read_ppm_task_program.dats", which
should give you a program named "bitmap_read_ppm_task_program". *)
 
(*
 
##myatsccdef=\
patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC \
-o $fname($1) $1 \
bitmap{,_{{read,write}_ppm,grayscale}}_task.{s,d}ats
 
*)
 
#include "share/atspre_staload.hats"
 
staload "bitmap_task.sats"
staload "bitmap_read_ppm_task.sats"
staload "bitmap_write_ppm_task.sats"
staload "bitmap_grayscale_task.sats"
 
staload _ = "bitmap_task.dats"
staload _ = "bitmap_read_ppm_task.dats"
staload _ = "bitmap_write_ppm_task.dats"
staload _ = "bitmap_grayscale_task.dats"
 
implement
main0 (argc, argv) =
let
val args = listize_argc_argv (argc, argv)
val nargs = length args
 
val inpf =
if nargs < 2 then
stdin_ref
else if args[1] = "-" then
stdin_ref
else
fileref_open_exn (args[1], file_mode_r)
val pix_opt = pixmap_read_ppm<rgb24> inpf
val () = fileref_close inpf
in
case+ pix_opt of
| ~ None_vt () =>
begin
free args;
println! ("For some reason, I failed to read the image.");
exit 1
end
| ~ Some_vt @(pfgc1 | pix1) =>
let
val @(pfgc2 | pix2) = pixmap_convert<rgb24,gray8> pix1
val () = free (pfgc1 | pix1)
val @(pfgc3 | pix3) = pixmap_convert<gray8,rgb24> pix2
val () = free (pfgc2 | pix2)
 
val outf =
if nargs < 3 then
stdout_ref
else if args[2] = "-" then
stdout_ref
else
fileref_open_exn (args[2], file_mode_w)
val success = pixmap_write_ppm<rgb24> (outf, pix3)
val () = fileref_close outf
 
val () = free (pfgc3 | pix3)
in
free args;
if ~success then
begin
println! ("For some reason, ",
"I failed to write a new image.");
exit 2
end
end
end
</syntaxhighlight>
 
You can compile the program with the shell command
 
<pre>myatscc bitmap_read_ppm_task_program.dats</pre>
 
If compilation is successful, the program will be called <code>bitmap_read_ppm_task_program</code>. You can give up to two arguments (any others will be ignored). The first argument is a file name for the input file, the second is the file name for the output file. Either argument can be "-", meaning to use the respective standard input or output. An argument omitted is equivalent to "-".
 
Shown in the margin are before and after for SIPI test image 4.1.06 (not counting that I have converted the PPM files to JPEGs).
 
=={{header|AutoHotkey}}==
Line 208 ⟶ 920:
Only ppm6 files supported.
 
<langsyntaxhighlight AutoHotkeylang="autohotkey">img := ppm_read("lena50.ppm") ;
x := img[4,4] ; get pixel(4,4)
y := img[24,24] ; get pixel(24,24)
Line 264 ⟶ 976:
return bitmap
}
#include bitmap_storage.ahk ; from http://rosettacode.org/wiki/Basic_bitmap_storage/AutoHotkey</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> f% = OPENIN("c:\lena.ppm")
IF f%=0 ERROR 100, "Failed to open input file"
Line 297 ⟶ 1,009:
GCOL 1
LINE x%*2,y%*2,x%*2,y%*2
ENDPROC</langsyntaxhighlight>
 
=={{header|C}}==
It is up to the caller to open the file and pass the handler to the function. So this code can be used in
Line 305 ⟶ 1,016:
Interface:
 
<syntaxhighlight lang ="c">image get_ppm(FILE *pf);</langsyntaxhighlight>
 
Implementation:
 
<langsyntaxhighlight lang="c">#include "imglib.h"
 
#define PPMREADBUFLEN 256
Line 346 ⟶ 1,057:
return img;
}
}</langsyntaxhighlight>
 
The following acts as a filter to convert a PPM file read from standard input into a PPM gray image, and it outputs the converted image to standard output (see [[Grayscale image]], [[Write ppm file]], and [[Raster graphics operations]] in general):
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include "imglib.h"
 
Line 365 ⟶ 1,076:
free_img(source); free_img((image)idest);
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
Tested with [[Write ppm file#C.23|this solution.]]
 
<langsyntaxhighlight lang="csharp">using System.IO;
class PPMReader
{
Line 402 ⟶ 1,112:
return bitmap;
}
}</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
 
The function read-ppm-image reads either a P6 or P3 file depending on the file contents. The package description assumes that you have the [[Basic bitmap storage#Common Lisp]] package.
 
<langsyntaxhighlight lang="lisp">
(in-package #:rgb-pixel-buffer)
 
Line 480 ⟶ 1,189:
 
(export 'read-ppm-image)
</syntaxhighlight>
</lang>
To read the feep.ppm file as shown on the description page for the ppm format use:
<langsyntaxhighlight lang="lisp">
(read-ppm-image "feep.ppm")
</syntaxhighlight>
</lang>
 
=={{header|D}}==
The Image module contains a loadPPM6 function to load binary PPM images.
 
=={{header|Delphi}}==
Class helper for read and write Bitmap's and Ppm's
{{Trans|C#}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program BtmAndPpm;
 
Line 620 ⟶ 1,327:
end;
end.
</syntaxhighlight>
</lang>
 
=={{header|E}}==
 
<langsyntaxhighlight lang="e">def chr := <import:java.lang.makeCharacter>.asChar
 
def readPPM(inputStream) {
Line 678 ⟶ 1,384:
image.replace(data.snapshot())
return image
}</langsyntaxhighlight>
 
[[Category:E examples needing attention]]Note: As of this writing the [[grayscale image]] task has not been implemented, so the task code (below) won't actually run yet. But readPPM above has been tested separately.
 
<langsyntaxhighlight lang="e">def readPPMTask(inputFile, outputFile) {
makeGrayscale \
.fromColor(readPPM(<import:java.io.makeFileInputStream>(inputFile))) \
.toColor() \
.writePPM(<import:java.io.makeFileOutputStream>(outputFile))
}</langsyntaxhighlight>
 
=={{header|Erlang}}==
 
<langsyntaxhighlight lang="erlang">
% This module provides basic operations on ppm files:
% Read from file, create ppm in memory (from generic bitmap) and save to file.
Line 794 ⟶ 1,499:
encode_decimal(Number) ->
integer_to_list(Number).
</syntaxhighlight>
</lang>
 
Usage in accordance with Grayscale Task:
<langsyntaxhighlight lang="erlang">
Colorful = ppm:read("colorful.ppm"),
Gray = ros_bitmap:convert(ros_bitmap:convert(Colorful, grey), rgb),
ppm:write(Gray, "gray.ppm"),
</syntaxhighlight>
</lang>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">include get.e
 
function get2(integer fn)
Line 844 ⟶ 1,548:
close(fn)
return image
end function</langsyntaxhighlight>
 
Converting an image to grayscale:
<langsyntaxhighlight lang="euphoria">sequence image
image = read_ppm("image.ppm")
image = to_gray(image)
image = to_color(image)
write_ppm("image_gray.ppm",image)</langsyntaxhighlight>
 
=={{header|FBSL}}==
Read a colored PPM file, convert it to grayscale and write back to disk under a different name. Sanity checks are omitted for brevity.
Line 858 ⟶ 1,561:
'''24-bpp P6 PPM solution:'''
[[File:FBSLLena.png|right]]
<langsyntaxhighlight lang="qbasic">#ESCAPECHARS ON
 
DIM colored = ".\\Lena.ppm", grayscale = ".\\LenaGry.ppm"
Line 875 ⟶ 1,578:
NEXT
 
FILEPUT(FILEOPEN(grayscale, BINARY_NEW), FILEGET): FILECLOSE(FILEOPEN) ' Save buffer</langsyntaxhighlight>
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: read-ppm { fid -- bmp }
pad dup 80 fid read-line throw 0= abort" Partial line"
s" P6" compare abort" Only P6 supported."
Line 915 ⟶ 1,617:
: bsize ( bmp -- len ) bdim * pixels bdata ;
 
test dup bsize test2 dup bsize compare . \ 0 if identical</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
Line 922 ⟶ 1,623:
(This function is part of module RCImageIO, see [[Write ppm file#Fortran|Write ppm file]])
 
<langsyntaxhighlight lang="fortran">subroutine read_ppm(u, img)
integer, intent(in) :: u
type(rgbimage), intent(out) :: img
Line 963 ⟶ 1,664:
end if
 
end subroutine read_ppm</langsyntaxhighlight>
 
'''Notes''':
Line 969 ⟶ 1,670:
* doing formatted I/O with Fortran is a pain... And unformatted does not mean ''free''; Fortran2003 has ''streams'', but they are not implemented (yet) in GNU Fortran compiler. Here (as in the write part) I've tried to handle the PPM format through formatted I/O. The tests worked but I have not tried still everything.
* comments after the first line are not handled
 
=={{header|FreeBASIC}}==
{{trans|Yabasic}}
<syntaxhighlight lang="vbnet">Dim As String imagen = "Lena.ppm"
 
Sub readPPM (fs As String)
Dim As Integer x, y, ancho, alto
Dim As String t, kolor
Dim As Ubyte r, g, b
If Len(fs) = 0 Then Print "No PPM file name indicated.": Exit Sub
Dim As Long ff = Freefile
Open fs For Binary As #ff
If Err Then Print "File "; fs; " not found.": Exit Sub
Input #ff, t, ancho, alto, kolor
If t = "P6" Then
Screenres ancho, alto, 32
For y = 0 To alto - 1
For x = 0 To ancho - 1
Get #ff, , r
Get #ff, , g
Get #ff, , b
Pset (x, y), Rgb(r, g, b)
Next x
Next y
Close #ff
Else
Print "File is NOT PPM P6 type."
End If
End Sub
 
readPPM(imagen)
Sleep</syntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package raster
 
import (
Line 1,038 ⟶ 1,775:
}
return b, f.Close()
}</langsyntaxhighlight>
Demonstration program, also demonstrating functions from task [[Grayscale image]]:
<langsyntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
Line 1,067 ⟶ 1,804:
fmt.Println(err)
}
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
The definition of <tt>Bitmap.Netpbm.readNetpbm</tt> is given [[Write ppm file|here]].
<langsyntaxhighlight lang="haskell">import Bitmap
import Bitmap.RGB
import Bitmap.Gray
Line 1,082 ⟶ 1,818:
(readNetpbm "original.ppm" :: IO (Image RealWorld RGB)) >>=
stToIO . toGrayImage >>=
writeNetpbm "new.pgm"</langsyntaxhighlight>
The above writes a PGM, not a PPM, since the image being output is in grayscale. If you actually want a gray PPM, convert the <tt>Image RealWorld Gray</tt> back to an <tt>Image RealWorld RGB</tt> first:
<langsyntaxhighlight lang="haskell">main =
(readNetpbm "original.ppm" :: IO (Image RealWorld RGB)) >>=
stToIO . (toRGBImage <=< toGrayImage) >>=
writeNetpbm "new.ppm"</langsyntaxhighlight>
 
=={{header|J}}==
'''Solution:'''<br>
Uses <tt>makeRGB</tt> from [[Basic bitmap storage#J|Basic bitmap storage]].
<langsyntaxhighlight lang="j">require 'files'
 
readppm=: monad define
Line 1,101 ⟶ 1,836:
if. (_99 0 +./@e. wbyh,maxval) +. 'P6' -.@-: 2{.t do. _1 return. end.
(a. i. dat) makeRGB |.wbyh NB. convert to basic bitmap format
)</langsyntaxhighlight>
 
'''Example:'''<br>
Using utilities and file from [[Grayscale image#J|Grayscale image]] and [[Write ppm file#J|Write ppm file]].<br>
Writes a gray PPM file (a color format) which is bigger than necessary. A PGM file would be more appropriate.
<langsyntaxhighlight lang="j">myimg=: readppm jpath '~temp/myimg.ppm'
myimgGray=: toColor toGray myimg
myimgGray writeppm jpath '~temp/myimgGray.ppm'</langsyntaxhighlight>
 
=={{header|Java}}==
For convenience, the code for the class used in the [[Bitmap]] task here and integrated with the code in the [[Grayscale image]] is included.
<syntaxhighlight lang="java">
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
import javax.imageio.ImageIO;
 
public class ReadPPMFile {
 
public static void main(String[] aArgs) throws IOException {
// Using the file created in the Bitmap task
String filePath = "output.ppm";
reader = new BufferedInputStream( new FileInputStream(filePath) );
final char header1 = (char) reader.read();
final char header2 = (char) reader.read();
final char header3 = (char) reader.read();
if ( header1 != 'P' || header2 != '6' || header3 != END_OF_LINE) {
reader.close();
throw new IllegalArgumentException("Not a valid P6 PPM file");
}
final int width = processCharacters(SPACE_CHARACTER);
final int height = processCharacters(END_OF_LINE);
final int maxColorValue = processCharacters(END_OF_LINE);
if ( maxColorValue < 0 || maxColorValue > 255 ) {
reader.close();
throw new IllegalArgumentException("Maximum color value is outside the range 0..255");
}
// Remove any comments before reading data
reader.mark(1);
while ( reader.read() == START_OF_COMMENT ) {
while ( reader.read() != END_OF_LINE );
reader.mark(1);
}
reader.reset();
// Read data
BasicBitmapStorage bitmap = new BasicBitmapStorage(width, height);
byte[] buffer = new byte[width * 3];
for ( int y = 0; y < height; y++ ) {
reader.read(buffer, 0, buffer.length);
for ( int x = 0; x < width; x++ ) {
Color color = new Color(Byte.toUnsignedInt(buffer[x * 3]),
Byte.toUnsignedInt(buffer[x * 3 + 1]),
Byte.toUnsignedInt(buffer[x * 3 + 2]));
bitmap.setPixel(x, y, color);
}
}
reader.close();
// Convert to gray scale and save to a file
bitmap.convertToGrayscale();
File grayFile = new File("outputGray.jpg");
ImageIO.write((RenderedImage) bitmap.getImage(), "jpg", grayFile);
}
private static int processCharacters(char aChar) throws IOException {
StringBuilder characters = new StringBuilder();
char ch;
while ( ( ch = (char) reader.read() ) != aChar ) {
if ( ch == START_OF_COMMENT ) {
while ( reader.read() != END_OF_LINE );
continue;
}
characters.append(ch);
}
return Integer.valueOf(characters.toString());
}
private static BufferedInputStream reader;
private static final char START_OF_COMMENT = '#';
private static final char SPACE_CHARACTER = ' ';
private static final char END_OF_LINE = '\n';
}
final class BasicBitmapStorage {
 
public BasicBitmapStorage(int aWidth, int aHeight) {
image = new BufferedImage(aWidth, aHeight, BufferedImage.TYPE_INT_RGB);
}
 
public void fill(Color aColor) {
Graphics graphics = image.getGraphics();
graphics.setColor(aColor);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
}
 
public Color getPixel(int aX, int aY) {
return new Color(image.getRGB(aX, aY));
}
public void setPixel(int aX, int aY, Color aColor) {
image.setRGB(aX, aY, aColor.getRGB());
}
public Image getImage() {
return image;
}
public void convertToGrayscale() {
for ( int y = 0; y < image.getHeight(); y++ ) {
for ( int x = 0; x < image.getWidth(); x++ ) {
int color = image.getRGB(x, y);
 
int alpha = ( color >> 24 ) & 255;
int red = ( color >> 16 ) & 255;
int green = ( color >> 8 ) & 255;
int blue = color & 255;
 
final int luminance = (int) ( 0.2126 * red + 0.7152 * green + 0.0722 * blue );
 
alpha = alpha << 24;
red = luminance << 16;
green = luminance << 8;
blue = luminance;
 
color = alpha + red + green + blue;
 
image.setRGB(x, y, color);
}
}
}
private final BufferedImage image;
 
}
</syntaxhighlight>
{{ out }}
[[Media:ColouredJava.png]] & [[Media:GrayscaleJava.png]]
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">using Images, FileIO, Netpbm
 
rgbimg = load("data/bitmapInputTest.ppm")
greyimg = Gray.(rgbimg)
save("data/bitmapOutputTest.ppm", greyimg)</langsyntaxhighlight>
 
=={{header|Kotlin}}==
For convenience, we repeat the code for the class used in the [[Bitmap]] task here and integrate the code in the [[Grayscale image]] task within it.
<langsyntaxhighlight lang="scala">// Version 1.2.40
 
import java.awt.Color
Line 1,250 ⟶ 2,129:
}
}
}</langsyntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function Read_PPM( filename )
local fp = io.open( filename, "rb" )
if fp == nil then return nil end
Line 1,286 ⟶ 2,164:
return image
end</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
Now function Bitmap has double signature. With two numbers make a bitmap,with all pixels white. With one number, expect that it is a file number and read file, and then return the bitmap.
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Function Bitmap {
Line 1,462 ⟶ 2,339:
Checkit
 
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/ {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">Import["file.ppm","PPM"]
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import strutils
import bitmap
import streams
Line 1,559 ⟶ 2,434:
when isMainModule:
let image = readPPM("output.ppm")
echo image.h, " ", image.w</langsyntaxhighlight>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">let read_ppm ~filename =
let ic = open_in filename in
let line = input_line ic in
Line 1,600 ⟶ 2,474:
r_channel,
g_channel,
b_channel)</langsyntaxhighlight>
 
and converting a given color file to grayscale:
<langsyntaxhighlight lang="ocaml">let () =
let img = read_ppm ~filename:"logo.ppm" in
let img = to_color(to_grayscale ~img) in
output_ppm ~oc:stdout ~img;
;;</langsyntaxhighlight>
sending the result to <tt>stdout</tt> allows to see the result without creating a temporary file sending it through a pipe to the '''display''' utility of ''ImageMagick'':
ocaml script.ml | display -
 
=={{header|Oz}}==
The read function in module <code>"BitmapIO.oz"</code>:
<langsyntaxhighlight lang="oz">functor
import
Bitmap
Line 1,696 ⟶ 2,569:
 
%% Omitted: Write
end</langsyntaxhighlight>
 
The actual task:
<langsyntaxhighlight lang="oz">declare
[BitmapIO Grayscale] = {Module.link ['BitmapIO.ozf' 'Grayscale.ozf']}
 
Line 1,705 ⟶ 2,578:
G = {Grayscale.toGraymap B}
in
{BitmapIO.write {Grayscale.fromGraymap G} "greyimage.ppm"}</langsyntaxhighlight>
 
=={{header|Perl}}==
 
{{libheader|Imlib2}}
 
<langsyntaxhighlight lang="perl">#! /usr/bin/perl
 
use strict;
Line 1,724 ⟶ 2,596:
$img->save("out1.png");
 
exit 0;</langsyntaxhighlight>
 
=={{header|Phix}}==
Based on [[Bitmap/Read_a_PPM_file#Euphoria|Euphoria]], requires write_ppm() from [[Bitmap/Write_a_PPM_file#Phix|Write_a_PPM_file]], to_grey from [[Grayscale_image#Phix|Grayscale_image]]<br>
Note that demo\rosetta\Bitmap_read_ppm.exw is just the last 3 lines with the include ppm.e since that contains the read_ppm() (abeit with a few more options and other tweaks) also used by several other examples, and covers the above requirements. Results may be verified with demo\rosetta\viewppm.exw
<langsyntaxhighlight Phixlang="phix">-- demo\rosetta\Bitmap_read_ppm.exw (runnable version)
 
function read_ppm(string filename)
Line 1,760 ⟶ 2,631:
sequence img = read_ppm("Lena.ppm")
img = to_grey(img)
write_ppm("LenaGray.ppm",img)</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de ppmRead (File)
(in File
(unless (and `(hex "5036") (rd 2)) # P6
Line 1,780 ⟶ 2,650:
(map
'((X) (set X (list (rd 1) (rd 1) (rd 1))))
Y ) ) ) ) ) )</langsyntaxhighlight>
Read a color image "img.ppm", convert and write to "img.pgm":
<langsyntaxhighlight PicoLisplang="picolisp">(pgmWrite (ppm->pgm (ppmRead "img.ppm")) "img.pgm")</langsyntaxhighlight>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
/* BITMAP FILE: read in a file in PPM format, P6 (binary). 14/5/2010 */
test: procedure options (main);
Line 1,849 ⟶ 2,718:
return (index('0123456789', ch) > 0);
end is_digit;
end test;</langsyntaxhighlight>
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Structure PPMColor
r.c
g.c
Line 1,909 ⟶ 2,777:
EndIf
EndIf
EndProcedure</langsyntaxhighlight>
 
To complete the task, the following code should be added to the above fragment and to the PureBasic solutions for [[Grayscale_image#PureBasic|Grayscale image]] and [[Bitmap/Write_a_PPM_file#PureBasic|Write a PPM file]]
<langsyntaxhighlight PureBasiclang="purebasic">Define file.s, file2.s, image = 3
file = OpenFileRequester("Select source image file", "", "PPM image (*.ppm)|*.ppm", 0)
If file And LCase(GetExtensionPart(file)) = "ppm"
Line 1,919 ⟶ 2,787:
file2 = Left(file, Len(file) - Len(GetExtensionPart(file))) + "_grayscale." + GetExtensionPart(file)
SaveImageAsPPM(image, file2, 1)
EndIf</langsyntaxhighlight>
 
=={{header|Python}}==
{{works with|Python|3.1}}
 
Extending the example given [[Basic_bitmap_storage#Alternative_version|here]]
<langsyntaxhighlight lang="python"># With help from http://netpbm.sourceforge.net/doc/ppm.html
 
# String masquerading as ppm file (version P3)
Line 1,993 ⟶ 2,860:
4 4 4 0 0 0 0 0 0 0 0 0
 
'''</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require racket/draw)
Line 2,019 ⟶ 2,885:
(send dc draw-point x y)))
bm))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
Line 2,026 ⟶ 2,891:
Uses pieces from [[Bitmap#Raku| Bitmap]], [[Bitmap/Write_a_PPM_file#Raku| Write a PPM file]] and [[Grayscale_image#Raku| Grayscale image]] tasks. Included here to make a complete, runnable program.
 
<syntaxhighlight lang="raku" perl6line>class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
has UInt ($.width, $.height);
Line 2,061 ⟶ 2,926:
grayscale($b);
 
'./camelia-gs.pgm'.IO.open(:bin, :w).write: $b.P5;</langsyntaxhighlight>
 
See [https://github.com/thundergnat/rc/blob/master/img/camelia.png camelia], and [https://github.com/thundergnat/rc/blob/master/img/camelia-gs.png camelia-gs] images. (converted to .png as .ppm format is not widely supported).
 
=={{header|REXX}}==
The input file &nbsp; '''Lenna50.ppm''' &nbsp; is a '''PPM''' format of
Line 2,070 ⟶ 2,934:
 
This REXX program handles alternative delimiters as well as comments within the PPM header.
<langsyntaxhighlight lang="rexx">/*REXX program reads a PPM formatted image file, and creates a gray─scale image of it. */
parse arg iFN oFN /*obtain optional argument from the CL.*/
if iFN=='' | iFN=="," then iFN= 'Lenna50' /*Not specified? Then use the default.*/
Line 2,105 ⟶ 2,969:
 
call charout oFID /*close the output file just to be safe*/
say 'File ' oFID " was created." /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output}}
<pre>
File greyscale.ppm was created.
</pre>
 
=={{header|Ruby}}==
Extending [[Basic_bitmap_storage#Ruby]]
<langsyntaxhighlight lang="ruby">class Pixmap
# 'open' is a class method
def self.open(filename)
Line 2,145 ⟶ 3,008:
 
# then, convert to grayscale
Pixmap.open('testcross.ppm').to_grayscale!.save('testgray.ppm')</langsyntaxhighlight>
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">
parser.rs:
use super::{Color, ImageFormat};
Line 2,431 ⟶ 3,293:
println!("Dimensions: {} x {}", image.height, image.width);
}
</syntaxhighlight>
</lang>
 
 
=={{header|Scala}}==
Uses the [[Basic_bitmap_storage#Scala|Basic Bitmap Storage]] and [[Grayscale_image#Scala|Grayscale Bitmap]] classes.
Line 2,439 ⟶ 3,299:
See also Task [[Write_ppm_file#Scala|Write a PPM File]] for save code.
 
<langsyntaxhighlight lang="scala">import scala.io._
import scala.swing._
import java.io._
Line 2,484 ⟶ 3,344:
out
}
}</langsyntaxhighlight>
 
Usage:
<langsyntaxhighlight lang="scala">object PixmapTest {
def main(args: Array[String]): Unit = {
val img=Pixmap.load("image.ppm").get
Line 2,501 ⟶ 3,361:
}
}
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "draw.s7i";
include "color.s7i";
Line 2,539 ⟶ 3,398:
close(ppmFile);
end if;
end func;</langsyntaxhighlight>
 
=={{header|Tcl}}==
{{libheader|Tk}}
The actual PPM reader is built into the photo image engine:
<langsyntaxhighlight lang="tcl">package require Tk
 
proc readPPM {image file} {
$image read $file -format ppm
}</langsyntaxhighlight>
Thus, to read a PPM, convert it to grayscale, and write it back out again becomes this (which requires Tcl 8.6 for <code>try</code>/<code>finally</code>); the PPM reader and writer are inlined because they are trivial at the script level:
<langsyntaxhighlight lang="tcl">package require Tk
 
proc grayscaleFile {filename {newFilename ""}} {
Line 2,570 ⟶ 3,428:
image delete $buffer
}
}</langsyntaxhighlight>
 
However, the Tk library also has built-in the ability to convert code to grayscale directly during the saving of an image to a file, leading to this minimal solution:
<langsyntaxhighlight lang="tcl">package require Tk
 
proc grayscaleFile {filename {newFilename ""}} {
Line 2,584 ⟶ 3,442:
image delete $buffer
}
}</langsyntaxhighlight>
 
=={{header|UNIX Shell}}==
{{works with|ksh93}}
Line 2,591 ⟶ 3,448:
 
Add the following functions to the <tt>RGBColor_t</tt> type
<langsyntaxhighlight lang="bash"> function setrgb {
_.r=$1
_.g=$2
Line 2,601 ⟶ 3,458:
_.g=$x
_.b=$x
}</langsyntaxhighlight>
 
Add the following function to the <tt>Bitmap_t</tt> type
<langsyntaxhighlight lang="bash"> function grayscale {
RGBColor_t c
for ((y=0; y<_.height; y++)); do
Line 2,642 ⟶ 3,499:
fi
exec 4<&-
}</langsyntaxhighlight>
 
Now we can:
<langsyntaxhighlight lang="bash">Bitmap_t c
c.read "$HOME/tmp/bitmap.ppm"
c.to_s
Line 2,657 ⟶ 3,514:
c.grayscale
c.to_s
c.write "$HOME/tmp/bitmap_g.ppm"</langsyntaxhighlight>
 
=={{header|Vedit macro language}}==
<langsyntaxhighlight lang="vedit">// Load a PPM file
// @10 = filename
// On return:
Line 2,676 ⟶ 3,532:
Search("|X", ADVANCE) // skip maxval (assume 255)
Del_Block(0,CP) // remove the header
Return</langsyntaxhighlight>
 
Example of usage. In addition to LOAD_PPM routine above, you need routine RGB_TO_GRAYSCALE from [[Grayscale image]] and routine SAVE_PPM from [[Write ppm file]].
<langsyntaxhighlight lang="vedit">// Load RGB image
Reg_Set(10, "|(USER_MACRO)\example.ppm")
Call("LOAD_PPM")
Line 2,697 ⟶ 3,553:
// Cleanup and exit
Buf_Switch(#20) Buf_Quit(OK)
return</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|DOME}}
This assumes that [https://rosettacode.org/wiki/File:Lenna100.jpg Lenna100.jpg], a 512 x 512 color image of the eponymous lady, has already been converted to Lenna100.ppm using a variation of the 'Write a PPM file' task.
<langsyntaxhighlight ecmascriptlang="wren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window, Process
import "io" for FileSystem
Line 2,728 ⟶ 3,583:
loadPPMFile(fileName) {
var ppm = FileSystem.load(fileName)
var count = ppm.count // ensure file is fully loaded before proceeding
if (ppm[0..1] != "P6") {
System.print("The loaded file is not a P6 file.")
Line 2,776 ⟶ 3,632:
}
 
var Game = Bitmap.new("Lenna100.ppm", "Lenna100_gs.jpg", 1048, 512)</langsyntaxhighlight>
 
=={{header|XPL0}}==
Line 2,783 ⟶ 3,639:
files larger than 1280x1024 are clipped to the screen dimensions.
 
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
func OpenInFile; \Open for input the file typed on command line
Line 2,827 ⟶ 3,683:
X:= ChIn(1); \wait for keystroke
SetVid(3); \restore normal text display
]</langsyntaxhighlight>
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">sub readPPM(f$)
local ff, x, y, t$, dcol$, wid, hei
 
Line 2,856 ⟶ 3,711:
return true
end sub</langsyntaxhighlight>
 
=={{header|zkl}}==
{{trans|FBSL}}
Line 2,864 ⟶ 3,718:
I used a slightly different image from what is shown, but the results are the same.
[[File:FBSLLena.png|right]]
<langsyntaxhighlight lang="zkl">//24-bpp P6 PPM solution:
image:=File("lena.ppm","rb").read();
start:=image.find("\n255\n")+5; // Get sizeof PPM header
Line 2,874 ⟶ 3,728:
}
 
File("lenaGrey.ppm","wb").write(image);</langsyntaxhighlight>
 
 
 
{{omit from|AWK}}
{{omit from|Lotus 123 Macro Scripting}}
2,122

edits