mirror of https://github.com/axmolengine/axmol.git
update libwebp to 2.1
add support RGB888, RGB565,RGBA4444
This commit is contained in:
parent
1dcb3742e9
commit
0b25220f22
|
@ -23,6 +23,8 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "CCImage.h"
|
#include "CCImage.h"
|
||||||
|
#include "CCTexture2D.h"
|
||||||
|
#include "ccMacros.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -35,21 +37,56 @@ bool CCImage::_initWithWebpData(void *pData, int nDataLen)
|
||||||
bool bRet = false;
|
bool bRet = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int width = 0;
|
WebPDecoderConfig config;
|
||||||
int height = 0;
|
if (WebPInitDecoderConfig(&config) == 0) break;
|
||||||
uint8_t *data = WebPDecodeRGBA((uint8_t*)pData, nDataLen, &width, &height);
|
if (WebPGetFeatures((uint8_t*)pData, nDataLen, &config.input) != VP8_STATUS_OK) break;
|
||||||
if(!data) break;
|
if (config.input.width == 0 || config.input.height == 0) break;
|
||||||
if(width == 0 || height == 0)
|
|
||||||
|
CCTexture2DPixelFormat destFormat = CCTexture2D::defaultAlphaPixelFormat();
|
||||||
|
switch (destFormat)
|
||||||
{
|
{
|
||||||
free(data);
|
case kTexture2DPixelFormat_RGB888:
|
||||||
|
config.output.colorspace = MODE_RGB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTexture2DPixelFormat_RGB565:
|
||||||
|
config.output.colorspace = MODE_RGB_565;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTexture2DPixelFormat_RGBA4444:
|
||||||
|
config.output.colorspace = MODE_RGBA_4444;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTexture2DPixelFormat_A8:
|
||||||
|
case kTexture2DPixelFormat_RGB5A1:
|
||||||
|
CCAssert(false, "kTexture2DPixelFormat_A8/kTexture2DPixelFormat_RGB5A1 not support");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTexture2DPixelFormat_RGBA8888:
|
||||||
|
default:
|
||||||
|
config.output.colorspace = MODE_RGBA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nBitsPerComponent = 8;
|
m_nBitsPerComponent = 8;
|
||||||
m_nHeight = (short)height;
|
m_nWidth = config.input.width;
|
||||||
m_nWidth = (short)width;
|
m_nHeight = config.input.height;
|
||||||
m_bHasAlpha = true;
|
m_bHasAlpha = config.input.has_alpha;
|
||||||
m_pData = (unsigned char*)data;
|
int bufferSize = m_nWidth * m_nHeight * 4;
|
||||||
|
m_pData = new unsigned char[bufferSize];
|
||||||
|
|
||||||
|
config.output.u.RGBA.rgba = (uint8_t*)m_pData;
|
||||||
|
config.output.u.RGBA.stride = m_nWidth;
|
||||||
|
config.output.u.RGBA.size = bufferSize;
|
||||||
|
config.output.is_external_memory = 1;
|
||||||
|
|
||||||
|
if (WebPDecode((uint8_t*)pData, nDataLen, &config) != VP8_STATUS_OK)
|
||||||
|
{
|
||||||
|
delete []m_pData;
|
||||||
|
m_pData = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bRet = true;
|
bRet = true;
|
||||||
} while (0);
|
} while (0);
|
||||||
return bRet;
|
return bRet;
|
||||||
|
|
|
@ -87,11 +87,7 @@ CCImage::CCImage()
|
||||||
|
|
||||||
CCImage::~CCImage()
|
CCImage::~CCImage()
|
||||||
{
|
{
|
||||||
// CC_SAFE_DELETE_ARRAY(m_pData);
|
CC_SAFE_DELETE_ARRAY(m_pData);
|
||||||
if (m_pData)
|
|
||||||
{
|
|
||||||
free(m_pData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
||||||
|
@ -318,8 +314,7 @@ bool CCImage::_initWithJpgData(void * data, int nSize)
|
||||||
row_pointer[0] = new unsigned char[cinfo.output_width*cinfo.output_components];
|
row_pointer[0] = new unsigned char[cinfo.output_width*cinfo.output_components];
|
||||||
CC_BREAK_IF(! row_pointer[0]);
|
CC_BREAK_IF(! row_pointer[0]);
|
||||||
|
|
||||||
// m_pData = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components];
|
m_pData = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components];
|
||||||
m_pData = (unsigned char*)malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components);
|
|
||||||
CC_BREAK_IF(! m_pData);
|
CC_BREAK_IF(! m_pData);
|
||||||
|
|
||||||
/* now actually read the jpeg into the raw buffer */
|
/* now actually read the jpeg into the raw buffer */
|
||||||
|
@ -434,8 +429,7 @@ bool CCImage::_initWithPngData(void * pData, int nDatalen)
|
||||||
|
|
||||||
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||||
|
|
||||||
//m_pData = new unsigned char[rowbytes * m_nHeight];
|
m_pData = new unsigned char[rowbytes * m_nHeight];
|
||||||
m_pData = (unsigned char*)malloc(rowbytes * m_nHeight);
|
|
||||||
CC_BREAK_IF(!m_pData);
|
CC_BREAK_IF(!m_pData);
|
||||||
|
|
||||||
for (unsigned short i = 0; i < m_nHeight; ++i)
|
for (unsigned short i = 0; i < m_nHeight; ++i)
|
||||||
|
@ -618,8 +612,7 @@ bool CCImage::_initWithTiffData(void* pData, int nDataLen)
|
||||||
m_nHeight = h;
|
m_nHeight = h;
|
||||||
m_nBitsPerComponent = 8;
|
m_nBitsPerComponent = 8;
|
||||||
|
|
||||||
//m_pData = new unsigned char[npixels * sizeof (uint32)];
|
m_pData = new unsigned char[npixels * sizeof (uint32)];
|
||||||
m_pData = (unsigned char*)malloc(npixels * sizeof (uint32));
|
|
||||||
|
|
||||||
uint32* raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
|
uint32* raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
|
||||||
if (raster != NULL)
|
if (raster != NULL)
|
||||||
|
@ -668,8 +661,7 @@ bool CCImage::_initWithRawData(void * pData, int nDatalen, int nWidth, int nHeig
|
||||||
// only RGBA8888 supported
|
// only RGBA8888 supported
|
||||||
int nBytesPerComponent = 4;
|
int nBytesPerComponent = 4;
|
||||||
int nSize = nHeight * nWidth * nBytesPerComponent;
|
int nSize = nHeight * nWidth * nBytesPerComponent;
|
||||||
//m_pData = new unsigned char[nSize];
|
m_pData = new unsigned char[nSize];
|
||||||
m_pData = (unsigned char*)malloc(nSize);
|
|
||||||
CC_BREAK_IF(! m_pData);
|
CC_BREAK_IF(! m_pData);
|
||||||
memcpy(m_pData, pData, nSize);
|
memcpy(m_pData, pData, nSize);
|
||||||
|
|
||||||
|
|
|
@ -284,8 +284,7 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
|
||||||
|
|
||||||
if (! context)
|
if (! context)
|
||||||
{
|
{
|
||||||
//delete[] data;
|
delete[] data;
|
||||||
free(data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,11 +344,7 @@ CCImage::CCImage()
|
||||||
|
|
||||||
CCImage::~CCImage()
|
CCImage::~CCImage()
|
||||||
{
|
{
|
||||||
//CC_SAFE_DELETE_ARRAY(m_pData);
|
CC_SAFE_DELETE_ARRAY(m_pData);
|
||||||
if (m_pData)
|
|
||||||
{
|
|
||||||
free(m_pData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
||||||
|
|
|
@ -132,8 +132,7 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
case kCCTexture2DPixelFormat_RGBA4444:
|
case kCCTexture2DPixelFormat_RGBA4444:
|
||||||
case kCCTexture2DPixelFormat_RGB5A1:
|
case kCCTexture2DPixelFormat_RGB5A1:
|
||||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
//data = new unsigned char[POTHigh * POTWide * 4];
|
data = new unsigned char[POTHigh * POTWide * 4];
|
||||||
data = (unsigned char*)malloc(POTHigh * POTWide * 4);
|
|
||||||
info = hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNoneSkipLast;
|
info = hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNoneSkipLast;
|
||||||
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
||||||
CGColorSpaceRelease(colorSpace);
|
CGColorSpaceRelease(colorSpace);
|
||||||
|
@ -141,15 +140,13 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
|
|
||||||
case kCCTexture2DPixelFormat_RGB565:
|
case kCCTexture2DPixelFormat_RGB565:
|
||||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
//data = new unsigned char[POTHigh * POTWide * 4];
|
data = new unsigned char[POTHigh * POTWide * 4];
|
||||||
data = (unsigned char*)malloc(POTHigh * POTWide * 4);
|
|
||||||
info = kCGImageAlphaNoneSkipLast;
|
info = kCGImageAlphaNoneSkipLast;
|
||||||
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
||||||
CGColorSpaceRelease(colorSpace);
|
CGColorSpaceRelease(colorSpace);
|
||||||
break;
|
break;
|
||||||
case kCCTexture2DPixelFormat_A8:
|
case kCCTexture2DPixelFormat_A8:
|
||||||
//data = new unsigned char[POTHigh * POTWide];
|
data = new unsigned char[POTHigh * POTWide];
|
||||||
data = (unsigned char*)malloc(POTHigh * POTWide);
|
|
||||||
info = kCGImageAlphaOnly;
|
info = kCGImageAlphaOnly;
|
||||||
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, NULL, info);
|
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, NULL, info);
|
||||||
break;
|
break;
|
||||||
|
@ -172,8 +169,7 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
if(pixelFormat == kCCTexture2DPixelFormat_RGB565)
|
if(pixelFormat == kCCTexture2DPixelFormat_RGB565)
|
||||||
{
|
{
|
||||||
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
|
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
|
||||||
//tempData = new unsigned char[POTHigh * POTWide * 2];
|
tempData = new unsigned char[POTHigh * POTWide * 2];
|
||||||
tempData = (unsigned char*)malloc(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)
|
||||||
|
@ -181,15 +177,14 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
*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);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
delete []data;
|
||||||
data = tempData;
|
data = tempData;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (pixelFormat == kCCTexture2DPixelFormat_RGBA4444)
|
else if (pixelFormat == kCCTexture2DPixelFormat_RGBA4444)
|
||||||
{
|
{
|
||||||
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
|
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
|
||||||
//tempData = new unsigned char[POTHigh * POTWide * 2];
|
tempData = new unsigned char[POTHigh * POTWide * 2];
|
||||||
tempData = (unsigned char*)malloc(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)
|
||||||
|
@ -201,15 +196,14 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
((((*inPixel32 >> 24) & 0xFF) >> 4) << 0); // A
|
((((*inPixel32 >> 24) & 0xFF) >> 4) << 0); // A
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
delete []data;
|
||||||
data = tempData;
|
data = tempData;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (pixelFormat == kCCTexture2DPixelFormat_RGB5A1)
|
else if (pixelFormat == kCCTexture2DPixelFormat_RGB5A1)
|
||||||
{
|
{
|
||||||
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
|
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
|
||||||
//tempData = new unsigned char[POTHigh * POTWide * 2];
|
tempData = new unsigned char[POTHigh * POTWide * 2];
|
||||||
tempData = (unsigned char*)malloc(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)
|
||||||
|
@ -221,7 +215,7 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
((((*inPixel32 >> 24) & 0xFF) >> 7) << 0); // A
|
((((*inPixel32 >> 24) & 0xFF) >> 7) << 0); // A
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
delete []data;
|
||||||
data = tempData;
|
data = tempData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,8 +228,7 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
|
|
||||||
if (pImageInfo->data)
|
if (pImageInfo->data)
|
||||||
{
|
{
|
||||||
//delete [] pImageInfo->data;
|
delete [] pImageInfo->data;
|
||||||
free(pImageInfo->data);
|
|
||||||
}
|
}
|
||||||
pImageInfo->data = data;
|
pImageInfo->data = data;
|
||||||
|
|
||||||
|
@ -475,8 +468,7 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
|
||||||
|
|
||||||
NSUInteger textureSize = POTWide*POTHigh*4;
|
NSUInteger textureSize = POTWide*POTHigh*4;
|
||||||
|
|
||||||
//unsigned char* dataNew = new unsigned char[textureSize];
|
unsigned char* dataNew = new unsigned char[textureSize];
|
||||||
unsigned char* dataNew = (unsigned char*)malloc(textureSize);
|
|
||||||
if (dataNew) {
|
if (dataNew) {
|
||||||
memcpy(dataNew, data, textureSize);
|
memcpy(dataNew, data, textureSize);
|
||||||
// output params
|
// output params
|
||||||
|
@ -573,11 +565,7 @@ CCImage::CCImage()
|
||||||
|
|
||||||
CCImage::~CCImage()
|
CCImage::~CCImage()
|
||||||
{
|
{
|
||||||
// CC_SAFE_DELETE_ARRAY(m_pData);
|
CC_SAFE_DELETE_ARRAY(m_pData);
|
||||||
if (m_pData)
|
|
||||||
{
|
|
||||||
free(m_pData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
|
||||||
|
@ -619,7 +607,7 @@ bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = e
|
||||||
unsigned long fileSize = 0;
|
unsigned long fileSize = 0;
|
||||||
unsigned char* pFileData = CCFileUtils::sharedFileUtils()->getFileData(strTemp.c_str(), "rb", &fileSize);
|
unsigned char* pFileData = CCFileUtils::sharedFileUtils()->getFileData(strTemp.c_str(), "rb", &fileSize);
|
||||||
bool ret = initWithImageData(pFileData, fileSize, eImgFmt);
|
bool ret = initWithImageData(pFileData, fileSize, eImgFmt);
|
||||||
free(pFileData);
|
delete []pFileData;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
// version numbers
|
// version numbers
|
||||||
#define DEC_MAJ_VERSION 0
|
#define DEC_MAJ_VERSION 0
|
||||||
#define DEC_MIN_VERSION 2
|
#define DEC_MIN_VERSION 2
|
||||||
#define DEC_REV_VERSION 0
|
#define DEC_REV_VERSION 1
|
||||||
|
|
||||||
#define ONLY_KEYFRAME_CODE // to remove any code related to P-Frames
|
#define ONLY_KEYFRAME_CODE // to remove any code related to P-Frames
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,9 @@ static VP8StatusCode ParseRIFF(const uint8_t** const data,
|
||||||
if (size < TAG_SIZE + CHUNK_HEADER_SIZE) {
|
if (size < TAG_SIZE + CHUNK_HEADER_SIZE) {
|
||||||
return VP8_STATUS_BITSTREAM_ERROR;
|
return VP8_STATUS_BITSTREAM_ERROR;
|
||||||
}
|
}
|
||||||
|
if (size > MAX_CHUNK_PAYLOAD) {
|
||||||
|
return VP8_STATUS_BITSTREAM_ERROR;
|
||||||
|
}
|
||||||
// We have a RIFF container. Skip it.
|
// We have a RIFF container. Skip it.
|
||||||
*riff_size = size;
|
*riff_size = size;
|
||||||
*data += RIFF_HEADER_SIZE;
|
*data += RIFF_HEADER_SIZE;
|
||||||
|
@ -177,6 +180,9 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk_size = get_le32(buf + TAG_SIZE);
|
chunk_size = get_le32(buf + TAG_SIZE);
|
||||||
|
if (chunk_size > MAX_CHUNK_PAYLOAD) {
|
||||||
|
return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
|
||||||
|
}
|
||||||
// For odd-sized chunk-payload, there's one byte padding at the end.
|
// For odd-sized chunk-payload, there's one byte padding at the end.
|
||||||
disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
|
disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
|
||||||
total_size += disk_chunk_size;
|
total_size += disk_chunk_size;
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
|
|
||||||
#include "./dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
|
||||||
|
|
||||||
#include "../dec/vp8i.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
|
|
||||||
|
#include "../dec/vp8i.h"
|
||||||
|
|
||||||
#define QRegs "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", \
|
#define QRegs "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", \
|
||||||
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
||||||
|
|
||||||
|
@ -311,19 +311,24 @@ static void TransformTwoNEON(const int16_t* in, uint8_t* dst, int do_two) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // WEBP_USE_NEON
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Entry point
|
||||||
|
|
||||||
extern void VP8DspInitNEON(void);
|
extern void VP8DspInitNEON(void);
|
||||||
|
|
||||||
void VP8DspInitNEON(void) {
|
void VP8DspInitNEON(void) {
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
VP8Transform = TransformTwoNEON;
|
VP8Transform = TransformTwoNEON;
|
||||||
|
|
||||||
VP8SimpleVFilter16 = SimpleVFilter16NEON;
|
VP8SimpleVFilter16 = SimpleVFilter16NEON;
|
||||||
VP8SimpleHFilter16 = SimpleHFilter16NEON;
|
VP8SimpleHFilter16 = SimpleHFilter16NEON;
|
||||||
VP8SimpleVFilter16i = SimpleVFilter16iNEON;
|
VP8SimpleVFilter16i = SimpleVFilter16iNEON;
|
||||||
VP8SimpleHFilter16i = SimpleHFilter16iNEON;
|
VP8SimpleHFilter16i = SimpleHFilter16iNEON;
|
||||||
|
#endif // WEBP_USE_NEON
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WEBP_USE_NEON
|
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
|
|
||||||
#include "./dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
|
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#include "../dec/vp8i.h"
|
#include "../dec/vp8i.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Transforms (Paragraph 14.4)
|
// Transforms (Paragraph 14.4)
|
||||||
|
|
||||||
|
@ -876,9 +876,15 @@ static void HFilter8iSSE2(uint8_t* u, uint8_t* v, int stride,
|
||||||
Store16x4(u, v, stride, &p1, &p0, &q0, &q1);
|
Store16x4(u, v, stride, &p1, &p0, &q0, &q1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Entry point
|
||||||
|
|
||||||
extern void VP8DspInitSSE2(void);
|
extern void VP8DspInitSSE2(void);
|
||||||
|
|
||||||
void VP8DspInitSSE2(void) {
|
void VP8DspInitSSE2(void) {
|
||||||
|
#if defined(WEBP_USE_SSE2)
|
||||||
VP8Transform = TransformSSE2;
|
VP8Transform = TransformSSE2;
|
||||||
|
|
||||||
VP8VFilter16 = VFilter16SSE2;
|
VP8VFilter16 = VFilter16SSE2;
|
||||||
|
@ -894,10 +900,9 @@ void VP8DspInitSSE2(void) {
|
||||||
VP8SimpleHFilter16 = SimpleHFilter16SSE2;
|
VP8SimpleHFilter16 = SimpleHFilter16SSE2;
|
||||||
VP8SimpleVFilter16i = SimpleVFilter16iSSE2;
|
VP8SimpleVFilter16i = SimpleVFilter16iSSE2;
|
||||||
VP8SimpleHFilter16i = SimpleHFilter16iSSE2;
|
VP8SimpleHFilter16i = SimpleHFilter16iSSE2;
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WEBP_USE_SSE2
|
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
|
|
||||||
#include "./dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
#include <stdlib.h> // for abs()
|
#include <stdlib.h> // for abs()
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
|
|
||||||
#include "../enc/vp8enci.h"
|
#include "../enc/vp8enci.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Compute susceptibility based on DCT-coeff histograms:
|
// Compute susceptibility based on DCT-coeff histograms:
|
||||||
// the higher, the "easier" the macroblock is to compress.
|
// the higher, the "easier" the macroblock is to compress.
|
||||||
|
@ -819,8 +819,15 @@ static int QuantizeBlockSSE2(int16_t in[16], int16_t out[16],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Entry point
|
||||||
|
|
||||||
extern void VP8EncDspInitSSE2(void);
|
extern void VP8EncDspInitSSE2(void);
|
||||||
|
|
||||||
void VP8EncDspInitSSE2(void) {
|
void VP8EncDspInitSSE2(void) {
|
||||||
|
#if defined(WEBP_USE_SSE2)
|
||||||
VP8CollectHistogram = CollectHistogramSSE2;
|
VP8CollectHistogram = CollectHistogramSSE2;
|
||||||
VP8EncQuantizeBlock = QuantizeBlockSSE2;
|
VP8EncQuantizeBlock = QuantizeBlockSSE2;
|
||||||
VP8ITransform = ITransformSSE2;
|
VP8ITransform = ITransformSSE2;
|
||||||
|
@ -828,10 +835,9 @@ void VP8EncDspInitSSE2(void) {
|
||||||
VP8SSE4x4 = SSE4x4SSE2;
|
VP8SSE4x4 = SSE4x4SSE2;
|
||||||
VP8TDisto4x4 = Disto4x4SSE2;
|
VP8TDisto4x4 = Disto4x4SSE2;
|
||||||
VP8TDisto16x16 = Disto16x16SSE2;
|
VP8TDisto16x16 = Disto16x16SSE2;
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WEBP_USE_SSE2
|
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
|
|
||||||
#include "./dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -18,10 +22,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "./yuv.h"
|
#include "./yuv.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FANCY_UPSAMPLING
|
#ifdef FANCY_UPSAMPLING
|
||||||
|
|
||||||
// We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows
|
// We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows
|
||||||
|
@ -184,26 +184,32 @@ SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePairSSE2, VP8YuvToBgra, 4)
|
||||||
#undef CONVERT2RGB
|
#undef CONVERT2RGB
|
||||||
#undef SSE2_UPSAMPLE_FUNC
|
#undef SSE2_UPSAMPLE_FUNC
|
||||||
|
|
||||||
|
#endif // FANCY_UPSAMPLING
|
||||||
|
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
|
extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
|
||||||
|
|
||||||
void WebPInitUpsamplersSSE2(void) {
|
void WebPInitUpsamplersSSE2(void) {
|
||||||
|
#if defined(WEBP_USE_SSE2)
|
||||||
WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePairSSE2;
|
WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePairSSE2;
|
||||||
WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePairSSE2;
|
WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePairSSE2;
|
||||||
WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePairSSE2;
|
WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePairSSE2;
|
||||||
WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePairSSE2;
|
WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePairSSE2;
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPInitPremultiplySSE2(void) {
|
void WebPInitPremultiplySSE2(void) {
|
||||||
|
#if defined(WEBP_USE_SSE2)
|
||||||
WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePairSSE2;
|
WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePairSSE2;
|
||||||
WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePairSSE2;
|
WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePairSSE2;
|
||||||
|
#endif // WEBP_USE_SSE2
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FANCY_UPSAMPLING
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WEBP_USE_SSE2
|
|
||||||
|
|
|
@ -459,8 +459,8 @@ static int BackwardReferencesHashChainDistanceOnly(
|
||||||
const int quality = 100;
|
const int quality = 100;
|
||||||
const int pix_count = xsize * ysize;
|
const int pix_count = xsize * ysize;
|
||||||
const int use_color_cache = (cache_bits > 0);
|
const int use_color_cache = (cache_bits > 0);
|
||||||
double* const cost =
|
float* const cost =
|
||||||
(double*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*cost));
|
(float*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*cost));
|
||||||
CostModel* cost_model = (CostModel*)malloc(sizeof(*cost_model));
|
CostModel* cost_model = (CostModel*)malloc(sizeof(*cost_model));
|
||||||
HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
|
HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
|
||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
|
@ -481,7 +481,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < pix_count; ++i) cost[i] = 1e100;
|
for (i = 0; i < pix_count; ++i) cost[i] = 1e38f;
|
||||||
|
|
||||||
// We loop one pixel at a time, but store all currently best points to
|
// We loop one pixel at a time, but store all currently best points to
|
||||||
// non-processed locations from this point.
|
// non-processed locations from this point.
|
||||||
|
@ -509,10 +509,9 @@ static int BackwardReferencesHashChainDistanceOnly(
|
||||||
prev_cost + GetDistanceCost(cost_model, code);
|
prev_cost + GetDistanceCost(cost_model, code);
|
||||||
int k;
|
int k;
|
||||||
for (k = 1; k < len; ++k) {
|
for (k = 1; k < len; ++k) {
|
||||||
const double cost_val =
|
const double cost_val = distance_cost + GetLengthCost(cost_model, k);
|
||||||
distance_cost + GetLengthCost(cost_model, k);
|
|
||||||
if (cost[i + k] > cost_val) {
|
if (cost[i + k] > cost_val) {
|
||||||
cost[i + k] = cost_val;
|
cost[i + k] = (float)cost_val;
|
||||||
dist_array[i + k] = k + 1;
|
dist_array[i + k] = k + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,7 +553,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
||||||
cost_val += GetLiteralCost(cost_model, argb[i]) * mul1;
|
cost_val += GetLiteralCost(cost_model, argb[i]) * mul1;
|
||||||
}
|
}
|
||||||
if (cost[i] > cost_val) {
|
if (cost[i] > cost_val) {
|
||||||
cost[i] = cost_val;
|
cost[i] = (float)cost_val;
|
||||||
dist_array[i] = 1; // only one is inserted.
|
dist_array[i] = 1; // only one is inserted.
|
||||||
}
|
}
|
||||||
if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
||||||
|
|
|
@ -55,9 +55,9 @@ VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
|
||||||
int i;
|
int i;
|
||||||
VP8LHistogramSet* set;
|
VP8LHistogramSet* set;
|
||||||
VP8LHistogram* bulk;
|
VP8LHistogram* bulk;
|
||||||
const uint64_t total_size = (uint64_t)sizeof(*set)
|
const uint64_t total_size = sizeof(*set)
|
||||||
+ size * sizeof(*set->histograms)
|
+ (uint64_t)size * sizeof(*set->histograms)
|
||||||
+ size * sizeof(**set->histograms);
|
+ (uint64_t)size * sizeof(**set->histograms);
|
||||||
uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
|
uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
|
||||||
if (memory == NULL) return NULL;
|
if (memory == NULL) return NULL;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
||||||
// version numbers
|
// version numbers
|
||||||
#define ENC_MAJ_VERSION 0
|
#define ENC_MAJ_VERSION 0
|
||||||
#define ENC_MIN_VERSION 2
|
#define ENC_MIN_VERSION 2
|
||||||
#define ENC_REV_VERSION 0
|
#define ENC_REV_VERSION 1
|
||||||
|
|
||||||
// size of histogram used by CollectHistogram.
|
// size of histogram used by CollectHistogram.
|
||||||
#define MAX_COEFF_THRESH 64
|
#define MAX_COEFF_THRESH 64
|
||||||
|
|
|
@ -529,7 +529,12 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||||
sizeof(*histogram_symbols));
|
sizeof(*histogram_symbols));
|
||||||
assert(histogram_bits >= MIN_HUFFMAN_BITS);
|
assert(histogram_bits >= MIN_HUFFMAN_BITS);
|
||||||
assert(histogram_bits <= MAX_HUFFMAN_BITS);
|
assert(histogram_bits <= MAX_HUFFMAN_BITS);
|
||||||
if (histogram_image == NULL || histogram_symbols == NULL) goto Error;
|
|
||||||
|
if (histogram_image == NULL || histogram_symbols == NULL) {
|
||||||
|
free(histogram_image);
|
||||||
|
free(histogram_symbols);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate backward references from ARGB image.
|
// Calculate backward references from ARGB image.
|
||||||
if (!VP8LGetBackwardReferences(width, height, argb, quality, cache_bits,
|
if (!VP8LGetBackwardReferences(width, height, argb, quality, cache_bits,
|
||||||
|
@ -898,11 +903,11 @@ static int GetHistoBits(const WebPConfig* const config,
|
||||||
const WebPPicture* const pic) {
|
const WebPPicture* const pic) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
const int height = pic->height;
|
const int height = pic->height;
|
||||||
const size_t hist_size = sizeof(VP8LHistogram);
|
const uint64_t hist_size = sizeof(VP8LHistogram);
|
||||||
// Make tile size a function of encoding method (Range: 0 to 6).
|
// Make tile size a function of encoding method (Range: 0 to 6).
|
||||||
int histo_bits = 7 - config->method;
|
int histo_bits = 7 - config->method;
|
||||||
while (1) {
|
while (1) {
|
||||||
const size_t huff_image_size = VP8LSubSampleSize(width, histo_bits) *
|
const uint64_t huff_image_size = VP8LSubSampleSize(width, histo_bits) *
|
||||||
VP8LSubSampleSize(height, histo_bits) *
|
VP8LSubSampleSize(height, histo_bits) *
|
||||||
hist_size;
|
hist_size;
|
||||||
if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
|
if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
|
||||||
|
|
|
@ -93,6 +93,8 @@ static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
|
||||||
#elif (BITS == 16)
|
#elif (BITS == 16)
|
||||||
// gcc will recognize a 'rorw $8, ...' here:
|
// gcc will recognize a 'rorw $8, ...' here:
|
||||||
bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8);
|
bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8);
|
||||||
|
#else // BITS == 8
|
||||||
|
bits = (bit_t)in_bits;
|
||||||
#endif
|
#endif
|
||||||
#else // LITTLE_ENDIAN
|
#else // LITTLE_ENDIAN
|
||||||
bits = (bit_t)in_bits;
|
bits = (bit_t)in_bits;
|
||||||
|
|
Loading…
Reference in New Issue