home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1990 by John Wiley & Sons, Inc.
- All Rights Reserved.
- */
- /****************************************/
- /* Image Processing Code */
- /* Point Process Functions */
- /* written in Turbo C 2.0 */
- /* by */
- /* Craig A. Lindley */
- /* */
- /* Vers: 1.0 Last Update: 11/07/89 */
- /****************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <alloc.h>
- #include <process.h>
- #include <graphics.h>
- #include "misc.h"
- #include "pcx.h"
- #include "vga.h"
- #include "imagesup.h"
-
-
- /* Histogram storage location */
- unsigned Histogram[MAXQUANTLEVELS];
-
- /*
- Look Up Table (LUT) Functions
-
- Initialize the Look Up Table (LUT) for straight through
- mapping. If a point transform is performed on an initialized
- LUT, output data will equal input data. This function is
- usually called in preparation for modification to a LUT.
- */
-
- void InitializeLUT(BYTE *LookUpTable)
- {
- register unsigned Index;
-
- for (Index = 0; Index < MAXQUANTLEVELS; Index++)
- LookUpTable[Index] = Index;
- }
-
- /*
- This function performs a point transform on the portion of the
- image specified by Col, Row, Width and Height. The actual
- transform is contained in the Look Up Table who address
- is passed as a parameter.
- */
-
- void PtTransform(BYTE huge *ImageData, unsigned Col, unsigned Row,
- unsigned Width, unsigned Height, BYTE *LookUpTable)
- {
-
- register unsigned ImageCol, ImageRow;
- register unsigned ColExtent, RowExtent;
-
- ColExtent = Col+Width;
- RowExtent = Row+Height;
-
- if (ParameterCheckOK(Col,Row,ColExtent,RowExtent,"PtTransform"))
- for (ImageRow=Row; ImageRow < RowExtent; ImageRow++)
- for (ImageCol=Col; ImageCol < ColExtent; ImageCol++)
- PutPixelInImage(ImageData,ImageCol,ImageRow,
- LookUpTable[GetPixelFromImage(ImageData,ImageCol,ImageRow)]);
- }
-
- /* start of histogram functions
-
- This function calculates the histogram of any portion of an image.
- */
-
- void GenHistogram(BYTE huge *ImageData, unsigned Col, unsigned Row,
- unsigned Width, unsigned Height)
- {
- register unsigned ImageRow, ImageCol, RowExtent, ColExtent;
- register unsigned Index;
-
- /* clear the histogram array */
- for (Index=0; Index < MAXQUANTLEVELS; Index++)
- Histogram[Index] = 0;
-
- RowExtent = Row+Height;
- ColExtent = Col+Width;
-
- if (ParameterCheckOK(Col,Row,ColExtent,RowExtent,"GenHistogram"))
- {
- /* calculate the histogram */
- for (ImageRow = Row; ImageRow < RowExtent; ImageRow++)
- for (ImageCol = Col; ImageCol < ColExtent; ImageCol++)
- Histogram[GetPixelFromImage(ImageData,ImageCol,ImageRow)] += 1;
- }
- }
-
- /*
- This function calculates and displays the histogram of an image
- or partial image. When called it assumes the VGA is already
- in mode 13 hex.
- */
-
- void DisplayHist(BYTE huge *ImageData, unsigned Col, unsigned Row,
- unsigned Width, unsigned Height)
- {
- BYTE huge *Buffer;
- register unsigned Index, LineLength, XPos, YPos;
- unsigned MaxRepeat;
-
- /* Allocate enough memory to save image under histogram */
- Buffer = (BYTE huge *) farcalloc((long)HISTOWIDTH*HISTOHEIGHT,sizeof(BYTE));
- if (Buffer == NULL)
- {
- printf("No buffer memory\n");
- exit(ENoMemory);
- }
- /* Save a copy of the image */
- ReadImageAreaToBuf(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH,HISTOHEIGHT,
- Buffer);
-
- /*
- Set VGA color register 65 to red, 66 to green and 67 to
- blue so the histogram can be visually separated from
- the continuous tone image.
- */
-
- SetAColorReg(65,63,0,0);
- SetAColorReg(66,0,63,0);
- SetAColorReg(67,0,0,63);
-
- /* Calculate the histogram for the image */
- GenHistogram(ImageData, Col, Row, Width, Height);
-
- MaxRepeat = 0;
-
- /*
- Find the pixel value repeated the most. It will be used for
- scaling.
- */
- for (Index=0; Index < MAXQUANTLEVELS; Index++)
- MaxRepeat = (Histogram[Index] > MaxRepeat) ?
- Histogram[Index]:MaxRepeat;
-
-
- /* Fill background area of histogram graph */
- ClearImageArea(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH,HISTOHEIGHT,67);
-
- /* Draw the bounding box for the histogram */
- DrawVLine(ImageData,HISTOCOL,HISTOROW,HISTOHEIGHT-1,BLACK);
- DrawVLine(ImageData,HISTOCOL+HISTOWIDTH-1,HISTOROW,HISTOHEIGHT-1,BLACK);
- DrawHLine(ImageData,HISTOCOL,HISTOROW+HISTOHEIGHT-1,HISTOWIDTH-1,BLACK);
- DrawHLine(ImageData,HISTOCOL,HISTOROW,HISTOWIDTH-1,BLACK);
-
- /* Data base line */
- DrawHLine(ImageData,AXISCOL,AXISROW,AXISLENGTH,WHITE);
- DrawHLine(ImageData,AXISCOL,AXISROW+1,AXISLENGTH,WHITE);
- /*
- Now do the actual histogram rendering into the
- image buffer.
- */
- for (Index=0; Index < MAXQUANTLEVELS; Index++)
- {
- LineLength = (unsigned)(((long) Histogram[Index] * MAXDEFLECTION) /
- (long) MaxRepeat);
- XPos = DATACOL + Index*2;
- YPos = DATAROW - LineLength;
- DrawVLine(ImageData,XPos,YPos,LineLength,66);
- }
-
- /*
- Display the image overlayed with the histogram
- */
- DisplayImageInBuf(ImageData,NOVGAINIT,WAITFORKEY);
-
- /* After display, restore image data under histogram */
- WriteImageAreaFromBuf(Buffer,HISTOWIDTH,HISTOHEIGHT,ImageData,
- HISTOCOL,HISTOROW);
- farfree((BYTE far *)Buffer);
- }
-
-
- /* Various Point Transformation Functions */
-
- void AdjImageBrightness(BYTE huge *ImageData, short BrightnessFactor,
- unsigned Col, unsigned Row,
- unsigned Width, unsigned Height)
- {
- register unsigned Index;
- register short NewLevel;
- BYTE LookUpTable[MAXQUANTLEVELS];
-
- for (Index = MINSAMPLEVAL; Index < MAXQUANTLEVELS; Index++)
- {
- NewLevel = Index + BrightnessFactor;
- NewLevel = (NewLevel < MINSAMPLEVAL) ? MINSAMPLEVAL:NewLevel;
- NewLevel = (NewLevel > MAXSAMPLEVAL) ? MAXSAMPLEVAL:NewLevel;
- LookUpTable[Index] = NewLevel;
- }
- PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
- }
-
- /*
- This function will negate an image pixel by pixel. Threshold is
- the value of image data where the negatation begins. If
- threshold is 0, all pixel values are negated. That is, pixel value 0
- becomes 63 and pixel value 63 becomes 0. If threshold is greater
- than 0, the pixel values in the range 0..Threshold-1 are left
- alone while pixel values between Threshold..63 are negated.
- */
-
- void NegateImage(BYTE huge *ImageData, unsigned Threshold,
- unsigned Col, unsigned Row,
- unsigned Width, unsigned Height)
- {
- register unsigned Index;
- BYTE LookUpTable[MAXQUANTLEVELS];
-
- /* Straight through mapping initially */
- InitializeLUT(LookUpTable);
-
- /* from Threshold onward, negate entry in LUT */
- for (Index = Threshold; Index < MAXQUANTLEVELS; Index++)
- LookUpTable[Index] = MAXSAMPLEVAL - Index;
-
- PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
- }
-
- /*
- This function converts a gray scale image to a binary image with each
- pixel either on (WHITE) or off (BLACK). The pixel level at
- which the cut off is made is controlled by Threshold. Pixels
- in the range 0..Threshold-1 become black while pixel values
- between Threshold..63 become white.
- */
-
- void ThresholdImage(BYTE huge *ImageData, unsigned Threshold,
- unsigned Col, unsigned Row,
- unsigned Width, unsigned Height)
- {
- register unsigned Index;
- BYTE LookUpTable[MAXQUANTLEVELS];
-
- for (Index = MINSAMPLEVAL; Index < Threshold; Index++)
- LookUpTable[Index] = BLACK;
-
- for (Index = Threshold; Index < MAXQUANTLEVELS; Index++)
- LookUpTable[Index] = WHITE;
-
- PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
- }
-
-
- void StretchImageContrast(BYTE huge *ImageData, unsigned *HistoData,
- unsigned Threshold,
- unsigned Col, unsigned Row,
- unsigned Width, unsigned Height)
- {
- register unsigned Index, NewMin, NewMax;
- double StepSiz, StepVal;
- BYTE LookUpTable[MAXQUANTLEVELS];
-
- /*
- Search from the low bin towards the high bin for the first one that
- exceeds the threshold
- */
-
- for (Index=0; Index < MAXQUANTLEVELS; Index++)
- if (HistoData[Index] > Threshold)
- break;
-
- NewMin = Index;
-
- /*
- Search from the high bin towards the low bin for the first one that
- exceeds the threshold
- */
-
- for (Index=MAXSAMPLEVAL; Index > NewMin; Index--)
- if (HistoData[Index] > Threshold)
- break;
-
- NewMax = Index;
-
- StepSiz = (double)MAXQUANTLEVELS/(double)(NewMax-NewMin+1);
- StepVal = 0.0;
-
- /* values below new minimum are assigned zero in the LUT */
- for (Index=0; Index < NewMin; Index++)
- LookUpTable[Index] = MINSAMPLEVAL;
-
- /* values above new maximum are assigned the max sample value */
- for (Index=NewMax+1; Index < MAXQUANTLEVELS; Index++)
- LookUpTable[Index] = MAXSAMPLEVAL;
-
- /* values between the new minimum and new maximum are stretched */
- for (Index=NewMin; Index <= NewMax; Index++)
- {
- LookUpTable[Index] = StepVal;
- StepVal += StepSiz;
- }
- /*
- Look Up Table is now prepared to point transform the image data.
- */
- PtTransform(ImageData,Col,Row,Width,Height,LookUpTable);
- }
-
-