static HRESULT CopyPixelsHelper(IWICBitmapSource* source, bool flipVertically, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) { HRESULT hr = S_OK; IWICImagingFactory* pWIC = _GetWIC(); if (!pWIC) return E_NOINTERFACE; if (flipVertically) { ComPtr<IWICBitmapFlipRotator> pFlipRotator; hr = pWIC->CreateBitmapFlipRotator(&pFlipRotator); if (FAILED(hr)) return hr; hr = pFlipRotator->Initialize(source, WICBitmapTransformFlipVertical); if (FAILED(hr)) return hr; hr = pFlipRotator->CopyPixels(0, cbStride, cbBufferSize, pbBuffer); if (FAILED(hr)) return hr; } else { hr = source->CopyPixels(0, cbStride, cbBufferSize, pbBuffer); if (FAILED(hr)) return hr; } return hr; }
//------------------------------------------------------------------------------------- // Do flip/rotate operation using WIC //------------------------------------------------------------------------------------- static HRESULT _PerformFlipRotateUsingWIC( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const WICPixelFormatGUID& pfGUID, _In_ const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; assert( srcImage.format == destImage.format ); IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ScopedObject<IWICBitmap> source; HRESULT hr = pWIC->CreateBitmapFromMemory( static_cast<UINT>( srcImage.width ), static_cast<UINT>( srcImage.height ), pfGUID, static_cast<UINT>( srcImage.rowPitch ), static_cast<UINT>( srcImage.slicePitch ), srcImage.pixels, &source ); if ( FAILED(hr) ) return hr; ScopedObject<IWICBitmapFlipRotator> FR; hr = pWIC->CreateBitmapFlipRotator( &FR ); if ( FAILED(hr) ) return hr; hr = FR->Initialize( source.Get(), static_cast<WICBitmapTransformOptions>( flags ) ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfFR; hr = FR->GetPixelFormat( &pfFR ); if ( FAILED(hr) ) return hr; if ( memcmp( &pfFR, &pfGUID, sizeof(GUID) ) != 0 ) { // Flip/rotate should return the same format as the source... return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } UINT nwidth, nheight; hr = FR->GetSize( &nwidth, &nheight ); if ( FAILED(hr) ) return hr; if ( destImage.width != nwidth || destImage.height != nheight ) return E_FAIL; hr = FR->CopyPixels( 0, static_cast<UINT>( destImage.rowPitch ), static_cast<UINT>( destImage.slicePitch ), destImage.pixels ); if ( FAILED(hr) ) return hr; return S_OK; }