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 #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__ #endif // __CCMACROS_H__

View File

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

View File

@ -38,36 +38,6 @@ THE SOFTWARE.
namespace cocos2d { 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_TYPE_MASK 0xff
#define PVR_TEXTURE_FLAG_FLIPPED_MASK 0x10000 #define PVR_TEXTURE_FLAG_FLIPPED_MASK 0x10000
@ -243,7 +213,7 @@ bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
header = (PVRTexHeader *)data; header = (PVRTexHeader *)data;
//Make sure that tag is in correct formatting //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 Check that given data really represents pvrtexture
@ -264,7 +234,7 @@ bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
CCConfiguration *configuration = CCConfiguration::sharedConfiguration(); CCConfiguration *configuration = CCConfiguration::sharedConfiguration();
//Get file flags (in correct byte order) //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 //Trim to only bites which are needed. Resulting flag is image format
formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK; formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
@ -304,17 +274,17 @@ bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
m_uNumberOfMipmaps = 0; m_uNumberOfMipmaps = 0;
//Get size of maimap //Get size of maimap
m_uWidth = width = CCSwapInt32LittleToHost(header->width); m_uWidth = width = CC_SWAP_INT32_LITTLE_TO_HOST(header->width);
m_uHeight = height = CCSwapInt32LittleToHost(header->height); m_uHeight = height = CC_SWAP_INT32_LITTLE_TO_HOST(header->height);
//Do we use alpha ? //Do we use alpha ?
if (CCSwapInt32LittleToHost(header->bitmaskAlpha)) if (CC_SWAP_INT32_LITTLE_TO_HOST(header->bitmaskAlpha))
m_bHasAlpha = true; m_bHasAlpha = true;
else else
m_bHasAlpha = false; m_bHasAlpha = false;
//Get ptr to where data starts.. //Get ptr to where data starts..
dataLength = CCSwapInt32LittleToHost(header->dataLength); dataLength = CC_SWAP_INT32_LITTLE_TO_HOST(header->dataLength);
//Move by size of header //Move by size of header
bytes = ((unsigned char *)data) + sizeof(PVRTexHeader); bytes = ((unsigned char *)data) + sizeof(PVRTexHeader);