Archived

This topic is now archived and is closed to further replies.

lejno

Raw image file format

Recommended Posts

lejno    122
I''m trying to find out a way to display raw images on the screen... I''ve made my own raw graphics format, the game will use 256 colors (1 byte per pixel), so it''s possible for me to store each pixel in one byte, the value of the byte describes a color, eg 132 = color number 132! GRAPHICS FORMAT (RAW 1 byte per pixel): --------------------- HEADER: 4 bytes (two integer values, first: width, second: height) PIXDATA: (width * height) bytes My problem is due to lack of experience on the subject, I want to load each raw data image into memory as soon as my program (game) starts, and then be able to acces it from the game... If anyone can give me a piece if code or a tutorial on the subject I would be grateful (I code in C++)...

Share this post


Link to post
Share on other sites
lejno    122
I know how to do that, I also know that the data I load should be loaded in binary format...
But wich data type should be the one that gets the data in the program, 1 unsigned char = 1 byte?
is there anyway to load all the data into different vektors, in a simple and elegant way, is use of pointers the best way to go, how should I interface with the loaded data from within the program?
That''s the type of things I would like to know...


Share this post


Link to post
Share on other sites
coelurus    259
Do something like this:


  
typedef unsigned char byte;
typedef unsigned short word;

/* Simple structure for your format */
typedef struct {
word width, height;
byte *data;
} Image;

/* Node for linked list */

typedef struct ImageListNode {
Image image;
ImageListNode *next;
} ImageList;

ImageList *imageList;


For each image you load, add a node into the linked list. You could also add some ID-tag on each image for searching.

Share this post


Link to post
Share on other sites
Ready4Dis    180


  
//Since you didn''t say what compiler I''m going to show you in standard C.


struct Image_S
{
short width, height;
unsigned long TotalBytes;
unsigned char *Data;
};

/* Returns:
0 = success
1 = File Not Found
2 = Not enough memory
*/

char Load_Image(char *fName, struct Image_S *Img)
{
FILE *in;
if (Img->Data) //Is something loaded already?

free(Img->Data); //Yup, lets free it!

in = fopen(fName,"rb"); //open for reading!

if (!in) //Is it open?

{
return 1; //File not found!

}
Img->width = getw(in);
Img->height = getw(in);
Img->TotalBytes = Img->width * Img->height;
Img->Data = (unsigned char*)malloc(Img->TotalBytes);
if (!Img->Data) //Did we get memory?

{
fclose(in); //Close our file

return 2; //Not enough memory

}
fread(Img->Data,1,Img->TotalBytes,in); //Read our file into our buffer!

fclose(in);
return 0; //Success!!

}

void Kill_Image(struct Image_S *Img)
{
if (Img->Data)
free(Img->Data);
Img->Data = 0; //Set it to null!

}

//now you use it like this


struct Image_S Image = {0,0,0}; //Initialize to 0!

char Ret;

Ret = Load_Image("Test.raw",&Image);
if (Ret)
{
//Failed!!!

return -1;
}

Kill_Image(&Image);



Of course you can put this into a class, or into a linked list, or a vector, or whatever you''d like. You can replace the malloc/free with new/delete, or whatever you''d like :D

Billy - BillyB@mrsnj.com
(Hey, I''''m no longer anonymous!)

Share this post


Link to post
Share on other sites
torquel    122
You could also just have a small primitive structure that has R, G, and B values to make up the color you want. Then maybe have a header for your image file that tells it the dimensions of the image and such. I have some old pascal code of this if you''d like to take a look at it, I did it back in 98.

Share this post


Link to post
Share on other sites
lejno    122
quote:
Original post by torquel
"I have some old pascal code of this if you''d like to take a look at it"
-----
Yes that''d be nice, torquel, please send it to this email adress:
1te01b_anle@tjelvar.org






Share this post


Link to post
Share on other sites
lejno    122
Hello, thanks for all the examples, I''ve been looking at your code and it looks great...
I decided to have all the images stored in one single file instead with the format:

WIDTH 1Byte
HEIGHT 1Byte
PIX_DATA XBytes

Here is my version of the code to load the images:
(I haven''t tried it yet, I hope just pray it will compile well)

typedef unsigned char byte;

byte numberOfImages;

typedef struct
{
byte imageWidth;
byte imageHeight;
byte imagePixels[imageWidth * imageHeigh];
}image;

void loadImages(void)
{
ifstream imageFile("test.dat", ios::binary);

imageFile.read((char *)&numberOfImages, sizeof(byte));

image images[numberOfImages];

while(currentImage <= numberOfImages)
{
imageFile.read((char *)&images[currentImage].imageWidth, sizeof(byte));
imageFile.read((char *)&images[currentImage].imageHeight, sizeof(byte));

imageFile.read((char *)&images[currentImage].imagePixels, sizeof(images[currentImage].imagePixels));

currentImage++;
}

imageFile.close();
}

I''m very fresh on C++ but this code seems all right to me...
My question is:
How do I prevent the hole lot of image data (the variable: images)
to be deleted when the function loadImages has executed, should I make it a pointer or what...

If you see anything else that is wrong with the code or just have any tips on how to improve it in general, please tell me...
(1te01b_anle@tjelvar.org or here in the forum)

Share this post


Link to post
Share on other sites
remi    150
lejno,
since u're working in the 256-color mode, u should not forget to take care of the PALETTE


[edited by - remi on May 1, 2002 7:28:24 AM]

Share this post


Link to post
Share on other sites
lejno    122
quote:
Original post by remi
lejno,
since u''re working in the 256-color mode, u should not forget to take care of the PALETTE


[edited by - remi on May 1, 2002 7:28:24 AM]


The palette is already allright to me I guess, there are 256 colors (0-255) and one can vary in that specific range, but I would like to know how I create a palette, I am currently using DOS interrupts to set the video mode i''ve made the following functions myself:

setVideoMode(modeNum) //I use 19 for graph and 3 for text
putPixel(x,y,color)
getPixel(x,y) //returns color

Im kind of prowd over those functions , after all that''s all I have so far to be prowd over as I have not got anything else to work...

Share this post


Link to post
Share on other sites
Ready4Dis    180
Haha, you said mode 19... aka, 13h. (most people refer to the standard 320x200x8 vga mode as mode 13h or 13 hex). What compiler are you using by the way?

To use the palette:


  
void SetSingleEntry(unsigned char Index, unsigned char R, unsigned char G, unsigned char B)
{
outportb(0x3c8,Index);
outportb(0x3c9,R);
outportb(0x3c9,G);
outportb(0x3c9,B);
}


Also, the RGB values are in the range of 0->63 (6 bits). You can simply take a value of 8 bits (0->255) and shift right 2 (or divide by 4)


  
void SetSingleEntry8Bit(unsigned char Index, unsigned char R, unsigned char G, unsigned char B)
{
outportb(0x3c8,Index);
outportb(0x3c9,R>>2);
outportb(0x3c9,G>>2);
outportb(0x3c9,B>>2);
}


You can do fading effects like this to (you can even read in the pallete using inportb:


  
void GetSingleEntry(unsigned char Index, unsigned char &R, unsigned char &G, unsigned char &B)
{
outportb(0x3c8,Index);
inportb(0x3c9,R);
inportb(0x3c9,G);
inportb(0x3c9,B);
}


Or the 8-bit version!


  
void GetSingleEntry8Bit(unsigned char Index, unsigned char &R, unsigned char &G, unsigned char &B)
{
outportb(0x3c8,Index);
inportb(0x3c9,R);
inportb(0x3c9,G);
inportb(0x3c9,B);
R<<=2;
G<<=2;
B<<=2;
}



Hope this helps :D

Billy - BillyB@mrsnj.com
(Hey, I''''m no longer anonymous!)

Share this post


Link to post
Share on other sites
Ready4Dis    180
Oh, and also.. you should use a back-buffer, and memcopy it to the screen buffer, it''s faster than reading/writing to the actual screen, and helps eliminate the tears/rips int he screen. Also, you could wait for vertical refresh to limit the speed, and to eliminate the tears completely (this code works under Turbo C/C++ 3.0 for Dos):


  
unsigned char far *screen_ptr = (unsigned char far*)0xa0000000l;
unsigned char far virt[64000]; //Our back-buffer


struct Sprite_S
{
unsigned short width, height;
//an unsigned char far would probably be better for this.

unsigned char *Data;
};

Sprite_S *Sprites;
unsigend char NumSprites;

char LoadImages(char *fName)
{
FILE *in;
unsigned char ctr;
in = fopen(fName,"rb");
if (!in)
{
return 1; //File not found!

}
NumSprites = getc(in);
Sprites = new Sprite_S[NumSprites];
for (ctr=0;ctr!=NumSprites;++ctr)
{
fread(&Sprites[ctr],2,2,in); //read in width/height

Sprites[ctr].Data = new unsigned char[Sprites[ctr].width*Sprites[ctr].height];
fread(Sprites[ctr].Data,Sprites[ctr].width,Sprites[ctr].height,in); //read in our data!

}
fclose(in);
}

void KillImages(void)
{
unsigned char ctr;
for (ctr=0;ctr!=NumSprites;++ctr)
delete Sprites[ctr].Data; //Free each sprites data!

delete Sprites; //Delete our sprite array!

}

void putPixel(short x, short y, unsigned char col)
{
unsigned long Off=(y<<6)+(y<<8)+x;
virt[Off]=col;
}

unsigned char getPixel(short x, short y)
{
unsigned long Off=(y<<6)+(y<<8)+x;
return virt[Off];
}

void SetMode(short mode)
{
asm mov ax, mode;
asm int 0x10;
}

main(void)
{
unsigned char key;
unsigned char done=0;
if (LoadImages("Test.raw")) //Load images

{
printf("Error loading images!"); //Oops, failed for some reason!

return -1;
}
SetMode(0x13); //Same thing as 19

while (!done)
{
if (kbhit()) //check if there was a key hit!

{
key = getch(); //get the key hit!

if (key==27) //Escape pressed?

{
done=1;
}
/*
Check for other keys here.
I don''t ussually use kbhit & getch, but my own custom keyboard handling routine (via my own interrupt 0x9 handler).
*/
}
/*
Draw stuff here!
*/

while (!(inportb(0x3da) & 0x8));
_fmemcpy(screen,virt,64000); //copy our buffer to our screen!

_fmemset(virt,0,64000); //erase the screen to color 0

}
SetMode(0x3);
KillImages();
return 0;
}


Of course a bit more error checking is in need, and this was all typed up in this window, so possibly a gramatical error or 2, and something overlooked, but it should give you a good idea on what I''m talking about :D

Billy - BillyB@mrsnj.com
(Hey, I''''m no longer anonymous!)

Share this post


Link to post
Share on other sites