mirror of https://github.com/axmolengine/axmol.git
fix for encoding images with WIC
This commit is contained in:
parent
425b2b62e1
commit
2ccff5671a
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue