gnuplot-iostream icon indicating copy to clipboard operation
gnuplot-iostream copied to clipboard

Support generic reading of Feedback

Open acidtonic opened this issue 6 years ago • 3 comments

First, thanks for your work on the project.

I am trying to create an image and dump it to the console instead of through a file. I am able to do so by setting the terminal to pngcairo and avoid setting an output.

It seems that the mechanism to read back from the process is geared towards mouse feedback, but I noticed you have all the required components already in the code, it's just private.

https://github.com/dstahlke/gnuplot-iostream/blob/master/gnuplot-iostream.h#L1821

Can we perhaps adjust things slightly so that allocFeedback is public and can be called by the user, and a public getter for the GnuplotFeedback pointer?

This way I could read the generated png out of the console instead of going to the disk.

My ideal usage would be something like....


gp << "graph commands here";
gp.allocFeedback();
GnuplotFeedback * feedback = gp.feedback //(or a const getter)
gp.send1d(mydata);
File * pngFile = feedback->handle();
//Code to render the file or do whatever here. 

acidtonic avatar May 23 '18 15:05 acidtonic

GnuplotFeedbackPty is actually a separate class from the main Gnuplot class, so you could actually just use it as-is. The feedback member variable in the Gnuplot class is just there to avoid having to re-create the PTY each time. If you want to make that public, feel free to send me a pull request. But you could also just do something like this from your code:

GnuplotFeedbackPty pty(debug_messages);
gp << "set output \"" << pty.filename() << "\"\n";
gp.send1d(mydata);
FILE * pngFile = feedback->handle();

But keep in mind that this mechanism only works in Linux.

dstahlke avatar May 25 '18 05:05 dstahlke

This actually was helpful. I didn't think about manually using the class which fits my use case a bit better.

I did however run into a problem which is slightly borderline....

gnuplot when using the pngcairo terminal apparently adds CRLF's to the binary output in the PTY. I am on linux so this was unexpected. Appears to be a bug upstream in gnuplot. To workaround I manually read character by character and used a state machine to skip the CR if the next character is LF. This way I directly have the image binary data without ever touching the filesystem.

But I did have to adjust the mode the GnuplotFeedbackPty opens the handle with to include binary mode and added a getter for the master_fd so I could fcntl the descriptor into non-blocking mode. Otherwise the transient EOFs from the PTY would block fread incorrectly (even with feof) and either give me an incomplete file, or a blocking read past the end.

It was a bit more challenging than I expected but in the end it works fantastically. Thanks for your help!

acidtonic avatar May 30 '18 19:05 acidtonic

I'm glad you got it (sort of) working. It surprises me that you had to open the PTY in binary mode, as I was under the impression that text and binary mode were equivalent on Unix.

Instead of a PTY, you could look into the O_TMPFILE option of open. This creates an unnamed temporary file, never being visible on disk and guaranteed to be deleted if your program crashes. You can then read the file from /proc/self/fd/. Beware that O_TMPFILE only exists in since Linux 3.11.

dstahlke avatar May 31 '18 05:05 dstahlke