Use IWICBitmap (rather than ID2D1Bitmap) for NativeImagePtr on FTW
[WebKit-https.git] / Source / WebCore / platform / graphics / win / NativeImageDirect2D.cpp
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "NativeImage.h"
28
29 #include "Color.h"
30 #include "FloatRect.h"
31 #include "GeometryUtilities.h"
32 #include "GraphicsContext.h"
33 #include "IntSize.h"
34 #include "NotImplemented.h"
35 #include <d2d1.h>
36 #include <wincodec.h>
37
38 namespace WebCore {
39
40 static IWICImagingFactory* imagingFactory()
41 {
42     static IWICImagingFactory* imagingFactory = nullptr;
43     if (!imagingFactory) {
44         HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&imagingFactory));
45         RELEASE_ASSERT(SUCCEEDED(hr));
46     }
47
48     return imagingFactory;
49 }
50
51 IntSize nativeImageSize(const NativeImagePtr& image)
52 {
53     UINT width = 0;
54     UINT height = 0;
55     if (!image)
56         return { };
57
58     HRESULT hr = image->GetSize(&width, &height);
59     if (!SUCCEEDED(hr))
60         return { };
61
62     return IntSize(width, height);
63 }
64
65 bool nativeImageHasAlpha(const NativeImagePtr& image)
66 {
67     if (!image)
68         return false;
69
70     WICPixelFormatGUID pixelFormatGUID = { };
71     HRESULT hr = image->GetPixelFormat(&pixelFormatGUID);
72     if (!SUCCEEDED(hr))
73         return false;
74
75     // FIXME: Should we just check the pixelFormatGUID for relevant ID's we use?
76
77     COMPtr<IWICComponentInfo> componentInfo;
78     hr = imagingFactory()->CreateComponentInfo(pixelFormatGUID, &componentInfo);
79     if (!SUCCEEDED(hr))
80         return false;
81
82     COMPtr<IWICPixelFormatInfo> pixelFormatInfo(Query, componentInfo.get());
83     if (!pixelFormatInfo)
84         return false;
85
86     UINT channelCount = 0;
87     hr = pixelFormatInfo->GetChannelCount(&channelCount);
88     if (!SUCCEEDED(hr))
89         return false;
90
91     return channelCount > 3;
92 }
93
94 Color nativeImageSinglePixelSolidColor(const NativeImagePtr& image)
95 {
96     if (!image || nativeImageSize(image) != IntSize(1, 1))
97         return Color();
98
99     notImplemented();
100
101     return Color();
102 }
103
104 void drawNativeImage(const NativeImagePtr& image, GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, const IntSize& srcSize, CompositeOperator compositeOp, BlendMode blendMode, const ImageOrientation& orientation)
105 {
106     auto platformContext = context.platformContext();
107
108     // Subsampling may have given us an image that is smaller than size().
109     IntSize subsampledImageSize = nativeImageSize(image);
110
111     // srcRect is in the coordinates of the unsubsampled image, so we have to map it to the subsampled image.
112     FloatRect adjustedSrcRect = srcRect;
113     if (subsampledImageSize != srcSize)
114         adjustedSrcRect = mapRect(srcRect, FloatRect({ }, srcSize), FloatRect({ }, subsampledImageSize));
115
116     float opacity = 1.0f;
117
118     COMPtr<ID2D1Bitmap> bitmap;
119     HRESULT hr = platformContext->CreateBitmapFromWicBitmap(image.get(), &bitmap);
120     if (!SUCCEEDED(hr))
121         return;
122
123     platformContext->DrawBitmap(bitmap.get(), destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, adjustedSrcRect);
124     context.flush();
125 }
126
127 void clearNativeImageSubimages(const NativeImagePtr& image)
128 {
129     notImplemented();
130
131 #if CACHE_SUBIMAGES
132     if (image)
133         subimageCache().clearImage(image.get());
134 #endif
135 }
136
137
138 }