fixed #638, add support for pvr ccz format. I've tested it on both ios & android, also with instrument memleak detection. But haven't tested on win32 & marmalde, in thoery it will work.

This commit is contained in:
Walzer 2011-08-16 11:56:17 +08:00
parent 7e4f44e9ff
commit 3afe6ebfb2
5 changed files with 91 additions and 104 deletions

View File

@ -165,4 +165,20 @@ Converts a rect in points to pixels
#endif
/**
Helper marcos which converts 4-byte little/big endian
integral number to the machine native number representation
It should work same as apples CFSwapInt32LittleToHost(..)
*/
/// when define returns true it means that our architecture uses big endian
#define CC_HOST_IS_BIG_ENDIAN (bool)(*(unsigned short *)"\0\xff" < 0x100)
#define CC_SWAP32(i) ((i & 0x000000ff) << 24 | (i & 0x0000ff00 << 8) | (i & 0x00ff0000) >> 8 | (i & 0xff000000) >> 24)
#define CC_SWAP16(i) ((i & 0x00ff) << 8 | (i &0xff00) >> 8)
#define CC_SWAP_INT32_LITTLE_TO_HOST(i) ((CC_HOST_IS_BIG_ENDIAN == true)? CC_SWAP32(i) : (i) )
#define CC_SWAP_INT16_LITTLE_TO_HOST(i) ((CC_HOST_IS_BIG_ENDIAN == true)? CC_SWAP16(i) : (i) )
#define CC_SWAP_INT32_BIG_TO_HOST(i) ((CC_HOST_IS_BIG_ENDIAN == true)? (i) : CC_SWAP32(i) )
#define CC_SWAP_INT16_BIG_TO_HOST(i) ((CC_HOST_IS_BIG_ENDIAN == true)? (i): CC_SWAP16(i) )
#endif // __CCMACROS_H__

View File

@ -27,6 +27,7 @@ THE SOFTWARE.
#include "ZipUtils.h"
#include "ccMacros.h"
#include "CCFileUtils.h"
namespace cocos2d
{
@ -209,75 +210,75 @@ namespace cocos2d
int ZipUtils::ccInflateCCZFile(const char *path, unsigned char **out)
{
///@todo implement CFSwapInt16BigToHost CFSwapInt32BigToHost
return -1;
assert( out );
assert( &*out );
// load file into memory
unsigned char *compressed = NULL;
int fileLen = 0;
compressed = CCFileUtils::getFileData(path, "rb", (unsigned long *)(&fileLen));
// int fileLen = CCFileUtils::ccLoadFileIntoMemory( path, &compressed );
// assert( out );
// assert( &*out );
//
// // load file into memory
// unsigned char *compressed = NULL;
// int fileLen = ccLoadFileIntoMemory( path, &compressed );
// if( fileLen < 0 )
// {
// CCLOG("cocos2d: Error loading CCZ compressed file");
// }
//
// struct CCZHeader *header = (struct CCZHeader*) compressed;
//
// // verify header
// if( header->sig[0] != 'C' || header->sig[1] != 'C' || header->sig[2] != 'Z' || header->sig[3] != '!' )
// {
// CCLOG("cocos2d: Invalid CCZ file");
// free(compressed);
// return -1;
// }
//
// // verify header version
//
// unsigned int version = CFSwapInt16BigToHost( header->version );
// if( version > 2 )
// {
// CCLOG("cocos2d: Unsupported CCZ header format");
// free(compressed);
// return -1;
// }
//
// // verify compression format
// if( CFSwapInt16BigToHost(header->compression_type) != CCZ_COMPRESSION_ZLIB )
// {
// CCLOG("cocos2d: CCZ Unsupported compression method");
// free(compressed);
// return -1;
// }
//
// uint32_t len = CFSwapInt32BigToHost( header->len );
//
// *out = malloc( len );
// if(! *out )
// {
// CCLOG("cocos2d: CCZ: Failed to allocate memory for texture");
// free(compressed);
// return -1;
// }
//
//
// uLongf destlen = len;
// uLongf source = (uLongf) compressed + sizeof(*header);
// int ret = uncompress(*out, &destlen, (Bytef*)source, fileLen - sizeof(*header) );
//
// free( compressed );
//
// if( ret != Z_OK )
// {
// CCLOG("cocos2d: CCZ: Failed to uncompress data");
// free( *out );
// *out = NULL;
// return -1;
// }
//
//
// return len;
if( fileLen < 0 )
{
CCLOG("cocos2d: Error loading CCZ compressed file");
return -1;
}
struct CCZHeader *header = (struct CCZHeader*) compressed;
// verify header
if( header->sig[0] != 'C' || header->sig[1] != 'C' || header->sig[2] != 'Z' || header->sig[3] != '!' )
{
CCLOG("cocos2d: Invalid CCZ file");
delete [] compressed;
return -1;
}
// verify header version
unsigned int version = CC_SWAP_INT16_BIG_TO_HOST( header->version );
if( version > 2 )
{
CCLOG("cocos2d: Unsupported CCZ header format");
delete [] compressed;
return -1;
}
// verify compression format
if( CC_SWAP_INT16_BIG_TO_HOST(header->compression_type) != CCZ_COMPRESSION_ZLIB )
{
CCLOG("cocos2d: CCZ Unsupported compression method");
delete [] compressed;
return -1;
}
unsigned int len = CC_SWAP_INT32_BIG_TO_HOST( header->len );
*out = (unsigned char*)malloc( len );
if(! *out )
{
CCLOG("cocos2d: CCZ: Failed to allocate memory for texture");
delete [] compressed;
return -1;
}
unsigned long destlen = len;
unsigned long source = (unsigned long) compressed + sizeof(*header);
int ret = uncompress(*out, &destlen, (Bytef*)source, fileLen - sizeof(*header) );
delete [] compressed;
if( ret != Z_OK )
{
CCLOG("cocos2d: CCZ: Failed to uncompress data");
free( *out );
*out = NULL;
return -1;
}
return len;
}
} // end of namespace cocos2d

View File

@ -38,36 +38,6 @@ THE SOFTWARE.
namespace cocos2d {
/*
When define returns true it means that our architecture
uses big endiant
NOTE: this should be placed somewhere in macros
*/
#define CC_HOST_IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100)
/*
Helper function which converts 4-byte little endian
integral number to the machine native number representation
It should work same as apples CFSwapInt32LittleToHost(..)
*/
static unsigned int CCSwapInt32LittleToHost(unsigned int i)
{
/*
When architecture is big endian (ARM) reorder bytes
otherwise return same numbeer
*/
if (CC_HOST_IS_BIG_ENDIAN == true)
{
return ((i&0xff)<<24) + ((i&0xff00)<<8) + ((i&0xff0000)>>8) + ((i>>24)&0xff);
}
else
{
return i;
}
}
#define PVR_TEXTURE_FLAG_TYPE_MASK 0xff
#define PVR_TEXTURE_FLAG_FLIPPED_MASK 0x10000
@ -243,7 +213,7 @@ bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
header = (PVRTexHeader *)data;
//Make sure that tag is in correct formatting
pvrTag = CCSwapInt32LittleToHost(header->pvrTag);
pvrTag = CC_SWAP_INT32_LITTLE_TO_HOST(header->pvrTag);
/*
Check that given data really represents pvrtexture
@ -264,7 +234,7 @@ bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
CCConfiguration *configuration = CCConfiguration::sharedConfiguration();
//Get file flags (in correct byte order)
flags = CCSwapInt32LittleToHost(header->flags);
flags = CC_SWAP_INT32_LITTLE_TO_HOST(header->flags);
//Trim to only bites which are needed. Resulting flag is image format
formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
@ -304,17 +274,17 @@ bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
m_uNumberOfMipmaps = 0;
//Get size of maimap
m_uWidth = width = CCSwapInt32LittleToHost(header->width);
m_uHeight = height = CCSwapInt32LittleToHost(header->height);
m_uWidth = width = CC_SWAP_INT32_LITTLE_TO_HOST(header->width);
m_uHeight = height = CC_SWAP_INT32_LITTLE_TO_HOST(header->height);
//Do we use alpha ?
if (CCSwapInt32LittleToHost(header->bitmaskAlpha))
if (CC_SWAP_INT32_LITTLE_TO_HOST(header->bitmaskAlpha))
m_bHasAlpha = true;
else
m_bHasAlpha = false;
//Get ptr to where data starts..
dataLength = CCSwapInt32LittleToHost(header->dataLength);
dataLength = CC_SWAP_INT32_LITTLE_TO_HOST(header->dataLength);
//Move by size of header
bytes = ((unsigned char *)data) + sizeof(PVRTexHeader);