fix for encoding images with WIC

This commit is contained in:
Dale Stammen 2015-04-17 09:20:23 -07:00
parent 425b2b62e1
commit 2ccff5671a
3 changed files with 56 additions and 29 deletions

View File

@ -880,12 +880,45 @@ bool Image::decodeWithWIC(const unsigned char *data, ssize_t dataLen)
bool Image::encodeWithWIC(const std::string& filePath, bool isToRGB, GUID containerFormat)
{
WICPixelFormatGUID format = isToRGB ? GUID_WICPixelFormat24bppRGB : GUID_WICPixelFormat32bppRGBA;
// Save formats supported by WIC
WICPixelFormatGUID targetFormat = isToRGB ? GUID_WICPixelFormat24bppBGR : GUID_WICPixelFormat32bppBGRA;
unsigned char *pSaveData = nullptr;
int saveLen = _dataLen;
int bpp = 4;
if (targetFormat == GUID_WICPixelFormat24bppBGR && _renderFormat == Texture2D::PixelFormat::RGBA8888)
{
bpp = 3;
saveLen = _width * _height * bpp;
pSaveData = new unsigned char[saveLen];
int indL = 0, indR = 0;
while (indL < saveLen && indR < _dataLen)
{
memcpy(&pSaveData[indL], &_data[indR], 3);
indL += 3;
indR += 4;
}
}
else
{
pSaveData = new unsigned char[saveLen];
memcpy(pSaveData, _data, saveLen);
}
for (int ind = 2; ind < saveLen; ind += bpp) {
std::swap(pSaveData[ind - 2], pSaveData[ind]);
}
bool bRet = false;
WICImageLoader img;
return img.encodeImageData(filePath, _data, _dataLen, format, _width, _height, containerFormat);
bRet = img.encodeImageData(filePath, pSaveData, saveLen, targetFormat, _width, _height, containerFormat);
delete[] pSaveData;
return bRet;
}
#endif //CC_USE_WIC
bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen)

View File

@ -325,23 +325,21 @@ WICPixelFormatGUID WICImageLoader::getPixelFormat()
return _format;
}
bool WICImageLoader::encodeImageData(std::string path, ImageBlob data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat)
bool WICImageLoader::encodeImageData(std::string path, const unsigned char* data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat)
{
assert(data != NULL);
assert(dataLen > 0 && width > 0 && height > 0);
IWICImagingFactory* pFact = getWICFactory();
HRESULT hr = S_FALSE;
HRESULT hr = E_FAIL;
IWICStream* pStream = NULL;
if(NULL != pFact)
{
if (NULL != pFact) {
hr = pFact->CreateStream(&pStream);
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
std::wstring wpath;
wpath.assign(path.begin(), path.end());
hr = pStream->InitializeFromFilename(wpath.c_str(), GENERIC_WRITE);
@ -349,54 +347,50 @@ bool WICImageLoader::encodeImageData(std::string path, ImageBlob data, size_t da
IWICBitmapEncoder* pEnc = NULL;
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pFact->CreateEncoder(containerFormat, NULL, &pEnc);
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pEnc->Initialize(pStream, WICBitmapEncoderNoCache);
}
IWICBitmapFrameEncode* pFrame = NULL;
IPropertyBag2* pProp = NULL;
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pEnc->CreateNewFrame(&pFrame, &pProp);
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pFrame->Initialize(pProp);
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pFrame->SetSize(width, height);
}
if(SUCCEEDED(hr))
{
hr = pFrame->SetPixelFormat(&pixelFormat);
if (SUCCEEDED(hr)) {
WICPixelFormatGUID targetFormat = pixelFormat;
hr = pFrame->SetPixelFormat(&targetFormat);
if (targetFormat != pixelFormat) {
hr = E_INVALIDARG;
}
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
size_t bpp = getBitsPerPixel(pixelFormat);
size_t stride = (width * bpp + 7) / 8;
hr = pFrame->WritePixels(height, stride, dataLen, (BYTE*)data);
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pFrame->Commit();
}
if(SUCCEEDED(hr))
{
if (SUCCEEDED(hr)) {
hr = pEnc->Commit();
}

View File

@ -59,7 +59,7 @@ public:
WICPixelFormatGUID getPixelFormat();
int getImageData(ImageBlob rawData, size_t dataLen);
bool decodeImageData(ImageBlob data, size_t dataLen);
bool encodeImageData(std::string path, ImageBlob data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat);
bool encodeImageData(std::string path, const unsigned char* data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat);
protected:
bool processImage(IWICBitmapDecoder* decoder);