Solved

Error in BMP loading program. Help.

Posted on 2001-06-09
5
614 Views
Last Modified: 2008-01-16
I keep getting an error message and can't seem to figure out how to debug it. Its in the last portion of the program at the "While loop" using the fread function.
Modox is simply a header file I use to achieve the same VGA 320x200x256 settings, so I blotted out the one used in the program, which works anyway. Here is my code (see bottom for error message:

#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <modox.h>

char far *Screen;
/*
//Sets the display to VGA 320x200x256
void VGAScreen (){
  union REGS r;
  r.h.ah = 0;
  r.h.al = 0x13;
  int86(0x10, &r, &r);
  return;
}

//Goes back to textmode
void TextScreen (){
/*  union REGS r;
  r.h.ah = 0;
  r.h.al = 0x3;
  int86(0x10, &r, &r);
  return;
}*/

//This sets a DAC register to a specific Red Green Blue-value
int SetDAC (unsigned char DAC, unsigned char R, unsigned char G, unsigned char B)
{
  outportb (0x3C8, DAC);
  outportb (0x3C9, R);
  outportb (0x3C9, G);
  outportb (0x3C9, B);
  return 0;
}

int LoadBMP ()
{
 struct BMPHeader           // The structure of a BMP Header file
 {
  unsigned short bfType;    // Specifies the type of file. It must be BM.

  long bfSize,              // Specifies the size in DWORDs of the file.
  bfReserved,               // Is reserved and must be set to zero.
  bfOffBits,                // Specifies in bytes the offset from the
                      // BMPHeader of the actual bitmap in the file.
  biSize,                   // Specifies the number of bytes required by the
                      // BMPHeader structure.
  biWidth,                  // Specifies the width of the bitmap in pixels.
  biHeight;                 // Specifies the height of the bitmap in pixels.

  unsigned short biPlanes,  // Specifies the number of planes for the target
                      //  device and must be set to 1.
  biBitCount;               // Specifies the number of bits per pixel.
                      //  This value must be 1, 4, 8, or 24.

  long biCompression,       // Specifies the type of compression for a
                      //  compressed bitmap.
  biSizeImage,              // Specifies the size in bytes of the image.
  biXPelsPerMeter,          // Specifies the horizontal resolution in pixels
                      //  per meter of the target device for the bitmap.
                      //  An application can use this value to select a
                      //  bitmap from a resource group that best matches
                      //  the characteristics of the current device.
  biYPelsPerMeter,          // Specifies the vertical resolution in pixels per
                      //  meter of the target device for the bitmap.
  biClrUsed,                // Specifies the number of color indexes in the
                      //  color table actually used by the bitmap.
  biClrImportant;           // Specifies the number of color indexes that are
                      //  considered important for displaying the bitmap.
                      //  If 0, then all colors are important.
  };

  BMPHeader Header;         // Assign BMPHeader structure to variable Header

  FILE *BMPFile;            // Create FILE type BMPFile

  unsigned char c, Palette[256][4];
  char *filename = "logo256.bmp"; // Name or path and name of file

  unsigned int offset, lines, paddedWidth;

  //This checks for the file
  BMPFile = fopen (filename, "rb");

  if (BMPFile == NULL)
  {
   printf ("Cant open file.");
   return 1;
  }

  //Read the headerinformation
  fread (&Header, 54, 1, BMPFile);
  /*
    fread (X, X1, X2, X3);
     X:Points to a block into which data is read
    X1:Length of each item read, in bytes
    X2:Number of items read
    X3:Points to input stream
  */

  if (Header.bfType != 19778 || Header.bfReserved != 0 || Header.biPlanes !=1)
  {
   //Not a valid bitmap file - don't display
   printf ("Not a valid bitmap.");
   fclose (BMPFile);
   return 1;
  }
  if (Header.biCompression != 0) {
       //Compressed file - don't display
       printf ("Compressed file.");
       fclose (BMPFile);
       return 1;
  }
  if (Header.biBitCount != 8) {
       //If the file is other than 8-bit dont read.
       printf ("Not an 8-bit bitmap.");
       fclose (BMPFile);
       return 1;
  }
  if (Header.biWidth > 320 || Header.biHeight > 200) {
       //If its larger than 320*200 dont load.
       printf ("Size too large.");
       fclose (BMPFile);
       return 1;
  }

  //Load the palette info
  fread (&Palette, 1024, 1, BMPFile);
  for (c = 0; c < 255; c++)
       SetDAC (c, Palette[c][2] >> 2, Palette[c][1] >> 2, Palette[c][0] >> 2);

  offset = (100 + (Header.biHeight >> 1)) * 320 + 160 - (Header.biWidth >> 1);

  lines = 0;

  paddedWidth = Header.biWidth & 0xFFFC;
  if (Header.biWidth != paddedWidth) paddedWidth += 4;
  //Loop for reading lines
  while (lines < Header.biHeight) {
141 ->       fread (Screen + offset, paddedWidth, 1, BMPFile);
       offset -= 320;
       lines++;
  }
  fclose (BMPFile);
  return 0;
}



void main (/*int argcount, char *argvalue[]*/)
{
  //Set up a pointer in vga memory
  Screen = (char far *)0xA0000000L;

//  VGAScreen ();
  Set_320x200();
  LoadBMP();
  getch ();
  textmode();
//  TextScreen ();
}


I get two error messages, both on line 141 (where the arrow is):
 Cannot convert 'char far*' to 'void*'
 Type mismatch in parameter '__ptr' in call to 'fread(void *, unsigned int, unsigned int, FILE *)'

Thank you to all who contribute. I've been trying to load bitmaps (just 256 uncompressed) for the longest time. I know of and have a working PCX loader, but its such an old format. If you need to know, I am currently using Borland's Turbo C++ 3.0. I plan on getting DevC++ from bloodshed.net or maybe an updated version of TC sometime soon.
0
Comment
Question by:Etregan
  • 2
5 Comments
 
LVL 2

Accepted Solution

by:
benhere earned 100 total points
ID: 6172511
ahh!!! DOS programming!! kill me!! ;-)

ok, don't panic..

It looks like you are giving to the function fread parameters of the wrong type.. I would suggest to use a temporary variable of the right type for the fread, and then convert it and assign it to where you want manually..

ex:

char tempByte[1];
fread (tempByte, paddedWidth, 1, BMPFile);


0
 
LVL 1

Assisted Solution

by:ninjadeathtouch
ninjadeathtouch earned 100 total points
ID: 7077900
Ah DOS - I love it.

You will find that the image data is upside down once you get it working - but this code accounts for that.  When you do support for the encoded forms of BMP this will not be the case - just though you'd want to know!.

Also, the palette [256][4] - you only really need [256][3]
- since the last part of the pallete isn't used in 256 colour modes. - which would save some memory.. :)

PCXs are much easier to work with b.t.w.

Also
 Screen = (char far *)0xA0000000L;
should be
 Screen = (unsigned char far *)0xA0000000L;

Did you know this could be:

 Screen = (unsigned long *)0xA0000000L;
??

If you did this - you can write data to screen in much bigger chunks! - it's a lot faster :)


oh and for fun :

for (c = 0; c < 255; c++)
      SetDAC (c, Palette[c][2] >> 2, Palette[c][1] >> 2, Palette[c][0] >> 2);

modify this code to:

for (c = 0; c < 255; c++){
SetDAC (c, 0,0,0);
}

display image here

for (i=0;i<steps;i++){
for (c = 0; c < 255; c++){
r=((Palette[c][2]>>2)>>steps)*i;
g=((Palette[c][1]>>2)>>steps)*i;
b=((Palette[c][0]>>2)>>steps)*i;
SetDAC (c, r,g,b);
}
}


and make sure steps is a multiple of 2
- an instant fade in!





0
 
LVL 1

Expert Comment

by:ninjadeathtouch
ID: 7077902
also - don't use getch() in DOS - look up keyboard handlers - interrupt 19 if I remember - anyway find one and copy and paste it into your code - honestly you can get up to 20% more speed!!

0
 
LVL 17

Expert Comment

by:Lobo042399
ID: 11408413
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.

I will leave the following recommendation for this question in the Cleanup topic area:
Split Points - benhere [http:M_462400.html] and ninjadeathtouch [http:M_717089.html]

Any objections should be posted here in the next 4 days. After that time, the question will be closed.

Lobo
EE Cleanup Volunteer
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Keep your audience engaged and get the most out of your next presentation with these quick Prezi tips.
Many programs have tried to outwit PowerPoint in terms of technology and skill. These programs, however, still lack several characteristics that PowerPoint has possessed from the start. Here's why PowerPoint replacements won't entirely work for desi…
Learn how to set up basic frames and paths in Prezi and understand the open space that Prezi allows you to create presentations in.
Learn how to download your full Prezi presentation for offline presenting. Prezi doesn’t have to be viewed and shared in a web browser, even with a free account you can download your full presentation to share with others. Be sure to download any vi…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now