This commit is contained in:
Ming 2010-09-18 06:14:51 +00:00
parent 5af16c3282
commit b87fb419fb
3 changed files with 158 additions and 326 deletions

View File

@ -32,6 +32,24 @@ THE SOFTWARE.
using namespace std; using namespace std;
namespace cocos2d { namespace cocos2d {
#ifdef _TRANZDA_VM_
#define CCX_RGB(vr,vg,vb) \
(ColorRefType)(((UInt32)(UInt8)(vb) << 16) | ((UInt32)(UInt8)(vg) << 8) | (UInt32)(UInt8)(vr) | ((UInt32)0xffL << 24))
#define CCX_RGB_APLHA(vr, vg, vb, va) \
(ColorRefType)(((UInt32)((UInt8)(vr) * ((UInt8)(va) + 1)) >> 8) | \
((UInt32)((UInt8)(vg) * ((UInt8)(va) + 1) >> 8) << 8) | \
((UInt32)((UInt8)(vb) * ((UInt8)(va) + 1) >> 8) << 16) | \
((UInt32)(UInt8)(va) << 24))
#define CCX_RGBA(vr,vg,vb,va) \
(((va) == 0xff)?CCX_RGB((vr), (vg), (vb)):CCX_RGB_APLHA((vr), (vg), (vb), (va)))
#else
#define CCX_RGB RGB
#define CCX_RGBA RGBA
#endif //_TRANZDA_VM_
typedef struct typedef struct
{ {
unsigned char* data; unsigned char* data;
@ -56,13 +74,70 @@ static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t leng
} }
} }
static void copyImageData(tImageInfo &imageInfo, png_bytep* rowPointers)
{
// allocate memory
imageInfo.data = new unsigned char[imageInfo.height * imageInfo.width * 4];
if (! imageInfo.data)
{
return;
}
// copy data
if(imageInfo.hasAlpha) {
unsigned int bytesPerRow = imageInfo.width * 4;
unsigned int *tmp = (unsigned int *)imageInfo.data;
for(unsigned int i = 0; i < imageInfo.height; i++)
{
for(unsigned int j = 0; j < bytesPerRow; j += 4)
{
*tmp++ = CCX_RGBA( rowPointers[i][j], rowPointers[i][j + 1],
rowPointers[i][j + 2], rowPointers[i][j + 3] );
}
}
}
else
{
unsigned int bytesPerRow = imageInfo.width * 3;
unsigned int *tmp = (unsigned int *)imageInfo.data;
for(unsigned int i = 0; i < imageInfo.height; i++)
{
for(unsigned int j = 0; j < bytesPerRow; j += 3)
{
*tmp++ = CCX_RGB( rowPointers[i][j], rowPointers[i][j + 1],
rowPointers[i][j + 2] );
}
}
}
}
UIImage::UIImage(void) UIImage::UIImage(void)
{ {
m_pBitmap = NULL; m_pBitmap = NULL;
m_imageInfo.hasAlpha = false;
m_imageInfo.isPremultipliedAlpha = false;
m_imageInfo.height = 0;
m_imageInfo.width = 0;
m_imageInfo.data = NULL;
m_imageInfo.bitsPerComponent = 0;
} }
UIImage::UIImage(TBitmap *bitmap) UIImage::UIImage(TBitmap *bitmap)
{ {
m_pBitmap = bitmap->Clone(); if (bitmap)
{
m_pBitmap = bitmap->DupBitmapTo32();
// init imageinfo
m_imageInfo.data = m_pBitmap->GetDataPtr();
m_imageInfo.height = m_pBitmap->GetHeight();
m_imageInfo.width = m_pBitmap->GetWidth();
m_imageInfo.hasAlpha = m_pBitmap->HasAlphaData();
// uphone only support predefined
m_imageInfo.isPremultipliedAlpha = true;
m_imageInfo.bitsPerComponent = m_pBitmap->GetDepth();
}
} }
UIImage::UIImage(int nX, int nY, void *buffer) UIImage::UIImage(int nX, int nY, void *buffer)
@ -74,100 +149,38 @@ UIImage::~UIImage(void)
{ {
if (m_pBitmap) if (m_pBitmap)
{ {
// the m_imageInfo's data points to m_pBitmap,
// so we don't release m_imageInfo's data
m_pBitmap->Destroy(); m_pBitmap->Destroy();
} }
else
{
if (m_imageInfo.data)
{
delete []m_imageInfo.data;
}
}
} }
bool UIImage::initWithContentsOfFile(const string &strPath) bool UIImage::initWithContentsOfFile(const string &strPath)
{ {
if (m_pBitmap) // use libpng load image
{ return loadPng(strPath.c_str());
return false;
}
bool bRet = false;
do
{
// load the image
/************************************************************************/
/* Use ImageToolKit load image */
// ImageLoader obImgLoader;
// Image obImg;
// TUChar *pszPath = new TUChar[strPath.size() + 1];
// TUString::StrGBToUnicode(pszPath, (const Char *) strPath.c_str());
// if (! obImgLoader.loadImage(obImg, pszPath, IT_LOAD_FMT_UNKNOWN))
// {
// bRet = false;
// break;
// }
//
// // init bitmap
// m_pBitmap = (TBitmap *) obImg.GetTBitmap();
// m_pBitmap = m_pBitmap->DupBitmapTo32();
// delete[] pszPath;
/************************************************************************/
// use libpng load image
bRet = loadPng(strPath.c_str());
// check if the loading action is successful
if (! bRet)
{
break;
}
// the hight is 0??
if (m_pBitmap->GetHeight() == 0)
{
m_pBitmap->Destroy();
m_pBitmap = NULL;
bRet = false;
break;
}
} while(0);
return bRet;
} }
unsigned int UIImage::width(void) unsigned int UIImage::width(void)
{ {
if (! m_pBitmap) return m_imageInfo.width;
{
return 0;
}
return m_pBitmap->GetWidth();
} }
unsigned int UIImage::height(void) unsigned int UIImage::height(void)
{ {
if (! m_pBitmap) return m_imageInfo.height;
{
return 0;
}
return m_pBitmap->GetHeight();
} }
bool UIImage::isAlphaPixelFormat(void) bool UIImage::isAlphaPixelFormat(void)
{ {
if (! m_pBitmap) return m_imageInfo.hasAlpha;
{
return false;
}
bool bRet;
if (m_pBitmap->HasAlphaData())
{
bRet = true;
}
else
{
bRet = false;
}
return bRet;
} }
// now, uphone only support premultiplied data // now, uphone only support premultiplied data
@ -180,27 +193,7 @@ bool UIImage::isPremultipliedAlpha(void)
// compute how many bits every color component // compute how many bits every color component
int UIImage::CGImageGetBitsPerComponent(void) int UIImage::CGImageGetBitsPerComponent(void)
{ {
if (! m_pBitmap) return m_imageInfo.bitsPerComponent;
{
return 0;
}
int nRet = 0;
int nRowBytes = m_pBitmap->GetRowBytes();
if (m_pBitmap->HasAlphaData())
{
// it has alpha data, so
// nRawBytes / 4 -> the bytes of per component
nRet = nRowBytes / 4 * 8;
}
else
{
// have not alpha data
// nRawBytes / 3 -> the bytes of per component
nRet = nRowBytes / 3 * 8;
}
return nRet;
} }
// 0 -> it is a mask // 0 -> it is a mask
@ -209,7 +202,7 @@ int UIImage::CGImageGetColorSpace(void)
{ {
int nRet = 1; int nRet = 1;
if (m_pBitmap->GetRowBytes() == 1) if (m_imageInfo.bitsPerComponent == 8)
{ {
nRet = 0; nRet = 0;
} }
@ -219,181 +212,53 @@ int UIImage::CGImageGetColorSpace(void)
unsigned char* UIImage::getRGBA8888Data(void) unsigned char* UIImage::getRGBA8888Data(void)
{ {
unsigned char *pBufferRet = NULL; return m_imageInfo.data;
do {
/*TBitmap *pBitmap;*/
int nW;
int nH;
unsigned char uR;
unsigned char uB;
if (m_pBitmap == NULL)
{
break;
}
// convert to RGBA8888 format
// pBitmap = m_pBitmap->DupBitmapTo32();
// if (pBitmap == NULL)
// {
// break;
// }
// compute width and height
nW = m_pBitmap->GetWidth();
nH = m_pBitmap->GetHeight();
// alloc memory and store the bitmap data
pBufferRet = new unsigned char[nW * nH * 4];
memcpy(pBufferRet, m_pBitmap->GetDataPtr(), nW * nH * 4);
#ifdef _TRANZDA_VM_
// translate BGRA to RGBA
for (int i = 0; i < nW; ++i)
{
for (int j = 0; j < nH; ++j)
{
int baseAddr = (j * nW + i) * 4;
uB = pBufferRet[baseAddr];
uR = pBufferRet[baseAddr + 2];
pBufferRet[baseAddr] = uR;
pBufferRet[baseAddr + 2] = uB;
}
}
#endif // _TRANZDA_VM_
/*pBitmap->Destroy();*/
} while(0);
return pBufferRet;
} }
bool UIImage::loadPng(const char* strFileName) bool UIImage::loadPng(const char* strFileName)
{ {
char header[8]; FILE *fp;
FILE *fp; unsigned char *buffer = NULL;
png_structp png_ptr; bool bRet = true;
png_infop info_ptr;
UInt32 * pBmpData;
Int32 bitDepth;
png_uint_32 width;
png_uint_32 height;
Int32 interlaceType;
png_bytep * rowPointers;
Int32 colorType;
fp = NULL; fp = NULL;
pBmpData = NULL;
// open file do
fp = fopen(strFileName, "rb"); {
if (!fp) // open file
return false; fp = fopen(strFileName, "rb");
if (!fp)
{
bRet = false;
break;
}
// read 8 bytes from the beginning of the file // compute the length of file
fread(header, 1, 8, fp); fseek(fp,0,SEEK_END);
int size = ftell(fp);
fseek(fp,0,SEEK_SET);
// close the file if it's not a png // allocate enough memory to save the data of file
if (png_sig_cmp((png_bytep)header, 0, 8)) buffer = new unsigned char[size];
{ if (! buffer)
fclose(fp); {
return false; bRet = false;
} break;
}
// init png_struct // read data
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); fread(buffer, sizeof(unsigned char), size, fp);
if (!png_ptr)
{
fclose(fp);
return false;
}
// init png_info bRet = loadPngFromStream(buffer, size);
info_ptr = png_create_info_struct(png_ptr); delete[] buffer;
if (!info_ptr) } while (0);
{
png_destroy_read_struct(&png_ptr, NULL, NULL); if (fp)
fclose(fp); {
return false; fclose(fp);
} }
// if something wrong,close file and return return bRet;
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
png_destroy_info_struct(png_ptr, &info_ptr);
fclose(fp);
return false;
}
// conect the file pointer to libpng
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
// read the data of the file
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, 0);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType,
&interlaceType, NULL, NULL);
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
png_destroy_info_struct(png_ptr, &info_ptr);
fclose(fp);
return false;
}
// get the image file data
rowPointers = png_get_rows(png_ptr, info_ptr);
// Create a bitmap of 32bits depth
if(!m_pBitmap)
{
m_pBitmap = TBitmap::Create(width, height, 32);
}
if(!m_pBitmap)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
png_destroy_info_struct(png_ptr, &info_ptr);
fclose(fp);
return false;
}
// Alpha data
pBmpData = (UInt32* )( m_pBitmap->GetDataPtr() );
if( info_ptr->color_type & PNG_COLOR_MASK_ALPHA ) {
for(unsigned int i = 0; i < height; i++)
{
for(unsigned int j = 0; j < (4 * width); j += 4)
{
*pBmpData++ = RGBA( rowPointers[i][j], rowPointers[i][j + 1],
rowPointers[i][j + 2], rowPointers[i][j + 3] );
}
}
}
else
{
for(unsigned int i = 0; i < height; i++)
{
for(unsigned int j = 0; j < (3 * width); j += 3)
{
*pBmpData++ = RGB( rowPointers[i][j], rowPointers[i][j + 1],
rowPointers[i][j + 2] );
}
}
}
// release
png_destroy_read_struct(&png_ptr, NULL, NULL);
png_destroy_info_struct(png_ptr, &info_ptr);
fclose(fp);
return true;
} }
bool UIImage::loadPngFromStream(unsigned char *data, int nLength) bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
@ -401,7 +266,6 @@ bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
char header[8]; char header[8];
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
UInt32 * pBmpData;
Int32 pos; Int32 pos;
Int32 bitDepth; Int32 bitDepth;
png_uint_32 width; png_uint_32 width;
@ -412,7 +276,6 @@ bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
tImageSource imageSource; tImageSource imageSource;
pos = 0; pos = 0;
pBmpData = NULL;
// read 8 bytes from the beginning of stream // read 8 bytes from the beginning of stream
unsigned char *tmp = data; unsigned char *tmp = data;
@ -453,6 +316,7 @@ bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
imageSource.offset = 0; imageSource.offset = 0;
png_set_read_fn(png_ptr, &imageSource, pngReadCallback); png_set_read_fn(png_ptr, &imageSource, pngReadCallback);
// read the data of the file // read the data of the file
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, 0); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, 0);
@ -469,42 +333,17 @@ bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
// get the image file data // get the image file data
rowPointers = png_get_rows(png_ptr, info_ptr); rowPointers = png_get_rows(png_ptr, info_ptr);
// Create a bitmap of 32bits depth // init image info
if(!m_pBitmap) m_imageInfo.height = height;
{ m_imageInfo.width = width;
m_pBitmap = TBitmap::Create(width, height, 32); m_imageInfo.hasAlpha = info_ptr->color_type & PNG_COLOR_MASK_ALPHA;
} m_imageInfo.isPremultipliedAlpha = true;
if(!m_pBitmap) copyImageData(m_imageInfo, rowPointers);
{ // we use CCX_RGA or CCX_RGB to save data
png_destroy_read_struct(&png_ptr, NULL, NULL); // so the bitsPerComponet is 32, and it also
png_destroy_info_struct(png_ptr, &info_ptr); // has the alpha data
return false; m_imageInfo.bitsPerComponent = 32;
} m_imageInfo.hasAlpha = true;
// Alpha data
pBmpData = reinterpret_cast< UInt32* >( m_pBitmap->GetDataPtr() );
if( info_ptr->color_type & PNG_COLOR_MASK_ALPHA ) {
for(unsigned int i = 0; i < height; i++)
{
for(unsigned int j = 0; j < (4 * width); j += 4)
{
*pBmpData++ = RGBA( rowPointers[i][j], rowPointers[i][j + 1],
rowPointers[i][j + 2], rowPointers[i][j + 3] );
}
}
}
else
{
for(unsigned int i = 0; i < height; i++)
{
for(unsigned int j = 0; j < (3 * width); j += 3)
{
*pBmpData++ = RGB( rowPointers[i][j], rowPointers[i][j + 1],
rowPointers[i][j + 2] );
}
}
}
// release // release
png_destroy_read_struct(&png_ptr, NULL, NULL); png_destroy_read_struct(&png_ptr, NULL, NULL);
@ -520,29 +359,7 @@ bool UIImage::save(const std::string &strFileName, int nFormat)
} }
bool UIImage::initWithData(unsigned char *pBuffer, int nLength) bool UIImage::initWithData(unsigned char *pBuffer, int nLength)
{ {
bool bRet = true; return loadPngFromStream(pBuffer, nLength);
do
{
bRet = loadPngFromStream(pBuffer, nLength);
// if load failed, break
if (! bRet)
{
break;
}
// the hight is 0??
if (m_pBitmap->GetHeight() == 0)
{
m_pBitmap->Destroy();
m_pBitmap = NULL;
bRet = false;
break;
}
} while(0);
return bRet;
} }
bool UIImage::initWithBuffer(int tx, int ty, unsigned char *pBuffer) bool UIImage::initWithBuffer(int tx, int ty, unsigned char *pBuffer)

View File

@ -31,6 +31,16 @@ THE SOFTWARE.
class TBitmap; class TBitmap;
namespace cocos2d { namespace cocos2d {
typedef struct
{
unsigned int height;
unsigned int width;
int bitsPerComponent;
bool hasAlpha;
bool isPremultipliedAlpha;
unsigned char *data;
} tImageInfo;
class CCX_DLL UIImage class CCX_DLL UIImage
{ {
public: public:
@ -65,6 +75,7 @@ private:
private: private:
TBitmap *m_pBitmap; TBitmap *m_pBitmap;
tImageInfo m_imageInfo;
}; };
}//namespace cocos2d }//namespace cocos2d

View File

@ -283,7 +283,8 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
NSAssert(tempData != NULL, "NULL image data."); NSAssert(tempData != NULL, "NULL image data.");
if(image->width() == POTWide && image->height() == POTHigh) if(image->width() == POTWide && image->height() == POTHigh)
{ {
data = tempData; data = new UINT8[POTHigh * POTWide * 4];
memcpy(data, tempData, POTHigh * POTWide * 4);
} }
else else
{ {
@ -297,7 +298,6 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
{ {
memcpy(pTargetData+POTWide*4*y, pPixelData+(image->width())*4*y, (image->width())*4); memcpy(pTargetData+POTWide*4*y, pPixelData+(image->width())*4*y, (image->width())*4);
} }
delete []tempData;
} }
break; break;
default: default:
@ -317,8 +317,10 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
tempData = new UINT8[POTHigh * POTWide * 2]; tempData = new UINT8[POTHigh * POTWide * 2];
inPixel32 = (unsigned int*)data; inPixel32 = (unsigned int*)data;
outPixel16 = (unsigned short*)tempData; outPixel16 = (unsigned short*)tempData;
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32) for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
*outPixel16++ = ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0); *outPixel16++ = ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0);
delete [] data; delete [] data;
data = tempData; data = tempData;
} }
@ -327,6 +329,7 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
tempData = new UINT8[POTHigh * POTWide * 2]; tempData = new UINT8[POTHigh * POTWide * 2];
inPixel32 = (unsigned int*)data; inPixel32 = (unsigned int*)data;
outPixel16 = (unsigned short*)tempData; outPixel16 = (unsigned short*)tempData;
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32) for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
*outPixel16++ = *outPixel16++ =
((((*inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R ((((*inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R
@ -342,6 +345,7 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
tempData = new UINT8[POTHigh * POTWide * 2]; tempData = new UINT8[POTHigh * POTWide * 2];
inPixel32 = (unsigned int*)data; inPixel32 = (unsigned int*)data;
outPixel16 = (unsigned short*)tempData; outPixel16 = (unsigned short*)tempData;
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32) for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
*outPixel16++ = *outPixel16++ =
((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R