home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- **
- ** SCALE.C
- **
- ** Hi,
- ** I've gotten a lot of questions from people about the scaling routine
- ** in my Image Processing program called Improces. Quite a few folks
- ** have been interested in getting the source code to the program. As a
- ** matter of policy, I decided a long time ago not to give away any part
- ** of the source code to the Improces program. Sorry.
- **
- ** Well, here is a _similar_ scaling routine. It works the same as the
- ** Improces one, only the one in the Improces program can handle images
- ** larger then 64K, and it does the scaling with a single buffer.
- ** Besides that, it's the same idea, and speed.
- **
- ** If you'ld like the shareware version of Improces, it can be had from:
- **
- ** Dust Devil BBS: (702)796-7134
- **
- ** The Matrix BBS (This board is a monster!)
- **
- ** 205-323-2016 for 2400 bps access only
- ** 205-323-6016 for HST/V.32bis access only (no 2400)
- ** 205-458-3449 for V.32bis access only (no 2400)
- **
- ** or CompuServe
- **
- ** I can be reached on any of the above BBS's, or CompuServe
- ** John Wagner, CIS-ID 72122,2412
- **
- **
- ** Legal stuff:
- ** Free, give it away, use it, not for resale, all that other
- ** good stuff... John Wagner, 1993
- **
- ** Not responsible for any damage this code may cause!!!
- **
- ** Small program that shows how to scale an when the source and
- ** destination are both under 64K. NO ERROR CHECKING IS PERFORMED!!!
- **
- ***************************************************************************
- ***************************************************************************
- ** *
- ** WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!!WARNING!!! *
- ** *
- ***************************************************************************
- ***************************************************************************
- ** Req. VGA hardware and file JOHN.CLB
- ** This program performs NO error checking, so make sure you have
- ** a VGA and the file JOHN.CLB. There is no error checking for
- ** memory allocation failures, add them if you like!
- **
- ** It should be noted that this program will only work in mode 0x13
- ** without some major modifications on GetImage and PutImage. This
- ** program lives, eats and breaths on the fact that each pixel is
- ** 8 bits, and video memory is linear. (Just like Improces<g>).
- **
- ** COMPILER: Borland C++ 3.1, Large model
- **
- ** Command line: bcc -ml scale.c
- **
- ** Should compile with Turbo C++ as well, tcc -ml scale.c
- ** and MS C family by modifying the #includes
- **
- **********************************************************************/
-
- #include <dos.h>
- #include <mem.h>
- #include <malloc.h>
- #include <io.h>
- #include <fcntl.h>
- #include <conio.h>
-
- #include "scale.h"
-
- /*********************************************************************
- **
- ** main
- **
- *********************************************************************/
- void main()
- {
- //These are the coords for a bounding box around John
- static Rect JohnRect = {0, 0, 191, 164};
-
- //this is the size of the screen in mode 0x13
- static Rect ScreenRect = {0, 0, 319, 199};
-
- //this is a rect that is smaller
- static Rect SmallerRect = {200, 40, 310, 120};
- Rect EffectRect;
- int i;
-
- //setup
- SetVideoMode(0x13);
- PalGrayScale();
- LoadJohn();
-
- //wait a sec...
- GetKey();
-
- //scale John to the screen rect
- Scale(&JohnRect, &ScreenRect);
-
- //wait another sec...
- GetKey();
-
- //reload
- LoadJohn();
-
- //wait...
- GetKey();
-
- //get small
- Scale(&JohnRect, &SmallerRect);
-
- //take a look-c...
- GetKey();
-
- //special effects!
- do
- {
- memcpy(&EffectRect, &SmallerRect, sizeof(Rect));
- for(i = 0 ; i < 30 ; i++)
- {
- EffectRect.Sx += 2;
- EffectRect.Sy += 2;
- EffectRect.Ex -= 2;
- EffectRect.Ey -= 2;
- Scale(&JohnRect, &EffectRect);
- }
- }while(!kbhit());
-
- //flush
- GetKey();
-
- //and exit
- SetVideoMode(3);
- }
-
- /*********************************************************************
- **
- ** ImageSize
- **
- ** Returns the number of bytes needed to capture a given image
- **
- *********************************************************************/
- unsigned int ImageSize(pRect r)
- {
- return (unsigned)((unsigned)((r->Ex - r->Sx)+1) *
- (unsigned)((r->Ey - r->Sy)+1));
- }
-
- /*********************************************************************
- **
- ** GetImage
- **
- ** Captures a given image and places it in a buffer
- **
- *********************************************************************/
- void GetImage(pRect r, unsigned char *Buffer)
- {
- int y, Width;
- unsigned char *Ptr = Buffer;
-
- Width = r->Ex - r->Sx + 1;
-
- for(y = r->Sy ; y <= r->Ey ; y++, Ptr+=Width)
- memcpy(Ptr, VgaMem + (y * 320) + r->Sx, Width);
- }
-
- /*********************************************************************
- **
- ** PutImage
- **
- ** Takes an image from a buffer and places it on the screen
- **
- *********************************************************************/
- void PutImage(pRect r, unsigned char * Buffer)
- {
- int y, Width;
- unsigned char *Ptr = Buffer;
-
- Width = r->Ex - r->Sx + 1;
-
- for(y = r->Sy ; y <= r->Ey ; y++, Ptr+=Width)
- memcpy(VgaMem + (y * 320) + r->Sx, Ptr, Width);
- }
-
- /*********************************************************************
- **
- ** Scale
- **
- ** Scales the image from Source to Dest
- **
- *********************************************************************/
- void Scale(pRect Source, pRect Dest)
- {
- unsigned char *Image, *Screen, *PtrScreen;
- float XRatio, YRatio, X, Y;
- int Xc, Yc;
- int DestWidth, DestHeight;
- int SourceWidth, SourceHeight;
- int *XPoints, *YPoints, Offset;
-
- SourceWidth = Source->Ex - Source->Sx + 1;
- SourceHeight = Source->Ey - Source->Sy + 1;
-
- DestWidth = Dest->Ex - Dest->Sx + 1;
- DestHeight = Dest->Ey - Dest->Sy + 1;
-
- //ok, I lied, a little error checking
- if(!SourceWidth || !SourceHeight || !DestWidth || !DestHeight)
- return;
-
- //should add error checking<g>
- Image = (unsigned char *)malloc(ImageSize(Source));
- Screen = (unsigned char *)malloc(ImageSize(Dest));
-
- //capture the source image
- GetImage(Source, Image);
-
- /************************************************************************
-
- Compute the scaling ratios
-
- ************************************************************************/
-
- XRatio = (float) ( (float)SourceWidth /
- (float)DestWidth );
-
- YRatio = (float) ( (float)SourceHeight /
- (float)DestHeight );
-
- //alloc the look up table
- XPoints = (int *)malloc(DestWidth * sizeof(int));
-
- for( Xc=0, X = Source->Sx ; Xc < DestWidth ; X+=XRatio, Xc++ )
- XPoints[Xc] = X;
-
- //same for the y axis
- YPoints = (int *)malloc(DestHeight * sizeof(int));
-
- for( Yc=0, Y = Source->Sy ; Yc < DestHeight ; Y+=YRatio, Yc++ )
- YPoints[Yc] = Y;
-
- //use a pointer to run through the array
- PtrScreen = Screen;
-
- //This is it, actually scales the bitmap using the look up table
- //to go from the dest to the source...
- for( Yc = 0 ; Yc < DestHeight ; Yc++ )
- {
- Offset = YPoints[Yc] * SourceWidth;
- for( Xc = 0 ; Xc < DestWidth ; Xc++)
- *PtrScreen++ = Image[Offset + XPoints[Xc]];
- }
-
- //put the result on the screen
- PutImage(Dest, Screen);
-
- //free up the allocated memory
- free(Screen);
- free(Image);
- free(YPoints);
- free(XPoints);
- }
-
- /*********************************************************************
- **
- ** LoadJohn
- **
- ** Loads an image of yours truly directly into video memory
- ** (JOHN.CLB is a 320x200 clipboard image saved with Improces)
- **
- *********************************************************************/
- void LoadJohn(void)
- {
- int FileHandle;
-
- FileHandle = open("john.clb", O_RDONLY | O_BINARY);
-
- read(FileHandle, VgaMem, 64000);
-
- close(FileHandle);
- }
-
- /*********************************************************************
- **
- ** SetVideoMode
- **
- ** Mixes six oranges and two pineapples...
- **
- *********************************************************************/
- void SetVideoMode(int Mode)
- {
- union REGS r;
-
- r.x.ax = Mode;
- int86(0x10, &r, &r); //click...
- }
-
- /*********************************************************************
- **
- ** PalGrayScale
- **
- ** Sets the VGA palette to grayscale
- **
- *********************************************************************/
- void PalGrayScale(void)
- {
- register i=0;
-
- //start at 0
- outp(VgaStartColor, 0);
-
- for(i = 0 ; i < 256 ; i++)
- {
- outp(VgaPort, i>>2); //Red
- outp(VgaPort, i>>2); //Green
- outp(VgaPort, i>>2); //Blue
- }
- }
-
- /*********************************************************************
- **
- ** GetKey
- **
- ** Returns the key pressed
- **
- *********************************************************************/
- int GetKey(void)
- {
- int Key;
-
- Key = getch();
-
- if(!Key)
- Key = getch() + 256;
-
- return Key;
- }
-