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) 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;
WICImageLoader img; if (targetFormat == GUID_WICPixelFormat24bppBGR && _renderFormat == Texture2D::PixelFormat::RGBA8888)
return img.encodeImageData(filePath, _data, _dataLen, format, _width, _height, containerFormat); {
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;
bRet = img.encodeImageData(filePath, pSaveData, saveLen, targetFormat, _width, _height, containerFormat);
delete[] pSaveData;
return bRet;
} }
#endif //CC_USE_WIC #endif //CC_USE_WIC
bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen) bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen)

View File

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

View File

@ -59,7 +59,7 @@ public:
WICPixelFormatGUID getPixelFormat(); WICPixelFormatGUID getPixelFormat();
int getImageData(ImageBlob rawData, size_t dataLen); int getImageData(ImageBlob rawData, size_t dataLen);
bool decodeImageData(ImageBlob data, 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: protected:
bool processImage(IWICBitmapDecoder* decoder); bool processImage(IWICBitmapDecoder* decoder);