[Win][Direct2D] Implement basic SVG support
[WebKit-https.git] / Source / WebCore / platform / graphics / ImageFrameCache.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 "ImageFrameCache.h"
28
29 #include "Image.h"
30 #include "ImageObserver.h"
31
32 #if USE(CG)
33 #include "ImageDecoderCG.h"
34 #elif USE(DIRECT2D)
35 #include "ImageDecoderDirect2D.h"
36 #include <WinCodec.h>
37 #else
38 #include "ImageDecoder.h"
39 #endif
40
41 #include <wtf/CheckedArithmetic.h>
42
43
44 namespace WebCore {
45
46 ImageFrameCache::ImageFrameCache(Image* image)
47     : m_image(image)
48 {
49 }
50
51 ImageFrameCache::ImageFrameCache(NativeImagePtr&& nativeImage)
52 {
53     m_frameCount = 1;
54     m_isSizeAvailable = true;
55     growFrames();
56
57     setNativeImage(WTFMove(nativeImage));
58
59     m_decodedSize = m_frames[0].frameBytes();
60
61     // The assumption is the memory image will be displayed with the default
62     // orientation. So set m_sizeRespectingOrientation to be the same as m_size.
63     m_size = m_frames[0].size();
64     m_sizeRespectingOrientation = m_size;
65 }
66
67 void ImageFrameCache::destroyDecodedData(bool destroyAll, size_t count)
68 {
69     if (destroyAll)
70         count = m_frames.size();
71     
72     unsigned decodedSize = 0;
73     for (size_t i = 0; i <  count; ++i)
74         decodedSize += m_frames[i].clearImage();
75
76     decodedSizeReset(decodedSize);
77 }
78
79 bool ImageFrameCache::destroyDecodedDataIfNecessary(bool destroyAll, size_t count)
80 {
81     unsigned decodedSize = 0;
82     for (auto& frame : m_frames)
83         decodedSize += frame.frameBytes();
84     
85     if (decodedSize < LargeAnimationCutoff)
86         return false;
87     
88     destroyDecodedData(destroyAll, count);
89     return true;
90 }
91
92 void ImageFrameCache::destroyIncompleteDecodedData()
93 {
94     unsigned decodedSize = 0;
95     
96     for (auto& frame : m_frames) {
97         if (!frame.hasMetadata() || frame.isComplete())
98             continue;
99         
100         decodedSize += frame.clear();
101     }
102
103     decodedSizeDecreased(decodedSize);
104 }
105
106 void ImageFrameCache::decodedSizeChanged(long long decodedSize)
107 {
108     if (!decodedSize || !m_image || !m_image->imageObserver())
109         return;
110     
111     m_image->imageObserver()->decodedSizeChanged(m_image, decodedSize);
112 }
113
114 void ImageFrameCache::decodedSizeIncreased(unsigned decodedSize)
115 {
116     if (!decodedSize)
117         return;
118     
119     m_decodedSize += decodedSize;
120     
121     // The fully-decoded frame will subsume the partially decoded data used
122     // to determine image properties.
123     long long changeSize = static_cast<long long>(decodedSize) - m_decodedPropertiesSize;
124     m_decodedPropertiesSize = 0;
125     decodedSizeChanged(changeSize);
126 }
127
128 void ImageFrameCache::decodedSizeDecreased(unsigned decodedSize)
129 {
130     if (!decodedSize)
131         return;
132
133     ASSERT(m_decodedSize >= decodedSize);
134     m_decodedSize -= decodedSize;
135     decodedSizeChanged(-static_cast<long long>(decodedSize));
136 }
137
138 void ImageFrameCache::decodedSizeReset(unsigned decodedSize)
139 {
140     ASSERT(m_decodedSize >= decodedSize);
141     m_decodedSize -= decodedSize;
142
143     // Clearing the ImageSource destroys the extra decoded data used for
144     // determining image properties.
145     decodedSize += m_decodedPropertiesSize;
146     m_decodedPropertiesSize = 0;
147     decodedSizeChanged(-static_cast<long long>(decodedSize));
148 }
149
150 void ImageFrameCache::didDecodeProperties(unsigned decodedPropertiesSize)
151 {
152     if (m_decodedSize)
153         return;
154
155     long long decodedSize = static_cast<long long>(decodedPropertiesSize) - m_decodedPropertiesSize;
156     m_decodedPropertiesSize = decodedPropertiesSize;
157     decodedSizeChanged(decodedSize);
158 }
159
160 void ImageFrameCache::growFrames()
161 {
162     ASSERT(isSizeAvailable());
163     ASSERT(m_frames.size() <= frameCount());
164     m_frames.grow(frameCount());
165 }
166
167 void ImageFrameCache::setNativeImage(NativeImagePtr&& nativeImage)
168 {
169     ASSERT(m_frames.size() == 1);
170     ImageFrame& frame = m_frames[0];
171
172     ASSERT(!isDecoderAvailable());
173
174     frame.m_nativeImage = WTFMove(nativeImage);
175
176     frame.m_decoding = ImageFrame::Decoding::Complete;
177     frame.m_size = nativeImageSize(frame.m_nativeImage);
178     frame.m_hasAlpha = nativeImageHasAlpha(frame.m_nativeImage);
179 }
180
181 void ImageFrameCache::setFrameNativeImage(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel)
182 {
183     ASSERT(index < m_frames.size());
184     ImageFrame& frame = m_frames[index];
185
186     ASSERT(isDecoderAvailable());
187
188     frame.m_nativeImage = WTFMove(nativeImage);
189     setFrameMetadata(index, subsamplingLevel);
190 }
191
192 void ImageFrameCache::setFrameMetadata(size_t index, SubsamplingLevel subsamplingLevel)
193 {
194     ASSERT(index < m_frames.size());
195     ImageFrame& frame = m_frames[index];
196
197     ASSERT(isDecoderAvailable());
198     frame.m_decoding = m_decoder->frameIsCompleteAtIndex(index) ? ImageFrame::Decoding::Complete : ImageFrame::Decoding::Partial;
199     if (frame.hasMetadata())
200         return;
201     
202     frame.m_subsamplingLevel = subsamplingLevel;
203     frame.m_size = m_decoder->frameSizeAtIndex(index, subsamplingLevel);
204     frame.m_orientation = m_decoder->frameOrientationAtIndex(index);
205     frame.m_hasAlpha = m_decoder->frameHasAlphaAtIndex(index);
206     
207     if (repetitionCount())
208         frame.m_duration = m_decoder->frameDurationAtIndex(index);
209 }
210
211 const ImageFrame& ImageFrameCache::frameAtIndex(size_t index, SubsamplingLevel subsamplingLevel, ImageFrame::Caching caching)
212 {
213     ASSERT(index < m_frames.size());
214     ImageFrame& frame = m_frames[index];
215     if (!isDecoderAvailable() || caching == ImageFrame::Caching::Empty)
216         return frame;
217     
218     if (subsamplingLevel == SubsamplingLevel::Undefinded)
219         subsamplingLevel = frame.subsamplingLevel();
220     
221     if (frame.hasInvalidNativeImage(subsamplingLevel)) {
222         unsigned decodedSize = frame.clear();
223         decodedSizeDecreased(decodedSize);
224     }
225     
226     if (!frame.isComplete() && caching == ImageFrame::Caching::Metadata)
227         setFrameMetadata(index, subsamplingLevel);
228     
229     if (!frame.hasNativeImage() && caching == ImageFrame::Caching::MetadataAndImage) {
230         size_t frameBytes = size().unclampedArea() * sizeof(RGBA32);
231
232         // Do not create the NativeImage if adding its frameByes to the MemoryCache will cause numerical overflow.
233         if (WTF::isInBounds<unsigned>(frameBytes + decodedSize())) {
234             setFrameNativeImage(m_decoder->createFrameImageAtIndex(index, subsamplingLevel), index, subsamplingLevel);
235             decodedSizeIncreased(frame.frameBytes());
236         }
237     }
238     
239     return frame;
240 }
241
242 void ImageFrameCache::clearMetadata()
243 {
244     m_frameCount = Nullopt;
245     m_singlePixelSolidColor = Nullopt;
246     m_maximumSubsamplingLevel = Nullopt;
247 }
248
249 template<typename T, T (ImageDecoder::*functor)() const>
250 T ImageFrameCache::metadata(const T& defaultValue, Optional<T>* cachedValue)
251 {
252     if (cachedValue && *cachedValue)
253         return cachedValue->value();
254
255     if (!isDecoderAvailable() || !m_decoder->isSizeAvailable())
256         return defaultValue;
257
258     if (!cachedValue)
259         return (m_decoder->*functor)();
260
261     *cachedValue = (m_decoder->*functor)();
262     didDecodeProperties(m_decoder->bytesDecodedToDetermineProperties());
263     return cachedValue->value();
264 }
265
266 template<typename T, T (ImageFrame::*functor)() const>
267 T ImageFrameCache::frameMetadataAtIndex(size_t index, SubsamplingLevel subsamplingLevel, ImageFrame::Caching caching, Optional<T>* cachedValue)
268 {
269     if (cachedValue && *cachedValue)
270         return cachedValue->value();
271     
272     const ImageFrame& frame = index < m_frames.size() ? frameAtIndex(index, subsamplingLevel, caching) : ImageFrame::defaultFrame();
273
274     // Don't cache any unavailable frame metadata.
275     if (!frame.hasMetadata() || !cachedValue)
276         return (frame.*functor)();
277     
278     *cachedValue = (frame.*functor)();
279     return cachedValue->value();
280 }
281
282 bool ImageFrameCache::isSizeAvailable()
283 {
284     if (m_isSizeAvailable)
285         return m_isSizeAvailable.value();
286     
287     if (!isDecoderAvailable() || !m_decoder->isSizeAvailable())
288         return false;
289     
290     m_isSizeAvailable = true;
291     didDecodeProperties(m_decoder->bytesDecodedToDetermineProperties());
292     return true;
293 }
294
295 size_t ImageFrameCache::frameCount()
296 {
297     return metadata<size_t, (&ImageDecoder::frameCount)>(m_frames.size(), &m_frameCount);
298 }
299
300 RepetitionCount ImageFrameCache::repetitionCount()
301 {
302     return metadata<RepetitionCount, (&ImageDecoder::repetitionCount)>(RepetitionCountNone, &m_repetitionCount);
303 }
304
305 String ImageFrameCache::filenameExtension()
306 {
307     return metadata<String, (&ImageDecoder::filenameExtension)>(String(), &m_filenameExtension);
308 }
309
310 Optional<IntPoint> ImageFrameCache::hotSpot()
311 {
312     return metadata<Optional<IntPoint>, (&ImageDecoder::hotSpot)>(Nullopt, &m_hotSpot);
313 }
314
315 IntSize ImageFrameCache::size()
316 {
317     return frameMetadataAtIndex<IntSize, (&ImageFrame::size)>(0, SubsamplingLevel::Default, ImageFrame::Caching::Metadata, &m_size);
318 }
319
320 IntSize ImageFrameCache::sizeRespectingOrientation()
321 {
322     return frameMetadataAtIndex<IntSize, (&ImageFrame::sizeRespectingOrientation)>(0, SubsamplingLevel::Default, ImageFrame::Caching::Metadata, &m_sizeRespectingOrientation);
323 }
324
325 Color ImageFrameCache::singlePixelSolidColor()
326 {
327     return frameCount() == 1 ? frameMetadataAtIndex<Color, (&ImageFrame::singlePixelSolidColor)>(0, SubsamplingLevel::Undefinded, ImageFrame::Caching::MetadataAndImage, &m_singlePixelSolidColor) : Color();
328 }
329
330 bool ImageFrameCache::frameIsCompleteAtIndex(size_t index)
331 {
332     return frameMetadataAtIndex<bool, (&ImageFrame::isComplete)>(index);
333 }
334
335 bool ImageFrameCache::frameHasAlphaAtIndex(size_t index)
336 {
337     return frameMetadataAtIndex<bool, (&ImageFrame::hasAlpha)>(index);
338 }
339
340 bool ImageFrameCache::frameHasImageAtIndex(size_t index)
341 {
342     return frameMetadataAtIndex<bool, (&ImageFrame::hasNativeImage)>(index);
343 }
344
345 bool ImageFrameCache::frameHasInvalidNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
346 {
347     return frameHasImageAtIndex(index) && subsamplingLevel < frameSubsamplingLevelAtIndex(index);
348 }
349
350 SubsamplingLevel ImageFrameCache::frameSubsamplingLevelAtIndex(size_t index)
351 {
352     return frameMetadataAtIndex<SubsamplingLevel, (&ImageFrame::subsamplingLevel)>(index);
353 }
354
355 IntSize ImageFrameCache::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
356 {
357     return frameMetadataAtIndex<IntSize, (&ImageFrame::size)>(index, subsamplingLevel, ImageFrame::Caching::Metadata);
358 }
359
360 unsigned ImageFrameCache::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
361 {
362     return frameMetadataAtIndex<unsigned, (&ImageFrame::frameBytes)>(index, subsamplingLevel, ImageFrame::Caching::Metadata);
363 }
364
365 float ImageFrameCache::frameDurationAtIndex(size_t index)
366 {
367     return frameMetadataAtIndex<float, (&ImageFrame::duration)>(index, SubsamplingLevel::Undefinded, ImageFrame::Caching::Metadata);
368 }
369
370 ImageOrientation ImageFrameCache::frameOrientationAtIndex(size_t index)
371 {
372     return frameMetadataAtIndex<ImageOrientation, (&ImageFrame::orientation)>(index, SubsamplingLevel::Undefinded, ImageFrame::Caching::Metadata);
373 }
374
375 NativeImagePtr ImageFrameCache::frameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
376 {
377     return frameMetadataAtIndex<NativeImagePtr, (&ImageFrame::nativeImage)>(index, subsamplingLevel, ImageFrame::Caching::MetadataAndImage);
378 }
379
380 }