1e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2011 Google Inc. 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 7e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com */ 8e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 9685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 10e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#define WIN32_LEAN_AND_MEAN 11e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#include <Windows.h> 12e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#include <wincodec.h> 13fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com#include "SkAutoCoInitialize.h" 14e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#include "SkImageDecoder.h" 15e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#include "SkImageEncoder.h" 16fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com#include "SkIStream.h" 17e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#include "SkMovie.h" 18e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com#include "SkStream.h" 19fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com#include "SkTScopedComPtr.h" 2069d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com#include "SkUnPreMultiply.h" 21e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 22c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com//All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol. 23c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com//In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported 24c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com//but CLSID_WICImagingFactory is then #defined to CLSID_WICImagingFactory2. 25c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com//Undo this #define if it has been done so that we link against the symbols 26c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com//we intended to link against on all SDKs. 27c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com#if defined(CLSID_WICImagingFactory) 28c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com#undef CLSID_WICImagingFactory 29c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com#endif 30c83bd26b9bd5e6942de2cd4e1b7cdb8f939cb5cabungeman@google.com 31e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comclass SkImageDecoder_WIC : public SkImageDecoder { 3206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.compublic: 3306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com // Decoding modes corresponding to SkImageDecoder::Mode, plus an extra mode for decoding 3406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com // only the format. 3506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com enum WICModes { 3606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com kDecodeFormat_WICMode, 3706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com kDecodeBounds_WICMode, 3806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com kDecodePixels_WICMode, 3906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com }; 4006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 4106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com /** 4206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com * Helper function to decode an SkStream. 4306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com * @param stream SkStream to decode. Must be at the beginning. 4406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com * @param bm SkBitmap to decode into. Only used if wicMode is kDecodeBounds_WICMode or 4506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com * kDecodePixels_WICMode, in which case it must not be NULL. 4606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com * @param format Out parameter for the SkImageDecoder::Format of the SkStream. Only used if 4706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com * wicMode is kDecodeFormat_WICMode. 4806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com */ 4906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format* format) const; 5006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 51e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comprotected: 5206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE; 5306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com}; 5406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 5506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstruct FormatConversion { 5606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com GUID fGuidFormat; 5706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com SkImageDecoder::Format fFormat; 58e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com}; 59e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 6006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstatic const FormatConversion gFormatConversions[] = { 6106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com { GUID_ContainerFormatBmp, SkImageDecoder::kBMP_Format }, 6206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com { GUID_ContainerFormatGif, SkImageDecoder::kGIF_Format }, 6306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com { GUID_ContainerFormatIco, SkImageDecoder::kICO_Format }, 6406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com { GUID_ContainerFormatJpeg, SkImageDecoder::kJPEG_Format }, 6506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com { GUID_ContainerFormatPng, SkImageDecoder::kPNG_Format }, 6606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com}; 6706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 6806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstatic SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) { 6906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) { 7006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (IsEqualGUID(guid, gFormatConversions[i].fGuidFormat)) { 7106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return gFormatConversions[i].fFormat; 7206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 7306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 7406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return SkImageDecoder::kUnknown_Format; 7506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com} 7606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 77e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.combool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { 7806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com WICModes wicMode; 7906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com switch (mode) { 8006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case SkImageDecoder::kDecodeBounds_Mode: 8106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com wicMode = kDecodeBounds_WICMode; 8206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com break; 8306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com case SkImageDecoder::kDecodePixels_Mode: 8406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com wicMode = kDecodePixels_WICMode; 8506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com break; 8606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 8706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return this->decodeStream(stream, bm, wicMode, NULL); 8806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com} 8906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 9006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.combool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, 9106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com Format* format) const { 92e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Initialize COM. 939560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com SkAutoCoInitialize scopedCo; 949560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com if (!scopedCo.succeeded()) { 959560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com return false; 969560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com } 97dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 989560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com HRESULT hr = S_OK; 99dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 100e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Create Windows Imaging Component ImagingFactory. 101fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICImagingFactory> piImagingFactory; 102e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 103e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = CoCreateInstance( 104e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com CLSID_WICImagingFactory 105e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , NULL 106e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , CLSCTX_INPROC_SERVER 107e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , IID_PPV_ARGS(&piImagingFactory) 108e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 109e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 110dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 111e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Convert SkStream to IStream. 112fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IStream> piStream; 113e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 114fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com hr = SkIStream::CreateFromSkStream(stream, false, &piStream); 115e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 116dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 117e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Make sure we're at the beginning of the stream. 118e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 119e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com LARGE_INTEGER liBeginning = { 0 }; 120e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, NULL); 121e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 122dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 123e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Create the decoder from the stream content. 124fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; 125e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 126e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piImagingFactory->CreateDecoderFromStream( 127e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com piStream.get() //Image to be decoded 128e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , NULL //No particular vendor 129e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , WICDecodeMetadataCacheOnDemand //Cache metadata when needed 130e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , &piBitmapDecoder //Pointer to the decoder 131e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 132e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 133dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 13406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (kDecodeFormat_WICMode == wicMode) { 13506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com SkASSERT(format != NULL); 13606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com //Get the format 13706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (SUCCEEDED(hr)) { 13806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com GUID guidFormat; 13906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com hr = piBitmapDecoder->GetContainerFormat(&guidFormat); 14006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (SUCCEEDED(hr)) { 14106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com *format = GuidContainerFormat_to_Format(guidFormat); 14206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return true; 14306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 14406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 14506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return false; 14606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 14706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 148e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Get the first frame from the decoder. 149fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; 150e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 151e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); 152e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 153dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 154e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Get the BitmapSource interface of the frame. 155fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; 156e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 157e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapFrameDecode->QueryInterface( 158e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com IID_PPV_ARGS(&piBitmapSourceOriginal) 159e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 160e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 161dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 162e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Get the size of the bitmap. 163e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com UINT width; 164e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com UINT height; 165e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 166e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapSourceOriginal->GetSize(&width, &height); 167e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 168dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 169e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Exit early if we're only looking for the bitmap bounds. 170e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 171e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); 17206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (kDecodeBounds_WICMode == wicMode) { 173e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return true; 174e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 175e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (!this->allocPixelRef(bm, NULL)) { 176e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return false; 177e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 178e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 179dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 180e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Create a format converter. 181fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICFormatConverter> piFormatConverter; 182e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 183e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piImagingFactory->CreateFormatConverter(&piFormatConverter); 184e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 185dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 186746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com GUID destinationPixelFormat; 187746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com if (this->getRequireUnpremultipliedColors()) { 188746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com destinationPixelFormat = GUID_WICPixelFormat32bppBGRA; 189746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com } else { 190746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com destinationPixelFormat = GUID_WICPixelFormat32bppPBGRA; 191746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com } 192746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com 193e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 194e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piFormatConverter->Initialize( 195e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com piBitmapSourceOriginal.get() //Input bitmap to convert 196746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com , destinationPixelFormat //Destination pixel format 197e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , WICBitmapDitherTypeNone //Specified dither patterm 198e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , NULL //Specify a particular palette 199e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , 0.f //Alpha threshold 200e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , WICBitmapPaletteTypeCustom //Palette translation type 201e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 202e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 203dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 204e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Get the BitmapSource interface of the format converter. 205fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted; 206e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 207e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piFormatConverter->QueryInterface( 208e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com IID_PPV_ARGS(&piBitmapSourceConverted) 209e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 210e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 211dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 212e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Copy the pixels into the bitmap. 213e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 2149a92670322442238277aa5a998c0841762ba7d41bungeman@google.com SkAutoLockPixels alp(*bm); 2156d7b99540d86e79bbc47dc0904f68a96eeb21c8cjunov@google.com bm->eraseColor(SK_ColorTRANSPARENT); 21604f3a5586b17cb4b4d2dc1ea2389d0e6691182e6bungeman@google.com const UINT stride = bm->rowBytes(); 217e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapSourceConverted->CopyPixels( 218e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com NULL, //Get all the pixels 219e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com stride, 220e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com stride * height, 221e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com reinterpret_cast<BYTE *>(bm->getPixels()) 222e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 22369d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com 22469d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com // Note: we don't need to premultiply here since we specified PBGRA 22569d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com bm->computeAndSetOpaquePredicate(); 226e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 227dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 228e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return SUCCEEDED(hr); 229e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com} 230e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 231e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com///////////////////////////////////////////////////////////////////////// 232e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 2339759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.comextern SkImageDecoder* image_decoder_from_stream(SkStream*); 2349759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com 235e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comSkImageDecoder* SkImageDecoder::Factory(SkStream* stream) { 2369759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com SkImageDecoder* decoder = image_decoder_from_stream(stream); 2379759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com if (NULL == decoder) { 2389759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com // If no image decoder specific to the stream exists, use SkImageDecoder_WIC. 2399759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com return SkNEW(SkImageDecoder_WIC); 2409759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com } else { 2419759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com return decoder; 2429759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com } 243e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com} 244e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 245e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com///////////////////////////////////////////////////////////////////////// 246e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 247e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comSkMovie* SkMovie::DecodeStream(SkStream* stream) { 248e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return NULL; 249e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com} 250e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 251e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com///////////////////////////////////////////////////////////////////////// 252e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 253e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comclass SkImageEncoder_WIC : public SkImageEncoder { 254e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.compublic: 255e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com SkImageEncoder_WIC(Type t) : fType(t) {} 256e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 257e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comprotected: 258e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); 259e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 260e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.comprivate: 261e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com Type fType; 262e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com}; 263e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 264e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.combool SkImageEncoder_WIC::onEncode(SkWStream* stream 265513776788194d255b64831265c30e6fdebf95f87bungeman@google.com , const SkBitmap& bitmapOrig 266e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , int quality) 267e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com{ 268e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com GUID type; 269e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com switch (fType) { 2709759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com case kBMP_Type: 2719759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com type = GUID_ContainerFormatBmp; 2729759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com break; 2739759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com case kICO_Type: 2749759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com type = GUID_ContainerFormatIco; 2759759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com break; 276e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com case kJPEG_Type: 277e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com type = GUID_ContainerFormatJpeg; 278e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com break; 279e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com case kPNG_Type: 280e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com type = GUID_ContainerFormatPng; 281e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com break; 282e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com default: 283e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return false; 284e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 285e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 286513776788194d255b64831265c30e6fdebf95f87bungeman@google.com //Convert to 8888 if needed. 287513776788194d255b64831265c30e6fdebf95f87bungeman@google.com const SkBitmap* bitmap; 288513776788194d255b64831265c30e6fdebf95f87bungeman@google.com SkBitmap bitmapCopy; 28969d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com if (SkBitmap::kARGB_8888_Config == bitmapOrig.config() && bitmapOrig.isOpaque()) { 290513776788194d255b64831265c30e6fdebf95f87bungeman@google.com bitmap = &bitmapOrig; 291513776788194d255b64831265c30e6fdebf95f87bungeman@google.com } else { 292513776788194d255b64831265c30e6fdebf95f87bungeman@google.com if (!bitmapOrig.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config)) { 293513776788194d255b64831265c30e6fdebf95f87bungeman@google.com return false; 294513776788194d255b64831265c30e6fdebf95f87bungeman@google.com } 295513776788194d255b64831265c30e6fdebf95f87bungeman@google.com bitmap = &bitmapCopy; 296513776788194d255b64831265c30e6fdebf95f87bungeman@google.com } 297513776788194d255b64831265c30e6fdebf95f87bungeman@google.com 29869d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com // We cannot use PBGRA so we need to unpremultiply ourselves 29969d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com if (!bitmap->isOpaque()) { 30069d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com SkAutoLockPixels alp(*bitmap); 30169d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com 30269d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels()); 30369d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com for (int y = 0; y < bitmap->height(); ++y) { 30469d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com for (int x = 0; x < bitmap->width(); ++x) { 30569d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel(); 30669d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com 30769d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes); 30869d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com SkColor* dst = reinterpret_cast<SkColor*>(bytes); 30969d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com 31069d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com *dst = SkUnPreMultiply::PMColorToColor(*src); 31169d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com } 31269d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com } 31369d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com } 31469d808cde9dea1d0c77ee6ad86f1cf3cff639254robertphillips@google.com 315e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Initialize COM. 3169560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com SkAutoCoInitialize scopedCo; 3179560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com if (!scopedCo.succeeded()) { 3189560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com return false; 3199560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com } 320dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 3219560b5d45b5aa6461acd75f79f796619dd84d491bungeman@google.com HRESULT hr = S_OK; 322dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 323e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Create Windows Imaging Component ImagingFactory. 324fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICImagingFactory> piImagingFactory; 325e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 326e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = CoCreateInstance( 327e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com CLSID_WICImagingFactory 328e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , NULL 329e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , CLSCTX_INPROC_SERVER 330e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com , IID_PPV_ARGS(&piImagingFactory) 331e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com ); 332e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 333dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 334fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com //Convert the SkWStream to an IStream. 335fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IStream> piStream; 336e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 337fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com hr = SkWIStream::CreateFromSkWStream(stream, &piStream); 338e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 339dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 340e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Create an encode of the appropriate type. 341fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICBitmapEncoder> piEncoder; 342e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 343e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piImagingFactory->CreateEncoder(type, NULL, &piEncoder); 344e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 345dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 346e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 347e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piEncoder->Initialize(piStream.get(), WICBitmapEncoderNoCache); 348e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 349dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 350e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Create a the frame. 351fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IWICBitmapFrameEncode> piBitmapFrameEncode; 352fb1875a762d3cf7d7fdb2adb802a7eb5190031f4bungeman@google.com SkTScopedComPtr<IPropertyBag2> piPropertybag; 353e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 354e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag); 355e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 356dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 357e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 358e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com PROPBAG2 name = { 0 }; 359e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com name.dwType = PROPBAG2_TYPE_DATA; 360e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com name.vt = VT_R4; 361e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com name.pstrName = L"ImageQuality"; 362dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 363e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com VARIANT value; 364e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com VariantInit(&value); 365e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com value.vt = VT_R4; 366e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com value.fltVal = (FLOAT)(quality / 100.0); 367dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 368e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Ignore result code. 369e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com // This returns E_FAIL if the named property is not in the bag. 370e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //TODO(bungeman) enumerate the properties, 371e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com // write and set hr iff property exists. 372e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com piPropertybag->Write(1, &name, &value); 373e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 374e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 375e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapFrameEncode->Initialize(piPropertybag.get()); 376e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 377dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 378e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Set the size of the frame. 379513776788194d255b64831265c30e6fdebf95f87bungeman@google.com const UINT width = bitmap->width(); 380513776788194d255b64831265c30e6fdebf95f87bungeman@google.com const UINT height = bitmap->height(); 381e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 382e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapFrameEncode->SetSize(width, height); 383e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 384dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 385e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Set the pixel format of the frame. 386e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA; 387e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com WICPixelFormatGUID formatGUID = formatDesired; 388e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 389e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID); 390e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 391e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 392e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Be sure the image format is the one requested. 393e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL; 394e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 395dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 396e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com //Write the pixels into the frame. 397e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 3989a92670322442238277aa5a998c0841762ba7d41bungeman@google.com SkAutoLockPixels alp(*bitmap); 39904f3a5586b17cb4b4d2dc1ea2389d0e6691182e6bungeman@google.com const UINT stride = bitmap->rowBytes(); 400e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapFrameEncode->WritePixels( 401e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com height 40204f3a5586b17cb4b4d2dc1ea2389d0e6691182e6bungeman@google.com , stride 40304f3a5586b17cb4b4d2dc1ea2389d0e6691182e6bungeman@google.com , stride * height 404513776788194d255b64831265c30e6fdebf95f87bungeman@google.com , reinterpret_cast<BYTE*>(bitmap->getPixels())); 405e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 406dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 407e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 408e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piBitmapFrameEncode->Commit(); 409e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 410dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 411e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com if (SUCCEEDED(hr)) { 412e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com hr = piEncoder->Commit(); 413e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 414dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 415e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return SUCCEEDED(hr); 416e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com} 417e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com 4189759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com/////////////////////////////////////////////////////////////////////////////// 4199759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com 4209759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com#include "SkTRegistry.h" 4219759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com 4229759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.comstatic SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { 423e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com switch (t) { 4249759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com case SkImageEncoder::kBMP_Type: 4259759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com case SkImageEncoder::kICO_Type: 4269759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com case SkImageEncoder::kJPEG_Type: 4279759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com case SkImageEncoder::kPNG_Type: 428e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com break; 429e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com default: 430e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return NULL; 431e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com } 432e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com return SkNEW_ARGS(SkImageEncoder_WIC, (t)); 433e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com} 4349759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.com 4359759beb59fc6bb942229f2ace8980ca52dbf25f4scroggo@google.comstatic SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_wic_factory); 43606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 43706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstatic SkImageDecoder::Format get_format_wic(SkStream* stream) { 43806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com SkImageDecoder::Format format; 43906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com SkImageDecoder_WIC codec; 44006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com if (!codec.decodeStream(stream, NULL, SkImageDecoder_WIC::kDecodeFormat_WICMode, &format)) { 44106a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com format = SkImageDecoder::kUnknown_Format; 44206a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com } 44306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com return format; 44406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com} 44506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com 44606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstatic SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_wic); 447