I know I've already asked this on the Yahoo dev list, but, I thought there might be some people here who can help who aren't subscribed to the list - What can I say? I'm desperate
Anyway, following is some code that is meant to decode a PNG, the problem is, is returns with a Z_BUF_ERROR when I try to uncompress the data.
Can anyone spot any obvious mistakes?
Cheers,
-Toris
Anyway, following is some code that is meant to decode a PNG, the problem is, is returns with a Z_BUF_ERROR when I try to uncompress the data.
Can anyone spot any obvious mistakes?
Cheers,
-Toris
Code:
// Loads a PNG image into memory from the SMC
u16 C_LoadPNGImage(const char *Directory, const char *Filename, u16 *ImageStore)
{
F_HANDLE ImageFileHandle;
u32 AmountRead;
GpRelativePathSet(Directory);
if(GpFileOpen(Filename, OPEN_R, &ImageFileHandle) == SM_OK)
{
char FileTypeTest[8];
u32 ChunkSize;
u32 ChunkType;
u32 ChunkCRC;
u32 ImageWidth;
u32 ImageHeight;
u8 BitDepth;
u8 ColorType;
u8 CompressionMethod;
u8 FilterMethod;
u8 InterlaceMethod;
u8 *WorkingMem = 0;
u32 BufferSize = 0;
u16 FileParsed = false;
u32 TotalChunkSize = 0;
GpFileRead(ImageFileHandle, &FileTypeTest, 8, &AmountRead);
// if(FileTypeTest != ".PNG....") { return C_ERROR; }
while(FileParsed != true)
{
GpFileRead(ImageFileHandle, &ChunkSize, 4, &AmountRead);
ChunkSize = ((ChunkSize&0xFF000000)>>24)|((ChunkSize&0x00FF0000)>>8)|((ChunkSize&0x0000FF00)<<8)|((ChunkSize&0x000000FF)<<24);
GpFileRead(ImageFileHandle, &ChunkType, 4, &AmountRead);
if(ChunkType == 1380206665) // IHDR
{
GpFileSeek(ImageFileHandle, FROM_CURRENT, ChunkSize, NULL);
}
else if(ChunkType == 1163152464) // PLTE
{
return C_ERROR;
}
else if(ChunkType == 1413563465) // IDAT
{
TotalChunkSize += ChunkSize;
GpFileSeek(ImageFileHandle, FROM_CURRENT, ChunkSize, NULL);
}
else if(ChunkType == 1145980233) // IEND
{
FileParsed = true;
}
else // Any other chunk
{
GpFileSeek(ImageFileHandle, FROM_CURRENT, ChunkSize, NULL);
}
GpFileSeek(ImageFileHandle, FROM_CURRENT, 4, NULL);
}
FileParsed = false;
u8 *ChunkMem = (u8*)gm_malloc(TotalChunkSize);
if (ChunkMem == 0) { return C_ERROR_OUTMEM; }
u32 ChunkAmountRead = 0;
GpFileSeek(ImageFileHandle, FROM_BEGIN, 0, NULL);
GpFileRead(ImageFileHandle, &FileTypeTest, 8, &AmountRead);
// if(FileTypeTest != ".PNG....") { return C_ERROR; }
while(FileParsed != true)
{
GpFileRead(ImageFileHandle, &ChunkSize, 4, &AmountRead);
ChunkSize = ((ChunkSize&0xFF000000)>>24)|((ChunkSize&0x00FF0000)>>8)|((ChunkSize&0x0000FF00)<<8)|((ChunkSize&0x000000FF)<<24);
GpFileRead(ImageFileHandle, &ChunkType, 4, &AmountRead);
if(ChunkType == 1380206665) // IHDR
{
GpFileRead(ImageFileHandle, &ImageWidth, 4, &AmountRead);
ImageWidth = ((ImageWidth&0xFF000000)>>24)|((ImageWidth&0x00FF0000)>>8)|((ImageWidth&0x0000FF00)<<8)|((ImageWidth&0x000000FF)<<24);
GpFileRead(ImageFileHandle, &ImageHeight, 4, &AmountRead);
ImageHeight = ((ImageHeight&0xFF000000)>>24)|((ImageHeight&0x00FF0000)>>8)|((ImageHeight&0x0000FF00)<<8)|((ImageHeight&0x000000FF)<<24);
GpFileRead(ImageFileHandle, &BitDepth, 1, &AmountRead);
GpFileRead(ImageFileHandle, &ColorType, 1, &AmountRead);
GpFileRead(ImageFileHandle, &CompressionMethod, 1, &AmountRead);
GpFileRead(ImageFileHandle, &FilterMethod, 1, &AmountRead);
GpFileRead(ImageFileHandle, &InterlaceMethod, 1, &AmountRead);
if(BitDepth != 8) { return C_ERROR; }
if(ColorType != 2) { return C_ERROR; }
if(CompressionMethod != 0) { return C_ERROR; }
if(FilterMethod != 0) { return C_ERROR; }
if(InterlaceMethod != 0) { return C_ERROR; }
}
else if(ChunkType == 1163152464) // PLTE
{
return C_ERROR;
}
else if(ChunkType == 1413563465) // IDAT
{
if(ChunkSize > 0)
{
if(WorkingMem != 0)
{
u8 *ChunkMemAddress = ChunkMem+ChunkAmountRead;
GpFileRead(ImageFileHandle, ChunkMemAddress, ChunkSize, &AmountRead);
if(AmountRead != ChunkSize) { return C_ERROR; }
ChunkAmountRead += ChunkSize;
}
else { return C_ERROR; }
}
}
else if(ChunkType == 1145980233) // IEND
{
FileParsed = true;
}
else // Any other chunk
{
GpFileSeek(ImageFileHandle, FROM_CURRENT, ChunkSize, NULL);
}
GpFileRead(ImageFileHandle, &ChunkCRC, 4, &AmountRead);
}
WorkingMem = (u8*)gm_malloc((ImageWidth*ImageHeight*3)+ImageHeight);
BufferSize = (ImageWidth*ImageHeight*3)+ImageHeight;
if(WorkingMem == 0) { return C_ERROR; }
int UncompressResult = uncompress(WorkingMem, &BufferSize, ChunkMem, ChunkSize);
if(UncompressResult == Z_OK) { }
else if(UncompressResult == Z_BUF_ERROR) { return C_ERROR; }
else { return C_ERROR; }
u32 OffsetWorking = 0;
u32 OffsetImage = 0;
for(u16 iY=0; iY < ImageHeight; iY++)
{
OffsetWorking++;
for(u16 iX=0; iX < ImageWidth; iX++)
{
ImageStore[OffsetImage] = C_GetRGB(WorkingMem[OffsetWorking], WorkingMem[OffsetWorking+1], WorkingMem[OffsetWorking+2]);
OffsetWorking += 3;
OffsetImage += 1;
}
}
gm_free(WorkingMem);
}
else
{
return C_ERROR;
}
GpFileClose(ImageFileHandle);
return C_OK;
}