Loading TGA picture

Started by
3 comments, last by epsylon 15 years, 12 months ago
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;
		fclose(inputfile);
	} else returncode = RNOFILE;
        return (returncode==RDONE)?0:1;
}
[...]
Thanks in advice!
Advertisement
Are you sure your reading the TGA spec right? Try x-referencing with another source using the web. You must be mis-interpreting the header.
unfortunately, I'm "sure" about TGA specs :(
(look here: http://local.wasp.uwa.edu.au/~pbourke/dataformats/tga/ or here: http://www.dca.fee.unicamp.br/%7Emartino/disciplinas/ea978/tgaffs.pdf)
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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

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.

This topic is closed to new replies.

Advertisement