Passing alpha to DeferredImageDecoder once decoding completes
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / DeferredImageDecoder.cpp
1 /*
2  * Copyright (C) 2012 Google 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 COMPUTER, 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 COMPUTER, 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 "DeferredImageDecoder.h"
28
29 #include "ImageDecodingStore.h"
30 #include "ImageFrameGenerator.h"
31 #include "LazyDecodingPixelRef.h"
32 #include <wtf/PassOwnPtr.h>
33
34 namespace WebCore {
35
36 namespace {
37
38 // URI label for a lazily decoded SkPixelRef.
39 const char labelLazyDecoded[] = "lazy";
40
41 } // namespace
42
43 bool DeferredImageDecoder::s_enabled = false;
44
45 DeferredImageDecoder::DeferredImageDecoder(ImageDecoder* actualDecoder)
46     : m_allDataReceived(false)
47     , m_actualDecoder(adoptPtr(actualDecoder))
48     , m_orientation(DefaultImageOrientation)
49 {
50 }
51
52 DeferredImageDecoder::~DeferredImageDecoder()
53 {
54 }
55
56 DeferredImageDecoder* DeferredImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorOption)
57 {
58     ImageDecoder* actualDecoder = ImageDecoder::create(data, alphaOption, gammaAndColorOption);
59     return actualDecoder ? new DeferredImageDecoder(actualDecoder) : 0;
60 }
61
62 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnPtr<ImageDecoder> decoder)
63 {
64     return adoptPtr(new DeferredImageDecoder(decoder.leakPtr()));
65 }
66
67 bool DeferredImageDecoder::isLazyDecoded(const SkBitmap& bitmap)
68 {
69     return bitmap.pixelRef()
70         && bitmap.pixelRef()->getURI()
71         && !memcmp(bitmap.pixelRef()->getURI(), labelLazyDecoded, sizeof(labelLazyDecoded));
72 }
73
74 SkBitmap DeferredImageDecoder::createResizedLazyDecodingBitmap(const SkBitmap& bitmap, const SkISize& scaledSize, const SkIRect& scaledSubset)
75 {
76     LazyDecodingPixelRef* pixelRef = static_cast<LazyDecodingPixelRef*>(bitmap.pixelRef());
77
78     int rowBytes = 0;
79     rowBytes = SkBitmap::ComputeRowBytes(SkBitmap::kARGB_8888_Config, scaledSize.width());
80
81     SkBitmap resizedBitmap;
82     resizedBitmap.setConfig(SkBitmap::kARGB_8888_Config, scaledSubset.width(), scaledSubset.height(), rowBytes);
83
84     // FIXME: This code has the potential problem that multiple
85     // LazyDecodingPixelRefs are created even though they share the same
86     // scaled size and ImageFrameGenerator.
87     resizedBitmap.setPixelRef(new LazyDecodingPixelRef(pixelRef->frameGenerator(), scaledSize, scaledSubset))->unref();
88
89     // See comments in createLazyDecodingBitmap().
90     resizedBitmap.setImmutable();
91     return resizedBitmap;
92 }
93
94 void DeferredImageDecoder::setEnabled(bool enabled)
95 {
96     s_enabled = enabled;
97 }
98
99 String DeferredImageDecoder::filenameExtension() const
100 {
101     return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameExtension;
102 }
103
104 ImageFrame* DeferredImageDecoder::frameBufferAtIndex(size_t index)
105 {
106     // Only defer image decoding if this is a single frame image. The reason is
107     // because a multiframe is usually animated GIF. Animation is handled by
108     // BitmapImage which uses some metadata functions that do synchronous image
109     // decoding.
110     if (s_enabled
111         && m_actualDecoder
112         && m_actualDecoder->repetitionCount() == cAnimationNone
113         && m_actualDecoder->isSizeAvailable()
114         && m_actualDecoder->frameCount() == 1) {
115
116         m_size = m_actualDecoder->size();
117         m_filenameExtension = m_actualDecoder->filenameExtension();
118         m_orientation = m_actualDecoder->orientation();
119
120         SkBitmap lazyDecodedSkBitmap = createLazyDecodingBitmap();
121         m_lazyDecodedFrame.setSkBitmap(lazyDecodedSkBitmap);
122
123         // Don't mark the frame as completely decoded until the underlying
124         // decoder has really decoded it. Until then, our data and metadata may
125         // be incorrect, so callers can't rely on them.
126         m_lazyDecodedFrame.setStatus(ImageFrame::FramePartial);
127     }
128
129     return m_actualDecoder ? m_actualDecoder->frameBufferAtIndex(index) : &m_lazyDecodedFrame;
130 }
131
132 void DeferredImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
133 {
134     if (m_actualDecoder) {
135         // Keep a reference to data until image decoding is deferred.
136         // When image decoding is deferred then ownership of m_data is
137         // transferred to ImageDecodingStore.
138         m_data = data;
139         m_allDataReceived = allDataReceived;
140         m_actualDecoder->setData(data, allDataReceived);
141     } else {
142         ASSERT(!m_data);
143         m_frameGenerator->setData(data, allDataReceived);
144     }
145 }
146
147 bool DeferredImageDecoder::isSizeAvailable()
148 {
149     // m_actualDecoder is 0 only if image decoding is deferred and that
150     // means image header decoded successfully and size is available.
151     return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true;
152 }
153
154 IntSize DeferredImageDecoder::size() const
155 {
156     return m_actualDecoder ? m_actualDecoder->size() : m_size;
157 }
158
159 IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const
160 {
161     return m_actualDecoder ? m_actualDecoder->frameSizeAtIndex(index) : m_size;
162 }
163
164 size_t DeferredImageDecoder::frameCount()
165 {
166     return m_actualDecoder ? m_actualDecoder->frameCount() : 1;
167 }
168
169 int DeferredImageDecoder::repetitionCount() const
170 {
171     return m_actualDecoder ? m_actualDecoder->repetitionCount() : cAnimationNone;
172 }
173
174 void DeferredImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
175 {
176     // If image decoding is deferred then frame buffer cache is managed by
177     // the compositor and this call is ignored.
178     if (m_actualDecoder)
179         m_actualDecoder->clearFrameBufferCache(clearBeforeFrame);
180 }
181
182 bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const
183 {
184     return m_actualDecoder ? m_actualDecoder->frameHasAlphaAtIndex(index) : m_frameGenerator->hasAlpha();
185 }
186
187 unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const
188 {
189     // If frame decoding is deferred then it is not managed by MemoryCache
190     // so return 0 here.
191     return m_actualDecoder ? m_actualDecoder->frameBytesAtIndex(index) : 0;
192 }
193
194 ImageOrientation DeferredImageDecoder::orientation() const
195 {
196     return m_actualDecoder ? m_actualDecoder->orientation() : m_orientation;
197 }
198
199 SkBitmap DeferredImageDecoder::createLazyDecodingBitmap()
200 {
201     SkISize fullSize = SkISize::Make(m_actualDecoder->size().width(), m_actualDecoder->size().height());
202     ASSERT(!fullSize.isEmpty());
203
204     SkIRect fullRect = SkIRect::MakeSize(fullSize);
205
206     // Creates a lazily decoded SkPixelRef that references the entire image without scaling.
207     SkBitmap bitmap;
208     bitmap.setConfig(SkBitmap::kARGB_8888_Config, fullSize.width(), fullSize.height());
209
210     m_frameGenerator = ImageFrameGenerator::create(fullSize, m_data.release(), m_allDataReceived);
211     m_actualDecoder.clear();
212
213     bitmap.setPixelRef(new LazyDecodingPixelRef(m_frameGenerator, fullSize, fullRect))->unref();
214
215     // Use the URI to identify this as a lazily decoded SkPixelRef of type LazyDecodingPixelRef.
216     // FIXME: It would be more useful to give the actual image URI.
217     bitmap.pixelRef()->setURI(labelLazyDecoded);
218
219     // Inform the bitmap that we will never change the pixels. This is a performance hint
220     // subsystems that may try to cache this bitmap (e.g. pictures, pipes, gpu, pdf, etc.)
221     bitmap.setImmutable();
222
223     // FIXME: Setting bitmap.setIsOpaque() is big performance gain if possible. We can
224     // do so safely if the image is fully loaded and it is a JPEG image, or if the image was
225     // decoded before.
226
227     return bitmap;
228 }
229
230 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const
231 {
232     return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false;
233 }
234
235 } // namespace WebCore