Problem puzzle me. Reading Tga file and caculate data size..

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Seagaetcm
Posts: 10
Joined: Sat Jun 30, 2007 2:09 pm
Location: Peking, China

Problem puzzle me. Reading Tga file and caculate data size..

Post by Seagaetcm »

I wrote code to read tge files. the code like that:

Code: Select all

#pack(1)
struct TgaFileHead
{
    ... // some value define
    short w;
    short h;
  ... // some value define
}
#pack()
// sizeof(TgaFileHead) = 18

// in function:
int DataSize = 0;
TgaFileHead Head;
fread(&f, 18, 1, file);  // read structure succeed. w is 256 and h is 256
DataSize = Head.w * Head.h;

But the result of DataSize is zero. I have no idea for that. Please help!!!
btw:sorry for my terrible english.
be2003
Posts: 144
Joined: Thu Apr 20, 2006 2:46 pm

Post by be2003 »

idk... i must be really out of it right now.
but it seems to me that you are reading into a structure called "f" instead of "Head", which would be the appropriate structure. since you are not reading anything to "Head" then all of the values in "Head" are still zero
that is why it is returning zero... try this...

Code: Select all

int DataSize = 0;
TgaFileHead Head;
fread(&Head, sizeof(TgaFileHead), 1, file); //this is where your mistake was before
DataSize = Head.w * Head.h;
good luck!
- be2003
blog
Seagaetcm
Posts: 10
Joined: Sat Jun 30, 2007 2:09 pm
Location: Peking, China

Post by Seagaetcm »

Sorry, I make a mistake in the post. I do not copy the code from file, so the code in my program really is

Code: Select all

fread(&Head, sizeof(TgaFileHead), 1, file); 
I debug the Head value by GDB, it is correct. but the next line

Code: Select all

DataSize = Head.w * Head.h; 
...DataSize is zero.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

do you have

Code: Select all

typedef struct TgaFileHead ;

// if not then
/////// TgaFileHead Head ; 
// would need to be
struct TgaFileHead Head ; 
or maybe more of your code is needed to find bug ;)
10011011 00101010 11010111 10001001 10111010
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

Sure you haven't defined DataSize as short by mistake?

Jim
Seagaetcm
Posts: 10
Joined: Sat Jun 30, 2007 2:09 pm
Location: Peking, China

Post by Seagaetcm »

I had tested the code at VS2005, it is correct.
here it is the code:

Code: Select all

#pragma pack(1)
struct TGAHeader 
{
   char  idlength;
   char  colourmaptype;
   char  datatypecode;
   short int colourmaporigin;
   short int colourmaplength;
   char  colourmapdepth;
   short int x_origin;
   short int y_origin;
   short width;
   short height;
   char  bitsperpixel;
   char  imagedescriptor;
};
#pragma pack()

GLuint loadTGA(const char *filename, bool mipmaps)
{
	int size = 0;

	FILE *f = fopen(filename,"rb");
	if (f == NULL)
		return 0;

	TGAHeader h;
	fread(&h,18,1,f);
	if (h.datatypecode != 2) 
		return 0;

	size = h.width * h.height;

	GLint bppformat;
	GLint format;
	//int bypp = h.bitsperpixel / 8;
	if (h.bitsperpixel == 24) {
		size *= 3;
		format = GL_RGB;
		bppformat = GL_RGB8;
	} else if (h.bitsperpixel == 32) {
		size *= 4;
		format = GL_RGBA;
		bppformat = GL_RGBA8;
	} else return 0;

	unsigned char *buf = new unsigned char[size];
	fread(buf,size,1,f);
	fclose(f);

	GLuint t;
	glGenTextures(1,&t);
	glBindTexture(GL_TEXTURE_2D, t);

	if (mipmaps) {
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
		gluBuild2DMipmaps (GL_TEXTURE_2D, bppformat, h.width, h.height, format, GL_UNSIGNED_BYTE, buf);
	} else {
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 4, h.width, h.height, 0, format, GL_UNSIGNED_BYTE, buf);
	}
    delete[] buf;
	return t;
}
I compiled this code with devkitpro and pspgl.
thanks for help.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

GCC doesn't support the #pragma afaik. Hence you'd have to resolve to a #define that checks which compiler is used and pack your structures depending on that:

VS:

Code: Select all

#pragma pack(1)
struct TGAHeader
{
   char  idlength;
   char  colourmaptype;
   char  datatypecode;
   short int colourmaporigin;
   short int colourmaplength;
   char  colourmapdepth;
   short int x_origin;
   short int y_origin;
   short width;
   short height;
   char  bitsperpixel;
   char  imagedescriptor;
};
#pragma pack() 
GCC:

Code: Select all

struct __attribute__ ((__packed__)) TGAHeader
{
   char  idlength;
   char  colourmaptype;
   char  datatypecode;
   short int colourmaporigin;
   short int colourmaplength;
   char  colourmapdepth;
   short int x_origin;
   short int y_origin;
   short width;
   short height;
   char  bitsperpixel;
   char  imagedescriptor;
};
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
ufoz
Posts: 86
Joined: Thu Nov 10, 2005 2:36 am
Location: Tokyo
Contact:

Post by ufoz »

Something like this, I guess...

Code: Select all

#ifdef WIN32
#pragma pack&#40;push&#41;
#pragma pack&#40;1&#41;
#define __PACKED__
#else
#define __PACKED__ __attribute__&#40;&#40;packed&#41;&#41;
#endif
struct bitmap_header &#123;
	uint16 id;
	uint32 size;
	uint32 reserved;
	uint32 offset;
	uint32 headersize;
	uint32 width;
	uint32 height;
	uint16 planes;
	uint16 bpp;
	uint32 compression;
	uint32 imagesize;
	uint32 xdpi;
	uint32 ydpi;
	uint32 colors;
	uint32 important_colors;
&#125; __PACKED__;
#ifdef WIN32
#pragma pack&#40;pop&#41;
#endif
#undef __PACKED__
Seagaetcm
Posts: 10
Joined: Sat Jun 30, 2007 2:09 pm
Location: Peking, China

Post by Seagaetcm »

My gcc version is "psp-gcc (GCC) 4.1.2 devkitPSP release 11 (PSPDEV 20060507)"

I tried struct __attribute__ ((__packed__)) TGAHeader, the value is
(gdb) p h
$1 = {idlength = 0 '\0', colourmaptype = 0 '\0', datatypecode = 2 '\002',
colourmaporigin = 0, colourmaplength = 0, colourmapdepth = 0 '\0',
x_origin = 0, y_origin = 256, width = 256, height = 8224,
bitsperpixel = -1 '&#63733;', imagedescriptor = -1 '&#63733;'}

and #pragma pack(1) is really work, the value is
(gdb) p h
$1 = {idlength = 0 '\0', colourmaptype = 0 '\0', datatypecode = 2 '\002',
colourmaporigin = 0, colourmaplength = 0, colourmapdepth = 0 '\0',
x_origin = 0, y_origin = 0, width = 256, height = 256,
bitsperpixel = 32 ' ', imagedescriptor = 32 ' '}

I dont know why...
Seagaetcm
Posts: 10
Joined: Sat Jun 30, 2007 2:09 pm
Location: Peking, China

Post by Seagaetcm »

I think there it is not problem with data alignment. I modify code as it:

Code: Select all

unsigned char unCompressHeader&#91;12&#93; = &#123;0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0&#125;;
	unsigned char tgaHeader&#91;12&#93;;
	unsigned char header&#91;6&#93;;

	fread&#40; &tgaHeader, 1, sizeof&#40;tgaHeader&#41;, f &#41;;

	//read only uncompressed TGA's
	if&#40; memcmp&#40; unCompressHeader, tgaHeader, sizeof&#40;unCompressHeader&#41;&#41; != 0 &#41;
	&#123;
		fclose&#40; f &#41;;
		return false;
	&#125;

	// Read Image info
	fread&#40; header, 1, sizeof&#40;header&#41;, f &#41;;

	// Calculate and save the Width & Height of Image
	int iImageWidth  = header&#91;1&#93; * 256 + header&#91;0&#93;;
	int iImageHeight = header&#91;3&#93; * 256 + header&#91;2&#93;;

	unsigned int c = iImageWidth * iImageHeight;
iImageWidth and iImageHeight is 256, but the value c is still zero. I debug the code with gdb, step with asm. the last line asm code like this:
(gdb) info r

Code: Select all

          zero       at       v0       v1       a0       a1       a2       a3
 R0   00000000 0008ff00 00000100 00000100 09f3eb9a 09f3eb98 00000000 00000001
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   09f3eb98 089b2540 09f3eb94 089b253c 00000000 00000e00 08973508 00088600
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  089b0ae0 09f3ee44 00000001 09f3eef0 0000000d 00000013 deadbeef deadbeef
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  0000012f 0000013c 09f3ef00 00000000 089a8870 09f3eb68 09f3eb68 0892a324
            sr       lo       hi      bad    cause       pc
      60088613 00000000 00000009 00010004 10000024 0892a34c
           fsr      fir
      00000e00 00003351
the code:
319 unsigned int c = iImageWidth * iImageHeight;
1: x/i $pc 0x892a34c <_Z7loadTGAPKcb+300>: lw v1,8(s8)
1: x/i $pc 0x892a350 <_Z7loadTGAPKcb+304>: lw v0,4(s8)
1: x/i $pc 0x892a354 <_Z7loadTGAPKcb+308>: mult v1,v0
1: x/i $pc 0x892a358 <_Z7loadTGAPKcb+312>: mflo v0

after this step ,registers v0 changed:

(gdb) info r

Code: Select all

          zero       at       v0       v1       a0       a1       a2       a3
 R0   00000000 0008ff00 deadbeef 00000100 09f3eb9a 09f3eb98 00000000 00000001
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   09f3eb98 089b2540 09f3eb94 089b253c 00000000 00000e00 08973508 00088600
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  089b0ae0 09f3ee44 00000001 09f3eef0 0000000d 00000013 deadbeef deadbeef
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  0000012f 0000013c 09f3ef00 00000000 089a8870 09f3eb68 09f3eb68 0892a324
            sr       lo       hi      bad    cause       pc
      60088613 deadbeef deadbeef 00010004 10000024 0892a35c
           fsr      fir
      00000e00 00003351
the last line
1: x/i $pc 0x892a35c <_Z7loadTGAPKcb+316>: sw v0,0(s8)

save the v0 value 0xdeadbeef into c. I dont know "mflo v0" means what but this step cause c error.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

It moves the value from the lo register after the mul (which contain the lower 32bits of the multiplied value) into the destination register. So this doesn't make much sense.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Post Reply