Posts Tagged ‘pipe’

Command line program to view 3d meshes from files and piped input

Thursday, December 15th, 2016

Here’s a little C++ program to directly render meshes in 3D viewer from the command line.

This let’s you write little test programs without worrying about linking to a 3D viewer. You just need to output a mesh in a standard format. For example, here’s a tiny program that outputs a cube in an .off format:

#include <igl/read_triangle_mesh.h>
#include <Eigen/Core>
#include <iostream>

int main(int argc, char * argv[])
{
  using namespace Eigen;
  MatrixXd V(8,3);
  MatrixXi Q(6,4);
  V<<
    0,0,1,
    0,1,1,
    1,1,1,
    1,0,1,
    0,0,0,
    0,1,0,
    1,1,0,
    1,0,0;
  Q<<
    3,2,1,0,
    0,1,5,4,
    6,5,1,2,
    3,7,6,2,
    4,7,3,0,
    4,5,6,7;
  std::cout<<
    "OFF\n"<<V.rows()<<" "<<Q.rows()<<" 0\n"<<
    V.format(IOFormat(FullPrecision,DontAlignCols," ","\n","","","","\n"))<<
    (Q.array()).format(IOFormat(FullPrecision,DontAlignCols," ","\n","4 ","","","\n"));
  return EXIT_SUCCESS;
}

Compile this into cube_off then issue:

./cube_off | view mesh

**Update: ** And here’s a funny, little one-liner you can call from matlab to display a mesh via the .obj format:

system(sprintf('echo \"%s%s\" | /usr/local/bin/viewmesh',sprintf('v %0.17f %0.17f %0.17f\n',V'),sprintf('f %d %d %d\n',F')))

Copy image file to clipboard

Saturday, January 25th, 2014

Here’s a small objective-c program to take an image file and copy it to the clipboard on Mac OS X. Dump this in a file called impbcopy.m:

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>
BOOL copy_to_clipboard(NSString *path)
{
  // http://stackoverflow.com/questions/2681630/how-to-read-png-image-to-nsimage
  NSImage * image;
  if([path isEqualToString:@"-"])
  {
    // http://caiustheory.com/read-standard-input-using-objective-c 
    NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
    image = [[NSImage alloc] initWithData:[input readDataToEndOfFile]];
  }else
  { 
    image =  [[NSImage alloc] initWithContentsOfFile:path];
  }
  // http://stackoverflow.com/a/18124824/148668
  BOOL copied = false;
  if (image != nil)
  {
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    NSArray *copiedObjects = [NSArray arrayWithObject:image];
    copied = [pasteboard writeObjects:copiedObjects];
    [pasteboard release];
  }
  [image release];
  return copied;
}

int main(int argc, char * const argv[])
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  if(argc<2)
  {
    printf("Usage:\n\n"
      "Copy file to clipboard:\n    ./impbcopy path/to/file\n\n"
      "Copy stdin to clipboard:\n    cat /path/to/file | ./impbcopy -");
    return EXIT_FAILURE;
  }
  NSString *path= [NSString stringWithUTF8String:argv[1]];
  BOOL success = copy_to_clipboard(path);
  [pool release];
  return (success?EXIT_SUCCESS:EXIT_FAILURE);
}

Then compile with:

gcc -Wall -g -O3 -ObjC -framework Foundation -framework AppKit -o impbcopy impbcopy.m

And run with something like:

./impbcopy path/to/file.png

or from stdin use:

cat path/to/file.jpg | ./impbcopy -

Update: For completeness, here’s a small program to paste the clipboard image to a file:

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>

@interface NSImage(saveAsPNGWithName)
- (void) saveAsPNGWithName:(NSString*) fileName;
@end

@implementation NSImage(saveAsPNGWithName)

- (void) saveAsPNGWithName:(NSString*) fileName
{
    // Cache the reduced image
    NSData *imageData = [self TIFFRepresentation];
    NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
    imageData = [imageRep representationUsingType:NSPNGFileType properties:imageProps];
    [imageData writeToFile:fileName atomically:NO];        
}

@end

BOOL paste_from_clipboard(NSString *path)
{
  // http://stackoverflow.com/a/18124824/148668
  NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
  NSArray *classArray = [NSArray arrayWithObject:[NSImage class]];
  NSDictionary *options = [NSDictionary dictionary];
  BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options]; 
  if(ok)
  {
    NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
    NSImage *image = [objectsToPaste objectAtIndex:0];
    // http://stackoverflow.com/a/3213017/148668
    [image release];
  }else
  {
    printf("Error: Clipboard doesn't seem to contain an image.\n");
  }
  return ok;
}

int main(int argc, char * const argv[])
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  if(argc<2)
  {
    printf("Usage:\n\n"
      "Paste clipboard to file:\n    ./impbcopy path/to/file\n\n");
    return EXIT_FAILURE;
  }
  NSString *path= [NSString stringWithUTF8String:argv[1]];
  BOOL success = paste_from_clipboard(path);
  [pool release];
  return (success?EXIT_SUCCESS:EXIT_FAILURE);
}

Compile with:

clang -Wall -g -O3 -ObjC -framework Foundation -framework AppKit -o impbpaste impbpaste.m

and run:

./impbpaste foo.png

Update: could also try the command line program pngpaste which has more features.

Use piped input like it’s from stdin in a C++ program

Tuesday, September 6th, 2011

I was dismayed to find out that the file pointer stdin works fine in a compiled C++ program from a unix/linux shell if you redirect a file to standard in like this:
Option #1:


./my_program <myinputfile

But it doesn’t work if the input is coming from a pipe like this:
Option #2:


cat myfile | ./myprogram

Now, there exist ways to read from the pipe correctly. It seems you should first determine which situation is occurring and process each situation differently. But for me this was not an option because I wanted to call a library function whose interface looked like this:


int lib_func(FILE * file_pointer);

For option #1, just calling the following works just fine:


lib_func(stdin);

But for option #2, I get a segmentation fault.

So I whipped up this small function you can save in stdin_to_temp.h:


#include <cstdio>
// Write stdin/piped input to a temporary file which can than be preprocessed as it
// is (a normal file).
// Outputs:
//   temp_file  pointer to temp file pointer, rewound to beginning of file so
//     its ready to be read
// Return true only if no errors were found
//
// Note: Caller is responsible for closing the file (tmpfile() automatically
// unlinks the file so there is no need to remove/delete/unlink the file)
bool stdin_to_temp(FILE ** temp_file);

// IMPLEMENTATION
#include <iostream>
using namespace std;

bool stdin_to_temp(FILE ** temp_file)
{
  // get a temporary file
  *temp_file = tmpfile();
  if(*temp_file == NULL)
  {
    fprintf(stderr,"IOError: temp file could not be created.\n");
    return false;
  }
  char c;
  // c++'s cin handles the stdind input in a reasonable way
  while (cin.good())
  {
    c = cin.get();
    if(cin.good())
    {
      if(1 != fwrite(&c,sizeof(char),1,*temp_file))
      {
        fprintf(stderr,"IOError: error writing to tempfile.\n");
        return false;
      }
    }
  }
  // rewind file getting it ready to read from
  rewind(*temp_file);
  return true;
}

The idea is to take advantage of the fact that in C++ the istream cin “correctly” treats stdin and piped input as the same. So if I read from cin and write it back to some temporary file then I get a file pointer that acts like how I wanted the stdin to act.

You can demo how it works with this small program. Save it in stdin_to_temp_demo.cpp


#include "stdin_to_temp.h"

/**
 * Compile with:
 *   g++ -O3 -o stdin_to_temp_demo stdin_to_temp_demo.cpp
 *
 * Run examples:
 *   cat file1 | ./stdin_to_temp_demo
 *   cat file1 | ./stdin_to_temp_demo | cat >file2
 *   cat file1 | ./stdin_to_temp_demo dummy1 dummy2 | cat >file2
 *   ./stdin_to_temp_demo <file1 | cat >file2
 *   ./stdin_to_temp_demo <file1 >file2
 *
 */

int main(int argc,char * argv[])
{
  // Process arguements and print to stderr
  for(int i = 1;i<argc;i++)
  {
    fprintf(stderr,"argv[%d] = %s\n",i,argv[i]);
  }

  FILE * temp_file;
  bool success = stdin_to_temp(&temp_file);
  if(!success)
  {
    fprintf(stderr,"Fatal Error: could not convert stdin to temp file\n");
    // try to close temp file
    fclose(temp_file);
    exit(1);
  }

  // Do something interesting with the temporary file. 
  // Read the file and write it to stdout
  char c;
  // Read file one character at a time and write to stdout
  while(fread(&c,sizeof(char),1,temp_file)==1)
  {
    fwrite(&c,sizeof(char),1,stdout);
  }
  // close file
  fclose(temp_file);
}

Surely this doesn’t not take full advantage of pipes. I think its actually defeating their intended purpose. But it allows me to have the familiar interface for my simple C++ program that I wanted.

Escape code for html <pre> or <code> tag into clipboard: Ruby Version

Thursday, November 5th, 2009

I previously posted a bash script to speed up posting code in a <pre> or <code> tag in an html page or blog. The script escapes all less than and greater than symbols (< with &lt; and > with &gt;) in a given file then puts the results in the clipboard to facilitate pasting into a text area or text editor. I have now rewritten this idea in ruby. Now you can either cat in a file to the ruby script using pipe, or enter (paste) the input text directly. Save the following the ruby source in a file called escape-copy.rb:


#!/usr/bin/ruby -w
# Usage:
# cat input_file | ruby escape-copy.rb | pbcopy
# or
# ruby escape-copy.rb | pbcopy
# (enter or paste your text then CTRL-D on its own line as EOF)
print ARGF.read.gsub(/</,"<").gsub(/>/,">")

Note: I of course used escape-copy.rb to make posting the source above super easy!