Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

STDOUT buffering problem

by illtud (Initiate)
on Apr 16, 2013 at 12:35 UTC ( #1028895=perlquestion: print w/ replies, xml ) Need Help??
illtud has asked for the wisdom of the Perl Monks concerning the following question:

I've read the buffering FAQs and I've peppered my code with '$| = 1;'and STDOUT->flush(); , tried STDOUT->autoflush(1); but since moving from a RHEL5 (perl 5.8.8) to RHEL6 (perl 5.10.1) this script (simplified from original, but still exhibits the problem) doesn't write out all the binary image data to STDOUT before the last line is written - the last line appears in the middle of the binary data about 150 bytes from the end.

Help!

ImageMagick-perl has gone from ImageMagick-perl-6.2.8.0-15.el5_8 to ImageMagick-perl-6.5.4.7-6.el6_2.x86_64

#!/usr/bin/perl use warnings; use Getopt::Long; use Image::Magick; use IO::Handle qw( ); $| = 1; STDOUT->autoflush(1); # Mandatory options: # -f photo jpeg file (full path) GetOptions ( 'f=s' => \$photofile) or die ("can't do getops\n"); #Open the image as an Perlmagick object $ffoto = new Image::Magick; $x = $ffoto->Read($photofile); warn "can't open photofile:$x" if "$x"; $ffoto->Resize(geometry=>'x296'); $ffoto->Set(depth=>8); $ffoto->Rotate(degrees=>270); $ffoto->Negate(); $ffoto->Evaluate(value=>8, operator=>'Divide'); #Copy image to new image objects $yellow = $ffoto->Clone(); #Separate the colours - need to set depth again $yellow->Separate(channel=>'yellow'); $yellow->Set(depth=>8); ## ## EPCL output section ## #yellow: binmode STDOUT; $yellow->Write('gray:-'); print ("\r"); print ("\x1bIS 0\r"); #DEBUG print ("should be last line\n"); exit 0;

Comment on STDOUT buffering problem
Download Code
Re: STDOUT buffering problem
by hdb (Prior) on Apr 16, 2013 at 12:52 UTC

    I do not have your modules nor your file but I am reminded of some old times when printing binary data to the screen resulted in the prompt appearing in the middle of the printed stuff (think Commodore 64). This was due to some of the printed characters being "movement instructions" such as backspace or start of screen or the like.

    Does the same thing happen if you redirect your output into a file and look at it in some (robust) editor?

    Just a hunch...

Re: STDOUT buffering problem
by RichardK (Priest) on Apr 16, 2013 at 12:55 UTC

    Are you sure you need '\r' not '\n' ?

    Are you just looking at the output on screen and the '\r' (return) is just over writing the last line whereas '\n' (newline) will put the output on a newline ?

      Thanks for the replies.

      No, I'm looking at the output in a binary editor, and \r is definitely what I need, not \n (this is a printer control language and it wants \r). The writes are definitely coming out in an unexpected order. I'm also piping these straight into a file and getting the same results.

Re: STDOUT buffering problem
by choroba (Abbot) on Apr 16, 2013 at 13:52 UTC
    Wild guess: What happens if you binmode STDOUT before setting its autoflush?
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Nothing, unfortunately.

Re: STDOUT buffering problem
by CountOrlok (Friar) on Apr 16, 2013 at 14:02 UTC
    This may be a longshot, but I wonder if the $yellow->Write() writes to stdout in a separate thread (in the imageMagick library) and so your print statements are disjoint from the Write. One of the imageMagick forums mentioned setting the environment variable MAGICK_THREAD_LIMIT to 1. Could be that may help.
      MAGICK_THREAD_LIMIT to 1. Could be that may help.

      Good idea! Nope, no different. Setting to 0 doesn't help either.

        OK, for a quick fix I rewrote it to output the image data to temporary files (in the full script there's an image for each of the CMY layers) and then write those out to stdout.

        I couldn't work out from Image::Magick how to get the binary data out using GetPixels to match the binary data that I got from writing out the files, at some point I'll go and ask the ImageMagick list and that will let me do without the temporary files.

        Thanks for your replies, this one was a puzzler to me, but I'm no perl guru! This is a snippet of what worked for me:

        ... binmode STDOUT; $yellow->Write('gray:/tmp/yellow'); open(FIN,"</tmp/yellow") || die("cannot access file /tmp/yellow\n"); while (sysread FIN, $buffer, 4096) { print $buffer; } close FIN; print("\r"); ...
Re: STDOUT buffering problem
by Khen1950fx (Canon) on Apr 16, 2013 at 16:46 UTC
    I noticed that you turned on autoflush twice. I would rather see something like this:
    #!/usr/bin/perl -l use strict; use warnings; use Getopt::Long; use Image::Magick; use IO::Handle (); STDOUT->autoflush(1);
    Easier on the eyes, no?

      The code snippet was what was left from stripping the full script down to just enough to illustrate the problem, and I had been peppering it with many attempts to fix the buffering issue. It's not production.

Re: STDOUT buffering problem
by Anonymous Monk on Apr 17, 2013 at 02:30 UTC
    What does gray in   $yellow->Write('gray:-'); mean? I've never heard of a gray image format

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1028895]
Approved by kcott
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (14)
As of 2014-10-02 16:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    What is your favourite meta-syntactic variable name?














    Results (65 votes), past polls