home *** CD-ROM | disk | FTP | other *** search
- Unit BGISave2;
- { This unit will save an image on the graphics screen to the }
- { disk file passed as a parameter. Because the size of an }
- { image retreived by the GetImage procedure can be larger }
- { 64K, it is necessary to get the image and restore it in }
- { several steps. It is possible to save an EGA screen in two }
- { steps, but the VGA screen in VGA Hi res mode is simply too }
- { large to store in two steps. Therefore, it is necessary to }
- { store such a screen in four steps. Why four? Because if }
- { I was to use 3 steps, it is much harder arrive at an exact }
- { size to make all 3 clips identical in size. }
- { The first thing the routine will do is save the Y position }
- { of each of the four sections as a word into the image file. }
- { This is then followed by the exact information stored by }
- { Turbo Pascal's GetImage procedure. }
- { To restore the image from the disk file, the restore }
- { routine will first read from the file the four Y positions }
- { stored in the file, and then recalculate the image size }
- { based on the values read. Later versions will add to the }
- { file the size of each of the four image chunks, thereby }
- { removing the need to pass the X2 and Y2 parameters to the }
- { RestoreImage procedure. }
-
- Interface
-
- Uses Graph;
-
- Procedure SaveImage( X1, Y1, X2, Y2 : Word; FileName : String );
- { This is the routine that is called to save an image to the }
- { specified disk file. It first determines if the image size }
- { can be retrieved by on call to GetImage. This is }
- { determined by a call to the ImageSize function, and if what }
- { is returened is less then what can be store in one block on }
- { the heap, one call is made to GetImage and this info is }
- { written to the file. }
-
- Procedure RestoreImage( X1,Y1,X2,Y2,PutPat : Word; FileName : String );
- { This routine is called to restore a previously store image. }
- { It is currently necessary to pass the X2 and Y2 parameters }
- { to the proecdure, so it can recalculate the size of each }
- { of the four image chuncks. Later version will be rewritten }
- { so as to remove this requirement. }
-
- Implementation
-
- Uses Dos; { Necessary to implement the Exist function. }
-
- Var
- ImSize : LongInt;
-
- Function Exists( FName : String ) : Boolean;
- { Checks for the existance of the image file. }
-
- Var
- Files : String;
-
- Begin
- Files := FSearch( FName, '' );
- Exists := Files <> '';
- End;
-
- Procedure SaveBlock( X1,Y1,X2,Y2 : Word; Var F : File );
- { THis procedure will save the block of the screen defined by }
- { X1 Y1 X2 Y2 into the file specified by F. }
- Var
- P : Pointer; { Location in heap to store the image }
- ISize : Word; { Size of Image to be stored on the heap }
-
- Begin
- ISize := ImageSize( X1,Y1,X2,Y2 );{ Determine size of Image }
- GetMem( P,ISize ); { Get the Memory to store }
- GetImage( X1,Y1,X2,Y2,P^ ); { Get the image }
- BlockWrite( F, P^, ISize ); { Write the Image to F }
- FreeMem( P, ISize ); { Release the heap memory }
- End;
-
- Procedure StoreExtendedImage( X1,Y1,X2,Y2 : Word; FName : String );
- { This procedure will break the requested image block into }
- { the four smaller blocks. This is necessary because some }
- { images are too large to store in one call to the GetImage }
- { procedure. In such cases, we will store the image in four }
- { different blocks within the output file. }
- Var
- F : File; { Output file variable. }
- YPos : Array[0..4] of Word; { Location to store Y coords }
- YRemain, { Remainder of division for image size }
- Y : Word; { Size of each block along Y coords }
- I : Byte; { Loop control variable. }
-
- Begin
- Y := ( Y2 - Y1 ) Div 4; { Calculate the Y increment. }
- YRemain := ( Y2 - Y1 ) Mod 4; { Remainder of calculation }
- YPos[0] := Y1 - 1; { Start at one less than what was passed }
- For I := 1 to 3 Do { Figure the other three starting Y vals }
- YPos[I] := YPos[I-1] + Y;
- YPos[4] := YPos[3] + Y + YRemain + 1;{ Tweek the last Y val }
- Assign( F, FName ); { Associate the File }
- Rewrite( F, 1 ); { Open it up for output }
- BlockWrite( F, YPos, SizeOf( YPos ) ); { Write the setup }
- For I := 0 to 3 Do { Save each block into file }
- SaveBlock( X1,( YPos[I] + 1 ),X2,YPos[I + 1], F );
- Close( F ); { Close it. }
- End;
-
- Procedure StoreImage( X1,Y1,X2,Y2 : Word; FName : String );
- { This procedure will save the image if it is small enough }
- { to fit into one block of memory on the Heap. }
- Var
- P : Pointer; { Memory location to keep image }
- F : File; { Output file variable }
-
- Begin
- GetMem( P, ImSize ); { Reserve memory for image }
- GetImage( X1,Y1,X2,Y2,P^ ); { Save image to Heap area }
- Assign( F, FName ); { Open the disk file }
- Rewrite( F, 1 );
- BlockWrite( F, P^, ImSize );{ Save the info into file }
- Close( F );
- End;
-
- Procedure SaveImage( X1, Y1, X2, Y2 : Word; FileName : String );
- Begin
- ImSize := ImageSize( X1, Y1, X2, Y2 );{ Check size of Image }
- { Is it in valid range? }
- If( ( ImSize > 0 ) And ( ImSize < 65535 ) ) Then
- StoreImage( X1,Y1,X2,Y2,FileName )
- Else
- StoreExtendedImage( X1,Y1,X2,Y2,FileName );
- End;
-
- Procedure RetrieveImage( FName : String; P : Pointer );
- { This procedure will restore an image if it was small enough }
- { to be stored with one call to GetImage. }
- Var
- F : File; { Input File variable }
-
- Begin
- Assign( F, FName ); { Associate the filename with F }
- Reset( F, ImSize ); { Open the file for input }
- BlockRead( F, P^, 1 ); { Read in the image. }
- Close( F ); { Close the File }
- End;
-
- Procedure PlaceImage( X1,Y1,X2,Y2,PutPat : Word; Var F : File );
- { This procedure calculates the size of each image block and }
- { reads the appropriate information from the file. }
- Var
- P : Pointer; { Pointer to where the image is stored }
- Begin
- ImSize := ImageSize( X1,Y1,X2,Y2 ); { Calculate the size }
- GetMem( P, ImSize ); { Allocate the necessary memory }
- BlockRead( F, P^, ImSize );{ Input the info from disk }
- PutImage( X1,Y1,P^,PutPat );{ Place it onto the screen }
- FreeMem( P, ImSize ); { Deallocate the heap memory }
- End;
-
- Procedure RestoreExtendedImage( X1,Y1,X2,Y2,PutPat : Word;
- FileName : String );
- { Driving procedure that will restore each of the four small }
- { images inside the file. }
- Var
- F : File; { File that stores the image }
- P : Pointer; { Location to store each of the images }
- YPos : Array[0..4] of Word; { Holds each Y position }
- I : Byte; { Loop control variable }
-
- Begin
- Assign( F, FileName ); { Associate the filename with F }
- Reset( F,1 ); { Open the file for Input }
- BlockRead( F, YPos, SizeOf( YPos ) ); { Read the info }
- For I := 0 to 3 Do { Now restore each of the images }
- PlaceImage( X1,( YPos[I] + 1 ),X2,YPos[I + 1],PutPat, F );
- Close( F ); { Close the file }
- End;
-
- Procedure RestoreImage( X1,Y1,X2,Y2,PutPat : Word;
- FileName : String );
- { This is the procedure that will determine how the image was }
- { originally stored. If it was done with one GetImage call, }
- { then this procedure will restore that one image. Otherwise }
- { it will call RestoreExtendedImage. }
- Var
- F : File of Byte; { Open file as byte to determine its size }
- BufPtr : Pointer; { Buffer to store the image read }
-
- Begin
- Assign( F, FileName );
- Reset( F ); { Open the file for input }
- ImSize := FileSize( F ); { Determine the files size }
- Close( F ); { Close the file }
- If( ImSize <= 65520 ) Then
- Begin { If it is small enough then restore it }
- GetMem( BufPtr, ImSize ); { Get the memory to store image }
- RetrieveImage( FileName, BufPtr ); { Read image from file }
- PutImage( X1,Y1,BufPtr^,PutPat ); { Restore it to screen }
- End
- Else { Otherwise, must restore in four steps }
- RestoreExtendedImage( X1,Y1,X2,Y2,PutPat,FileName );
- End;
-
- End.