How to resolve the algorithm Bitmap/Read an image through a pipe step by step in the ATS programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Bitmap/Read an image through a pipe step by step in the ATS programming language
Table of Contents
Problem Statement
This task is the opposite of the PPM conversion through a pipe. In this task, using a delegate tool (like cjpeg, one of the netpbm package, or convert of the ImageMagick package) we read an image file and load it into the data storage type defined here. We can also use the code from Read ppm file, so that we can use PPM format like a (natural) bridge between the foreign image format and our simple data storage.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Bitmap/Read an image through a pipe step by step in the ATS programming language
Source code in the ats programming language
(* I both read AND write the image through pipes connected to
ImageMagick. One can also pass options and such but I won't go into
the details. *)
(*
##myatsccdef=\
patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC \
-o $fname($1) $1 \
bitmap{,_{read,write}_ppm}_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_task.dats"
staload _ = "bitmap_read_ppm_task.dats"
staload _ = "bitmap_write_ppm_task.dats"
(*------------------------------------------------------------------*)
(* There is support for pipe-I/O in libats/libc, but I cannot (at
least when in a hurry) figure out how it is supposed to be
used. So, as elsewhere in the "raster graphics operations"
category, what is not in the prelude itself I implement with the
foreign function interfaces. :) Using FFI is a typical part of ATS
programming, and one should get used to doing it.
Anyway, here is some UNSAFE support for pipe-I/O. *)
typedef charstar = $extype"char *"
typedef FILEstar = $extype"FILE *"
fn {}
fileref_popen_unsafe (command : string,
mode : string)
: Option_vt FILEref =
let
val p = $extfcall (ptr, "popen", $UNSAFE.cast{charstar} command,
$UNSAFE.cast{charstar} mode)
in
if iseqz p then
None_vt ()
else
Some_vt ($UNSAFE.cast{FILEref} p)
end
fn {}
fileref_pclose_unsafe (f : FILEref)
: int = (* Returns the exit status of the command. *)
$extfcall (int, "pclose", $UNSAFE.cast{FILEstar} f)
(*------------------------------------------------------------------*)
implement
main0 (argc, argv) =
let
val args = listize_argc_argv (argc, argv)
val nargs = length args
val inpf_name = if nargs < 2 then "-" else args[1]
val command = string_append ("magick ", inpf_name, " ppm:-")
val pipe_opt =
(* Temporarily treating a strptr as a string, just to make a
function call of this sort, is not actually unsafe. *)
fileref_popen_unsafe ($UNSAFE.strptr2string command, "r")
val () = free command
in
case+ pipe_opt of
| ~ None_vt () =>
begin
free args;
println! ("For some reason, I failed to open a pipe ",
"for reading from magick.");
exit 1
end
| ~ Some_vt inpf =>
let
val pix_opt = pixmap_read_ppm inpf
in
ignoret (fileref_pclose_unsafe inpf);
case+ pix_opt of
| ~ None_vt () =>
begin
free args;
println! ("For some reason, I failed to pipe the image ",
"from magick.");
exit 1
end
| ~ Some_vt @(pfgc1 | pix1) =>
let
val outf_name = if nargs < 3 then "-" else args[2]
val command = string_append ("magick ppm:- ", outf_name)
val () = free args
val pipe_opt =
(* Temporarily treating a strptr as a string, just to
make a function call of this sort, is not actually
unsafe. *)
fileref_popen_unsafe
($UNSAFE.strptr2string command, "w")
val () = free command
in
case+ pipe_opt of
| ~ None_vt () =>
begin
free (pfgc1 | pix1);
println! ("For some reason, I failed to open a pipe ",
"for writing to magick.");
exit 3
end
| ~ Some_vt outf =>
let
val success = pixmap_write_ppm (outf, pix1)
in
ignoret (fileref_pclose_unsafe outf);
free (pfgc1 | pix1);
if ~success then
begin
println! ("For some reason, I failed to pipe ",
"the image to magick.");
exit 2
end
end
end
end
end
You may also check:How to resolve the algorithm Lucas-Lehmer test step by step in the C++ programming language
You may also check:How to resolve the algorithm Window creation/X11 step by step in the BaCon programming language
You may also check:How to resolve the algorithm ADFGVX cipher step by step in the Rust programming language
You may also check:How to resolve the algorithm Price fraction step by step in the Bracmat programming language
You may also check:How to resolve the algorithm Cartesian product of two or more lists step by step in the Ring programming language