Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

kainjow

Moderator emeritus
Original poster
Jun 15, 2000
7,958
7
I'm trying to convert an MFC app (iPodWizard) to Cocoa, and am having some problems. The program reads in images and other resources from the iPod's firmware.

I am going slowly, making sure everything works piece by piece, but am running into a problem that I can't seem to figure out.

I've got a class that loads the firmware, and then inside this class it loads all the images from the firmware. I'm debugging piece by piece on my PC and Mac but this code just isn't working like it should on the PC:

I've kept all the Windows types in for simplicity.
Code:
// windows types
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;

typedef BYTE *LPBYTE;
typedef WORD *LPWORD;
typedef DWORD *LPDWORD;

// ipod image struct
typedef struct
{
	BYTE b1[8];
	DWORD height;
	DWORD width;
	WORD w1;
	WORD bitDepth;
	DWORD d2;
	DWORD blockLen;
} IPOD_PICTURE_HEADER;

Here's where it starts. After this is done, cc = 2 on the Mac, and on the equivalent PC code, it's 35.
Code:
- (void)scanFirmware
{
	DWORD i;
	
	int cc = 0;
	PWXPicture *pic;
	for (i = 0; i < m_BufferSize; i+= 4)
	{
		if (pic = [PWXPicture pictureWithData:&m_Buffer[i] scan:TRUE])
		{
			[m_Pictures addObject:pic];
			i += 4;
			cc++;
		}
	}
}

Code:
- (BOOL)read:(LPBYTE)lpBuffer scan:(BOOL)bScan
{
	if (lpBuffer == NULL)
		return FALSE;
	
	m_pHeader = (IPOD_PICTURE_HEADER *)lpBuffer;
	if (m_pHeader == NULL)
		return FALSE;
	
	// swap bytes
	m_pHeader->height = CFSwapInt32LittleToHost(m_pHeader->height);
	m_pHeader->width = CFSwapInt32LittleToHost(m_pHeader->width);
	m_pHeader->w1 = CFSwapInt16LittleToHost(m_pHeader->w1);
	m_pHeader->bitDepth = CFSwapInt16LittleToHost(m_pHeader->bitDepth);
	m_pHeader->d2 = CFSwapInt32LittleToHost(m_pHeader->d2);
	m_pHeader->blockLen = CFSwapInt32LittleToHost(m_pHeader->blockLen);
	
	// validity checks
	if ((bScan && m_pHeader->d2 != 0) || m_pHeader->width > 511 || m_pHeader->height > 511 ||
		m_pHeader->width == 0 || m_pHeader->height == 0 ||
		m_pHeader->blockLen < (m_pHeader->height * m_pHeader->width * m_pHeader->bitDepth / 8) ||
		(m_pHeader->bitDepth != 1 && m_pHeader->bitDepth != 2 &&
		 m_pHeader->bitDepth != 4 && m_pHeader->bitDepth != 16))
	{
		// bad image
		m_pHeader = NULL;
		return FALSE;
	}
	
	m_pData = lpBuffer + sizeof(IPOD_PICTURE_HEADER);
	
	return TRUE;
}

The problem I've noticed in the debugger is that m_pHeader is almost always null, yet lpBuffer is the same as it is on Windows (I'm testing with the exact same firmware file - which I've confirmed is the exact same length on both computers).

I don't get why it would be null. lpBuffer is always huge, and so shouldn't typecasting it to a IPOD_PICTURE_HEADER struct only take the first X bytes, where X = sizeof(IPOD_PICTURE_HEADER) ?

So basically the problem is somewhere in the read: method. Anyone see anything wrong in there? My strenghts aren't in C, although I know how to get around, but sometimes pointer typecasting stuff confuses me.
 

kainjow

Moderator emeritus
Original poster
Jun 15, 2000
7,958
7
OK so I figured out part of my problem. However, here's the real problem:

I found out that during that loop, when comparing the values of the IPOD_PICTURE_HEADER struct on each loop pass on both Mac and PC, the values aren't always the same. The first time they are, than the 2nd time some are different, and the third time some others are different.. and so forth. However, when I manually set i to a value that works on the PC, it works on my Mac.

Soooo... something's screwy with that type casting I think. Not sure why but I feel like it's not working... and I may have to go another route to grab those 28 bytes needed for that struct... hmm

(ok probably anyone reading this has no clue what's going on, but whatever... ;) )
 

kainjow

Moderator emeritus
Original poster
Jun 15, 2000
7,958
7
SWEET so my idea worked!!

Here's the new code I'm now using:
Code:
data = [NSData dataWithBytes:m_Buffer length:m_BufferSize];

...

PWXPicture *pic = nil;
for (i = 0; i < m_BufferSize; i+= 4)
{
	BYTE buf[28];
	[data getBytes:buf range:NSMakeRange(i, 28)];
	pic = [PWXPicture pictureWithData:buf scan:TRUE];
	if (pic != nil)
	{
		[m_Pictures addObject:pic];
		i += 4;
	}
}
Soo somehow that typecasting isn't working. Anyone have any ideas why? It seems like that is more efficient method, but maybe not.
 

stunna

macrumors member
Dec 27, 2005
83
0
This is pretty cool lookin at how your code works
What type of experience do you have, just curious
 

kainjow

Moderator emeritus
Original poster
Jun 15, 2000
7,958
7
stunna said:
This is pretty cool lookin at how your code works
What type of experience do you have, just curious
I pretty much dropped that project (porting iPodWizard to OS X) because the code is so heavily based on MFC it's a huge pain to work with, and it's also written for x86, and at the time I was working on a G5. So I pretty much would have to had to make major changes for it to work on PPC.

But anyways, what do you mean by experiences? Programming?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.