PDA

Click to See Complete Forum and Search --> : VGA / VGR Image Viewing In VB


Jun 19th, 2000, 09:51 PM
I am programming an application that will allow viewing of the old Borland BGI format "VGA" and "VGR" files.

I have found the C source code and documentation on the internet, but I'm having trouble translating a few things.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-Here's the info I got in the C source code documentation:

.VGA and .VGR image file format

The .VGA file format is a linear bitmap format which is pretty
straight forward but a little quirky. This is Borland's BGI format
which nobody uses. We have no great love of this format, but our
favorite paint program has used it from day one, so we are stuck with it.

Basically, the first two 16bit words in the file are the x and y size.
Well, actuall they are (xsize-1) and (ysize-1). Why the 'minus one'?
We have no idea.

After that comes the image bitmap data. The first byte is the color
index of the upper left pixel in the image. The 2nd byte is the color index
in the next pixel to the right, and so on. After (xsize) pixels, the next
byte is the color index of the pixel one down from the upper left of the
image. This continues of course until you get to the byte (xsize*ysize)-1,
which is the lowerest rightmost pixel of the image.

After that is a strange amount of unused 'dead' space, and then a
SVGACODE. The dead space has a variable amount that depends on a formula
that takes the xsize and ysize as arguments. For that formula, see the
C source code given below.

The SVGACODE is two bytes that come after the dead space. These two bytes
form some mysterious code that we never use. If they are incorrect, GCSPAINT
will complain a little, but let you load the image anyway.

After that the file either ends (no palette attached), or else there are
768 more bytes (palette attached). The way to determine if a palette is
attached is to see if there is any more data in the file after the SVGACODE.
The palette is just 256 sets of 8-bit RGB values. These RGB values range
from 0 to 63. The color (0,0,0) is black, and the color (63,63,63) is white.
The color (63,0,0) is bright red, etc.

The .VGR variation

A .VGR file is nothing but a .VGA file saved with no palette, and it is
understood that any .VGR file is to be displayed on it's side. A .VGR
file can be no larger than 200x200. For years we did all our artwork with
.VGA files, but we realized that many non-programmers would never be happy
if all their artwork had to be laid on it's side before using in the game
engine. Hence the .VGR format was born!


C source code to read in VGA/VGR image

Here is a function that can read a .VGA/VGR file and return it's size
and a pointer to the bitmap data. This function might contain mistakes, since
it was adapted from some slightly different function for illustration purposes.
But is basically correct.


/* call with vga filename in nameptr, and int ptrs so that info can be */
/* returned. Integer return code is normally 0, but -1 if file not openable */
/* Other errors in the .VGA, like too big etc are other negative ints */
/* -1 could not open file */
/* -2 Could not alloc ram for reading in whole image */
/* -3 Could not alloc ram for Leftovers */
/* -4 Could not read leftovers, IE .VGA missing some data */
/* -5 Could not alloc ram for reading in palette */
/* -6 Could not read palette data from file */
/* -8 VGA image too large for this program, or BAD size numbers */
int getvgainfo( filename, xszptr, yszptr, **imageptrptr);
char *filename;
int *xszptr,*yszptr;
char **imageptrptr;
{
register int i;
int ix,iy,ihbeg,ihline,ival,nholes;
int fp,nread,nleft;
long fsize;
long thfsize;
int nonzeros;
unsigned int xsize,ysize;
unsigned char svgacode[2];
unsigned char sizeinfo[4];
unsigned char *imageptr;
unsigned char *leftoverptr;
unsigned char *palptr;


fp=open(filename, O_RDONLY | O_BINARY);
if(fp<0) return -1;

nread=read(fp,sizeinfo,4);
if(nread<4) return -1;

xsize=sizeinfo[0]+sizeinfo[1]*256+1;
ysize=sizeinfo[2]+sizeinfo[3]*256+1;

if( ((long) xsize * (long) ysize) > 65535L ) {
close(fp);
return -8;
}

/* get file size to figure out later if palette attached or not */
fsize=filelength(fp);

/* now calculate theoretical size of bitmap image and dead space */
thfsize=4L+( (long) ((xsize+7) & 0xfff8 ))* ((long) ysize);
nleft=thfsize-(4L+(long) xsize*(long) ysize);

/* leave room for an extra line */
imageptr=malloc( (unsigned) xsize*(unsigned)(ysize+1));
if(imageptr==NULL) return -2;

/* read the actual linear bitmap data */
nread=read(fp,imageptr,(unsigned int) xsize*(unsigned int)ysize);
if(nread==0) return -1;

/* double last line to make 3D engine happy. Unrelated to .VGA fmt. */
memcpy( imageptr+((long) xsize*(long)(ysize)),
imageptr+((long) xsize*(long)(ysize-1)),xsize);

palptr=NULL;


/* Here we read the dead space after the image just to advance the */
/* file pointer. LSEEK would have been good here too. */
if(nleft>0) {
leftoverptr=malloc(nleft);
if(leftoverptr==NULL) return -3;
nread=read(fp,leftoverptr,nleft);
if(nread==0) return -4;
free(leftoverptr);
}


/* now we see if a palette is attached. We don't know the meaning */
/* behind the 'svgacode'. We certainly always just skip over it. */
if(fsize-thfsize > 2 ) {
nread=read(fp,svgacode,2);
if(nread==0) {printf("\nsvga Read error\n"); exit(0); }
if(fsize-thfsize == 770) {
palptr=malloc(768L);
if(palptr==NULL) return -5;
nread=read(fp,palptr,768);
if(nread==0) return -6;
free(palptr);
}
}
*imageptrptr=imageptr;
return 0;
}


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-Here's what I've translated into VB so far:


'#############################
'## VGA/VGR VIEWING PROGRAM ##
'#############################

'char *filename;
Dim Filename As String

'int *xszptr,*yszptr;
Dim xszptr As Integer
Dim yszptr As Integer

'char **imageptrptr;
Dim imageptrptr As String

'int ix,iy,ihbeg,ihline,ival,nholes;
Dim ix, iy, ihbeg, ihline, ival, nholes As Integer

'int fp,nread,nleft;
Dim nread, nleft As Integer
Dim fp As Byte

'long fsize;
Dim fsize As Long

'long thfsize;
Dim thfsize As Long

'int nonzeros;
Dim nonzeros As Integer

'///////////////////////////////////////////////////////////
'I have read that in C code "unsigned" means that a variable
'can only hold a minimum value of 0 (no negative values) and
'the max value is controlled by the []
'///////////////////////////////////////////////////////////

'unsigned int xsize,ysize;
Dim xsize, ysize As Integer

'unsigned char svgacode[2];
Dim svgacode(0 To 2) As String

'unsigned char sizeinfo[4];
Dim sizeinfo(0 To 4) As Byte

'unsigned char *imageptr;
Dim imageptr As String

'unsigned char *leftoverptr;
Dim leftoverptr As String

'unsigned char *palptr;
Dim palptr As String


Sub GetVgaInfo()

' call with vga filename in nameptr, and int ptrs so that info can be */
' returned. Integer return code is normally 0, but -1 if file not openable */
' Other errors in the .VGA, like too big etc are other negative ints */
' -1 could not open file */
' -2 Could not alloc ram for reading in whole image */
' -3 Could not alloc ram for Leftovers */
' -4 Could not read leftovers, IE .VGA missing some data */
' -5 Could not alloc ram for reading in palette */
' -6 Could not read palette data from file */
' -8 VGA image too large for this program, or BAD size numbers */

'On Error Resume Next

'Check to see if the file is valid
Open Filename For Binary Access Read As #1
Get #1, , fp
If UCase(fp) < 0 Then
MsgBox "Could Not Open File!" '-1
Exit Sub
End If
Close #1

Open Filename For Binary Access Read As #1
Get #1, , sizeinfo
'The xsize and ysize have been checked and work perfectly!
xsize = sizeinfo(0) + sizeinfo(1) * 256 + 1
ysize = sizeinfo(2) + sizeinfo(4) * 256 + 1
frmMain.picBoard.Width = xsize
frmMain.picBoard.Height = ysize

'/* get file size to figure out later if palette attached or not */
fsize = FileLen(Filename)

'/* now calculate theoretical size of bitmap image and dead space */
'thfsize = 4L + ((Long)((xsize + 7) & 0xfff8 ))* ((long) ysize);
'nleft = th fsize - (4L + (long) xsize * (long) ysize);

Close #1

End Sub


So as you can see, I left off at the code that calculates the theoretical size of the bitmap image and dead space. I don't understand what the 4L stands for and what a Long is. I guess the 0xfff8 is hex code.

Can someone help me out here?

-Simon Bingier