home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1990 by John Wiley & Sons, Inc.
- All Rights Reserved.
- */
- /****************************************/
- /* Image Processing Code */
- /* Geometric Processing Functions */
- /* written in Turbo C 2.0 */
- /* by */
- /* Craig A. Lindley */
- /* */
- /* Vers: 1.0 Last Update: 11/16/89 */
- /****************************************/
-
- #include <stdio.h>
- #include <conio.h>
- #include <dos.h>
- #include <alloc.h>
- #include <process.h>
- #include <math.h>
- #include <graphics.h>
- #include "misc.h"
- #include "pcx.h"
- #include "vga.h"
- #include "imagesup.h"
-
-
- void ScaleImage(BYTE huge *InImage, unsigned SCol, unsigned SRow,
- unsigned SWidth, unsigned SHeight,
- double ScaleH, double ScaleV,
- BYTE huge *OutImage,
- unsigned DCol, unsigned DRow,
- unsigned Interpolate)
- {
- unsigned DestWidth, DestHeight;
- unsigned PtA, PtB, PtC, PtD, PixelValue;
- register unsigned SPixelColNum, SPixelRowNum, DestCol, DestRow;
- double SPixelColAddr, SPixelRowAddr;
- double ColDelta, RowDelta;
- double ContribFromAandB, ContribFromCandD;
-
- DestWidth = ScaleH * SWidth + 0.5;
- DestHeight = ScaleV * SHeight+ 0.5;
-
- if (ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"ScaleImage") &&
- ParameterCheckOK(DCol,DRow,DCol+DestWidth,DRow+DestHeight,"ScaleImage"))
- {
- /* Calculations from destination perspective */
- for (DestRow = 0; DestRow < DestHeight; DestRow++)
- {
- SPixelRowAddr = DestRow/ScaleV;
- SPixelRowNum = (unsigned) SPixelRowAddr;
- RowDelta = SPixelRowAddr - SPixelRowNum;
- SPixelRowNum += SRow;
-
- for (DestCol = 0; DestCol < DestWidth; DestCol++)
- {
- SPixelColAddr = DestCol/ScaleH;
- SPixelColNum = (unsigned) SPixelColAddr;
- ColDelta = SPixelColAddr - SPixelColNum;
- SPixelColNum += SCol;
-
- if (Interpolate)
- {
- /*
- SPixelColNum and SPixelRowNum now contain the pixel
- coordinates of the upper left pixel of the targetted
- pixel's (point X) neighborhood. This is point A below:
- A B
- X
- C D
- We must retrieve the brightness level of each of the
- four pixels to calculate the value of the pixel put into
- the destination image.
-
- Get point A brightness as it will always lie within the
- input image area. Check to make sure the other points are
- within also. If so use their values for the calculations.
- If not, set them all equal to point A's value. This induces
- an error but only at the edges on an image.
- */
-
- PtA = GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum);
- if (((SPixelColNum+1) < MAXCOLS) && ((SPixelRowNum+1) < MAXROWS))
- {
- PtB = GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum);
- PtC = GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum+1);
- PtD = GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum+1);
- }
- else
- {
- /* All points have equal brightness */
- PtB=PtC=PtD=PtA;
- }
- /*
- Interpolate to find brightness contribution of each pixel
- in neighborhood. Done in both the horizontal and vertical
- directions.
- */
- ContribFromAandB = ColDelta*((double)PtB - PtA) + PtA;
- ContribFromCandD = ColDelta*((double)PtD - PtC) + PtC;
- PixelValue = 0.5 + ContribFromAandB +
- (ContribFromCandD - ContribFromAandB)*RowDelta;
- }
- else
- PixelValue=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum);
-
- /* Put the pixel into the destination buffer */
- PutPixelInImage(OutImage,DestCol+DCol,DestRow+DRow,PixelValue);
- }
- }
- }
- }
-
-
- void SizeImage(BYTE huge *InImage, unsigned SCol, unsigned SRow,
- unsigned SWidth, unsigned SHeight,
- BYTE huge *OutImage,
- unsigned DCol, unsigned DRow,
- unsigned DWidth, unsigned DHeight,
- unsigned Interpolate)
- {
- double HScale, VScale;
-
- /* Check for parameters out of range */
- if (ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"SizeImage") &&
- ParameterCheckOK(DCol,DRow,DCol+DWidth,DRow+DHeight,"SizeImage"))
- {
- /*
- Calculate horizontal and vertical scale factors required
- to fit specified portion of input image into specified portion
- of output image.
- */
- HScale = (double)DWidth/(double)SWidth;
- VScale = (double)DHeight/(double)SHeight;
-
- /* Call ScaleImage to do the actual work */
- ScaleImage(InImage,SCol,SRow,SWidth,SHeight,HScale,VScale,
- OutImage,DCol,DRow,Interpolate);
- }
- }
-
- void RotateImage(BYTE huge *InImage, unsigned Col, unsigned Row,
- unsigned Width, unsigned Height, double Angle,
- BYTE huge *OutImage, unsigned Interpolate)
- {
- register unsigned ImageCol, ImageRow;
- unsigned CenterCol, CenterRow, SPixelColNum, SPixelRowNum;
- unsigned ColExtent, RowExtent, PixelValue;
- unsigned PtA, PtB, PtC, PtD;
- double DPixelRelativeColNum, DPixelRelativeRowNum;
- double CosAngle, SinAngle, SPixelColAddr, SPixelRowAddr;
- double ColDelta, RowDelta;
- double ContribFromAandB, ContribFromCandD;
-
- if (ParameterCheckOK(Col,Row,Col+Width,Row+Height,"RotateImage"))
- {
- /* Angle must be in 0..359.9 */
- while (Angle >= 360.0)
- Angle -= 360.0;
-
- /* Convert angle from degrees to radians */
- Angle *= ((double) 3.14159/(double) 180.0);
-
- /* Calculate angle values for rotation */
- CosAngle = cos(Angle);
- SinAngle = sin(Angle);
-
- /* Center of rotation */
- CenterCol = Col + Width/2;
- CenterRow = Row + Height/2;
-
- ColExtent = Col + Width;
- RowExtent = Row + Height;
-
- /*
- All calculations are performed from the destination image
- perspective. Absolute pixel values must be converted into
- inches of display distance to keep the aspect value
- correct when image is rotated. After rotation, the calculated
- display distance is converted back to real pixel values.
- */
-
- for (ImageRow = Row; ImageRow < RowExtent; ImageRow++)
- {
- DPixelRelativeRowNum = (double)ImageRow - CenterRow;
- /* Convert row value to display distance from image center */
- DPixelRelativeRowNum *= LRINCHESPERPIXELVERT;
-
- for (ImageCol = Col; ImageCol < ColExtent; ImageCol++)
- {
- DPixelRelativeColNum = (double)ImageCol - CenterCol;
- /* Convert col value to display distance from image center */
- DPixelRelativeColNum *= LRINCHESPERPIXELHORIZ;
- /*
- Calculate source pixel address from destination
- pixels position.
- */
- SPixelColAddr = DPixelRelativeColNum*CosAngle-
- DPixelRelativeRowNum*SinAngle;
- SPixelRowAddr = DPixelRelativeColNum*SinAngle+
- DPixelRelativeRowNum*CosAngle;
-
- /*
- Convert from coordinates relative to image
- center back into absolute coordinates.
- */
- /* Convert display distance to pixel location */
- SPixelColAddr *= LRPIXELSPERINCHHORIZ;
- SPixelColAddr += CenterCol;
- SPixelRowAddr *= LRPIXELSPERINCHVERT;
- SPixelRowAddr += CenterRow;
-
- SPixelColNum = (unsigned) SPixelColAddr;
- SPixelRowNum = (unsigned) SPixelRowAddr;
- ColDelta = SPixelColAddr - SPixelColNum;
- RowDelta = SPixelRowAddr - SPixelRowNum;
-
- if (Interpolate)
- {
- /*
- SPixelColNum and SPixelRowNum now contain the pixel
- coordinates of the upper left pixel of the targetted
- pixel's (point X) neighborhood. This is point A below:
- A B
- X
- C D
- We must retrieve the brightness level of each of the
- four pixels to calculate the value of the pixel put into
- the destination image.
-
- Get point A brightness as it will always lie within the
- input image area. Check to make sure the other points are
- within also. If so use their values for the calculations.
- If not, set them all equal to point A's value. This induces
- an error but only at the edges on an image.
- */
-
- PtA = GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum);
- if (((SPixelColNum+1) < MAXCOLS) && ((SPixelRowNum+1) < MAXROWS))
- {
- PtB = GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum);
- PtC = GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum+1);
- PtD = GetPixelFromImage(InImage,SPixelColNum+1,SPixelRowNum+1);
- }
- else
- {
- /* All points have equal brightness */
- PtB=PtC=PtD=PtA;
- }
- /*
- Interpolate to find brightness contribution of each pixel
- in neighborhood. Done in both the horizontal and vertical
- directions.
- */
- ContribFromAandB = ColDelta*((double)PtB - PtA) + PtA;
- ContribFromCandD = ColDelta*((double)PtD - PtC) + PtC;
- PixelValue = 0.5 + ContribFromAandB +
- (ContribFromCandD - ContribFromAandB)*RowDelta;
- }
- else
- PixelValue=GetPixelFromImage(InImage,SPixelColNum,SPixelRowNum);
-
- /* Put the pixel into the destination buffer */
- PutPixelInImage(OutImage,ImageCol,ImageRow,PixelValue);
- }
- }
- }
- }
-
-
- /*
- Caution: images must not overlap
- */
- void TranslateImage(BYTE huge *InImage,
- unsigned SCol, unsigned SRow,
- unsigned SWidth, unsigned SHeight,
- BYTE huge *OutImage,
- unsigned DCol, unsigned DRow,
- unsigned EraseFlag)
- {
- register unsigned SImageCol, SImageRow, DestCol;
- unsigned SColExtent, SRowExtent;
-
- /* Check for parameters out of range */
- if (ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"TranslateImage") &&
- ParameterCheckOK(DCol,DRow,DCol+SWidth,DRow+SHeight,"TranslateImage"))
- {
- SColExtent = SCol+SWidth;
- SRowExtent = SRow+SHeight;
-
- for (SImageRow = SRow; SImageRow < SRowExtent; SImageRow++)
- {
- /* Reset the destination Column count every row */
- DestCol = DCol;
- for (SImageCol = SCol; SImageCol < SColExtent; SImageCol++)
- {
- /* Transfer byte of the image data between buffers */
- PutPixelInImage(OutImage,DestCol++,DRow,
- GetPixelFromImage(InImage,SImageCol,SImageRow));
- }
- /* Bump to next row in the destination image */
- DRow++;
- }
- /* If erasure specified, blot out original image */
- if (EraseFlag)
- ClearImageArea(InImage,SCol,SRow,SWidth,SHeight,BLACK);
- }
- }
-
- void MirrorImage(BYTE huge *InImage,
- unsigned SCol, unsigned SRow,
- unsigned SWidth, unsigned SHeight,
- enum MirrorType WhichMirror,
- BYTE huge *OutImage,
- unsigned DCol, unsigned DRow)
- {
- register unsigned SImageCol, SImageRow, DestCol;
- unsigned SColExtent, SRowExtent;
-
- /* Check for parameters out of range */
- if (ParameterCheckOK(SCol,SRow,SCol+SWidth,SRow+SHeight,"MirrorImage") &&
- ParameterCheckOK(DCol,DRow,DCol+SWidth,DRow+SHeight,"MirrorImage"))
- {
- SColExtent = SCol+SWidth;
- SRowExtent = SRow+SHeight;
-
- switch(WhichMirror)
- {
- case HorizMirror:
- for (SImageRow = SRow; SImageRow < SRowExtent; SImageRow++)
- {
- /* Reset the destination Column count every row */
- DestCol = DCol + SWidth;
- for (SImageCol = SCol; SImageCol < SColExtent; SImageCol++)
- {
- /* Transfer byte of the image data between buffers */
- PutPixelInImage(OutImage,--DestCol,DRow,
- GetPixelFromImage(InImage,SImageCol,SImageRow));
- }
- /* Bump to next row in the destination image */
- DRow++;
- }
- break;
- case VertMirror:
- DRow += (SHeight-1);
- for (SImageRow = SRow; SImageRow < SRowExtent; SImageRow++)
- {
- /* Reset the destination Column count every row */
- DestCol = DCol;
- for (SImageCol = SCol; SImageCol < SColExtent; SImageCol++)
- {
- /* Transfer byte of the image data between buffers */
- PutPixelInImage(OutImage,DestCol++,DRow,
- GetPixelFromImage(InImage,SImageCol,SImageRow));
- }
- /* Bump to next row in the destination image */
- DRow--;
- }
- break;
- }
- }
- }
-
-