标签:
CCTextureCache类源码分析(2):
在CCTextureCache类源码分析(1)中,我们分析了CCTextureCache如何实现
纹理缓存的,但是在分析的过程中,我们忽略了很多东西,比如CCImage类
如何加载纹理图片,这一篇我们分析一下CCImage:
源码分析:
1、CCImage继承自CCObject
2、成员变量,这些变量需要我们通过解析图片文件获得
unsigned char *m_pData; //图片数据
CC_SYNTHESIZE_READONLY(unsigned short, m_nWidth, Width); //宽高
CC_SYNTHESIZE_READONLY(unsigned short, m_nHeight, Height);
CC_SYNTHESIZE_READONLY(int, m_nBitsPerComponent, BitsPerComponent); //每个颜色分量的位数
bool m_bHasAlpha; //是否有alpha分量
3、
//对于.pvr 和 .pkm 图片格式文件需要特殊处理,后面分析
if (std::string::npos != lowerCase.find(".pvr"))
{
texture = this->addPVRImage(fullpath.c_str());
}
else if (std::string::npos != lowerCase.find(".pkm"))
{
// ETC1 file format, only supportted on Android
texture = this->addETCImage(fullpath.c_str());
}
else
{
//针对下面这些图片格式,我们需要使用CCImage类来读取
//图片文件数据到内存中,并进行分析,因为每一种图片格式
//文件对图片信息的存储方式是不同的,比如那几个字节存放图片的大小信息,
//那些字节存放图片颜色信息,我们需要根据每种文件格式进行不同的分析处理,
//从而得到我们需要的信息。
//从这里也可以看出cocos2dx支持的图片格式:
CCImage::EImageFormat eImageFormat = CCImage::kFmtUnKnown;
if (std::string::npos != lowerCase.find(".png"))
{
eImageFormat = CCImage::kFmtPng;
}
else if (std::string::npos != lowerCase.find(".jpg") || std::string::npos != lowerCase.find(".jpeg"))
{
eImageFormat = CCImage::kFmtJpg;
}
else if (std::string::npos != lowerCase.find(".tif") || std::string::npos != lowerCase.find(".tiff"))
{
eImageFormat = CCImage::kFmtTiff;
}
else if (std::string::npos != lowerCase.find(".webp"))
{
eImageFormat = CCImage::kFmtWebp;
}
pImage = new CCImage();
CC_BREAK_IF(NULL == pImage);
bool bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat);
CC_BREAK_IF(!bRet);
----initWithImageFile---->>
strPath : 文件路径
eImgFmt : 图片格式
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
{
bool bRet = false;
#ifdef EMSCRIPTEN
....这部分就不管了
#else
//读取图片的文件数据
unsigned long nSize = 0;
std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(strPath);
unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullPath.c_str(), "rb", &nSize);
if (pBuffer != NULL && nSize > 0)
{
bRet = initWithImageData(pBuffer, nSize, eImgFmt);
}
CC_SAFE_DELETE_ARRAY(pBuffer);
#endif // EMSCRIPTEN
return bRet;
}
------initWithImageData------>>
bool CCImage::initWithImageData(void * pData,
int nDataLen,
EImageFormat eFmt/* = eSrcFmtPng*/,
int nWidth/* = 0*/,
int nHeight/* = 0*/,
int nBitsPerComponent/* = 8*/)
{
bool bRet = false;
do
{
CC_BREAK_IF(! pData || nDataLen <= 0);
//根据图片文件格式,调用不同的解析函数
if (kFmtPng == eFmt)
{
//对png图片进行解析,_initWithPngData函数里面调用png解析的库
//对png文件进行解析,然后得到我们所需的所有信息
bRet = _initWithPngData(pData, nDataLen);
break;
}
else if (kFmtJpg == eFmt)
{
bRet = _initWithJpgData(pData, nDataLen);
break;
}
else if (kFmtTiff == eFmt)
{
bRet = _initWithTiffData(pData, nDataLen);
break;
}
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
else if (kFmtWebp == eFmt)
{
bRet = _initWithWebpData(pData, nDataLen);
break;
}
#endif
else if (kFmtRawData == eFmt)
{
bRet = _initWithRawData(pData, nDataLen, nWidth, nHeight, nBitsPerComponent, false);
break;
}
else
{
// if it is a png file buffer.
if (nDataLen > 8)
{
unsigned char* pHead = (unsigned char*)pData;
if ( pHead[0] == 0x89
&& pHead[1] == 0x50
&& pHead[2] == 0x4E
&& pHead[3] == 0x47
&& pHead[4] == 0x0D
&& pHead[5] == 0x0A
&& pHead[6] == 0x1A
&& pHead[7] == 0x0A)
{
bRet = _initWithPngData(pData, nDataLen);
break;
}
}
// if it is a tiff file buffer.
if (nDataLen > 2)
{
unsigned char* pHead = (unsigned char*)pData;
if ( (pHead[0] == 0x49 && pHead[1] == 0x49)
|| (pHead[0] == 0x4d && pHead[1] == 0x4d)
)
{
bRet = _initWithTiffData(pData, nDataLen);
break;
}
}
// if it is a jpeg file buffer.
if (nDataLen > 2)
{
unsigned char* pHead = (unsigned char*)pData;
if ( pHead[0] == 0xff
&& pHead[1] == 0xd8)
{
bRet = _initWithJpgData(pData, nDataLen);
break;
}
}
}
} while (0);
return bRet;
}
总结:
CCImage所做的工作就是根据不同的图片格式调用不同的底层库,
如png,jpg解析库,通过这些库对图片文件进行分析,
从而得到我们所需要的所有信息,这里有个疑惑,就是通过底层库
解析图片文件之后得到的数据到底是什么格式存储的?
因为我在CCTextureCache类源码分析(1) 通过下面这行
// Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
猜测数据的存储都是每个颜色分量是8位,但是因为我对png这些图片的解析不熟悉,
所以在这里并没有很好的证据证明上面的猜测,所以把这个疑惑记录在此。
标签:
原文地址:http://blog.csdn.net/tianxiawuzhei/article/details/45483453