Sign in to follow this  

Loading TGA picture

Recommended Posts

Hello! I'm here with a question about targa pictures for you experts ;) ! I'm building a 3D engine using openGL basics routines (just wasting my time ) but I've got a problem with my ctarga class: in fact, loading the targa's header, the width and the height fields (with a 640x480 image) get negative values. I've tried to put them into unsigned short, but the values jump from 20000 to 50000 :( This is my code!
// from etarga.h
typedef struct eeTGAheader {
	char headersize, colortype, imagetype;
	short colorindex, colorlength;
	char colorbits;
	unsigned short xorigin, yorigin, width, height;
	char bpp, description;
} eeTGAheader;

// from etarga.cpp
int ctarga::initialize (const char *filename) {
	FILE *inputfile = fopen(filename, "rb");
	unsigned char backup;
	unsigned int total = 0, index;
	int bppmode = 0;
	eeTGAresult returncode = RDONE;
	if (inputfile) {
		if (fread(&header, 1, sizeof(eeTGAheader), inputfile) >= sizeof(eeTGAheader)) {
			if ((header.imagetype == 2) || (header.imagetype == 3)) {
				bppmode = (header.bpp/8);
				total = (header.height * header.width * bppmode);
				if (datablock) { free(datablock); datablock = NULL; }
				if (datablock = (unsigned char *) malloc (total)) {
					if (header.headersize > 0) fseek(inputfile, SEEK_CUR, header.headersize);
					fread(datablock, total, 1, inputfile);
					if (bppmode >= 3) {
						for (index = 0; index < total; index += bppmode) {
							backup = datablock[index];
							datablock[index] = datablock[index+2];
							datablock[index+2] = backup;
				} else returncode = RNOSPACE;
			} else returncode = RRLE;
		} else returncode = RBROKEN;
	} else returncode = RNOFILE;
        return (returncode==RDONE)?0:1;
Thanks in advice!

Share this post

Link to post
Share on other sites
If you are getting negative numbers, perhaps the fields are unsigned? the char type is signed by default on many platforms, so use unsigned char instead.

Also have you checked the endianess of the file? You may need to byte-swap the header.

Share this post

Link to post
Share on other sites
Doing binary read / writes is highly system / compiler dependant and thus dangerous : the struct might have padding bytes, and endianness might be wrong. Read the header byte by byte, and assign the corresponding bytes to the values in your struct accordingly. You can also disable alignment for the structure using a compiler directive, but you'd probably still have the endianness issue.
Make sure that the sizes of your types DO match the number of bytes in the file, if your unsigned short happened to be 4 bytes long, you'd be screwed if you tried a direct fread.
So the most portable solution is still to do it byte per byte.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this