Mail Archives: djgpp/1999/07/13/05:23:31
Pavlos a écrit:
> >I know how to load a BMP file but no the palette, so it's ugly...
> >if someone could mail me a DJGPP source...it would help me a lot.
> >
> I don't have any source to send you (except Allegro's sources) so here's a
> tip:
>
> For palette BMP files, the palette follows the header of the file. For 8 bit
> files, the palette's size is 1024 bytes.
> Each 4 byte set represents one palette entry (R, G, B, 0). The 4th byte is
> always 0, ignore it. Also note that
> the values stored in the palette of a BMP file are 0-255, not 0-63, so you
> have to convert them yourself before setting the palette.
>
> I think this is how I did it a long time ago. I hope I remember it ok.
> Pavlos
Tanks for your help, since my last message i have found how to load the palette,
for those
who are interrested , here's the complete source code for a 256 color (8bits)
320*200 picture using djgpp 2.0
if someone could explain me why did this :
for(y=4;y>b->width%4;y--) fgetc(fp); is needed if the picture weight can't be
divide by 4 ???
that's the only thing i don't understand in this code.
Domi.
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#include <sys/nearptr.h>
#include <go32.h> /* for _dos_ds */
#include <string.h>
#define VIDEO_INT 0x10 /* the BIOS video interrupt. */
#define SET_MODE 0x00 /* BIOS func to set the video mode. */
#define VGA_256_COLOR_MODE 0x13 /* use to set 256-color mode. */
#define TEXT_MODE 0x03 /* use to set 80x25 text mode. */
#define SCREEN_WIDTH 320 /* width in pixels of mode 0x13 */
#define SCREEN_HEIGHT 200 /* height in pixels of mode 0x13 */
#define NUM_COLORS 256 /* number of colors in mode 0x13 */
#define RGB_RESET 0x03C6
#define RGB_READ 0x03C7
#define RGB_WRITE 0x03C8
#define RGB_DATA 0x03C9
/* macro to skip bytes in a file */
#define fskip(fp,n) \
{ \
int i; \
\
for (i=0;i<n;i++) \
fgetc(fp); \
}
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
/* this points to video memory. */
char *VGA = (char *)0xa0000;
char palette[768];
FILE *fp;
typedef struct tagBITMAP /* the structure for a bitmap. */
{
unsigned int width;
unsigned int height;
byte *data;
} BITMAP;
/**************************************************************************
* set_mode *
* Sets the video mode. *
**************************************************************************/
void set_mode(byte mode)
{
union REGS regs;
regs.h.ah = SET_MODE;
regs.h.al = mode;
int86(VIDEO_INT, ®s, ®s);
}
/**************************************************************************
* read_bmp_palette *
* lit la palette *
**************************************************************************/
void read_bmp_palette(void)
{
register int i;
for(i=0;i<256;i++) {
palette[i*3+2]=getc(fp)>>2;
palette[i*3+1]=getc(fp)>>2;
palette[i*3+0]=getc(fp)>>2;
getc(fp);
}
}
/**************************************************************************
* write_bmp_palette *
* ecrit la palette *
**************************************************************************/
void write_bmp_palette(void)
{
register int i;
outp(RGB_RESET, 0xFF); // Prepare the VGA card
outp(RGB_WRITE, 0); // Tell that we'll write all the palette
for(i=0;i<256;i++) {
outp(RGB_DATA, palette[i*3]); // Red
outp(RGB_DATA, palette[i*3+1]); // Green
outp(RGB_DATA, palette[i*3+2]); // Blue
}
}
/**************************************************************************
* load_bmp *
* Loads a bitmap file into memory. *
**************************************************************************/
void load_bmp(char *file,BITMAP *b)
{
long index;
int x,y;
int image_capacite;
/* open the file */
if ((fp = fopen(file,"rb")) == NULL)
{
printf("Error opening file %s.\n",file);
exit(1);
}
/* check to see if it is a valid bitmap file */
if (fgetc(fp)!='B' || fgetc(fp)!='M')
{
fclose(fp);
printf("%s is not a bitmap file.\n",file);
exit(1);
}
fskip(fp,16);
fread(&b->width, sizeof(unsigned int), 1, fp);
fread(&b->height,sizeof(unsigned int), 1, fp);
fskip(fp,28);
read_bmp_palette();
/* try to allocate memory */
image_capacite=b->width*b->height;
if ((b->data = (byte *) malloc((word)(image_capacite))) == NULL)
{
fclose(fp);
printf("Erreur de memoire pour le fichier %s.\n",file);
exit(1);
}
/* read the bitmap */
for(index=(b->height-1)*b->width;index>=0;index-=b->width)
{
for(x=0;x<b->width;x++)
b->data[(word)index+x]=(byte)fgetc(fp);
if (b->width%4 != 0){
for(y=4;y>b->width%4;y--) fgetc(fp);
}
}
fclose(fp);
}
/**************************************************************************
* draw_bitmap *
* Draws a bitmap. *
**************************************************************************/
void draw_bitmap(BITMAP *bmp,int x,int y)
{
int j;
word screen_offset = (y<<8)+(y<<6)+x;
word bitmap_offset = 0;
for(j=0;j<bmp->height;j++)
{
memcpy(&VGA[screen_offset],&bmp->data[bitmap_offset],bmp->width);
bitmap_offset+=bmp->width; /* ligne suivante de l'image */
screen_offset+=SCREEN_WIDTH; /* passe a la ligne suivante de l'ecran */
}
}
/**************************************************************************
* Main *
* Draws bitmaps *
**************************************************************************/
int main()
{
int i,x,y;
BITMAP bmp;
register int r;
load_bmp("m.bmp",&bmp); /* open the file */
/* disable all memory protection */
__djgpp_nearptr_enable();
VGA += __djgpp_conventional_base;
set_mode(VGA_256_COLOR_MODE); /* set the video mode. */
write_bmp_palette();
draw_bitmap(&bmp,120,100);
getch();
free(bmp.data); /* free up memory used */
set_mode(TEXT_MODE); /* set the video mode back to
text mode. */
/* reenable memory protection */
__djgpp_nearptr_disable();
}
- Raw text -