mirror of https://github.com/axmolengine/axmol.git
Merge pull request #1124 from minggo/iss1403_png8
fixed #1403:support png8
This commit is contained in:
commit
5814dbd8ca
|
@ -317,82 +317,76 @@ bool CCImage::_initWithPngData(void * pData, int nDatalen)
|
||||||
m_nWidth = png_get_image_width(png_ptr, info_ptr);
|
m_nWidth = png_get_image_width(png_ptr, info_ptr);
|
||||||
m_nHeight = png_get_image_height(png_ptr, info_ptr);
|
m_nHeight = png_get_image_height(png_ptr, info_ptr);
|
||||||
m_nBitsPerComponent = png_get_bit_depth(png_ptr, info_ptr);
|
m_nBitsPerComponent = png_get_bit_depth(png_ptr, info_ptr);
|
||||||
png_uint_32 channels = png_get_channels(png_ptr, info_ptr);
|
|
||||||
png_uint_32 color_type = png_get_color_type(png_ptr, info_ptr);
|
png_uint_32 color_type = png_get_color_type(png_ptr, info_ptr);
|
||||||
|
|
||||||
CCLOG("color type %u", color_type);
|
CCLOG("color type %u", color_type);
|
||||||
// only support color type: PNG_COLOR_TYPE_RGB, PNG_COLOR_TYPE_RGB_ALPHA PNG_COLOR_TYPE_PALETTE
|
|
||||||
// and expand bit depth to 8
|
// force palette images to be expanded to 24-bit RGB
|
||||||
switch (color_type) {
|
// it may include alpha channel
|
||||||
case PNG_COLOR_TYPE_RGB:
|
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
{
|
||||||
// do nothing
|
png_set_palette_to_rgb(png_ptr);
|
||||||
|
|
||||||
break;
|
|
||||||
case PNG_COLOR_TYPE_PALETTE:
|
|
||||||
png_set_palette_to_rgb(png_ptr);
|
|
||||||
channels = 3;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case PNG_COLOR_TYPE_GRAY:
|
|
||||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
|
||||||
if (m_nBitsPerComponent < 8)
|
|
||||||
{
|
|
||||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
|
||||||
}
|
|
||||||
png_set_gray_to_rgb(png_ptr);
|
|
||||||
channels = 3;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
CCLog("unsopprted color type %u", color_type);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
// low-bit-depth grayscale iamges are to be expanded to 8 bits
|
||||||
|
if (color_type == PNG_COLOR_TYPE_GRAY && m_nBitsPerComponent < 8)
|
||||||
|
{
|
||||||
|
png_set_gray_1_2_4_to_8(png_ptr);
|
||||||
|
}
|
||||||
|
// expand any tRNS chunk data into a full alpha channel
|
||||||
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||||
|
{
|
||||||
|
png_set_tRNS_to_alpha(png_ptr);
|
||||||
|
}
|
||||||
|
// reduce images with 16-bit samples to 8 bits
|
||||||
if (m_nBitsPerComponent == 16)
|
if (m_nBitsPerComponent == 16)
|
||||||
{
|
{
|
||||||
png_set_strip_16(png_ptr);
|
png_set_strip_16(png_ptr);
|
||||||
m_nBitsPerComponent = 8;
|
|
||||||
}
|
}
|
||||||
|
// expand grayscale images to RGB
|
||||||
m_bHasAlpha = (color_type & PNG_COLOR_MASK_ALPHA) ? true : false;
|
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||||
if (m_bHasAlpha)
|
|
||||||
{
|
{
|
||||||
channels = 4;
|
png_set_gray_to_rgb(png_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read png data
|
// read png data
|
||||||
// m_nBitsPerComponent will always be 8
|
// m_nBitsPerComponent will always be 8
|
||||||
m_pData = new unsigned char[m_nWidth * m_nHeight * channels];
|
m_nBitsPerComponent = 8;
|
||||||
png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep)*m_nHeight);
|
png_uint_32 rowbytes;
|
||||||
if (row_pointers)
|
png_bytep row_pointers[m_nHeight];
|
||||||
|
|
||||||
|
png_read_update_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
m_pData = new unsigned char[rowbytes * m_nHeight];
|
||||||
|
CC_BREAK_IF(!m_pData);
|
||||||
|
|
||||||
|
for (unsigned short i = 0; i < m_nHeight; ++i)
|
||||||
{
|
{
|
||||||
const unsigned int stride = m_nWidth * channels;
|
row_pointers[i] = m_pData + i*rowbytes;
|
||||||
for (unsigned short i = 0; i < m_nHeight; ++i)
|
|
||||||
{
|
|
||||||
png_uint_32 q = i * stride;
|
|
||||||
row_pointers[i] = (png_bytep)m_pData + q;
|
|
||||||
}
|
|
||||||
png_read_image(png_ptr, row_pointers);
|
|
||||||
|
|
||||||
if (m_bHasAlpha)
|
|
||||||
{
|
|
||||||
unsigned int *tmp = (unsigned int *)m_pData;
|
|
||||||
for(unsigned short i = 0; i < m_nHeight; i++)
|
|
||||||
{
|
|
||||||
for(unsigned int j = 0; j < m_nWidth * channels; j += 4)
|
|
||||||
{
|
|
||||||
*tmp++ = CC_RGB_PREMULTIPLY_APLHA( row_pointers[i][j], row_pointers[i][j + 1],
|
|
||||||
row_pointers[i][j + 2], row_pointers[i][j + 3] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bPreMulti = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(row_pointers);
|
|
||||||
bRet = true;
|
|
||||||
}
|
}
|
||||||
|
png_read_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
|
png_read_end(png_ptr, NULL);
|
||||||
|
|
||||||
|
png_uint_32 channel = rowbytes/m_nWidth;
|
||||||
|
if (channel == 4)
|
||||||
|
{
|
||||||
|
m_bHasAlpha = true;
|
||||||
|
unsigned int *tmp = (unsigned int *)m_pData;
|
||||||
|
for(unsigned short i = 0; i < m_nHeight; i++)
|
||||||
|
{
|
||||||
|
for(unsigned int j = 0; j < rowbytes; j += 4)
|
||||||
|
{
|
||||||
|
*tmp++ = CC_RGB_PREMULTIPLY_APLHA( row_pointers[i][j], row_pointers[i][j + 1],
|
||||||
|
row_pointers[i][j + 2], row_pointers[i][j + 3] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bPreMulti = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bRet = true;
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue