mirror of https://github.com/axmolengine/axmol.git
282 lines
7.3 KiB
C++
282 lines
7.3 KiB
C++
/****************************************************************************
|
|
Copyright (c) 2011 cocos2d-x.org http://cocos2d-x.org
|
|
Copyright (c) 2011 Максим Аксенов
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
#include "CCImage.h"
|
|
#include "CCCommon.h"
|
|
#include "CCStdC.h"
|
|
#include "CCFileUtils.h"
|
|
#include "s3eFile.h"
|
|
#include "IwRuntime.h"
|
|
#include "IwDebug.h"
|
|
#include "png.h"
|
|
|
|
#include <string>
|
|
typedef struct
|
|
{
|
|
unsigned char* data;
|
|
int size;
|
|
int offset;
|
|
}tImageSource;
|
|
|
|
NS_CC_BEGIN;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Implement CCImage
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CCImage::CCImage()
|
|
: m_nWidth(0)
|
|
, m_nHeight(0)
|
|
, m_nBitsPerComponent(0)
|
|
, m_pData(0)
|
|
, m_bHasAlpha(false)
|
|
, m_bPreMulti(false)
|
|
{
|
|
|
|
}
|
|
|
|
CCImage::~CCImage()
|
|
{
|
|
CC_SAFE_DELETE_ARRAY(m_pData);
|
|
}
|
|
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
|
{
|
|
IW_CALLSTACK("UIImage::initWithImageFile");
|
|
CCFileData data(CCFileUtils::fullPathFromRelativePath(strPath), "rb");
|
|
return initWithImageData(data.getBuffer(), data.getSize(), eImgFmt);
|
|
}
|
|
|
|
bool CCImage::initWithImageFileThreadSafe(const char *fullpath, EImageFormat imageType)
|
|
{
|
|
CC_UNUSED_PARAM(imageType);
|
|
CCFileData data(fullpath, "rb");
|
|
return initWithImageData(data.getBuffer(), data.getSize(), imageType);
|
|
}
|
|
|
|
bool CCImage::initWithImageData(void * pData,
|
|
int nDataLen,
|
|
EImageFormat eFmt,
|
|
int nWidth,
|
|
int nHeight,
|
|
int nBitsPerComponent)
|
|
{
|
|
bool bRet = false;
|
|
do
|
|
{
|
|
CC_BREAK_IF(! pData || nDataLen <= 0);
|
|
|
|
if (kFmtPng == eFmt)
|
|
{
|
|
bRet = _initWithPngData(pData, nDataLen);
|
|
break;
|
|
}
|
|
else if (kFmtJpg == eFmt)
|
|
{
|
|
bRet = _initWithJpgData(pData, nDataLen);
|
|
break;
|
|
}
|
|
} while (0);
|
|
return bRet;
|
|
}
|
|
|
|
bool CCImage::_initWithJpgData(void * data, int nSize)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void userReadData(png_structp pngPtr, png_bytep data, png_size_t length) {
|
|
png_voidp png_pointer = png_get_io_ptr(pngPtr);
|
|
s3eFileRead((char*)data, length, 1, (s3eFile*)png_pointer);
|
|
}
|
|
|
|
#define PNGSIGSIZE 8
|
|
bool CCImage::_initWithPngData(void * pData, int nDatalen)
|
|
{
|
|
IW_CALLSTACK("CCImage::_initWithPngData");
|
|
|
|
bool bRet = false;
|
|
|
|
s3eFile* pFile = s3eFileOpenFromMemory(pData, nDatalen);
|
|
|
|
IwAssert(GAME, pFile);
|
|
|
|
png_byte pngsig[PNGSIGSIZE];
|
|
|
|
bool is_png = false;
|
|
|
|
s3eFileRead((char*)pngsig, PNGSIGSIZE, 1, pFile);
|
|
|
|
is_png = png_sig_cmp(pngsig, 0, PNGSIGSIZE) == 0 ? true : false;
|
|
|
|
if (!is_png)
|
|
return false;
|
|
|
|
png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
|
|
if (!pngPtr)
|
|
return false;
|
|
|
|
png_infop infoPtr = png_create_info_struct(pngPtr);
|
|
|
|
if (!infoPtr)
|
|
return false;
|
|
|
|
png_bytep* rowPtrs = NULL;
|
|
m_pData = NULL;
|
|
|
|
if (setjmp(png_jmpbuf(pngPtr))) {
|
|
png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0);
|
|
if (rowPtrs != NULL) delete [] rowPtrs;
|
|
if (m_pData != NULL) delete [] m_pData;
|
|
|
|
CCLog("ERROR: An error occured while reading the PNG file");
|
|
|
|
return false;
|
|
}
|
|
|
|
png_set_read_fn(pngPtr, pFile, userReadData);
|
|
png_set_sig_bytes(pngPtr, PNGSIGSIZE);
|
|
png_read_info(pngPtr, infoPtr);
|
|
|
|
|
|
png_uint_32 bitdepth = png_get_bit_depth(pngPtr, infoPtr);
|
|
png_uint_32 channels = png_get_channels(pngPtr, infoPtr);
|
|
png_uint_32 color_type = png_get_color_type(pngPtr, infoPtr);
|
|
|
|
// Convert palette color to true color
|
|
if (color_type ==PNG_COLOR_TYPE_PALETTE)
|
|
png_set_palette_to_rgb(pngPtr);
|
|
|
|
// Convert low bit colors to 8 bit colors
|
|
if (png_get_bit_depth(pngPtr, infoPtr) < 8)
|
|
{
|
|
if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
png_set_gray_1_2_4_to_8(pngPtr);
|
|
else
|
|
png_set_packing(pngPtr);
|
|
}
|
|
|
|
if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS))
|
|
png_set_tRNS_to_alpha(pngPtr);
|
|
|
|
// Convert high bit colors to 8 bit colors
|
|
if (bitdepth == 16)
|
|
png_set_strip_16(pngPtr);
|
|
|
|
// Convert gray color to true color
|
|
if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
png_set_gray_to_rgb(pngPtr);
|
|
|
|
// Update the changes
|
|
png_read_update_info(pngPtr, infoPtr);
|
|
|
|
// init image info
|
|
m_bPreMulti = true;
|
|
|
|
unsigned int bytesPerComponent = png_get_channels(pngPtr, infoPtr);
|
|
|
|
m_bHasAlpha = (bytesPerComponent == 4 ? true : false);
|
|
|
|
m_nHeight = (unsigned int)png_get_image_height(pngPtr, infoPtr);
|
|
m_nWidth = (unsigned int) png_get_image_width(pngPtr, infoPtr);
|
|
|
|
m_nBitsPerComponent = (unsigned int)png_get_bit_depth(pngPtr, infoPtr);
|
|
|
|
m_pData = new unsigned char[m_nHeight * m_nWidth * bytesPerComponent];
|
|
|
|
unsigned int bytesPerRow = m_nWidth * bytesPerComponent;
|
|
|
|
{
|
|
unsigned char *ptr = m_pData;
|
|
rowPtrs = new png_bytep[m_nHeight];
|
|
|
|
for (int i = 0; i < m_nHeight; i++) {
|
|
|
|
int q = (i) * bytesPerRow;
|
|
|
|
rowPtrs[i] = (png_bytep)m_pData + q;
|
|
}
|
|
|
|
png_read_image(pngPtr, rowPtrs);
|
|
|
|
delete[] (png_bytep)rowPtrs;
|
|
png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0);
|
|
|
|
s3eFileClose(pFile);
|
|
pFile = 0;
|
|
}
|
|
|
|
// premultiplay if alpha
|
|
if(m_bHasAlpha)
|
|
for(unsigned int i = 0; i < m_nHeight*bytesPerRow; i += bytesPerComponent){
|
|
*(m_pData + i + 0) = (*(m_pData + i + 0) * *(m_pData + i + 3) + 1) >> 8;
|
|
*(m_pData + i + 1) = (*(m_pData + i + 1) * *(m_pData + i + 3) + 1) >> 8;
|
|
*(m_pData + i + 2) = (*(m_pData + i + 2) * *(m_pData + i + 3) + 1) >> 8;
|
|
*(m_pData + i + 3) = *(m_pData + i + 3);
|
|
}
|
|
|
|
|
|
|
|
bRet = true;
|
|
return bRet;
|
|
}
|
|
|
|
bool CCImage::initWithString(
|
|
const char * pText,
|
|
int nWidth/* = 0*/,
|
|
int nHeight/* = 0*/,
|
|
ETextAlign eAlignMask/* = kAlignCenter*/,
|
|
const char * pFontName/* = nil*/,
|
|
int nSize/* = 0*/)
|
|
{
|
|
bool bRet = false;
|
|
return bRet;
|
|
}
|
|
|
|
bool CCImage::saveToFile(const char *pszFilePath, bool bIsToRGB)
|
|
{
|
|
// todo
|
|
return false;
|
|
}
|
|
|
|
bool CCImage::_initWithRawData(void * pData, int nDatalen, int nWidth, int nHeight, int nBitsPerComponent)
|
|
{
|
|
// todo
|
|
return false;
|
|
}
|
|
|
|
bool CCImage::_saveImageToPNG(const char * pszFilePath, bool bIsToRGB)
|
|
{
|
|
// todo
|
|
return false;
|
|
}
|
|
|
|
bool CCImage::_saveImageToJPG(const char * pszFilePath)
|
|
{
|
|
// todo
|
|
return false;
|
|
}
|
|
|
|
NS_CC_END;
|