home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / IMGPROC.ZIP / C5GVIDEO.ZIP / ACQUIRE.C next >
Encoding:
C/C++ Source or Header  |  1990-04-06  |  9.3 KB  |  295 lines

  1. /*  
  2. Copyright 1990 by John Wiley & Sons, Inc.
  3.           All Rights Reserved.
  4. */
  5. /****************************************/
  6. /*      Image Acquisition Program       */
  7. /* Digitizes, Displays and Saves Images */
  8. /*   in low resolution digitizer mode   */
  9. /*  Images corrected for Aspect Ratio   */
  10. /*       written in Turbo C 2.0         */
  11. /*                 by                   */
  12. /*          Craig A. Lindley            */
  13. /*                                      */
  14. /*   Vers: 1.0  Last Update: 11/20/89   */
  15. /****************************************/
  16.  
  17. #include <stdio.h>
  18. #include <conio.h>
  19. #include <dos.h>
  20. #include <process.h>
  21. #include <string.h>
  22. #include <graphics.h>
  23. #include <alloc.h>
  24. #include "misc.h"
  25. #include "pcx.h"
  26. #include "vga.h"
  27. #include "digitizer.h"
  28.  
  29.  
  30. #define MaxFileNameLen 13    /* filename str length including null */
  31. /*
  32. As mentioned in the text, the pixels in 320x200 resolution are
  33. "non square". This results in aspect ratio problems when the acquired
  34. images are displayed. For a correct 4:3 aspect ratio yielding
  35. square pixels, the resolution would have to be boosted to 320x240.
  36. Square pixels can be approximated by having the digitizer acquire
  37. a 240 line image and by displaying the 240 lines of video information
  38. in the 200 vertical display pixels. In other words, by  compressing
  39. the 240 lines of video into just 200 lines. This is accomplished
  40. by interpolating pixel values on the fly during the display
  41. process. The define below is the conversion factor that causes
  42. the terversal through the video image buffer to proceed at a rate
  43. of 1.2 rows of video per display row instead of the original
  44. one for one. The factor of 1.2 is produced by dividing the 240 lines of
  45. video to be compressed by the 200 vertical pixels of display resolution
  46. available.
  47. */
  48. #define RowAspectCorrection (double) 1.2
  49. #define NumberOfVideoLines 240
  50.  
  51. /* Global Variables */
  52.  
  53. struct     ImageReq Req;
  54. char huge *PictureData;
  55.  
  56.  
  57. /*
  58. Display the digitized image in VGA mode 13h with 64 levels of gray.
  59. Correct the aspect ratio of the 320x200 image.
  60. */
  61.  
  62. void DisplayPictData (char huge *PictData)
  63. {
  64.    register unsigned Col, Row, Color, LowerColor, UpperColor;
  65.    unsigned LowerBufferRow, UpperBufferRow;
  66.    unsigned long PixelBufOffset;
  67.    double   FractionalRowAddr, RowDelta;
  68.  
  69.    /* For each column of the display. 320 total */
  70.    for (Col=0; Col < LRMAXCOLS; Col++)
  71.    {
  72.       /*
  73.       Calculate the start of the digitized video information
  74.       in the image buffer for this row.
  75.       */
  76.       PixelBufOffset = (long) NumberOfVideoLines * Col;
  77.       /*
  78.       For each of the 200 rows available in this display
  79.       mode ...
  80.       */
  81.       for (Row=0; Row < LRMAXROWS; Row++)
  82.       {
  83.      /*
  84.      Which actual digitized video row out of the
  85.      total of 240 should we accessed ? The calculated
  86.      address will reside between two actual addresses.
  87.      The address will be fractional.
  88.      */
  89.      FractionalRowAddr = RowAspectCorrection * (double) Row;
  90.      /*
  91.      Get the address of the row bytes just below and just
  92.      above the calculated fractional address. Fetch the
  93.      intensity values of each.
  94.      */
  95.      LowerBufferRow = (unsigned) FractionalRowAddr;
  96.      UpperBufferRow = LowerBufferRow + 1;
  97.      LowerColor = PictData[PixelBufOffset + LowerBufferRow];
  98.      UpperColor = PictData[PixelBufOffset + UpperBufferRow];
  99.  
  100.      /*
  101.      Calculate the distance the fractional address is off
  102.      from the lower real address. This distance is required
  103.      for the interpolation process.
  104.      */
  105.      RowDelta = FractionalRowAddr - LowerBufferRow;
  106.      /*
  107.      Interpolate for the value of the intensity to assign
  108.      to the pixel at this row.
  109.      */
  110.      Color = RowDelta*((double) UpperColor - LowerColor) +
  111.                LowerColor;
  112.  
  113.      /*
  114.      Display this calculated intensity on the display
  115.      */
  116.      PutPixel256(Col,Row,Color);
  117.       }
  118.    }
  119. }
  120.  
  121.  
  122. /*
  123. This function provides help in the advent of operator error. Program
  124. terminates after help is given
  125. */
  126.  
  127. void ShowHelp( void )
  128. {
  129.    printf("\nThis program digitizes, displays and optionally\n");
  130.    printf("saves in PCX format a single digitized image in\n");
  131.    printf("low resolution mode. Its usage is as follows:\n\n");
  132.    printf("acquire [-o] filename <cr>\n");
  133.    printf("  -o creates output PCX files\n");
  134.    printf("  filename is name given to the PCX file. Do not\n");
  135.    printf("  specify a file extension, it will be provided.\n\n");
  136.    exit(1);
  137. }
  138.  
  139. /* main digitizer program */
  140.  
  141. void main(short argc, char *argv[])
  142. {
  143.    unsigned long RasterSize;
  144.    unsigned GenPCXFile;
  145.    unsigned FileNameCounter, ArgIndex, StrLength;
  146.    char    *ImageFileName;
  147.    char     ProcessedFileName[MaxFileNameLen];
  148.    char     LRName[MaxFileNameLen];
  149.  
  150.  
  151.    InitGraphics();
  152.  
  153.    clrscr();
  154.    printf("Digitize, Display and Save Gray Scale Images in Low Resolution\n");
  155.    printf("  Images are aspect ratio corrected\n\n");
  156.  
  157.    /* install default options */
  158.    GenPCXFile = FALSE;                 /* don't generate a. PCX file */
  159.  
  160.    /* parse command line arguments */
  161.  
  162.    FileNameCounter = 0;                /* count of user specified filenames */
  163.    for (ArgIndex=1; ArgIndex < argc; ArgIndex++)
  164.    {
  165.       if (*argv[ArgIndex] != '-')      /* if not a cmd line switch */
  166.       {                                /* must be a filename */
  167.      if (*argv[ArgIndex] == '?')   /* help requested ? */
  168.         ShowHelp();
  169.      if (FileNameCounter > 1)      /* only one filename allowed */
  170.             ShowHelp();                /* if more then error exit */
  171.      ImageFileName = argv[ArgIndex];  /* save image filename */
  172.          FileNameCounter++;            /* inc count for error check */
  173.       }
  174.       else                             /* its a cmd line switch */
  175.       {
  176.      switch (*(argv[ArgIndex]+1))  /* parse the cmd line */
  177.          {
  178.         case 'o':                  /* o or O = output files */
  179.         case 'O':
  180.           GenPCXFile = TRUE;
  181.               break;
  182.         default:
  183.           printf("Error - invalid cmd line switch encountered\n");
  184.           ShowHelp();
  185.          }
  186.       }
  187.    }
  188.    if (GenPCXFile && (FileNameCounter != 1))
  189.    {
  190.       printf("Error - single filename required for PCX file\n");
  191.       ShowHelp();
  192.    }
  193.  
  194.    /*
  195.    Preprocess any filename input from the cmd line. Strip
  196.    off any specified extension and limit the filename
  197.    length to six characters max. This will allow the
  198.    designations LR.PCX, MR.PCX and HR.PCX to be appended.
  199.    */
  200.  
  201.    if (GenPCXFile)           /* only process if necessary */
  202.    {
  203.  
  204.       strcpy(ProcessedFileName,"");    /* empty string */
  205.  
  206.       /* find filename length minus the extension */
  207.       StrLength = strcspn(ImageFileName,".");
  208.  
  209.       if (StrLength > 8)     /* exceeds max length ? */
  210.      strncat(ProcessedFileName,ImageFileName,8); /* cat only 8 chars */
  211.       else
  212.      strncat(ProcessedFileName,ImageFileName,StrLength);
  213.       /*
  214.       Copy the processed file name to each of the PCX
  215.       filename storage areas and append the appropriate string.
  216.       */
  217.       strcpy(LRName,ProcessedFileName);
  218.       strcat(LRName,".PCX");
  219.       strupr(LRName);
  220.  
  221.    }
  222.  
  223.    if (GenPCXFile)
  224.    {
  225.       printf("Image filename will be: %s\n\n",LRName);
  226.    }
  227.    else
  228.       printf("a PCX file will not be generated\n");
  229.  
  230.    printf("\nPress any key after image display to terminate program.\n\n");
  231.    delay(4000);
  232.  
  233.    /*
  234.    Pick largest size image buffer required. A buffer large enough
  235.    for a 320x240 image is required for 320x200 aspect ratio corrected
  236.    images.
  237.    */
  238.  
  239.    RasterSize = 76800L;     /* big enough for 320x240 image */
  240.  
  241.    /* allocate picture buffer and set it to zeros */
  242.  
  243.    if ((PictureData = (char huge *) farcalloc(RasterSize,
  244.         (unsigned long) sizeof(char))) == NULL)
  245.    {
  246.       printf("Acquire Error: Not enough memory\n");
  247.       exit(ENoMemory);
  248.    }
  249.  
  250.    /*
  251.    Build a structure that defines what the digitizer should acquire. this
  252.    will be passed to the digitizer by a call to InitializeDigitizer
  253.    function. The following portion of the ImageReq structure does
  254.    not change as the image resolution changes.
  255.    */
  256.  
  257.    Req.ComputerType   = PS220;
  258.    Req.PrtBase        = 0x3BC;
  259.    Req.NumberOfPasses = 1;
  260.    Req.Flags          = 0L;
  261.    Req.PictBuf        = PictureData;     /* put buffer addr into ImageReq */
  262.  
  263.    Set256ColorMode();        /* 320x200 256 color VGA mode */
  264.    LoadGray64Palette();      /* load the gray scale palette */
  265.  
  266.    /*
  267.    This portion of the structure changes with image resolution.
  268.    Prepare to digitize a full 320x240 image.
  269.    */
  270.  
  271.    Req.HMode          = LowRes;
  272.    Req.VMode          = NonInterlace;
  273.    Req.FirstLine      = 0;
  274.    Req.FirstPixel     = 0;
  275.    Req.LastLine       = 240;      /* do a 320x240 image */
  276.    Req.LastPixel      = 320;
  277.  
  278.    InitializeDigitizer(&Req);     /* initialize digitizer */
  279.  
  280.    while (!kbhit())
  281.    {
  282.       GetPicture();                  /* acquire the picture */
  283.       DisplayPictData(PictureData);  /* display the picture */
  284.  
  285.       if (GenPCXFile)                /* write out the PCX file */
  286.      WritePCXFile(LRName,8,320,200,1,320);
  287.    }
  288.    getch();                       /* clear key */
  289.    getch();                       /* wait for operator */
  290.    restorecrtmode();              /* clean up and quit */
  291.    farfree((char far *)PictureData);
  292.    closegraph();
  293. }
  294.  
  295.