Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkImageGeneratorWIC.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
13
14#include <wincodec.h>
15
16// All Windows SDKs back to XPSP2 export the CLSID_WICImagingFactory symbol.
17// In the Windows8 SDK the CLSID_WICImagingFactory symbol is still exported
18// but CLSID_WICImagingFactory is then #defined to CLSID_WICImagingFactory2.
19// Undo this #define if it has been done so that we link against the symbols
20// we intended to link against on all SDKs.
21#if defined(CLSID_WICImagingFactory)
22 #undef CLSID_WICImagingFactory
23#endif
24
25namespace {
26class ImageGeneratorWIC : public SkImageGenerator {
27public:
28 /*
29 * Takes ownership of the imagingFactory
30 * Takes ownership of the imageSource
31 */
32 ImageGeneratorWIC(const SkImageInfo& info, IWICImagingFactory* imagingFactory,
33 IWICBitmapSource* imageSource, sk_sp<SkData>);
34protected:
36
37 bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options&)
38 override;
39
40private:
41 SkTScopedComPtr<IWICImagingFactory> fImagingFactory;
42 SkTScopedComPtr<IWICBitmapSource> fImageSource;
43 sk_sp<SkData> fData;
44
46};
47} // namespace
48
49std::unique_ptr<SkImageGenerator> SkImageGeneratorWIC::MakeFromEncodedWIC(sk_sp<SkData> data) {
50 // Create Windows Imaging Component ImagingFactory.
51 SkTScopedComPtr<IWICImagingFactory> imagingFactory;
52 HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER,
53 IID_PPV_ARGS(&imagingFactory));
54 if (FAILED(hr)) {
55 return nullptr;
56 }
57
58 // Create an IStream.
59 SkTScopedComPtr<IStream> iStream;
60 // Note that iStream will take ownership of the new memory stream because
61 // we set |deleteOnRelease| to true.
62 hr = SkIStream::CreateFromSkStream(std::make_unique<SkMemoryStream>(data), &iStream);
63 if (FAILED(hr)) {
64 return nullptr;
65 }
66
67 // Create the decoder from the stream.
68 SkTScopedComPtr<IWICBitmapDecoder> decoder;
69 hr = imagingFactory->CreateDecoderFromStream(iStream.get(), nullptr,
70 WICDecodeMetadataCacheOnDemand, &decoder);
71 if (FAILED(hr)) {
72 return nullptr;
73 }
74
75 // Select the first frame from the decoder.
76 SkTScopedComPtr<IWICBitmapFrameDecode> imageFrame;
77 hr = decoder->GetFrame(0, &imageFrame);
78 if (FAILED(hr)) {
79 return nullptr;
80 }
81
82 // Treat the frame as an image source.
83 SkTScopedComPtr<IWICBitmapSource> imageSource;
84 hr = imageFrame->QueryInterface(IID_PPV_ARGS(&imageSource));
85 if (FAILED(hr)) {
86 return nullptr;
87 }
88
89 // Get the size of the image.
90 UINT width;
92 hr = imageSource->GetSize(&width, &height);
93 if (FAILED(hr)) {
94 return nullptr;
95 }
96
97 // Get the encoded pixel format.
98 WICPixelFormatGUID format;
99 hr = imageSource->GetPixelFormat(&format);
100 if (FAILED(hr)) {
101 return nullptr;
102 }
103
104 // Recommend kOpaque if the image is opaque and kPremul otherwise.
105 // FIXME: We are stuck recommending kPremul for all indexed formats
106 // (Ex: GUID_WICPixelFormat8bppIndexed) because we don't have
107 // a way to check if the image has alpha.
109
110 if (GUID_WICPixelFormat16bppBGR555 == format ||
111 GUID_WICPixelFormat16bppBGR565 == format ||
112 GUID_WICPixelFormat32bppBGR101010 == format ||
113 GUID_WICPixelFormatBlackWhite == format ||
114 GUID_WICPixelFormat2bppGray == format ||
115 GUID_WICPixelFormat4bppGray == format ||
116 GUID_WICPixelFormat8bppGray == format ||
117 GUID_WICPixelFormat16bppGray == format ||
118 GUID_WICPixelFormat16bppGrayFixedPoint == format ||
119 GUID_WICPixelFormat16bppGrayHalf == format ||
120 GUID_WICPixelFormat32bppGrayFloat == format ||
121 GUID_WICPixelFormat32bppGrayFixedPoint == format ||
122 GUID_WICPixelFormat32bppRGBE == format ||
123 GUID_WICPixelFormat24bppRGB == format ||
124 GUID_WICPixelFormat24bppBGR == format ||
125 GUID_WICPixelFormat32bppBGR == format ||
126 GUID_WICPixelFormat48bppRGB == format ||
127 GUID_WICPixelFormat48bppBGR == format ||
128 GUID_WICPixelFormat48bppRGBFixedPoint == format ||
129 GUID_WICPixelFormat48bppBGRFixedPoint == format ||
130 GUID_WICPixelFormat48bppRGBHalf == format ||
131 GUID_WICPixelFormat64bppRGBFixedPoint == format ||
132 GUID_WICPixelFormat64bppRGBHalf == format ||
133 GUID_WICPixelFormat96bppRGBFixedPoint == format ||
134 GUID_WICPixelFormat128bppRGBFloat == format ||
135 GUID_WICPixelFormat128bppRGBFixedPoint == format ||
136 GUID_WICPixelFormat32bppRGB == format ||
137 GUID_WICPixelFormat64bppRGB == format ||
138 GUID_WICPixelFormat96bppRGBFloat == format ||
139 GUID_WICPixelFormat32bppCMYK == format ||
140 GUID_WICPixelFormat64bppCMYK == format ||
141 GUID_WICPixelFormat8bppY == format ||
142 GUID_WICPixelFormat8bppCb == format ||
143 GUID_WICPixelFormat8bppCr == format ||
144 GUID_WICPixelFormat16bppCbCr == format)
145 {
146 alphaType = kOpaque_SkAlphaType;
147 }
148
149 // FIXME: If we change the implementation to handle swizzling ourselves,
150 // we can support more output formats.
152 return std::unique_ptr<SkImageGenerator>(
153 new ImageGeneratorWIC(info, imagingFactory.release(), imageSource.release(),
154 std::move(data)));
155}
156
157ImageGeneratorWIC::ImageGeneratorWIC(const SkImageInfo& info,
158 IWICImagingFactory* imagingFactory, IWICBitmapSource* imageSource, sk_sp<SkData> data)
159 : INHERITED(info)
160 , fImagingFactory(imagingFactory)
161 , fImageSource(imageSource)
162 , fData(std::move(data))
163{}
164
165sk_sp<SkData> ImageGeneratorWIC::onRefEncodedData() {
166 return fData;
167}
168
169bool ImageGeneratorWIC::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
170 const Options&) {
171 if (kN32_SkColorType != info.colorType()) {
172 return false;
173 }
174
175 // Create a format converter.
176 SkTScopedComPtr<IWICFormatConverter> formatConverter;
177 HRESULT hr = fImagingFactory->CreateFormatConverter(&formatConverter);
178 if (FAILED(hr)) {
179 return false;
180 }
181
182 GUID format = GUID_WICPixelFormat32bppPBGRA;
183 if (kUnpremul_SkAlphaType == info.alphaType()) {
184 format = GUID_WICPixelFormat32bppBGRA;
185 }
186
187 hr = formatConverter->Initialize(fImageSource.get(), format, WICBitmapDitherTypeNone, nullptr,
188 0.0, WICBitmapPaletteTypeCustom);
189 if (FAILED(hr)) {
190 return false;
191 }
192
193 // Treat the format converter as an image source.
194 SkTScopedComPtr<IWICBitmapSource> formatConverterSrc;
195 hr = formatConverter->QueryInterface(IID_PPV_ARGS(&formatConverterSrc));
196 if (FAILED(hr)) {
197 return false;
198 }
199
200 // Set the destination pixels.
201 hr = formatConverterSrc->CopyPixels(nullptr, (UINT) rowBytes, (UINT) rowBytes * info.height(),
202 (BYTE*) pixels);
203
204 return SUCCEEDED(hr);
205}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
kUnpremul_SkAlphaType
SkAlphaType
Definition SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define INHERITED(method,...)
virtual sk_sp< SkData > onRefEncodedData()
virtual bool onGetPixels(const SkImageInfo &, void *, size_t, const Options &)
uint32_t uint32_t * format
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
Definition ref_ptr.h:256
int32_t height
int32_t width
static SkImageInfo MakeS32(int width, int height, SkAlphaType at)
#define SUCCEEDED(hr)
unsigned int UINT
unsigned char BYTE
#define FAILED(hr)
struct _GUID GUID