home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1990 by John Wiley & Sons, Inc.
- All Rights Reserved.
- */
- /****************************************/
- /* Image Acquisition Program */
- /* Digitizes, Displays and Saves Images */
- /* in low resolution digitizer mode */
- /* Images corrected for Aspect Ratio */
- /* written in Turbo C 2.0 */
- /* by */
- /* Craig A. Lindley */
- /* */
- /* Vers: 1.0 Last Update: 11/20/89 */
- /****************************************/
-
- #include <stdio.h>
- #include <conio.h>
- #include <dos.h>
- #include <process.h>
- #include <string.h>
- #include <graphics.h>
- #include <alloc.h>
- #include "misc.h"
- #include "pcx.h"
- #include "vga.h"
- #include "digitizer.h"
-
-
- #define MaxFileNameLen 13 /* filename str length including null */
- /*
- As mentioned in the text, the pixels in 320x200 resolution are
- "non square". This results in aspect ratio problems when the acquired
- images are displayed. For a correct 4:3 aspect ratio yielding
- square pixels, the resolution would have to be boosted to 320x240.
- Square pixels can be approximated by having the digitizer acquire
- a 240 line image and by displaying the 240 lines of video information
- in the 200 vertical display pixels. In other words, by compressing
- the 240 lines of video into just 200 lines. This is accomplished
- by interpolating pixel values on the fly during the display
- process. The define below is the conversion factor that causes
- the terversal through the video image buffer to proceed at a rate
- of 1.2 rows of video per display row instead of the original
- one for one. The factor of 1.2 is produced by dividing the 240 lines of
- video to be compressed by the 200 vertical pixels of display resolution
- available.
- */
- #define RowAspectCorrection (double) 1.2
- #define NumberOfVideoLines 240
-
- /* Global Variables */
-
- struct ImageReq Req;
- char huge *PictureData;
-
-
- /*
- Display the digitized image in VGA mode 13h with 64 levels of gray.
- Correct the aspect ratio of the 320x200 image.
- */
-
- void DisplayPictData (char huge *PictData)
- {
- register unsigned Col, Row, Color, LowerColor, UpperColor;
- unsigned LowerBufferRow, UpperBufferRow;
- unsigned long PixelBufOffset;
- double FractionalRowAddr, RowDelta;
-
- /* For each column of the display. 320 total */
- for (Col=0; Col < LRMAXCOLS; Col++)
- {
- /*
- Calculate the start of the digitized video information
- in the image buffer for this row.
- */
- PixelBufOffset = (long) NumberOfVideoLines * Col;
- /*
- For each of the 200 rows available in this display
- mode ...
- */
- for (Row=0; Row < LRMAXROWS; Row++)
- {
- /*
- Which actual digitized video row out of the
- total of 240 should we accessed ? The calculated
- address will reside between two actual addresses.
- The address will be fractional.
- */
- FractionalRowAddr = RowAspectCorrection * (double) Row;
- /*
- Get the address of the row bytes just below and just
- above the calculated fractional address. Fetch the
- intensity values of each.
- */
- LowerBufferRow = (unsigned) FractionalRowAddr;
- UpperBufferRow = LowerBufferRow + 1;
- LowerColor = PictData[PixelBufOffset + LowerBufferRow];
- UpperColor = PictData[PixelBufOffset + UpperBufferRow];
-
- /*
- Calculate the distance the fractional address is off
- from the lower real address. This distance is required
- for the interpolation process.
- */
- RowDelta = FractionalRowAddr - LowerBufferRow;
- /*
- Interpolate for the value of the intensity to assign
- to the pixel at this row.
- */
- Color = RowDelta*((double) UpperColor - LowerColor) +
- LowerColor;
-
- /*
- Display this calculated intensity on the display
- */
- PutPixel256(Col,Row,Color);
- }
- }
- }
-
-
- /*
- This function provides help in the advent of operator error. Program
- terminates after help is given
- */
-
- void ShowHelp( void )
- {
- printf("\nThis program digitizes, displays and optionally\n");
- printf("saves in PCX format a single digitized image in\n");
- printf("low resolution mode. Its usage is as follows:\n\n");
- printf("acquire [-o] filename <cr>\n");
- printf(" -o creates output PCX files\n");
- printf(" filename is name given to the PCX file. Do not\n");
- printf(" specify a file extension, it will be provided.\n\n");
- exit(1);
- }
-
- /* main digitizer program */
-
- void main(short argc, char *argv[])
- {
- unsigned long RasterSize;
- unsigned GenPCXFile;
- unsigned FileNameCounter, ArgIndex, StrLength;
- char *ImageFileName;
- char ProcessedFileName[MaxFileNameLen];
- char LRName[MaxFileNameLen];
-
-
- InitGraphics();
-
- clrscr();
- printf("Digitize, Display and Save Gray Scale Images in Low Resolution\n");
- printf(" Images are aspect ratio corrected\n\n");
-
- /* install default options */
- GenPCXFile = FALSE; /* don't generate a. PCX file */
-
- /* parse command line arguments */
-
- FileNameCounter = 0; /* count of user specified filenames */
- for (ArgIndex=1; ArgIndex < argc; ArgIndex++)
- {
- if (*argv[ArgIndex] != '-') /* if not a cmd line switch */
- { /* must be a filename */
- if (*argv[ArgIndex] == '?') /* help requested ? */
- ShowHelp();
- if (FileNameCounter > 1) /* only one filename allowed */
- ShowHelp(); /* if more then error exit */
- ImageFileName = argv[ArgIndex]; /* save image filename */
- FileNameCounter++; /* inc count for error check */
- }
- else /* its a cmd line switch */
- {
- switch (*(argv[ArgIndex]+1)) /* parse the cmd line */
- {
- case 'o': /* o or O = output files */
- case 'O':
- GenPCXFile = TRUE;
- break;
- default:
- printf("Error - invalid cmd line switch encountered\n");
- ShowHelp();
- }
- }
- }
- if (GenPCXFile && (FileNameCounter != 1))
- {
- printf("Error - single filename required for PCX file\n");
- ShowHelp();
- }
-
- /*
- Preprocess any filename input from the cmd line. Strip
- off any specified extension and limit the filename
- length to six characters max. This will allow the
- designations LR.PCX, MR.PCX and HR.PCX to be appended.
- */
-
- if (GenPCXFile) /* only process if necessary */
- {
-
- strcpy(ProcessedFileName,""); /* empty string */
-
- /* find filename length minus the extension */
- StrLength = strcspn(ImageFileName,".");
-
- if (StrLength > 8) /* exceeds max length ? */
- strncat(ProcessedFileName,ImageFileName,8); /* cat only 8 chars */
- else
- strncat(ProcessedFileName,ImageFileName,StrLength);
- /*
- Copy the processed file name to each of the PCX
- filename storage areas and append the appropriate string.
- */
- strcpy(LRName,ProcessedFileName);
- strcat(LRName,".PCX");
- strupr(LRName);
-
- }
-
- if (GenPCXFile)
- {
- printf("Image filename will be: %s\n\n",LRName);
- }
- else
- printf("a PCX file will not be generated\n");
-
- printf("\nPress any key after image display to terminate program.\n\n");
- delay(4000);
-
- /*
- Pick largest size image buffer required. A buffer large enough
- for a 320x240 image is required for 320x200 aspect ratio corrected
- images.
- */
-
- RasterSize = 76800L; /* big enough for 320x240 image */
-
- /* allocate picture buffer and set it to zeros */
-
- if ((PictureData = (char huge *) farcalloc(RasterSize,
- (unsigned long) sizeof(char))) == NULL)
- {
- printf("Acquire Error: Not enough memory\n");
- exit(ENoMemory);
- }
-
- /*
- Build a structure that defines what the digitizer should acquire. this
- will be passed to the digitizer by a call to InitializeDigitizer
- function. The following portion of the ImageReq structure does
- not change as the image resolution changes.
- */
-
- Req.ComputerType = PS220;
- Req.PrtBase = 0x3BC;
- Req.NumberOfPasses = 1;
- Req.Flags = 0L;
- Req.PictBuf = PictureData; /* put buffer addr into ImageReq */
-
- Set256ColorMode(); /* 320x200 256 color VGA mode */
- LoadGray64Palette(); /* load the gray scale palette */
-
- /*
- This portion of the structure changes with image resolution.
- Prepare to digitize a full 320x240 image.
- */
-
- Req.HMode = LowRes;
- Req.VMode = NonInterlace;
- Req.FirstLine = 0;
- Req.FirstPixel = 0;
- Req.LastLine = 240; /* do a 320x240 image */
- Req.LastPixel = 320;
-
- InitializeDigitizer(&Req); /* initialize digitizer */
-
- while (!kbhit())
- {
- GetPicture(); /* acquire the picture */
- DisplayPictData(PictureData); /* display the picture */
-
- if (GenPCXFile) /* write out the PCX file */
- WritePCXFile(LRName,8,320,200,1,320);
- }
- getch(); /* clear key */
- getch(); /* wait for operator */
- restorecrtmode(); /* clean up and quit */
- farfree((char far *)PictureData);
- closegraph();
- }
-