epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 2 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 3 | * Copyright 2011 Google Inc. |
| 4 | * |
| 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 7 | */ |
| 8 | |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 9 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 10 | #define WIN32_LEAN_AND_MEAN |
| 11 | #include <Windows.h> |
| 12 | #include <wincodec.h> |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 13 | #include "SkAutoCoInitialize.h" |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 14 | #include "SkImageDecoder.h" |
| 15 | #include "SkImageEncoder.h" |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 16 | #include "SkIStream.h" |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 17 | #include "SkMovie.h" |
| 18 | #include "SkStream.h" |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 19 | #include "SkTScopedComPtr.h" |
robertphillips@google.com | 59bfb12 | 2012-11-08 15:06:52 +0000 | [diff] [blame] | 20 | #include "SkUnPreMultiply.h" |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 21 | |
bungeman@google.com | c18143e | 2013-01-11 20:02:32 +0000 | [diff] [blame] | 22 | //All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol. |
| 23 | //In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported |
| 24 | //but CLSID_WICImagingFactory is then #defined to CLSID_WICImagingFactory2. |
| 25 | //Undo this #define if it has been done so that we link against the symbols |
| 26 | //we intended to link against on all SDKs. |
| 27 | #if defined(CLSID_WICImagingFactory) |
| 28 | #undef CLSID_WICImagingFactory |
| 29 | #endif |
| 30 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 31 | class SkImageDecoder_WIC : public SkImageDecoder { |
| 32 | protected: |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 33 | virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 34 | }; |
| 35 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 36 | bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| 37 | //Initialize COM. |
bungeman@google.com | 2e2f3f5 | 2011-09-16 15:37:20 +0000 | [diff] [blame] | 38 | SkAutoCoInitialize scopedCo; |
| 39 | if (!scopedCo.succeeded()) { |
| 40 | return false; |
| 41 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 42 | |
bungeman@google.com | 2e2f3f5 | 2011-09-16 15:37:20 +0000 | [diff] [blame] | 43 | HRESULT hr = S_OK; |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 44 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 45 | //Create Windows Imaging Component ImagingFactory. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 46 | SkTScopedComPtr<IWICImagingFactory> piImagingFactory; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 47 | if (SUCCEEDED(hr)) { |
| 48 | hr = CoCreateInstance( |
| 49 | CLSID_WICImagingFactory |
| 50 | , NULL |
| 51 | , CLSCTX_INPROC_SERVER |
| 52 | , IID_PPV_ARGS(&piImagingFactory) |
| 53 | ); |
| 54 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 55 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 56 | //Convert SkStream to IStream. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 57 | SkTScopedComPtr<IStream> piStream; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 58 | if (SUCCEEDED(hr)) { |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 59 | hr = SkIStream::CreateFromSkStream(stream, false, &piStream); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 60 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 61 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 62 | //Make sure we're at the beginning of the stream. |
| 63 | if (SUCCEEDED(hr)) { |
| 64 | LARGE_INTEGER liBeginning = { 0 }; |
| 65 | hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, NULL); |
| 66 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 67 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 68 | //Create the decoder from the stream content. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 69 | SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 70 | if (SUCCEEDED(hr)) { |
| 71 | hr = piImagingFactory->CreateDecoderFromStream( |
| 72 | piStream.get() //Image to be decoded |
| 73 | , NULL //No particular vendor |
| 74 | , WICDecodeMetadataCacheOnDemand //Cache metadata when needed |
| 75 | , &piBitmapDecoder //Pointer to the decoder |
| 76 | ); |
| 77 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 78 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 79 | //Get the first frame from the decoder. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 80 | SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 81 | if (SUCCEEDED(hr)) { |
| 82 | hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); |
| 83 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 84 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 85 | //Get the BitmapSource interface of the frame. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 86 | SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 87 | if (SUCCEEDED(hr)) { |
| 88 | hr = piBitmapFrameDecode->QueryInterface( |
| 89 | IID_PPV_ARGS(&piBitmapSourceOriginal) |
| 90 | ); |
| 91 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 92 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 93 | //Get the size of the bitmap. |
| 94 | UINT width; |
| 95 | UINT height; |
| 96 | if (SUCCEEDED(hr)) { |
| 97 | hr = piBitmapSourceOriginal->GetSize(&width, &height); |
| 98 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 99 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 100 | //Exit early if we're only looking for the bitmap bounds. |
| 101 | if (SUCCEEDED(hr)) { |
| 102 | bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 103 | if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
| 104 | return true; |
| 105 | } |
| 106 | if (!this->allocPixelRef(bm, NULL)) { |
| 107 | return false; |
| 108 | } |
| 109 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 110 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 111 | //Create a format converter. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 112 | SkTScopedComPtr<IWICFormatConverter> piFormatConverter; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 113 | if (SUCCEEDED(hr)) { |
| 114 | hr = piImagingFactory->CreateFormatConverter(&piFormatConverter); |
| 115 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 116 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 117 | if (SUCCEEDED(hr)) { |
| 118 | hr = piFormatConverter->Initialize( |
| 119 | piBitmapSourceOriginal.get() //Input bitmap to convert |
| 120 | , GUID_WICPixelFormat32bppPBGRA //Destination pixel format |
| 121 | , WICBitmapDitherTypeNone //Specified dither patterm |
| 122 | , NULL //Specify a particular palette |
| 123 | , 0.f //Alpha threshold |
| 124 | , WICBitmapPaletteTypeCustom //Palette translation type |
| 125 | ); |
| 126 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 127 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 128 | //Get the BitmapSource interface of the format converter. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 129 | SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 130 | if (SUCCEEDED(hr)) { |
| 131 | hr = piFormatConverter->QueryInterface( |
| 132 | IID_PPV_ARGS(&piBitmapSourceConverted) |
| 133 | ); |
| 134 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 135 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 136 | //Copy the pixels into the bitmap. |
| 137 | if (SUCCEEDED(hr)) { |
bungeman@google.com | 955bb07 | 2011-08-01 20:18:45 +0000 | [diff] [blame] | 138 | SkAutoLockPixels alp(*bm); |
junov@google.com | dbfac8a | 2012-12-06 21:47:40 +0000 | [diff] [blame] | 139 | bm->eraseColor(SK_ColorTRANSPARENT); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 140 | const int stride = bm->rowBytes(); |
| 141 | hr = piBitmapSourceConverted->CopyPixels( |
| 142 | NULL, //Get all the pixels |
| 143 | stride, |
| 144 | stride * height, |
| 145 | reinterpret_cast<BYTE *>(bm->getPixels()) |
| 146 | ); |
robertphillips@google.com | 59bfb12 | 2012-11-08 15:06:52 +0000 | [diff] [blame] | 147 | |
| 148 | // Note: we don't need to premultiply here since we specified PBGRA |
| 149 | bm->computeAndSetOpaquePredicate(); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 150 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 151 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 152 | return SUCCEEDED(hr); |
| 153 | } |
| 154 | |
| 155 | ///////////////////////////////////////////////////////////////////////// |
| 156 | |
| 157 | SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) { |
| 158 | return SkNEW(SkImageDecoder_WIC); |
| 159 | } |
| 160 | |
| 161 | ///////////////////////////////////////////////////////////////////////// |
| 162 | |
| 163 | SkMovie* SkMovie::DecodeStream(SkStream* stream) { |
| 164 | return NULL; |
| 165 | } |
| 166 | |
| 167 | ///////////////////////////////////////////////////////////////////////// |
| 168 | |
| 169 | class SkImageEncoder_WIC : public SkImageEncoder { |
| 170 | public: |
| 171 | SkImageEncoder_WIC(Type t) : fType(t) {} |
| 172 | |
| 173 | protected: |
| 174 | virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); |
| 175 | |
| 176 | private: |
| 177 | Type fType; |
| 178 | }; |
| 179 | |
| 180 | bool SkImageEncoder_WIC::onEncode(SkWStream* stream |
bungeman@google.com | 22b4950 | 2011-08-01 19:37:43 +0000 | [diff] [blame] | 181 | , const SkBitmap& bitmapOrig |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 182 | , int quality) |
| 183 | { |
| 184 | GUID type; |
| 185 | switch (fType) { |
| 186 | case kJPEG_Type: |
| 187 | type = GUID_ContainerFormatJpeg; |
| 188 | break; |
| 189 | case kPNG_Type: |
| 190 | type = GUID_ContainerFormatPng; |
| 191 | break; |
| 192 | default: |
| 193 | return false; |
| 194 | } |
| 195 | |
bungeman@google.com | 22b4950 | 2011-08-01 19:37:43 +0000 | [diff] [blame] | 196 | //Convert to 8888 if needed. |
| 197 | const SkBitmap* bitmap; |
| 198 | SkBitmap bitmapCopy; |
robertphillips@google.com | 59bfb12 | 2012-11-08 15:06:52 +0000 | [diff] [blame] | 199 | if (SkBitmap::kARGB_8888_Config == bitmapOrig.config() && bitmapOrig.isOpaque()) { |
bungeman@google.com | 22b4950 | 2011-08-01 19:37:43 +0000 | [diff] [blame] | 200 | bitmap = &bitmapOrig; |
| 201 | } else { |
| 202 | if (!bitmapOrig.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config)) { |
| 203 | return false; |
| 204 | } |
| 205 | bitmap = &bitmapCopy; |
| 206 | } |
| 207 | |
robertphillips@google.com | 59bfb12 | 2012-11-08 15:06:52 +0000 | [diff] [blame] | 208 | // We cannot use PBGRA so we need to unpremultiply ourselves |
| 209 | if (!bitmap->isOpaque()) { |
| 210 | SkAutoLockPixels alp(*bitmap); |
| 211 | |
| 212 | uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels()); |
| 213 | for (int y = 0; y < bitmap->height(); ++y) { |
| 214 | for (int x = 0; x < bitmap->width(); ++x) { |
| 215 | uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel(); |
| 216 | |
| 217 | SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes); |
| 218 | SkColor* dst = reinterpret_cast<SkColor*>(bytes); |
| 219 | |
| 220 | *dst = SkUnPreMultiply::PMColorToColor(*src); |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 225 | //Initialize COM. |
bungeman@google.com | 2e2f3f5 | 2011-09-16 15:37:20 +0000 | [diff] [blame] | 226 | SkAutoCoInitialize scopedCo; |
| 227 | if (!scopedCo.succeeded()) { |
| 228 | return false; |
| 229 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 230 | |
bungeman@google.com | 2e2f3f5 | 2011-09-16 15:37:20 +0000 | [diff] [blame] | 231 | HRESULT hr = S_OK; |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 232 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 233 | //Create Windows Imaging Component ImagingFactory. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 234 | SkTScopedComPtr<IWICImagingFactory> piImagingFactory; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 235 | if (SUCCEEDED(hr)) { |
| 236 | hr = CoCreateInstance( |
| 237 | CLSID_WICImagingFactory |
| 238 | , NULL |
| 239 | , CLSCTX_INPROC_SERVER |
| 240 | , IID_PPV_ARGS(&piImagingFactory) |
| 241 | ); |
| 242 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 243 | |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 244 | //Convert the SkWStream to an IStream. |
| 245 | SkTScopedComPtr<IStream> piStream; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 246 | if (SUCCEEDED(hr)) { |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 247 | hr = SkWIStream::CreateFromSkWStream(stream, &piStream); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 248 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 249 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 250 | //Create an encode of the appropriate type. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 251 | SkTScopedComPtr<IWICBitmapEncoder> piEncoder; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 252 | if (SUCCEEDED(hr)) { |
| 253 | hr = piImagingFactory->CreateEncoder(type, NULL, &piEncoder); |
| 254 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 255 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 256 | if (SUCCEEDED(hr)) { |
| 257 | hr = piEncoder->Initialize(piStream.get(), WICBitmapEncoderNoCache); |
| 258 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 259 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 260 | //Create a the frame. |
bungeman@google.com | 9df621d | 2011-06-23 21:43:52 +0000 | [diff] [blame] | 261 | SkTScopedComPtr<IWICBitmapFrameEncode> piBitmapFrameEncode; |
| 262 | SkTScopedComPtr<IPropertyBag2> piPropertybag; |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 263 | if (SUCCEEDED(hr)) { |
| 264 | hr = piEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertybag); |
| 265 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 266 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 267 | if (SUCCEEDED(hr)) { |
| 268 | PROPBAG2 name = { 0 }; |
| 269 | name.dwType = PROPBAG2_TYPE_DATA; |
| 270 | name.vt = VT_R4; |
| 271 | name.pstrName = L"ImageQuality"; |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 272 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 273 | VARIANT value; |
| 274 | VariantInit(&value); |
| 275 | value.vt = VT_R4; |
| 276 | value.fltVal = (FLOAT)(quality / 100.0); |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 277 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 278 | //Ignore result code. |
| 279 | // This returns E_FAIL if the named property is not in the bag. |
| 280 | //TODO(bungeman) enumerate the properties, |
| 281 | // write and set hr iff property exists. |
| 282 | piPropertybag->Write(1, &name, &value); |
| 283 | } |
| 284 | if (SUCCEEDED(hr)) { |
| 285 | hr = piBitmapFrameEncode->Initialize(piPropertybag.get()); |
| 286 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 287 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 288 | //Set the size of the frame. |
bungeman@google.com | 22b4950 | 2011-08-01 19:37:43 +0000 | [diff] [blame] | 289 | const UINT width = bitmap->width(); |
| 290 | const UINT height = bitmap->height(); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 291 | if (SUCCEEDED(hr)) { |
| 292 | hr = piBitmapFrameEncode->SetSize(width, height); |
| 293 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 294 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 295 | //Set the pixel format of the frame. |
| 296 | const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA; |
| 297 | WICPixelFormatGUID formatGUID = formatDesired; |
| 298 | if (SUCCEEDED(hr)) { |
| 299 | hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID); |
| 300 | } |
| 301 | if (SUCCEEDED(hr)) { |
| 302 | //Be sure the image format is the one requested. |
| 303 | hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL; |
| 304 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 305 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 306 | //Write the pixels into the frame. |
| 307 | if (SUCCEEDED(hr)) { |
bungeman@google.com | 955bb07 | 2011-08-01 20:18:45 +0000 | [diff] [blame] | 308 | SkAutoLockPixels alp(*bitmap); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 309 | hr = piBitmapFrameEncode->WritePixels( |
| 310 | height |
bungeman@google.com | 22b4950 | 2011-08-01 19:37:43 +0000 | [diff] [blame] | 311 | , bitmap->rowBytes() |
| 312 | , bitmap->rowBytes()*height |
| 313 | , reinterpret_cast<BYTE*>(bitmap->getPixels())); |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 314 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 315 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 316 | if (SUCCEEDED(hr)) { |
| 317 | hr = piBitmapFrameEncode->Commit(); |
| 318 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 319 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 320 | if (SUCCEEDED(hr)) { |
| 321 | hr = piEncoder->Commit(); |
| 322 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 323 | |
bungeman@google.com | 242bb89 | 2011-06-22 20:42:34 +0000 | [diff] [blame] | 324 | return SUCCEEDED(hr); |
| 325 | } |
| 326 | |
| 327 | SkImageEncoder* SkImageEncoder::Create(Type t) { |
| 328 | switch (t) { |
| 329 | case kJPEG_Type: |
| 330 | case kPNG_Type: |
| 331 | break; |
| 332 | default: |
| 333 | return NULL; |
| 334 | } |
| 335 | return SkNEW_ARGS(SkImageEncoder_WIC, (t)); |
| 336 | } |