1/*
2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2007-2018 Apple Inc. All rights reserved.
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#pragma once
29
30#include "AffineTransform.h"
31#include "ColorSpace.h"
32#include "GraphicsTypes.h"
33#include "GraphicsTypes3D.h"
34#include "ImageBufferData.h"
35#include "IntSize.h"
36#include "PlatformLayer.h"
37#include <JavaScriptCore/Uint8ClampedArray.h>
38#include <memory>
39#include <wtf/Forward.h>
40#include <wtf/RefPtr.h>
41#include <wtf/Vector.h>
42
43namespace WebCore {
44
45class FloatRect;
46class GraphicsContext;
47class GraphicsContext3D;
48class Image;
49class ImageData;
50class IntPoint;
51class IntRect;
52class HostWindow;
53
54enum BackingStoreCopy {
55 CopyBackingStore, // Guarantee subsequent draws don't affect the copy.
56 DontCopyBackingStore // Subsequent draws may affect the copy.
57};
58
59enum class PreserveResolution {
60 No,
61 Yes,
62};
63
64class ImageBuffer {
65 WTF_MAKE_NONCOPYABLE(ImageBuffer); WTF_MAKE_FAST_ALLOCATED;
66 friend class IOSurface;
67public:
68 // Will return a null pointer on allocation failure.
69 WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, float resolutionScale = 1, ColorSpace = ColorSpaceSRGB, const HostWindow* = nullptr);
70#if USE(DIRECT2D)
71 WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, const GraphicsContext*, float resolutionScale = 1, ColorSpace = ColorSpaceSRGB, const HostWindow* = nullptr);
72#endif
73
74 // Create an image buffer compatible with the context and copy rect from this buffer into this new one.
75 std::unique_ptr<ImageBuffer> copyRectToBuffer(const FloatRect&, ColorSpace, const GraphicsContext&);
76
77 // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
78 static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
79 static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, ColorSpace, const GraphicsContext&);
80 static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, float resolutionScale, ColorSpace, const GraphicsContext&);
81
82 static IntSize compatibleBufferSize(const FloatSize&, const GraphicsContext&);
83 bool isCompatibleWithContext(const GraphicsContext&) const;
84
85 WEBCORE_EXPORT ~ImageBuffer();
86
87 // The actual resolution of the backing store
88 const IntSize& internalSize() const { return m_size; }
89 const IntSize& logicalSize() const { return m_logicalSize; }
90
91 FloatSize sizeForDestinationSize(FloatSize) const;
92
93 float resolutionScale() const { return m_resolutionScale; }
94
95 WEBCORE_EXPORT GraphicsContext& context() const;
96
97 WEBCORE_EXPORT RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const;
98 WEBCORE_EXPORT static RefPtr<Image> sinkIntoImage(std::unique_ptr<ImageBuffer>, PreserveResolution = PreserveResolution::No);
99 // Give hints on the faster copyImage Mode, return DontCopyBackingStore if it supports the DontCopyBackingStore behavior
100 // or return CopyBackingStore if it doesn't.
101 static BackingStoreCopy fastCopyImageMode();
102
103 enum CoordinateSystem { LogicalCoordinateSystem, BackingStoreCoordinateSystem };
104
105 RefPtr<Uint8ClampedArray> getUnmultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const;
106 RefPtr<Uint8ClampedArray> getPremultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const;
107
108 void putByteArray(const Uint8ClampedArray&, AlphaPremultiplication bufferFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem = LogicalCoordinateSystem);
109
110 void convertToLuminanceMask();
111
112 String toDataURL(const String& mimeType, Optional<double> quality = WTF::nullopt, PreserveResolution = PreserveResolution::No) const;
113 Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const;
114 Vector<uint8_t> toBGRAData() const;
115
116#if !USE(CG)
117 AffineTransform baseTransform() const { return AffineTransform(); }
118 void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace);
119 void platformTransformColorSpace(const std::array<uint8_t, 256>&);
120#else
121 AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.backingStoreSize.height()); }
122#endif
123 PlatformLayer* platformLayer() const;
124
125 size_t memoryCost() const;
126 size_t externalMemoryCost() const;
127
128 // FIXME: current implementations of this method have the restriction that they only work
129 // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type.
130 bool copyToPlatformTexture(GraphicsContext3D&, GC3Denum, Platform3DObject, GC3Denum, bool, bool);
131
132 // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper.
133 static bool sizeNeedsClamping(const FloatSize&);
134 static bool sizeNeedsClamping(const FloatSize&, FloatSize& scale);
135 static FloatSize clampedSize(const FloatSize&);
136 static FloatSize clampedSize(const FloatSize&, FloatSize& scale);
137 static FloatRect clampedRect(const FloatRect&);
138
139private:
140#if USE(CG)
141 // The returned image might be larger than the internalSize(). If you want the smaller
142 // image, crop the result.
143 RetainPtr<CGImageRef> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
144 static RetainPtr<CGImageRef> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
145 void flushContext() const;
146#elif USE(DIRECT2D)
147 COMPtr<ID2D1Bitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
148 static COMPtr<ID2D1Bitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>);
149 void flushContext() const;
150#endif
151
152 void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, BlendMode = BlendMode::Normal);
153 void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode = BlendMode::Normal);
154
155 static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, BlendMode = BlendMode::Normal);
156
157 inline void genericConvertToLuminanceMask();
158
159 friend class GraphicsContext;
160 friend class GeneratedImage;
161 friend class CrossfadeGeneratedImage;
162 friend class NamedImageGeneratedImage;
163 friend class GradientImage;
164 friend class CustomPaintImage;
165
166private:
167 ImageBufferData m_data;
168 IntSize m_size;
169 IntSize m_logicalSize;
170 float m_resolutionScale;
171
172 // This constructor will place its success into the given out-variable
173 // so that create() knows when it should return failure.
174 WEBCORE_EXPORT ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, const HostWindow*, bool& success);
175#if USE(CG)
176 ImageBuffer(const FloatSize&, float resolutionScale, CGColorSpaceRef, RenderingMode, const HostWindow*, bool& success);
177 RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const;
178#elif USE(DIRECT2D)
179 ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, const HostWindow*, const GraphicsContext*, bool& success);
180#endif
181};
182
183#if USE(CG)
184String dataURL(const ImageData&, const String& mimeType, Optional<double> quality);
185Vector<uint8_t> data(const ImageData&, const String& mimeType, Optional<double> quality);
186#endif
187
188} // namespace WebCore
189
190