metgrab.c

/*
 * Meteor Capture utility
 * Captures one frame in PPM format from /dev/meteor0
 *
 * Brian "Paco" Hope	paco@cs.virginia.edu
 * University of Virginia
 * Computer Science Department
 * Multimedia Networks Lab
 * 
 * This code heavily based on code written by Jim Lowe
 * (james@cs.uwm.edu) who also wrote a good chunk of the Meteor driver.
 *
 * compile this way:
 * gcc -O2 -o metgrab metgrab.c
 */

#include <stdio.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <machine/ioctl_meteor.h>

extern int errno;
#define ROWS 128
#define COLS 128
#define SIZE (ROWS * COLS * 4)
#define OUTSIZE (SIZE * 3 / 4)
#define DEVICE "/dev/meteor0"

int
main( int argc, char* argv[] )
{
    struct meteor_geomet geo;
    char inBuf[SIZE];
    char outBuf[OUTSIZE];
    int meteorHandle;
    int i,j;
    int outputFile;
    int command;
    
   
    if( argc < 2 )
    {
	printf( "\nUsage: %s filename \n", argv[0] );
	exit( 1 );
    }

    /* set up the capture type and size */
    geo.rows = ROWS;
    geo.columns = COLS;
    geo.frames = 1;
    geo.oformat = METEOR_GEO_RGB24;
    
    /* Open the Meteor */
    if ((meteorHandle = open( DEVICE, O_RDONLY ) ) < 0) 
    {
	perror( "open failed" );
	exit( 1 );
    }

    /* Set the Geometry */
    if (ioctl(meteorHandle, METEORSETGEO, &geo) < 0) 
    {
	perror( "ioctl METEORSETGEO failed" );
	exit( 1 );
    }

    /* Set the Format */
    command = METEOR_FMT_NTSC;
    if (ioctl(meteorHandle, METEORSFMT, &command) < 0) 
    {
	perror( "ioctl METEORSFMT failed" );
	exit( 1 );
    }
    
    /* Set the input device */
    command = METEOR_INPUT_DEV0;
    if (ioctl(meteorHandle, METEORSINPUT, &command) < 0) 
    {
	perror( "ioctl METEORSINPUT failed" );
	exit( 1 );
    }

    /* Read the frame */
    if ( (command = read(meteorHandle, &inBuf[0], SIZE) ) < 1) 
    {
	fprintf( stderr, "read failed %d %d %d\n", command,
                 meteorHandle, errno);

	close( meteorHandle );
	exit( 1 );
    }
    close( meteorHandle );
    
    /* The card returns 4 bytes per pixel as follows: */
    /* BLUE | RED | GREEN | NULL */
    /* We turn that into RED | GREEN | BLUE for ppm format */
    for( i=0,j=0; i < SIZE; i+=4,j+=3 )
    {
	outBuf[j+2] = inBuf[i];
	outBuf[j+1] = inBuf[i+1];
	outBuf[j]   = inBuf[i+2];
    }

    /* Now that we have a buffer full of rgb data, write it out to */
    /* a file */
    
    if ( (outputFile = open( argv[1], O_WRONLY | O_CREAT, 0644) ) < 0) 
    {
	fprintf( stderr, "open file \"%s\" failed: %d\n", argv[1], errno );
	exit( 1 );
    }

    sprintf( inBuf, "P6\n# Meteor Grab Utility\n%d %d\n255\n",
	    COLS, ROWS );

    /* Write PPM header to file */ 
    write( outputFile, inBuf, strlen( inBuf ) );
    /* save the RGB data to PPM file */
    write( outputFile, outBuf, OUTSIZE );
    close( outputFile );
    exit( 0 );
}

paco@cs.virginia.edu
Last modified: Wed Jun 19 11:03:04 1996