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 = E_FAIL; IWICStream* pStream = NULL; if (NULL != pFact) { hr = pFact->CreateStream(&pStream); } if (SUCCEEDED(hr)) { hr = pStream->InitializeFromFilename(StringUtf8ToWideChar(path).c_str(), GENERIC_WRITE); } IWICBitmapEncoder* pEnc = NULL; if (SUCCEEDED(hr)) { hr = pFact->CreateEncoder(containerFormat, NULL, &pEnc); } if (SUCCEEDED(hr)) { hr = pEnc->Initialize(pStream, WICBitmapEncoderNoCache); } IWICBitmapFrameEncode* pFrame = NULL; IPropertyBag2* pProp = NULL; if (SUCCEEDED(hr)) { hr = pEnc->CreateNewFrame(&pFrame, &pProp); } if (SUCCEEDED(hr)) { hr = pFrame->Initialize(pProp); } if (SUCCEEDED(hr)) { hr = pFrame->SetSize(width, height); } if (SUCCEEDED(hr)) { WICPixelFormatGUID targetFormat = pixelFormat; hr = pFrame->SetPixelFormat(&targetFormat); if (targetFormat != pixelFormat) { hr = E_INVALIDARG; } } if (SUCCEEDED(hr)) { size_t bpp = getBitsPerPixel(pixelFormat); size_t stride = (width * bpp + 7) / 8; hr = pFrame->WritePixels(height, static_cast<UINT>(stride), static_cast<UINT>(dataLen), (BYTE*)data); } if (SUCCEEDED(hr)) { hr = pFrame->Commit(); } if (SUCCEEDED(hr)) { hr = pEnc->Commit(); } SafeRelease(&pStream); SafeRelease(&pEnc); SafeRelease(&pFrame); SafeRelease(&pProp); return SUCCEEDED(hr); }
bool WICImageLoader::decodeImageData(ImageBlob blob, size_t size) { bool bRet = false; HRESULT hr = E_FAIL; IWICStream* pWicStream = NULL; IWICImagingFactory* pWicFactory = getWICFactory(); if(NULL != pWicFactory) { hr = pWicFactory->CreateStream(&pWicStream); } if(SUCCEEDED(hr)) { hr = pWicStream->InitializeFromMemory((BYTE*)blob, static_cast<DWORD>(size)); } IWICBitmapDecoder* pDecoder = NULL; if(SUCCEEDED(hr)) { hr = pWicFactory->CreateDecoderFromStream(pWicStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder); } bRet = processImage(pDecoder); SafeRelease(&pWicStream); SafeRelease(&pDecoder); return bRet; }
HRESULT WICImageLoader::convertFormatIfRequired(IWICBitmapFrameDecode* pFrame, IWICFormatConverter** ppConv) { *ppConv = NULL; if( (memcmp(&_format, &GUID_WICPixelFormat8bppGray, sizeof(WICPixelFormatGUID)) == 0) || (memcmp(&_format, &GUID_WICPixelFormat8bppAlpha, sizeof(WICPixelFormatGUID)) == 0) || (memcmp(&_format, &GUID_WICPixelFormat24bppRGB, sizeof(WICPixelFormatGUID)) == 0) || (memcmp(&_format, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID)) == 0)) { return S_OK; } HRESULT hr = E_FAIL; IWICImagingFactory* pFactory = getWICFactory(); IWICFormatConverter* pConv = NULL; if(NULL != pFactory) { hr = pFactory->CreateFormatConverter(&pConv); } WICPixelFormatGUID destFormat = GUID_WICPixelFormat32bppRGBA; // Fallback to RGBA 32-bit format which is supported by all devices for( size_t i=0; i < _countof(g_WICConvert); ++i ) { if ( memcmp( &g_WICConvert[i].source, &_format, sizeof(WICPixelFormatGUID) ) == 0 ) { memcpy( &destFormat, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); break; } } BOOL bCanConv = FALSE; if(SUCCEEDED(hr)) { hr = pConv->CanConvert(_format, destFormat, &bCanConv); } if(SUCCEEDED(hr) && bCanConv == TRUE) { hr = pConv->Initialize(pFrame, destFormat, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom); } if(SUCCEEDED(hr)) { memcpy(&_format, &destFormat, sizeof(WICPixelFormatGUID)); *ppConv = pConv; } return SUCCEEDED(hr); }
size_t WICImageLoader::getBitsPerPixel(WICPixelFormatGUID format) { HRESULT hr = E_FAIL; IWICImagingFactory* pfactory = getWICFactory(); IWICComponentInfo* pCInfo = NULL; if(pfactory != NULL) { hr = pfactory->CreateComponentInfo(format, &pCInfo); } WICComponentType cType; if(SUCCEEDED(hr)) { hr = pCInfo->GetComponentType(&cType); } IWICPixelFormatInfo* pPInfo = NULL; if(SUCCEEDED(hr) && cType == WICPixelFormat) { hr = pCInfo->QueryInterface(IID_IWICPixelFormatInfo, (void**)&pPInfo); } UINT bpp = 0; if(SUCCEEDED(hr)) { hr = pPInfo->GetBitsPerPixel(&bpp); } SafeRelease(&pCInfo); SafeRelease(&pPInfo); return bpp; }
bool WICImageLoader::encodeImageData(std::string path, ImageBlob 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; IWICStream* pStream = NULL; if(NULL != pFact) { hr = pFact->CreateStream(&pStream); } if(SUCCEEDED(hr)) { std::wstring wpath; wpath.assign(path.begin(), path.end()); hr = pStream->InitializeFromFilename(wpath.c_str(), GENERIC_WRITE); } IWICBitmapEncoder* pEnc = NULL; if(SUCCEEDED(hr)) { hr = pFact->CreateEncoder(containerFormat, NULL, &pEnc); } if(SUCCEEDED(hr)) { hr = pEnc->Initialize(pStream, WICBitmapEncoderNoCache); } IWICBitmapFrameEncode* pFrame = NULL; IPropertyBag2* pProp = NULL; if(SUCCEEDED(hr)) { hr = pEnc->CreateNewFrame(&pFrame, &pProp); } if(SUCCEEDED(hr)) { hr = pFrame->Initialize(pProp); } if(SUCCEEDED(hr)) { hr = pFrame->SetSize(width, height); } if(SUCCEEDED(hr)) { hr = pFrame->SetPixelFormat(&pixelFormat); } 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)) { hr = pFrame->Commit(); } if(SUCCEEDED(hr)) { hr = pEnc->Commit(); } SafeRelease(&pStream); SafeRelease(&pEnc); SafeRelease(&pFrame); SafeRelease(&pProp); return SUCCEEDED(hr); }