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

  1. /*  
  2. Copyright 1990 by John Wiley & Sons, Inc.
  3.           All Rights Reserved.
  4. */
  5. /****************************************/
  6. /*       Image Processing Code          */
  7. /*      Point Process Functions         */
  8. /*       written in Turbo C 2.0         */
  9. /*                by                    */
  10. /*         Craig A. Lindley             */
  11. /*                                      */
  12. /*   Vers: 1.0  Last Update: 11/07/89   */
  13. /****************************************/
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <conio.h>
  18. #include <dos.h>
  19. #include <alloc.h>
  20. #include <process.h>
  21. #include <graphics.h>
  22. #include "misc.h"
  23. #include "pcx.h"
  24. #include "vga.h"
  25. #include "imagesup.h"
  26.  
  27.  
  28. /* Histogram storage location */
  29. unsigned Histogram[MAXQUANTLEVELS];
  30.  
  31. /*
  32. Look Up Table (LUT) Functions
  33.  
  34. Initialize the Look Up Table (LUT) for straight through
  35. mapping. If a point transform is performed on an initialized
  36. LUT, output data will equal input data. This function is
  37. usually called in preparation for modification to a LUT.
  38. */
  39.  
  40. void InitializeLUT(BYTE *LookUpTable)
  41. {
  42.   register unsigned Index;
  43.  
  44.   for (Index = 0; Index < MAXQUANTLEVELS; Index++)
  45.      LookUpTable[Index] = Index;
  46. }
  47.  
  48. /*
  49. This function performs a point transform on the portion of the
  50. image specified by Col, Row, Width and Height. The actual
  51. transform is contained in the Look Up Table who address
  52. is passed as a parameter.
  53. */
  54.  
  55. void PtTransform(BYTE huge *ImageData, unsigned Col, unsigned Row,
  56.          unsigned Width, unsigned Height, BYTE *LookUpTable)
  57. {
  58.  
  59.    register unsigned ImageCol, ImageRow;
  60.    register unsigned ColExtent, RowExtent;
  61.  
  62.    ColExtent = Col+Width;
  63.    RowExtent = Row+Height;
  64.  
  65.    if (ParameterCheckOK(Col,Row,ColExtent,RowExtent,"PtTransform"))
  66.       for (ImageRow=Row; ImageRow < RowExtent; ImageRow++)
  67.      for (ImageCol=Col; ImageCol < ColExtent; ImageCol++)
  68.         PutPixelInImage(ImageData,ImageCol,ImageRow,
  69.          LookUpTable[GetPixelFromImage(ImageData,ImageCol,ImageRow)]);
  70. }
  71.  
  72. /* start of histogram functions
  73.  
  74. This function calculates the histogram of any portion of an image.
  75. */
  76.  
  77. void GenHistogram(BYTE huge *ImageData, unsigned Col, unsigned Row,
  78.           unsigned Width, unsigned Height)
  79. {
  80.    register unsigned ImageRow, ImageCol, RowExtent, ColExtent;
  81.    register unsigned Index;
  82.  
  83.    /* clear the histogram array */
  84.    for (Index=0; Index < MAXQUANTLEVELS; Index++)
  85.       Histogram[Index] = 0;
  86.  
  87.    RowExtent = Row+Height;
  88.    ColExtent = Col+Width;
  89.  
  90.    if (ParameterCheckOK(Col,Row,ColExtent,RowExtent,"GenHistogram"))
  91.    {
  92.       /* calculate the histogram */
  93.       for (ImageRow = Row; ImageRow < RowExtent; ImageRow++)
  94.      for (ImageCol = Col; ImageCol < ColExtent; ImageCol++)
  95.         Histogram[GetPixelFromImage(ImageData,ImageCol,ImageRow)] += 1;
  96.    }
  97. }
  98.  
  99. /*
  100. This function calculates and displays the histogram of an image
  101. or partial image. When called it assumes the VGA is already
  102. in mode 13 hex.
  103. */
  104.  
  105. void DisplayHist(BYTE huge *ImageData, unsigned Col, unsigned Row,
  106.          unsigned Width, unsigned Height)
  107. {
  108.    BYTE huge *Buffer;
  109.    register unsigned Index, LineLength, XPos, YPos;
  110.    unsigned MaxRepeat;
  111.  
  112.    /* Allocate enough memory to save image under histogram */
  113.    Buffer = (BYTE huge *) farcalloc((long)HISTOWIDTH*HISTOHEIGHT,sizeof(BYTE));
  114.    if (Buffer == NULL)
  115.    {
  116.       printf("No buffer memory\n");
  117.       exit(ENoMemory);
  118.    }
  119.    /* Save a copy of the image */
  120.    ReadImageAreaToBuf(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH,HISTOHEIGHT,
  121.               Buffer);
  122.  
  123.    /*
  124.    Set VGA color register 65 to red, 66 to green and 67 to
  125.    blue so the histogram can be visually separated from
  126.    the continuous tone image.
  127.    */
  128.  
  129.    SetAColorReg(65,63,0,0);
  130.    SetAColorReg(66,0,63,0);
  131.    SetAColorReg(67,0,0,63);
  132.  
  133.    /* Calculate the histogram for the image */
  134.    GenHistogram(ImageData, Col, Row, Width, Height);
  135.  
  136.    MaxRepeat = 0;
  137.  
  138.    /*
  139.    Find the pixel value repeated the most. It will be used for
  140.    scaling.
  141.    */
  142.    for (Index=0; Index < MAXQUANTLEVELS; Index++)
  143.      MaxRepeat = (Histogram[Index] > MaxRepeat) ?
  144.                   Histogram[Index]:MaxRepeat;
  145.  
  146.  
  147.    /* Fill background area of histogram graph */
  148.    ClearImageArea(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH,HISTOHEIGHT,67);
  149.  
  150.    /* Draw the bounding box for the histogram */
  151.    DrawVLine(ImageData,HISTOCOL,HISTOROW,HISTOHEIGHT-1,BLACK);
  152.    DrawVLine(ImageData,HISTOCOL+HISTOWIDTH-1,HISTOROW,HISTOHEIGHT-1,BLACK);
  153.    DrawHLine(ImageData,HISTOCOL,HISTOROW+HISTOHEIGHT-1,HISTOWIDTH-1,BLACK);
  154.    DrawHLine(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH-1,BLACK);
  155.  
  156.    /* Data base line */
  157.    DrawHLine(ImageData,AXISCOL,AXISROW,AXISLENGTH,WHITE);
  158.    DrawHLine(ImageData,AXISCOL,AXISROW+1,AXISLENGTH,WHITE);
  159.    /*
  160.    Now do the actual histogram rendering into the
  161.    image buffer.
  162.    */
  163.    for (Index=0; Index < MAXQUANTLEVELS; Index++)
  164.    {
  165.       LineLength = (unsigned)(((long) Histogram[Index] * MAXDEFLECTION) /
  166.                    (long) MaxRepeat);
  167.       XPos = DATACOL + Index*2;
  168.       YPos = DATAROW - LineLength;
  169.       DrawVLine(ImageData,XPos,YPos,LineLength,66);
  170.    }
  171.  
  172.    /*
  173.    Display the image overlayed with the histogram
  174.    */
  175.    DisplayImageInBuf(ImageData,NOVGAINIT,WAITFORKEY);
  176.  
  177.    /* After display, restore image data under histogram */
  178.    WriteImageAreaFromBuf(Buffer,HISTOWIDTH,HISTOHEIGHT,ImageData,
  179.              HISTOCOL,HISTOROW);
  180.    farfree((BYTE far *)Buffer);
  181. }
  182.  
  183.  
  184. /* Various Point Transformation Functions */
  185.  
  186. void AdjImageBrightness(BYTE huge *ImageData, short BrightnessFactor,
  187.             unsigned Col, unsigned Row,
  188.             unsigned Width, unsigned Height)
  189. {
  190.    register unsigned Index;
  191.    register short NewLevel;
  192.    BYTE     LookUpTable[MAXQUANTLEVELS];
  193.  
  194.    for (Index = MINSAMPLEVAL; Index < MAXQUANTLEVELS; Index++)
  195.    {
  196.       NewLevel = Index + BrightnessFactor;
  197.       NewLevel = (NewLevel < MINSAMPLEVAL) ? MINSAMPLEVAL:NewLevel;
  198.       NewLevel = (NewLevel > MAXSAMPLEVAL) ? MAXSAMPLEVAL:NewLevel;
  199.       LookUpTable[Index] = NewLevel;
  200.    }
  201.    PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
  202. }
  203.  
  204. /*
  205. This function will negate an image pixel by pixel. Threshold is
  206. the value of image data where the negatation begins. If
  207. threshold is 0, all pixel values are negated. That is, pixel value 0
  208. becomes 63 and pixel value 63 becomes 0. If threshold is greater
  209. than 0, the pixel values in the range 0..Threshold-1 are left
  210. alone while pixel values between Threshold..63 are negated.
  211. */
  212.  
  213. void NegateImage(BYTE huge *ImageData, unsigned Threshold,
  214.                  unsigned Col, unsigned Row,
  215.          unsigned Width, unsigned Height)
  216. {
  217.    register unsigned Index;
  218.    BYTE     LookUpTable[MAXQUANTLEVELS];
  219.  
  220.    /* Straight through mapping initially */
  221.    InitializeLUT(LookUpTable);
  222.  
  223.    /* from Threshold onward, negate entry in LUT */
  224.    for (Index = Threshold; Index < MAXQUANTLEVELS; Index++)
  225.     LookUpTable[Index] = MAXSAMPLEVAL - Index;
  226.  
  227.    PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
  228. }
  229.  
  230. /*
  231. This function converts a gray scale image to a binary image with each
  232. pixel either on (WHITE) or off (BLACK). The pixel level at
  233. which the cut off is made is controlled by Threshold. Pixels
  234. in the range 0..Threshold-1 become black while pixel values
  235. between Threshold..63 become white.
  236. */
  237.  
  238. void ThresholdImage(BYTE huge *ImageData, unsigned Threshold,
  239.                     unsigned Col, unsigned Row,
  240.             unsigned Width, unsigned Height)
  241. {
  242.    register unsigned Index;
  243.    BYTE     LookUpTable[MAXQUANTLEVELS];
  244.  
  245.    for (Index = MINSAMPLEVAL; Index < Threshold; Index++)
  246.     LookUpTable[Index] = BLACK;
  247.  
  248.    for (Index = Threshold; Index < MAXQUANTLEVELS; Index++)
  249.     LookUpTable[Index] = WHITE;
  250.  
  251.    PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
  252. }
  253.  
  254.  
  255. void StretchImageContrast(BYTE huge *ImageData, unsigned *HistoData,
  256.               unsigned Threshold,
  257.                           unsigned Col, unsigned Row,
  258.               unsigned Width, unsigned Height)
  259. {
  260.    register unsigned Index, NewMin, NewMax;
  261.    double   StepSiz, StepVal;
  262.    BYTE     LookUpTable[MAXQUANTLEVELS];
  263.  
  264.    /*
  265.    Search from the low bin towards the high bin for the first one that
  266.    exceeds the threshold
  267.    */
  268.  
  269.    for (Index=0; Index < MAXQUANTLEVELS; Index++)
  270.       if (HistoData[Index] > Threshold)
  271.          break;
  272.  
  273.    NewMin = Index;
  274.  
  275.    /*
  276.    Search from the high bin towards the low bin for the first one that
  277.    exceeds the threshold
  278.    */
  279.  
  280.    for (Index=MAXSAMPLEVAL; Index > NewMin; Index--)
  281.       if (HistoData[Index] > Threshold)
  282.          break;
  283.  
  284.    NewMax = Index;
  285.  
  286.    StepSiz = (double)MAXQUANTLEVELS/(double)(NewMax-NewMin+1);
  287.    StepVal = 0.0;
  288.  
  289.    /* values below new minimum are assigned zero in the LUT */
  290.    for (Index=0; Index < NewMin; Index++)
  291.       LookUpTable[Index] = MINSAMPLEVAL;
  292.  
  293.    /* values above new maximum are assigned the max sample value */
  294.    for (Index=NewMax+1; Index < MAXQUANTLEVELS; Index++)
  295.       LookUpTable[Index] = MAXSAMPLEVAL;
  296.  
  297.    /* values between the new minimum and new maximum are stretched */
  298.    for (Index=NewMin; Index <= NewMax; Index++)
  299.    {
  300.       LookUpTable[Index] = StepVal;
  301.       StepVal += StepSiz;
  302.    }
  303.    /*
  304.    Look Up Table is now prepared to point transform the image data.
  305.    */
  306.    PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
  307. }
  308.  
  309.  
  310.