Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(339)

Side by Side Diff: Source/platform/image-decoders/ImageDecoder.h

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #ifndef ImageDecoder_h
28 #define ImageDecoder_h
29
30 #include "SkColorPriv.h"
31 #include "platform/PlatformExport.h"
32 #include "platform/PlatformScreen.h"
33 #include "platform/SharedBuffer.h"
34 #include "platform/graphics/ImageSource.h"
35 #include "platform/image-decoders/ImageFrame.h"
36 #include "public/platform/Platform.h"
37 #include "wtf/Assertions.h"
38 #include "wtf/RefPtr.h"
39 #include "wtf/text/WTFString.h"
40 #include "wtf/Vector.h"
41
42 #if USE(QCMSLIB)
43 #include "qcms.h"
44 #if OS(MACOSX)
45 #include <ApplicationServices/ApplicationServices.h>
46 #include "platform/graphics/cg/GraphicsContextCG.h"
47 #include "wtf/RetainPtr.h"
48 #endif
49 #endif
50
51 namespace WebCore {
52
53 // ImageDecoder is a base for all format-specific decoders
54 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
55 //
56 class PLATFORM_EXPORT ImageDecoder {
57 WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
58 public:
59 static const size_t noDecodedImageByteLimit = blink::Platform::noDecodedImag eByteLimit;
60
61 ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColo rProfileOption gammaAndColorProfileOption, size_t maxDecodedBytes)
62 : m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
63 , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource ::GammaAndColorProfileIgnored)
64 , m_maxDecodedBytes(maxDecodedBytes)
65 , m_sizeAvailable(false)
66 , m_isAllDataReceived(false)
67 , m_failed(false) { }
68
69 virtual ~ImageDecoder() { }
70
71 // Returns a caller-owned decoder of the appropriate type. Returns 0 if
72 // we can't sniff a supported type from the provided data (possibly
73 // because there isn't enough data yet).
74 // Sets m_maxDecodedBytes to Platform::maxImageDecodedBytes().
75 static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource ::AlphaOption, ImageSource::GammaAndColorProfileOption);
76
77 // Returns a decoder with custom maxDecodedSize.
78 static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource ::AlphaOption, ImageSource::GammaAndColorProfileOption, size_t maxDecodedSize);
79
80 virtual String filenameExtension() const = 0;
81
82 bool isAllDataReceived() const { return m_isAllDataReceived; }
83
84 virtual void setData(SharedBuffer* data, bool allDataReceived)
85 {
86 if (m_failed)
87 return;
88 m_data = data;
89 m_isAllDataReceived = allDataReceived;
90 }
91
92 // Lazily-decodes enough of the image to get the size (if possible).
93 // FIXME: Right now that has to be done by each subclass; factor the
94 // decode call out and use it here.
95 virtual bool isSizeAvailable()
96 {
97 return !m_failed && m_sizeAvailable;
98 }
99
100 virtual IntSize size() const { return m_size; }
101
102 // Decoders which downsample images should override this method to
103 // return the actual decoded size.
104 virtual IntSize decodedSize() const { return size(); }
105
106 // This will only differ from size() for ICO (where each frame is a
107 // different icon) or other formats where different frames are different
108 // sizes. This does NOT differ from size() for GIF or WebP, since
109 // decoding GIF or WebP composites any smaller frames against previous
110 // frames to create full-size frames.
111 virtual IntSize frameSizeAtIndex(size_t) const
112 {
113 return size();
114 }
115
116 // Returns whether the size is legal (i.e. not going to result in
117 // overflow elsewhere). If not, marks decoding as failed.
118 virtual bool setSize(unsigned width, unsigned height)
119 {
120 if (sizeCalculationMayOverflow(width, height))
121 return setFailed();
122 m_size = IntSize(width, height);
123 m_sizeAvailable = true;
124 return true;
125 }
126
127 // Lazily-decodes enough of the image to get the frame count (if
128 // possible), without decoding the individual frames.
129 // FIXME: Right now that has to be done by each subclass; factor the
130 // decode call out and use it here.
131 virtual size_t frameCount() { return 1; }
132
133 virtual int repetitionCount() const { return cAnimationNone; }
134
135 // Decodes as much of the requested frame as possible, and returns an
136 // ImageDecoder-owned pointer.
137 virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
138
139 // Make the best effort guess to check if the requested frame has alpha chan nel.
140 virtual bool frameHasAlphaAtIndex(size_t) const;
141
142 // Whether or not the frame is fully received.
143 virtual bool frameIsCompleteAtIndex(size_t) const;
144
145 // Duration for displaying a frame in seconds. This method is used by animat ed images only.
146 virtual float frameDurationAtIndex(size_t) const { return 0; }
147
148 // Number of bytes in the decoded frame requested. Return 0 if not yet decod ed.
149 virtual unsigned frameBytesAtIndex(size_t) const;
150
151 void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
152 bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfi le; }
153
154 ImageOrientation orientation() const { return m_orientation; }
155
156 enum { iccColorProfileHeaderLength = 128 };
157
158 static bool rgbColorProfile(const char* profileData, unsigned profileLength)
159 {
160 ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLengt h);
161
162 return !memcmp(&profileData[16], "RGB ", 4);
163 }
164
165 static bool inputDeviceColorProfile(const char* profileData, unsigned profil eLength)
166 {
167 ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLengt h);
168
169 return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
170 }
171
172 #if USE(QCMSLIB)
173 static qcms_profile* qcmsOutputDeviceProfile()
174 {
175 static qcms_profile* outputDeviceProfile = 0;
176
177 static bool qcmsInitialized = false;
178 if (!qcmsInitialized) {
179 qcmsInitialized = true;
180 // FIXME: Add optional ICCv4 support.
181 #if OS(MACOSX)
182 RetainPtr<CGColorSpaceRef> monitorColorSpace(AdoptCF, CGDisplayCopyC olorSpace(CGMainDisplayID()));
183 CFDataRef iccProfile(CGColorSpaceCopyICCProfile(monitorColorSpace.ge t()));
184 if (iccProfile) {
185 size_t length = CFDataGetLength(iccProfile);
186 const unsigned char* systemProfile = CFDataGetBytePtr(iccProfile );
187 outputDeviceProfile = qcms_profile_from_memory(systemProfile, le ngth);
188 }
189 #else
190 // FIXME: add support for multiple monitors.
191 ColorProfile profile;
192 screenColorProfile(profile);
193 if (!profile.isEmpty())
194 outputDeviceProfile = qcms_profile_from_memory(profile.data(), p rofile.size());
195 #endif
196 if (outputDeviceProfile && qcms_profile_is_bogus(outputDeviceProfile )) {
197 qcms_profile_release(outputDeviceProfile);
198 outputDeviceProfile = 0;
199 }
200 if (!outputDeviceProfile)
201 outputDeviceProfile = qcms_profile_sRGB();
202 if (outputDeviceProfile)
203 qcms_profile_precache_output_transform(outputDeviceProfile);
204 }
205 return outputDeviceProfile;
206 }
207 #endif
208
209 // Sets the "decode failure" flag. For caller convenience (since so
210 // many callers want to return false after calling this), returns false
211 // to enable easy tailcalling. Subclasses may override this to also
212 // clean up any local data.
213 virtual bool setFailed()
214 {
215 m_failed = true;
216 return false;
217 }
218
219 bool failed() const { return m_failed; }
220
221 // Clears decoded pixel data from all frames except the provided frame.
222 // Callers may pass WTF::kNotFound to clear all frames.
223 // Note: If |m_frameBufferCache| contains only one frame, it won't be cleare d.
224 // Returns the number of bytes of frame data actually cleared.
225 virtual size_t clearCacheExceptFrame(size_t);
226
227 // If the image has a cursor hot-spot, stores it in the argument
228 // and returns true. Otherwise returns false.
229 virtual bool hotSpot(IntPoint&) const { return false; }
230
231 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator)
232 {
233 // FIXME: this doesn't work for images with multiple frames.
234 if (m_frameBufferCache.isEmpty()) {
235 m_frameBufferCache.resize(1);
236 m_frameBufferCache[0].setRequiredPreviousFrameIndex(
237 findRequiredPreviousFrame(0, false));
238 }
239 m_frameBufferCache[0].setMemoryAllocator(allocator);
240 }
241
242 protected:
243 // Calculates the most recent frame whose image data may be needed in
244 // order to decode frame |frameIndex|, based on frame disposal methods
245 // and |frameRectIsOpaque|, where |frameRectIsOpaque| signifies whether
246 // the rectangle of frame at |frameIndex| is known to be opaque.
247 // If no previous frame's data is required, returns WTF::kNotFound.
248 //
249 // This function requires that the previous frame's
250 // |m_requiredPreviousFrameIndex| member has been set correctly. The
251 // easiest way to ensure this is for subclasses to call this method and
252 // store the result on the frame via setRequiredPreviousFrameIndex()
253 // as soon as the frame has been created and parsed sufficiently to
254 // determine the disposal method; assuming this happens for all frames
255 // in order, the required invariant will hold.
256 //
257 // Image formats which do not use more than one frame do not need to
258 // worry about this; see comments on
259 // ImageFrame::m_requiredPreviousFrameIndex.
260 size_t findRequiredPreviousFrame(size_t frameIndex, bool frameRectIsOpaque);
261
262 virtual void clearFrameBuffer(size_t frameIndex);
263
264 RefPtr<SharedBuffer> m_data; // The encoded data.
265 Vector<ImageFrame, 1> m_frameBufferCache;
266 bool m_premultiplyAlpha;
267 bool m_ignoreGammaAndColorProfile;
268 ImageOrientation m_orientation;
269
270 // The maximum amount of memory a decoded image should require. Ideally,
271 // image decoders should downsample large images to fit under this limit
272 // (and then return the downsampled size from decodedSize()). Ignoring
273 // this limit can cause excessive memory use or even crashes on low-
274 // memory devices.
275 size_t m_maxDecodedBytes;
276
277 private:
278 // Some code paths compute the size of the image as "width * height * 4"
279 // and return it as a (signed) int. Avoid overflow.
280 static bool sizeCalculationMayOverflow(unsigned width, unsigned height)
281 {
282 unsigned long long total_size = static_cast<unsigned long long>(width)
283 * static_cast<unsigned long long>(height);
284 return total_size > ((1 << 29) - 1);
285 }
286
287 IntSize m_size;
288 bool m_sizeAvailable;
289 bool m_isAllDataReceived;
290 bool m_failed;
291 };
292
293 } // namespace WebCore
294
295 #endif
OLDNEW
« no previous file with comments | « Source/platform/graphics/test/MockDiscardablePixelRef.h ('k') | Source/platform/image-decoders/ImageDecoder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698