OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #define WIN32_LEAN_AND_MEAN | 10 #define WIN32_LEAN_AND_MEAN |
(...skipping 11 matching lines...) Expand all Loading... |
22 //All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol. | 22 //All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol. |
23 //In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported | 23 //In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported |
24 //but CLSID_WICImagingFactory is then #defined to CLSID_WICImagingFactory2. | 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 | 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. | 26 //we intended to link against on all SDKs. |
27 #if defined(CLSID_WICImagingFactory) | 27 #if defined(CLSID_WICImagingFactory) |
28 #undef CLSID_WICImagingFactory | 28 #undef CLSID_WICImagingFactory |
29 #endif | 29 #endif |
30 | 30 |
31 class SkImageDecoder_WIC : public SkImageDecoder { | 31 class SkImageDecoder_WIC : public SkImageDecoder { |
| 32 public: |
| 33 virtual Format getFormat() const SK_OVERRIDE { return kMultiple_Formats; } |
| 34 |
| 35 virtual Format onGetFormat(SkStream*) const SK_OVERRIDE; |
| 36 |
32 protected: | 37 protected: |
33 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode); | 38 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE
; |
| 39 |
| 40 private: |
| 41 // Decoding modes corresponding to SkImageDecoder::Mode, plus an extra mode
for decoding |
| 42 // only the format. |
| 43 enum WICModes { |
| 44 kDecodeFormat_WICMode, |
| 45 kDecodeBounds_WICMode, |
| 46 kDecodePixels_WICMode, |
| 47 }; |
| 48 |
| 49 /** |
| 50 * Helper function to decode an SkStream. |
| 51 * @param stream SkStream to decode. Must be at the beginning. |
| 52 * @param bm SkBitmap to decode into. Only used if wicMode is kDecodeBoun
ds_WICMode or |
| 53 * kDecodePixels_WICMode, in which case it must not be NULL. |
| 54 * @param format Out parameter for the SkImageDecoder::Format of the SkStre
am. Only used if |
| 55 * wicMode is kDecodeFormat_WICMode. |
| 56 */ |
| 57 bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format*
format) const; |
34 }; | 58 }; |
35 | 59 |
| 60 struct FormatConversion { |
| 61 GUID fGuidFormat; |
| 62 SkImageDecoder::Format fFormat; |
| 63 }; |
| 64 |
| 65 static const FormatConversion gFormatConversions[] = { |
| 66 { GUID_ContainerFormatBmp, SkImageDecoder::kBMP_Format }, |
| 67 { GUID_ContainerFormatGif, SkImageDecoder::kGIF_Format }, |
| 68 { GUID_ContainerFormatIco, SkImageDecoder::kICO_Format }, |
| 69 { GUID_ContainerFormatJpeg, SkImageDecoder::kJPEG_Format }, |
| 70 { GUID_ContainerFormatPng, SkImageDecoder::kPNG_Format }, |
| 71 }; |
| 72 |
| 73 static SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) { |
| 74 for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) { |
| 75 if (IsEqualGUID(guid, gFormatConversions[i].fGuidFormat)) { |
| 76 return gFormatConversions[i].fFormat; |
| 77 } |
| 78 } |
| 79 return SkImageDecoder::kUnknown_Format; |
| 80 } |
| 81 |
36 bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | 82 bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| 83 WICModes wicMode; |
| 84 switch (mode) { |
| 85 case SkImageDecoder::kDecodeBounds_Mode: |
| 86 wicMode = kDecodeBounds_WICMode; |
| 87 break; |
| 88 case SkImageDecoder::kDecodePixels_Mode: |
| 89 wicMode = kDecodePixels_WICMode; |
| 90 break; |
| 91 } |
| 92 return this->decodeStream(stream, bm, wicMode, NULL); |
| 93 } |
| 94 |
| 95 SkImageDecoder::Format SkImageDecoder_WIC::onGetFormat(SkStream* stream) const { |
| 96 Format format; |
| 97 if (!this->decodeStream(stream, NULL, kDecodeFormat_WICMode, &format)) { |
| 98 format = kUnknown_Format; |
| 99 } |
| 100 return format; |
| 101 } |
| 102 |
| 103 bool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes w
icMode, |
| 104 Format* format) const { |
37 //Initialize COM. | 105 //Initialize COM. |
38 SkAutoCoInitialize scopedCo; | 106 SkAutoCoInitialize scopedCo; |
39 if (!scopedCo.succeeded()) { | 107 if (!scopedCo.succeeded()) { |
40 return false; | 108 return false; |
41 } | 109 } |
42 | 110 |
43 HRESULT hr = S_OK; | 111 HRESULT hr = S_OK; |
44 | 112 |
45 //Create Windows Imaging Component ImagingFactory. | 113 //Create Windows Imaging Component ImagingFactory. |
46 SkTScopedComPtr<IWICImagingFactory> piImagingFactory; | 114 SkTScopedComPtr<IWICImagingFactory> piImagingFactory; |
(...skipping 22 matching lines...) Expand all Loading... |
69 SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; | 137 SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; |
70 if (SUCCEEDED(hr)) { | 138 if (SUCCEEDED(hr)) { |
71 hr = piImagingFactory->CreateDecoderFromStream( | 139 hr = piImagingFactory->CreateDecoderFromStream( |
72 piStream.get() //Image to be decoded | 140 piStream.get() //Image to be decoded |
73 , NULL //No particular vendor | 141 , NULL //No particular vendor |
74 , WICDecodeMetadataCacheOnDemand //Cache metadata when needed | 142 , WICDecodeMetadataCacheOnDemand //Cache metadata when needed |
75 , &piBitmapDecoder //Pointer to the decoder | 143 , &piBitmapDecoder //Pointer to the decoder |
76 ); | 144 ); |
77 } | 145 } |
78 | 146 |
| 147 if (kDecodeFormat_WICMode == wicMode) { |
| 148 SkASSERT(format != NULL); |
| 149 //Get the format |
| 150 if (SUCCEEDED(hr)) { |
| 151 GUID guidFormat; |
| 152 hr = piBitmapDecoder->GetContainerFormat(&guidFormat); |
| 153 if (SUCCEEDED(hr)) { |
| 154 *format = GuidContainerFormat_to_Format(guidFormat); |
| 155 return true; |
| 156 } |
| 157 } |
| 158 return false; |
| 159 } |
| 160 |
79 //Get the first frame from the decoder. | 161 //Get the first frame from the decoder. |
80 SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; | 162 SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; |
81 if (SUCCEEDED(hr)) { | 163 if (SUCCEEDED(hr)) { |
82 hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); | 164 hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); |
83 } | 165 } |
84 | 166 |
85 //Get the BitmapSource interface of the frame. | 167 //Get the BitmapSource interface of the frame. |
86 SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; | 168 SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; |
87 if (SUCCEEDED(hr)) { | 169 if (SUCCEEDED(hr)) { |
88 hr = piBitmapFrameDecode->QueryInterface( | 170 hr = piBitmapFrameDecode->QueryInterface( |
89 IID_PPV_ARGS(&piBitmapSourceOriginal) | 171 IID_PPV_ARGS(&piBitmapSourceOriginal) |
90 ); | 172 ); |
91 } | 173 } |
92 | 174 |
93 //Get the size of the bitmap. | 175 //Get the size of the bitmap. |
94 UINT width; | 176 UINT width; |
95 UINT height; | 177 UINT height; |
96 if (SUCCEEDED(hr)) { | 178 if (SUCCEEDED(hr)) { |
97 hr = piBitmapSourceOriginal->GetSize(&width, &height); | 179 hr = piBitmapSourceOriginal->GetSize(&width, &height); |
98 } | 180 } |
99 | 181 |
100 //Exit early if we're only looking for the bitmap bounds. | 182 //Exit early if we're only looking for the bitmap bounds. |
101 if (SUCCEEDED(hr)) { | 183 if (SUCCEEDED(hr)) { |
102 bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); | 184 bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
103 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 185 if (kDecodeBounds_WICMode == wicMode) { |
104 return true; | 186 return true; |
105 } | 187 } |
106 if (!this->allocPixelRef(bm, NULL)) { | 188 if (!this->allocPixelRef(bm, NULL)) { |
107 return false; | 189 return false; |
108 } | 190 } |
109 } | 191 } |
110 | 192 |
111 //Create a format converter. | 193 //Create a format converter. |
112 SkTScopedComPtr<IWICFormatConverter> piFormatConverter; | 194 SkTScopedComPtr<IWICFormatConverter> piFormatConverter; |
113 if (SUCCEEDED(hr)) { | 195 if (SUCCEEDED(hr)) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 | 269 |
188 bool SkImageEncoder_WIC::onEncode(SkWStream* stream | 270 bool SkImageEncoder_WIC::onEncode(SkWStream* stream |
189 , const SkBitmap& bitmapOrig | 271 , const SkBitmap& bitmapOrig |
190 , int quality) | 272 , int quality) |
191 { | 273 { |
192 GUID type; | 274 GUID type; |
193 switch (fType) { | 275 switch (fType) { |
194 case kBMP_Type: | 276 case kBMP_Type: |
195 type = GUID_ContainerFormatBmp; | 277 type = GUID_ContainerFormatBmp; |
196 break; | 278 break; |
197 case kGIF_Type: | |
198 type = GUID_ContainerFormatGif; | |
199 break; | |
200 case kICO_Type: | 279 case kICO_Type: |
201 type = GUID_ContainerFormatIco; | 280 type = GUID_ContainerFormatIco; |
202 break; | 281 break; |
203 case kJPEG_Type: | 282 case kJPEG_Type: |
204 type = GUID_ContainerFormatJpeg; | 283 type = GUID_ContainerFormatJpeg; |
205 break; | 284 break; |
206 case kPNG_Type: | 285 case kPNG_Type: |
207 type = GUID_ContainerFormatPng; | 286 type = GUID_ContainerFormatPng; |
208 break; | 287 break; |
209 default: | 288 default: |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 return SUCCEEDED(hr); | 420 return SUCCEEDED(hr); |
342 } | 421 } |
343 | 422 |
344 /////////////////////////////////////////////////////////////////////////////// | 423 /////////////////////////////////////////////////////////////////////////////// |
345 | 424 |
346 #include "SkTRegistry.h" | 425 #include "SkTRegistry.h" |
347 | 426 |
348 static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { | 427 static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { |
349 switch (t) { | 428 switch (t) { |
350 case SkImageEncoder::kBMP_Type: | 429 case SkImageEncoder::kBMP_Type: |
351 case SkImageEncoder::kGIF_Type: | |
352 case SkImageEncoder::kICO_Type: | 430 case SkImageEncoder::kICO_Type: |
353 case SkImageEncoder::kJPEG_Type: | 431 case SkImageEncoder::kJPEG_Type: |
354 case SkImageEncoder::kPNG_Type: | 432 case SkImageEncoder::kPNG_Type: |
355 break; | 433 break; |
356 default: | 434 default: |
357 return NULL; | 435 return NULL; |
358 } | 436 } |
359 return SkNEW_ARGS(SkImageEncoder_WIC, (t)); | 437 return SkNEW_ARGS(SkImageEncoder_WIC, (t)); |
360 } | 438 } |
361 | 439 |
362 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_
wic_factory); | 440 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_
wic_factory); |
OLD | NEW |