mckenney@talos.UUCP ( APL Consultant) (03/23/89)
A few weeks ago I downloaded the QRT source, documentation, and sample files from the Cleveland Area-Amiga Users' Group BBS. I am extremely impressed with the work Mr. Koren has put into this software. I have ported it to PC-DOS, and have it up and running under Microsoft C 5.1 (compact model). In the process I wound up making the following changes: - Changed text/source file line delimiter from \x0A to \x0A\x0D - Set CNUM to 256, so the post-processor can do color reduction - Fix for malloc(strlen()) bug - Added #ifdefs for MSC which call appropriate #include files - Added qrtfn.h containing function declarations in ANSI form - Fixed side-effect problem with toupper() macro - Installed calls for def_colorinfo() for all new CINFOs - Added ACTIVITY option to RAY.C to show activity while tracing - Added "default to VGA" in QRT.H specifications - Fixed fopen() calls to use BINARY mode - Changed byte array definitions from 'short' to 'unsigned char' in Screen_Trace() and Dump_Line(). - Limited trace statement in Screen_Trace() to 0..255 to prevent misleading trace information. - Update defaults for ambient light and threshold in QRT.C - Corrected CNUM to CNUM-1 in a number of places - Changed ASPECT from .56 to 1.20 for 320x200 mode A QRT post-processor which generates .PIC files suitable for GRASP (PICTOR) and PC Paint is attached for those interested. Further work will probably be in two areas: 1) Better palette color selection through a pre-scan of the raw data file. 2) A method for producing a quick 'preview' of a scene. This would allow me to play around with object placement and correct any obvious errors before I turn the machine loose for several hours. For those of you interested in timings, the PIANO.QRT file took 95 minutes to process on an Everex System 1800 (10MHz, 1ws) with an 80287 installed. The following files are available from the Cleveland Area-Amiga Users' Group BBS at (216) 292-4404: QRTSRC14.ARC 57344 08-24-88 Source for QRT 1.4 (C) QRTDOC4A.ARC 56320 09-24-88 Includes 'UserMan.Doc' from 1.4 QRTINP14.ARC 16512 11-05-88 6 QRT inp scripts, plus QRT news TABLE.ARC 72704 08-24-88 Demo for QRT1.4-glass table PIANO.ARC 4736 06-25-88 QRT image spec for grand piano MIRRORS.ARC 2560 06-15-88 QRT source (not pic) /*-------------- QRTIBM.C --------------------------------------------------*/ /**************************************************************************** QRTIBM Version 1.0 IBM VGA Post-processor for QRT Syntax: QRTIBM Input[.RAW] [ Output[.PIC] ] Written by: Frank McKenney, McKenney Associates Last Updated: 03/22/89 Compiler: Microsoft C 5.1 Model: Small ********************************************************************** QRTIBM is a QRT post-processor which converts QRT raw output (.RAW) files to GRASP/PICTOR (.PIC) Mode L format (320x200, 256-color). The format of the QRT raw data file is as follows: Offset Length Description ------ ------ ----------- 0 2 XRES - X resolution (pixels), Intel format (low,high) 2 2 YRES - Y resolution (pixels), Intel format (low,high) 4 ... Up to YRES sets of scan line information. Each line is (2+3*XRES) bytes long, formatted as follows: -------- ------ +0 2 Line number, Intel format (low,high) Top is line 0. +2 XRES Red intensity values (1 byte each, 0-255) +XRES+2 XRES Green intensity values (1 byte each, 0-255) +2*XRES+2 XRES Blue intensity values (1 byte each, 0-255) Note 1: Scan lines may be omitted from the file, but the scan line number will always be in the range 0..YRES-1. Note 2: The GRASP .PIC format assumes that scan line 0 is at the BOTTOM of the screen, while QRT assumes it to be at the TOP. As a result, we have to work our way backwards through the input file. Note 3: The current version of QRTIBM assumes that QRT's CNUM value (the number of shades per color) has been set to 255, and maps the resulting R/G/B values into 2/3/3 bits (respectively). This yields a reasonable variety of colors within the 256 color limit imposed by the VGA adapter. It is possible that the palette could be improved through a pre- scan of the input. Suggestions are welcomed. *****************************************************************************/ #include <stdio.h> #include <string.h> /* #define DEBUG */ #define TRACK_RGB #define MAXXRES 320 /* Largest X resolution currently supported */ #define LineSizeL (2L + (3L * (long)xres)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define OBUF_SIZE 8192 /* Just a nice large buffer */ char obuf[OBUF_SIZE]; /* Output buffer (.PIC file) */ /* Temporary (!) Kluge */ char pichdr[17] = /* File header for uncompressed MCGA/VGA image */ "\x34\x12\x40\x01\xC8\x00\x00\x00\x00\x00\x08\xFF\x4C\x04\x00\x00\x03"; char InFile[65], OutFile[65]; /* Input and output file names */ main(argc,argv) int argc; char *argv[]; { int xres, yres, scanline, lastline; int i, j, rv, gv, bv, iv, v; float iflt; unsigned char r[MAXXRES], g[MAXXRES], b[MAXXRES]; long inpos; FILE *in, *out; char *p; #ifdef TRACK_RGB int maxr = 0, maxg = 0, maxb = 0; /* Track .RAW file RGB values */ #endif /* Quick parameter check / help message */ if (argc < 2 || argc > 3) { printf("Usage: %s Input[.RAW] Output[.PIC]\n",argv[0]); exit(1); } strcpy(InFile,argv[1]); if (argc == 3) /* Output file name supplied */ strcpy(OutFile,argv[2]); else /* Default to same base name as input file */ { strcpy(OutFile,InFile); if ( (p=strchr(OutFile,'.')) != NULL ) *p = '\0'; /* (but don't retain any extension). */ } if ( strchr(InFile,'.') == NULL ) strcat(InFile,".RAW"); if ( strchr(OutFile,'.') == NULL ) strcat(OutFile,".PIC"); /* Open input and output files in BINARY Mode. Abort if error */ if ((in = fopen(InFile,"rb")) == NULL) { printf("Unable to open input file %s\n",InFile); exit(1); } if ((out = fopen(OutFile,"wb")) == NULL) { printf("Unable to open output file %s\n",OutFile); exit(1); } /* Set up buffer for output file */ setvbuf(out,obuf,_IOFBF,sizeof(obuf)); /* Retrieve X and Y pixel counts from input file */ xres = fgetc(in) & 0x00FF; /* Reconstruct word */ xres |= (fgetc(in) & 0x00FF) << 8; yres = fgetc(in) & 0x00FF; /* Reconstruct word */ yres |= (fgetc(in) & 0x00FF) << 8; printf("Input: %s\n",InFile); printf("Output: %s\n",OutFile); printf("Screen: %dh x %dv\n",xres,yres); /* Write out .PIC header for Mode L (kluge for now) */ for (i=0; i<sizeof(pichdr); i++) fputc(pichdr[i],out); for (i=0; i<256; i++) /* Make up a .PIC palette */ { /* Set up palette so we can index it with rrrgggbb */ #define MAX_IVAL 63 #define N_REDS 8 #define N_GREENS 8 #define N_BLUES 4 #define K1_RED ((float)(MAX_IVAL)/(N_REDS-1)) #define K1_GREEN ((float)(MAX_IVAL)/(N_GREENS-1)) #define K1_BLUE ((float)(MAX_IVAL)/(N_BLUES-1)) rv = K1_RED * ((i & 0xE0) >> 5); rv = MIN(MAX_IVAL,rv); gv = K1_GREEN * ((i & 0x1C) >> 2); gv = MIN(MAX_IVAL,gv); bv = K1_BLUE * (i & 0x03); bv = MIN(MAX_IVAL,bv); fputc(rv,out); fputc(gv,out); fputc(bv,out); } fputc('\x00',out); fputc('\x00',out); /* Mark as unpacked file */ /* Seek to end of file, just past end of last scan line. */ /* Read resulting position and check for validity. */ fseek(in, 0L, SEEK_END); inpos = ftell(in); /* Works since file opened in binary mode */ if ( (inpos - 4) % LineSizeL ) { printf("Input file has one or more partial scan lines\n"); exit(1); } if ( inpos > (long)(4L + (long)yres * LineSizeL) ) { printf("Input file not valid - too large for resolution\n"); exit(1); } for (lastline = yres - 1; lastline >= 0; lastline--) { inpos -= LineSizeL; /* Back up to previous line in file */ fseek(in, inpos, SEEK_SET); /* Get scan line number from file and validate */ scanline = fgetc(in) & 0xFF; /* Reconstruct word */ scanline += (fgetc(in) & 0xFF) << 8; #ifdef DEBUG printf("File pos: %ld, file scanline %.3d, lastline: %.3d\n", inpos, scanline, lastline); #endif if ( scanline > yres ) { printf("Input contains bad scan line (%d) at position %ld\n", scanline, inpos); exit(1); } if ( scanline > lastline ) { printf("Input scan line %d out of order at position %ld\n", scanline, inpos); exit(1); } /* Possibly provide blank (Black) scan lines */ while ( lastline > scanline ) { #ifdef DEBUG printf("Filling scan line %.3d\n",lastline); #endif for (i=0; i < xres; i++) /* Write one line of black */ fputc('\x00',out); lastline--; } /* Read Red, Green, and Blue intensity values from file */ for (i=0; i < xres; i++) r[i] = fgetc(in); for (i=0; i < xres; i++) g[i] = fgetc(in); for (i=0; i < xres; i++) b[i] = fgetc(in); /* Convert intensity values to palette index */ /* and write out to file. */ for (i=0; i < xres; i++) { rv = r[i]; gv = g[i]; bv = b[i]; #ifdef TRACK_RGB maxr = MAX(rv,maxr); maxg = MAX(gv,maxg); maxb = MAX(bv,maxb); #endif /* Create a one byte rrrgggbb palette index from RGB values */ rv = (rv+15) >> 5; gv = (gv+15) >> 5; bv = (bv+31) >> 6; rv = MIN(0x07,rv); gv = MIN(0x07,gv); bv = MIN(0x03,bv); v = (rv << 5) | (gv << 2) | bv; fputc(v,out); } /* End for (each pixel in scan line) */ } /* End for (each scan line) */ #ifdef TRACK_RGB printf("Max R/G/B: %d/%d/%d\n",maxr,maxg,maxb); #endif fclose(in); /* Close Files */ fclose(out); exit(0); } /*-------------- End of QRTIBM.C -------------------------------------------*/ -------------------------------------------------------- Frank McKenney, President | {uunet,rti}!talos!mckenney McKenney Associates | 3464 Northview Place | guest account - access Richmond, Virginia 23225 | provided as a courtesy by USA (804) 320-4887 | Philip Morris USA --------------------------------------------------------