1242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com */ 8242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 985302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#include "SkTypes.h" 1085302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com 111ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#if defined(SK_BUILD_FOR_WIN32) 121ee76510f5dbf632d30975fc3509ef4f609156d2mtklein 1385302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// Workaround for: 1485302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// http://connect.microsoft.com/VisualStudio/feedback/details/621653/ 1585302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// http://crbug.com/225822 1685302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// In VS2010 both intsafe.h and stdint.h define the following without guards. 1785302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// SkTypes brought in windows.h and stdint.h and the following defines are 1885302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// not used by this file. However, they may be re-introduced by wincodec.h. 1985302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT8_MIN 2085302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT16_MIN 2185302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT32_MIN 2285302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT64_MIN 2385302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT8_MAX 2485302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef UINT8_MAX 2585302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT16_MAX 2685302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef UINT16_MAX 2785302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT32_MAX 2885302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef UINT32_MAX 2985302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef INT64_MAX 3085302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#undef UINT64_MAX 31ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 32242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include <wincodec.h> 339df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com#include "SkAutoCoInitialize.h" 34242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include "SkImageDecoder.h" 35242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include "SkImageEncoder.h" 369df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com#include "SkIStream.h" 37242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include "SkMovie.h" 38242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include "SkStream.h" 399df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com#include "SkTScopedComPtr.h" 4059bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com#include "SkUnPreMultiply.h" 41242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 42c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com//All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol. 43c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com//In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported 44c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com//but CLSID_WICImagingFactory is then #defined to CLSID_WICImagingFactory2. 45c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com//Undo this #define if it has been done so that we link against the symbols 46c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com//we intended to link against on all SDKs. 47c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com#if defined(CLSID_WICImagingFactory) 48c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com#undef CLSID_WICImagingFactory 49c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com#endif 50c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.com 51242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comclass SkImageDecoder_WIC : public SkImageDecoder { 5239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.compublic: 5339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com // Decoding modes corresponding to SkImageDecoder::Mode, plus an extra mode for decoding 5439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com // only the format. 5539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com enum WICModes { 5639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com kDecodeFormat_WICMode, 5739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com kDecodeBounds_WICMode, 5839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com kDecodePixels_WICMode, 5939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com }; 6039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 6139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com /** 6239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com * Helper function to decode an SkStream. 6339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com * @param stream SkStream to decode. Must be at the beginning. 6439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com * @param bm SkBitmap to decode into. Only used if wicMode is kDecodeBounds_WICMode or 6596fcdcc219d2a0d3579719b84b28bede76efba64halcanary * kDecodePixels_WICMode, in which case it must not be nullptr. 6639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com * @param format Out parameter for the SkImageDecoder::Format of the SkStream. Only used if 6739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com * wicMode is kDecodeFormat_WICMode. 6839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com */ 6939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format* format) const; 7039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 71242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comprotected: 7236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override; 7339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com}; 7439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 7539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comstruct FormatConversion { 7639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com GUID fGuidFormat; 7739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com SkImageDecoder::Format fFormat; 78242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}; 79242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 8039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comstatic const FormatConversion gFormatConversions[] = { 8139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com { GUID_ContainerFormatBmp, SkImageDecoder::kBMP_Format }, 8239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com { GUID_ContainerFormatGif, SkImageDecoder::kGIF_Format }, 8339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com { GUID_ContainerFormatIco, SkImageDecoder::kICO_Format }, 8439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com { GUID_ContainerFormatJpeg, SkImageDecoder::kJPEG_Format }, 8539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com { GUID_ContainerFormatPng, SkImageDecoder::kPNG_Format }, 8639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com}; 8739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 8839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comstatic SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) { 8939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) { 9039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (IsEqualGUID(guid, gFormatConversions[i].fGuidFormat)) { 9139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return gFormatConversions[i].fFormat; 9239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 9339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 9439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return SkImageDecoder::kUnknown_Format; 9539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com} 9639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 972a1208017dd676f94a53bbb228197c3978dbdd8ascroggoSkImageDecoder::Result SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { 9839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com WICModes wicMode; 9939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com switch (mode) { 10039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case SkImageDecoder::kDecodeBounds_Mode: 10139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com wicMode = kDecodeBounds_WICMode; 10239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com break; 10339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com case SkImageDecoder::kDecodePixels_Mode: 10439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com wicMode = kDecodePixels_WICMode; 10539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com break; 10639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 10796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return this->decodeStream(stream, bm, wicMode, nullptr) ? kSuccess : kFailure; 10839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com} 10939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 11039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.combool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, 11139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com Format* format) const { 112242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Initialize COM. 1132e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com SkAutoCoInitialize scopedCo; 1142e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com if (!scopedCo.succeeded()) { 1152e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com return false; 1162e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com } 117d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 1182e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com HRESULT hr = S_OK; 119d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 120242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Create Windows Imaging Component ImagingFactory. 1219df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICImagingFactory> piImagingFactory; 122242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 123242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = CoCreateInstance( 124242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com CLSID_WICImagingFactory 12596fcdcc219d2a0d3579719b84b28bede76efba64halcanary , nullptr 126242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , CLSCTX_INPROC_SERVER 127242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , IID_PPV_ARGS(&piImagingFactory) 128242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 129242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 130d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 131242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Convert SkStream to IStream. 1329df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IStream> piStream; 133242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 1349df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com hr = SkIStream::CreateFromSkStream(stream, false, &piStream); 135242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 136d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 137242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Make sure we're at the beginning of the stream. 138242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 139242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com LARGE_INTEGER liBeginning = { 0 }; 14096fcdcc219d2a0d3579719b84b28bede76efba64halcanary hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, nullptr); 141242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 142d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 143242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Create the decoder from the stream content. 1449df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; 145242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 146242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piImagingFactory->CreateDecoderFromStream( 147242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com piStream.get() //Image to be decoded 14896fcdcc219d2a0d3579719b84b28bede76efba64halcanary , nullptr //No particular vendor 149242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , WICDecodeMetadataCacheOnDemand //Cache metadata when needed 150242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , &piBitmapDecoder //Pointer to the decoder 151242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 152242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 15439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (kDecodeFormat_WICMode == wicMode) { 15596fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(format != nullptr); 15639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com //Get the format 15739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (SUCCEEDED(hr)) { 15839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com GUID guidFormat; 15939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com hr = piBitmapDecoder->GetContainerFormat(&guidFormat); 16039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (SUCCEEDED(hr)) { 16139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com *format = GuidContainerFormat_to_Format(guidFormat); 16239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return true; 16339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 16439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 16539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return false; 16639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 16739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 168242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Get the first frame from the decoder. 1699df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; 170242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 171242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); 172242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 173d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 174242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Get the BitmapSource interface of the frame. 1759df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; 176242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 177242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapFrameDecode->QueryInterface( 178242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com IID_PPV_ARGS(&piBitmapSourceOriginal) 179242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 180242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 182242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Get the size of the bitmap. 183242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com UINT width; 184242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com UINT height; 185242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 186242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapSourceOriginal->GetSize(&width, &height); 187242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 188d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 189242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Exit early if we're only looking for the bitmap bounds. 190242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 191a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org bm->setInfo(SkImageInfo::MakeN32Premul(width, height)); 19239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (kDecodeBounds_WICMode == wicMode) { 193242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com return true; 194242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 19596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!this->allocPixelRef(bm, nullptr)) { 196242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com return false; 197242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 198242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 199d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 200242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Create a format converter. 2019df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICFormatConverter> piFormatConverter; 202242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 203242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piImagingFactory->CreateFormatConverter(&piFormatConverter); 204242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 2062bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com GUID destinationPixelFormat; 2072bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com if (this->getRequireUnpremultipliedColors()) { 2082bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com destinationPixelFormat = GUID_WICPixelFormat32bppBGRA; 2092bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com } else { 2102bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com destinationPixelFormat = GUID_WICPixelFormat32bppPBGRA; 2112bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com } 2122bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com 213242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 214242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piFormatConverter->Initialize( 215242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com piBitmapSourceOriginal.get() //Input bitmap to convert 2162bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com , destinationPixelFormat //Destination pixel format 217242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , WICBitmapDitherTypeNone //Specified dither patterm 21896fcdcc219d2a0d3579719b84b28bede76efba64halcanary , nullptr //Specify a particular palette 219242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , 0.f //Alpha threshold 220242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , WICBitmapPaletteTypeCustom //Palette translation type 221242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 222242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 223d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 224242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Get the BitmapSource interface of the format converter. 2259df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted; 226242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 227242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piFormatConverter->QueryInterface( 228242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com IID_PPV_ARGS(&piBitmapSourceConverted) 229242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 230242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 231d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 232242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Copy the pixels into the bitmap. 233242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 234955bb0751a0d48e47a341c7c0adda94977bc8170bungeman@google.com SkAutoLockPixels alp(*bm); 235dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com bm->eraseColor(SK_ColorTRANSPARENT); 2368b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com const UINT stride = (UINT) bm->rowBytes(); 237242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapSourceConverted->CopyPixels( 23896fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, //Get all the pixels 239242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com stride, 240242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com stride * height, 241242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com reinterpret_cast<BYTE *>(bm->getPixels()) 242242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 24359bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com 24459bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com // Note: we don't need to premultiply here since we specified PBGRA 245e7e29b7815e97e9c4db55fa9dac48b419352b2c6reed@google.com if (SkBitmap::ComputeIsOpaque(*bm)) { 246383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com bm->setAlphaType(kOpaque_SkAlphaType); 247383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com } 248242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 249d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 250242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com return SUCCEEDED(hr); 251242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com} 252242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 253242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com///////////////////////////////////////////////////////////////////////// 254242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 255b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comextern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); 2564c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com 257b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comSkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) { 2584c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com SkImageDecoder* decoder = image_decoder_from_stream(stream); 25996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == decoder) { 2604c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com // If no image decoder specific to the stream exists, use SkImageDecoder_WIC. 261385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkImageDecoder_WIC; 2624c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com } else { 2634c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com return decoder; 2644c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com } 265242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com} 266242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 267242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com///////////////////////////////////////////////////////////////////////// 268242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 269b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comSkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) { 27096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 271242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com} 272242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 273242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com///////////////////////////////////////////////////////////////////////// 274242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 275242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comclass SkImageEncoder_WIC : public SkImageEncoder { 276242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.compublic: 277242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com SkImageEncoder_WIC(Type t) : fType(t) {} 278242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 279242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comprotected: 280242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); 281242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 282242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comprivate: 283242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com Type fType; 284242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}; 285242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 286242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.combool SkImageEncoder_WIC::onEncode(SkWStream* stream 28722b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com , const SkBitmap& bitmapOrig 288242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , int quality) 289242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com{ 290242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com GUID type; 291242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com switch (fType) { 2924c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com case kBMP_Type: 2934c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com type = GUID_ContainerFormatBmp; 2944c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com break; 2954c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com case kICO_Type: 2964c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com type = GUID_ContainerFormatIco; 2974c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com break; 298242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com case kJPEG_Type: 299242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com type = GUID_ContainerFormatJpeg; 300242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com break; 301242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com case kPNG_Type: 302242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com type = GUID_ContainerFormatPng; 303242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com break; 304242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com default: 305242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com return false; 306242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 307242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 30822b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com //Convert to 8888 if needed. 30922b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com const SkBitmap* bitmap; 31022b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com SkBitmap bitmapCopy; 31128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org if (kN32_SkColorType == bitmapOrig.colorType() && bitmapOrig.isOpaque()) { 31222b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com bitmap = &bitmapOrig; 31322b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com } else { 31428fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org if (!bitmapOrig.copyTo(&bitmapCopy, kN32_SkColorType)) { 31522b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com return false; 31622b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com } 31722b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com bitmap = &bitmapCopy; 31822b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com } 31922b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com 32059bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com // We cannot use PBGRA so we need to unpremultiply ourselves 32159bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com if (!bitmap->isOpaque()) { 32259bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com SkAutoLockPixels alp(*bitmap); 32359bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com 32459bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels()); 32559bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com for (int y = 0; y < bitmap->height(); ++y) { 32659bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com for (int x = 0; x < bitmap->width(); ++x) { 32759bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel(); 32859bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com 32959bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes); 33059bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com SkColor* dst = reinterpret_cast<SkColor*>(bytes); 33159bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com 33259bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com *dst = SkUnPreMultiply::PMColorToColor(*src); 33359bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com } 33459bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com } 33559bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com } 33659bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com 337242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Initialize COM. 3382e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com SkAutoCoInitialize scopedCo; 3392e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com if (!scopedCo.succeeded()) { 3402e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com return false; 3412e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com } 342d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 3432e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com HRESULT hr = S_OK; 344d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 345242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Create Windows Imaging Component ImagingFactory. 3469df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICImagingFactory> piImagingFactory; 347242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 348242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = CoCreateInstance( 349242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com CLSID_WICImagingFactory 35096fcdcc219d2a0d3579719b84b28bede76efba64halcanary , nullptr 351242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , CLSCTX_INPROC_SERVER 352242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com , IID_PPV_ARGS(&piImagingFactory) 353242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com ); 354242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 355d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 3569df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com //Convert the SkWStream to an IStream. 3579df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IStream> piStream; 358242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 3599df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com hr = SkWIStream::CreateFromSkWStream(stream, &piStream); 360242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 361d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 362242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Create an encode of the appropriate type. 3639df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICBitmapEncoder> piEncoder; 364242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 36596fcdcc219d2a0d3579719b84b28bede76efba64halcanary hr = piImagingFactory->CreateEncoder(type, nullptr, &piEncoder); 366242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 367d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 368242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 369242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piEncoder->Initialize(piStream.get(), WICBitmapEncoderNoCache); 370242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 371d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 372242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Create a the frame. 3739df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IWICBitmapFrameEncode> piBitmapFrameEncode; 3749df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com SkTScopedComPtr<IPropertyBag2> piPropertybag; 375242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 376242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag); 377242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 378d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 379242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 380242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com PROPBAG2 name = { 0 }; 381242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com name.dwType = PROPBAG2_TYPE_DATA; 382242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com name.vt = VT_R4; 383242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com name.pstrName = L"ImageQuality"; 384d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 385242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com VARIANT value; 386242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com VariantInit(&value); 387242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com value.vt = VT_R4; 388242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com value.fltVal = (FLOAT)(quality / 100.0); 389d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 390242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Ignore result code. 391242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com // This returns E_FAIL if the named property is not in the bag. 392242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //TODO(bungeman) enumerate the properties, 393242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com // write and set hr iff property exists. 394242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com piPropertybag->Write(1, &name, &value); 395242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 396242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 397242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapFrameEncode->Initialize(piPropertybag.get()); 398242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 399d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 400242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Set the size of the frame. 40122b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com const UINT width = bitmap->width(); 40222b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com const UINT height = bitmap->height(); 403242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 404242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapFrameEncode->SetSize(width, height); 405242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 406d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 407242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Set the pixel format of the frame. 408242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA; 409242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com WICPixelFormatGUID formatGUID = formatDesired; 410242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 411242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID); 412242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 413242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 414242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Be sure the image format is the one requested. 415242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL; 416242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 417d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 418242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com //Write the pixels into the frame. 419242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 420955bb0751a0d48e47a341c7c0adda94977bc8170bungeman@google.com SkAutoLockPixels alp(*bitmap); 4218b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com const UINT stride = (UINT) bitmap->rowBytes(); 422242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapFrameEncode->WritePixels( 423242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com height 4244b18f5767ab1df7fedf0ff2e3a9eac7f7c500c36bungeman@google.com , stride 4254b18f5767ab1df7fedf0ff2e3a9eac7f7c500c36bungeman@google.com , stride * height 42622b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com , reinterpret_cast<BYTE*>(bitmap->getPixels())); 427242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 428d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 429242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 430242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piBitmapFrameEncode->Commit(); 431242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 432d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 433242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com if (SUCCEEDED(hr)) { 434242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com hr = piEncoder->Commit(); 435242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 436d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 437242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com return SUCCEEDED(hr); 438242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com} 439242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com 4404c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com/////////////////////////////////////////////////////////////////////////////// 4414c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com 4424c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.comstatic SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { 443242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com switch (t) { 4444c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com case SkImageEncoder::kBMP_Type: 4454c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com case SkImageEncoder::kICO_Type: 4464c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com case SkImageEncoder::kJPEG_Type: 4474c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com case SkImageEncoder::kPNG_Type: 448242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com break; 449242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com default: 45096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 451242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com } 452385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkImageEncoder_WIC(t); 453242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com} 4544c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com 455b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comstatic SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory); 45639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 457b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comstatic SkImageDecoder::Format get_format_wic(SkStreamRewindable* stream) { 45839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com SkImageDecoder::Format format; 45939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com SkImageDecoder_WIC codec; 46096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!codec.decodeStream(stream, nullptr, SkImageDecoder_WIC::kDecodeFormat_WICMode, &format)) { 46139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com format = SkImageDecoder::kUnknown_Format; 46239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 46339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return format; 46439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com} 46539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 466b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comstatic SkImageDecoder_FormatReg gFormatReg(get_format_wic); 4671ee76510f5dbf632d30975fc3509ef4f609156d2mtklein 4681ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#endif // defined(SK_BUILD_FOR_WIN32) 469