/**
    : pcraw2st.c
    : Chris Herborth, Sept.8/92
    
    : This is to convert PC RAW files, produced by ray tracers such as QRT,
      DKB, and POV-Ray, into ST format RAW files.  I'm not sure why the guy
      who ported QRT to the ST decided to munge their format, but...

    : Usage: pcraw2st infile.raw outfile.raw
    
    : To do list:
        a) A brightness option, to make the brightest colour 100% saturation
           in that colour, and increas all other colours by that amount.  The
           QRT2GIF.EXE seems to make _really_ dark GIFs.
        b) Image size conversion.  Reduce a 800x600 (or whatever) file to
           320x200 for viewing on the ST with PhotoChrome.  Increase smaller
           images to 320x200.
        c) Nice GEM interface.
        d) Other formats -> ST raw
        e) Cropping images > 320x200
        f) Nice image processing functions.
        g) Pad the file to the desired size with BLACK if it's only a partial
           image.
        h) More error checking.
        i) Sanity checking.
        
        NOTE: Most of those aren't too realistic for a simple filter.  They'd
              be in a nice RAWTOOL GEM program.
**/

/** : Header files...                                                       **/
#include <stdio.h>
#include <string.h>
#ifdef SOZOBON
#include <malloc.h>
#endif

/** : Define error messages...                                              **/
#define OK           0      /* No errors.               */
#define USAGE_ERR   -1      /* Dumb user error.         */
#define FILE_SAME   -2      /* infile == outfile error  */
#define NO_MEMORY   -3      /* Insufficient memory      */

int        main( argc, argv )
unsigned   argc;
char     **argv;
{
    FILE *infile,           /* Input file handle.  */
         *outfile;          /* Output file handle. */
    
    char *r_line,           /* RGB lines from the PC RAW file */
         *g_line,           /* malloc() these                 */
         *b_line,
          thing,            /* One input byte       */
         *in_name,          /* Filename pointers    */
         *out_name;
    
    int   width,            /* Image width              */
          height,           /* Image height             */
          line,             /* Line loop                */
          loop,             /* Pixel loop               */
          err_mess,         /* Error number             */
          ret;              /* Function return value.   */

    union
    {
    	int  w;
    	char b[1];
    } spam;

    /* Initialize our variables...                                            */
    infile  = NULL;         /* File pointers don't point yet... */
    outfile = NULL;

    r_line = NULL;          /* Neither do our line pointers...  */
    g_line = NULL;
    b_line = NULL;
    
    err_mess = OK;          /* We haven't had any errors yet... */

    /* Parse the command line...  This is mostly here for future expansion... */
    if( argc < 2 )
        err_mess = USAGE_ERR;
    else
    {
        if( argv[loop][0] == '-' )
            switch( argv[loop][1] )
            {
                case '?':
                case 'h':
                case 'H':
                    err_mess = USAGE_ERR;
                    break;

		case 'V':
		    puts( "pcraw2st 0.2" );
		    err_mess = -13;
		    break;

                default:
                    err_mess = USAGE_ERR;
                    break;
            }
        else
        {
            in_name  = argv[1];
            out_name = argv[2];
            ret = strcmp( in_name, out_name );
            if( ret == 0 )
                err_mess = FILE_SAME;
        }
    }  


    /* If we haven't had any problems, try to process the files... */
    if( err_mess == OK )
    {
        infile  = fopen( in_name, "rb" );
        if( infile == NULL )
        {
            printf( "Unable to open %s...\n", infile );
            exit( -1 );
        }
        
        outfile = fopen( out_name, "wb" );
        if( outfile == NULL )
        {
            printf( "Unable to create %s...\n", outfile );
            exit( -1 );
        }
        
        /* Get our image width... */
	/* These have to be swapped around for Intel Idiotic format. */        
        spam.b[1] = fgetc( infile );
        spam.b[0] = fgetc( infile );
        width = spam.w;
       
        /* Get our image height... */
	/* These have to be swapped around for Intel Idiotic format. */        
        spam.b[1] = fgetc( infile );
        spam.b[0] = fgetc( infile );
        height = spam.w;
        
        /* Talk to the user... */
        printf( "Converting %d x %d image:\n", width, height );
        
        /* Put the width/height into the new file... */
        fprintf( outfile, "%d %d%c", width, height, 0x0a );
        fflush( outfile );
        
        r_line = (char *)malloc( width );
        g_line = (char *)malloc( width );
        b_line = (char *)malloc( width );
        if( r_line == NULL || g_line == NULL || b_line == NULL )
            err_mess = NO_MEMORY;
        
        if( err_mess == OK )
            for( line = 0; line < height; line++ )
            {
		/* Get the current line number. We don't do anything with it. */
		/* These have to be swapped around for Intel Idiotic format. */
                spam.b[1] = fgetc( infile );
                spam.b[0] = fgetc( infile ); /* Kill the line number */
                fread( r_line, width, 1, infile );
                fread( g_line, width, 1, infile );
                fread( b_line, width, 1, infile );
                
                for( loop = 0; loop < width; loop++ )
                    fprintf( outfile, "%c%c%c", r_line[loop], g_line[loop],
                             b_line[loop] );
                
                fflush( outfile );
                printf( "." );
                if( ( line + 1 ) % 50 == 0 )
                    printf( "%d", line + 1 );
		fflush( stdout );
            }     
    }    
                    
    switch( err_mess )
    {
        case OK:
            puts( " done." );
            break;
            
        case USAGE_ERR:
            puts( "Usage:  pcraw2st infile.raw outfile.raw" );
            break;

        case FILE_SAME:
            printf( "Cannot convert %s to %s!\n", in_name, out_name );
            puts( "File names must be different!" );
            break;

        case NO_MEMORY:
            puts( "Insufficient memory!" );
            break;

        default:
            break;
    }

    /* Close our files... */
    if( infile != NULL )
        fclose( infile );
    if( outfile != NULL )
        fclose( outfile );
        
    /* Toss our memory... */
    if( r_line != NULL )
        free( r_line );
    if( g_line != NULL )
        free( g_line );
    if( b_line != NULL )
        free( b_line );

    /* Beat it... */                
    exit( err_mess );
}
