Mail Archives: djgpp/2004/10/09/22:45:43

X-Authentication-Warning: mail set sender to djgpp-bounces using -f
From: jbs30000 AT aol DOT com (Joel)
Newsgroups: comp.os.msdos.djgpp
Subject: Need help with a bmp loading routine
Date: 9 Oct 2004 19:39:02 -0700
Lines: 104
Message-ID: <>
X-Trace: 1097375942 31494 (10 Oct 2004 02:39:02 GMT)
X-Complaints-To: groups-abuse AT google DOT com
NNTP-Posting-Date: Sun, 10 Oct 2004 02:39:02 +0000 (UTC)
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

I have tried just about everything to make my routine work right, and
the best I can get it to do is display the bottom half of a bmp file
correctly, but the top half doesn't work right.

Before showing my code, I just want to say, yes, I'm aware of Allegro,
but am choosing to write my own code (with your help).

Also, sorry about the length of this post, but I'm trying to include
all relevant information.

OK, this routine loads a 24 bit bmp file and displays it on VGA screen
mode 0x13.  I have the palette set up for (6, 6, 6) colors.  The
routine reads the RGB values and the Plot13 routine translates that
into the appropriate pixel color.  Each value (red, green, blue) is
divided by 51 since 255 / 5 = 51.

First, I have the bmp header struct:

struct Windows_Bitmap_Header
        unsigned short Signature __attribute__((packed));
        unsigned long Size __attribute__((packed));
        unsigned short Reserved_1 __attribute__((packed));
        unsigned short Reserved_2 __attribute__((packed));
        unsigned long Image_Offset __attribute__((packed));
        unsigned long Header_Size __attribute__((packed));
        unsigned long Length __attribute__((packed));
        unsigned long Height __attribute__((packed));
        unsigned short Planes __attribute__((packed));
        unsigned short Bits_Per_Pixel __attribute__((packed));
        unsigned long Compression_Type __attribute__((packed));
        unsigned long Size_in_Bytes __attribute__((packed));
        unsigned long H_Res __attribute__((packed));
        unsigned long V_Res __attribute__((packed));
        unsigned long Colors_In_Image __attribute__((packed));
        unsigned long Important_Colors __attribute__((packed));

Next, I have a routine to identify how my bits per pixel a bmp file
is, and choose the appropriate routine.  This routine, works fine.
I changed all short's to unsigned short's in a last attempt to make my
code work.  As expected, it didn't do anything.

FILE *File_Handle;
unsigned char Display_BMP(unsigned short x, unsigned short y, char
       File_Handle = fopen(FileName, "r");
       fread(&BMP, 54, 1, File_Handle);
       if(BMP.Signature!= 0x4D42)
                return 0;
                case 4: BMP_16(x, y); break;
                case 8: BMP_256(x, y); break;
                case 24: BMP_16mil(x, y); break;

Now, here's the code for BMP_16mil.  I haven't written code for the 16
color and 256 color routines.  I have changed most of this code lots
of times, all with crappy, or only half way decent, results.
In another file, I have this struct:
struct Bitmap_Colors
        unsigned char R;
        unsigned char G;
        unsigned char B;
Basically, this stores bmp scanlines.  I chose 2048 just because it
will be more than enough bytes.  I don't have any code to check if the
length of a bmp file exceeds 2048, but right now, that's not

Oh, and while almost everybody goes by height and width, I'm going by
height and length.

Anyway, here's the code:

void BMP_16mil(unsigned short x, unsigned short y)
        short x2;
        unsigned long B_Length, X_Counter, Y_Counter, P_Length;
        P_Length = BMP.Length * 3;
        if((P_Length % 4) != 0) P_Length+= (4 - (P_Length % 4));
        fseek(File_Handle, BMP.Image_Offset, SEEK_SET);
        for(Y_Counter = BMP.Height, y+= Y_Counter; Y_Counter > 0;
Y_Counter--, y--)
                fread(&BC, P_Length, 1, File_Handle);
                for(X_Counter = 0, x2 = x; X_Counter < BMP.Length;
X_Counter++, x2++)
                        Plot13(x2, y, BC[X_Counter].B / 51,
BC[X_Counter].G / 51,  BC[X_Counter].R / 51);

And, that's it.  Thanks in advance for your help.

- Raw text -

  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019