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 // Decoding modes corresponding to SkImageDecoder::Mode, plus an extra mode
for decoding |
| 34 // only the format. |
| 35 enum WICModes { |
| 36 kDecodeFormat_WICMode, |
| 37 kDecodeBounds_WICMode, |
| 38 kDecodePixels_WICMode, |
| 39 }; |
| 40 |
| 41 /** |
| 42 * Helper function to decode an SkStream. |
| 43 * @param stream SkStream to decode. Must be at the beginning. |
| 44 * @param bm SkBitmap to decode into. Only used if wicMode is kDecodeBoun
ds_WICMode or |
| 45 * kDecodePixels_WICMode, in which case it must not be NULL. |
| 46 * @param format Out parameter for the SkImageDecoder::Format of the SkStre
am. Only used if |
| 47 * wicMode is kDecodeFormat_WICMode. |
| 48 */ |
| 49 bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format*
format) const; |
| 50 |
32 protected: | 51 protected: |
33 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode); | 52 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE
; |
34 }; | 53 }; |
35 | 54 |
| 55 struct FormatConversion { |
| 56 GUID fGuidFormat; |
| 57 SkImageDecoder::Format fFormat; |
| 58 }; |
| 59 |
| 60 static const FormatConversion gFormatConversions[] = { |
| 61 { GUID_ContainerFormatBmp, SkImageDecoder::kBMP_Format }, |
| 62 { GUID_ContainerFormatGif, SkImageDecoder::kGIF_Format }, |
| 63 { GUID_ContainerFormatIco, SkImageDecoder::kICO_Format }, |
| 64 { GUID_ContainerFormatJpeg, SkImageDecoder::kJPEG_Format }, |
| 65 { GUID_ContainerFormatPng, SkImageDecoder::kPNG_Format }, |
| 66 }; |
| 67 |
| 68 static SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) { |
| 69 for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) { |
| 70 if (IsEqualGUID(guid, gFormatConversions[i].fGuidFormat)) { |
| 71 return gFormatConversions[i].fFormat; |
| 72 } |
| 73 } |
| 74 return SkImageDecoder::kUnknown_Format; |
| 75 } |
| 76 |
36 bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | 77 bool SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| 78 WICModes wicMode; |
| 79 switch (mode) { |
| 80 case SkImageDecoder::kDecodeBounds_Mode: |
| 81 wicMode = kDecodeBounds_WICMode; |
| 82 break; |
| 83 case SkImageDecoder::kDecodePixels_Mode: |
| 84 wicMode = kDecodePixels_WICMode; |
| 85 break; |
| 86 } |
| 87 return this->decodeStream(stream, bm, wicMode, NULL); |
| 88 } |
| 89 |
| 90 bool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes w
icMode, |
| 91 Format* format) const { |
37 //Initialize COM. | 92 //Initialize COM. |
38 SkAutoCoInitialize scopedCo; | 93 SkAutoCoInitialize scopedCo; |
39 if (!scopedCo.succeeded()) { | 94 if (!scopedCo.succeeded()) { |
40 return false; | 95 return false; |
41 } | 96 } |
42 | 97 |
43 HRESULT hr = S_OK; | 98 HRESULT hr = S_OK; |
44 | 99 |
45 //Create Windows Imaging Component ImagingFactory. | 100 //Create Windows Imaging Component ImagingFactory. |
46 SkTScopedComPtr<IWICImagingFactory> piImagingFactory; | 101 SkTScopedComPtr<IWICImagingFactory> piImagingFactory; |
(...skipping 22 matching lines...) Expand all Loading... |
69 SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; | 124 SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; |
70 if (SUCCEEDED(hr)) { | 125 if (SUCCEEDED(hr)) { |
71 hr = piImagingFactory->CreateDecoderFromStream( | 126 hr = piImagingFactory->CreateDecoderFromStream( |
72 piStream.get() //Image to be decoded | 127 piStream.get() //Image to be decoded |
73 , NULL //No particular vendor | 128 , NULL //No particular vendor |
74 , WICDecodeMetadataCacheOnDemand //Cache metadata when needed | 129 , WICDecodeMetadataCacheOnDemand //Cache metadata when needed |
75 , &piBitmapDecoder //Pointer to the decoder | 130 , &piBitmapDecoder //Pointer to the decoder |
76 ); | 131 ); |
77 } | 132 } |
78 | 133 |
| 134 if (kDecodeFormat_WICMode == wicMode) { |
| 135 SkASSERT(format != NULL); |
| 136 //Get the format |
| 137 if (SUCCEEDED(hr)) { |
| 138 GUID guidFormat; |
| 139 hr = piBitmapDecoder->GetContainerFormat(&guidFormat); |
| 140 if (SUCCEEDED(hr)) { |
| 141 *format = GuidContainerFormat_to_Format(guidFormat); |
| 142 return true; |
| 143 } |
| 144 } |
| 145 return false; |
| 146 } |
| 147 |
79 //Get the first frame from the decoder. | 148 //Get the first frame from the decoder. |
80 SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; | 149 SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; |
81 if (SUCCEEDED(hr)) { | 150 if (SUCCEEDED(hr)) { |
82 hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); | 151 hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); |
83 } | 152 } |
84 | 153 |
85 //Get the BitmapSource interface of the frame. | 154 //Get the BitmapSource interface of the frame. |
86 SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; | 155 SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; |
87 if (SUCCEEDED(hr)) { | 156 if (SUCCEEDED(hr)) { |
88 hr = piBitmapFrameDecode->QueryInterface( | 157 hr = piBitmapFrameDecode->QueryInterface( |
89 IID_PPV_ARGS(&piBitmapSourceOriginal) | 158 IID_PPV_ARGS(&piBitmapSourceOriginal) |
90 ); | 159 ); |
91 } | 160 } |
92 | 161 |
93 //Get the size of the bitmap. | 162 //Get the size of the bitmap. |
94 UINT width; | 163 UINT width; |
95 UINT height; | 164 UINT height; |
96 if (SUCCEEDED(hr)) { | 165 if (SUCCEEDED(hr)) { |
97 hr = piBitmapSourceOriginal->GetSize(&width, &height); | 166 hr = piBitmapSourceOriginal->GetSize(&width, &height); |
98 } | 167 } |
99 | 168 |
100 //Exit early if we're only looking for the bitmap bounds. | 169 //Exit early if we're only looking for the bitmap bounds. |
101 if (SUCCEEDED(hr)) { | 170 if (SUCCEEDED(hr)) { |
102 bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); | 171 bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
103 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 172 if (kDecodeBounds_WICMode == wicMode) { |
104 return true; | 173 return true; |
105 } | 174 } |
106 if (!this->allocPixelRef(bm, NULL)) { | 175 if (!this->allocPixelRef(bm, NULL)) { |
107 return false; | 176 return false; |
108 } | 177 } |
109 } | 178 } |
110 | 179 |
111 //Create a format converter. | 180 //Create a format converter. |
112 SkTScopedComPtr<IWICFormatConverter> piFormatConverter; | 181 SkTScopedComPtr<IWICFormatConverter> piFormatConverter; |
113 if (SUCCEEDED(hr)) { | 182 if (SUCCEEDED(hr)) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 | 256 |
188 bool SkImageEncoder_WIC::onEncode(SkWStream* stream | 257 bool SkImageEncoder_WIC::onEncode(SkWStream* stream |
189 , const SkBitmap& bitmapOrig | 258 , const SkBitmap& bitmapOrig |
190 , int quality) | 259 , int quality) |
191 { | 260 { |
192 GUID type; | 261 GUID type; |
193 switch (fType) { | 262 switch (fType) { |
194 case kBMP_Type: | 263 case kBMP_Type: |
195 type = GUID_ContainerFormatBmp; | 264 type = GUID_ContainerFormatBmp; |
196 break; | 265 break; |
197 case kGIF_Type: | |
198 type = GUID_ContainerFormatGif; | |
199 break; | |
200 case kICO_Type: | 266 case kICO_Type: |
201 type = GUID_ContainerFormatIco; | 267 type = GUID_ContainerFormatIco; |
202 break; | 268 break; |
203 case kJPEG_Type: | 269 case kJPEG_Type: |
204 type = GUID_ContainerFormatJpeg; | 270 type = GUID_ContainerFormatJpeg; |
205 break; | 271 break; |
206 case kPNG_Type: | 272 case kPNG_Type: |
207 type = GUID_ContainerFormatPng; | 273 type = GUID_ContainerFormatPng; |
208 break; | 274 break; |
209 default: | 275 default: |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 return SUCCEEDED(hr); | 407 return SUCCEEDED(hr); |
342 } | 408 } |
343 | 409 |
344 /////////////////////////////////////////////////////////////////////////////// | 410 /////////////////////////////////////////////////////////////////////////////// |
345 | 411 |
346 #include "SkTRegistry.h" | 412 #include "SkTRegistry.h" |
347 | 413 |
348 static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { | 414 static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { |
349 switch (t) { | 415 switch (t) { |
350 case SkImageEncoder::kBMP_Type: | 416 case SkImageEncoder::kBMP_Type: |
351 case SkImageEncoder::kGIF_Type: | |
352 case SkImageEncoder::kICO_Type: | 417 case SkImageEncoder::kICO_Type: |
353 case SkImageEncoder::kJPEG_Type: | 418 case SkImageEncoder::kJPEG_Type: |
354 case SkImageEncoder::kPNG_Type: | 419 case SkImageEncoder::kPNG_Type: |
355 break; | 420 break; |
356 default: | 421 default: |
357 return NULL; | 422 return NULL; |
358 } | 423 } |
359 return SkNEW_ARGS(SkImageEncoder_WIC, (t)); | 424 return SkNEW_ARGS(SkImageEncoder_WIC, (t)); |
360 } | 425 } |
361 | 426 |
362 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_
wic_factory); | 427 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_imageencoder_
wic_factory); |
| 428 |
| 429 static SkImageDecoder::Format get_format_wic(SkStream* stream) { |
| 430 SkImageDecoder::Format format; |
| 431 SkImageDecoder_WIC codec; |
| 432 if (!codec.decodeStream(stream, NULL, SkImageDecoder_WIC::kDecodeFormat_WICM
ode, &format)) { |
| 433 format = SkImageDecoder::kUnknown_Format; |
| 434 } |
| 435 return format; |
| 436 } |
| 437 |
| 438 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_wic)
; |
OLD | NEW |