Skip to content

Instantly share code, notes, and snippets.

@thundergnat
Last active October 27, 2017 23:36
Show Gist options
  • Save thundergnat/a729e01d50f33a0a29ad5cfa6db105ec to your computer and use it in GitHub Desktop.
Save thundergnat/a729e01d50f33a0a29ad5cfa6db105ec to your computer and use it in GitHub Desktop.
Problem writing to Proc :in on default filehandle
# When trying to read and write some PPM files through a pipe, able to read a Proc through a pipe using default filehandle '-'
# but not able to figure out the syntax to write to the default file handle throug a Proc pipe.
# The two scripts below demonstrate. Both require that imagemagick is installed and ready to use, specifically the 'convert' program.
# Using the camelia.png file from from:
# https://github.com/thundergnat/rc/blob/master/img/camelia.png
# downloaded to the same directory that the script is in; ppm-read.pipe.p6 succesfully reads a Proc on the
# default file handle to generate camelia.ppm, but ppm-convert.pipe.p6 is unable to write to a Proc on the
# default file handle. Returns error:
# 'convert.im6: unable to read image data `-' @ error/pnm.c/ReadPNMImage/903.'
# It seems the hyphen is being passed as data rather than used as a filehandle.
# If you just run the command 'cat ./camelia.ppm | ppm:- camelia.jpg' at a bash prompt it works as expected.
# problem in line 30. syntax?
class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
has UInt ($.width, $.height);
has Pixel @.data;
}
role PPM {
method P6 returns Blob {
"P6\n{self.width} {self.height}\n255\n".encode('ascii')
~ Blob.new: flat map { .R, .G, .B }, self.data
}
}
sub load-ppm ( $ppm ) {
my $fh = $ppm.IO.open( :enc('ISO-8859-1') );
my $type = $fh.get;
my ($width, $height) = $fh.get.split: ' ';
my $depth = $fh.get;
Bitmap.new( width => $width.Int, height => $height.Int,
data => ( $fh.slurp.ords.rotor(3).map:
{ Pixel.new(R => .[0], G => .[1], B => .[2]) } )
)
}
my $filename = './camelia.ppm';
my Bitmap $b = load-ppm( $filename ) but PPM;
my $proc = shell 'convert ppm:- camelia.jpg', :in; # <-- not working as expected
$proc.in.write: $b.P6;
# works as expected. run to generate camelia.ppm
class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
has UInt ($.width, $.height);
has Pixel @.data;
}
role PPM {
method P6 returns Blob {
"P6\n{self.width} {self.height}\n255\n".encode('ascii')
~ Blob.new: flat map { .R, .G, .B }, self.data
}
}
my $filename = './camelia.png';
my $proc = run 'convert', $filename, 'ppm:-', :enc('ISO-8859-1'), :out;
my Bitmap $b = do {
my $type = getline($proc);
my ($width, $height) = getline($proc).split: ' ';
my $depth = getline($proc);
Bitmap.new( width => $width.Int, height => $height.Int) but PPM;
}
$b.data = $proc.out.slurp.ords.rotor(3).map:
{ Pixel.new(R => .[0], G => .[1], B => .[2]) };
# fill out pixmap that may be missing some pixels
$b.data.push($b.data[*-1].clone) while $b.data.elems < $b.width * $b.height;
'./camelia.ppm'.IO.open(:bin, :w).write: $b.P6;
sub getline ( $proc ) {
my $line = '#'; # skip comments when reading
$line = $proc.out.get while $line.substr(0,1) eq '#';
$line;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment