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/Vector.h" 40 #include "wtf/text/WTFString.h" 41 42 #if USE(QCMSLIB) 43 #include "qcms.h" 44 #endif 45 46 typedef Vector<char> ColorProfile; 47 48 namespace blink { 49 50 // ImagePlanes can be used to decode color components into provided buffers instead of using an ImageFrame. 51 class PLATFORM_EXPORT ImagePlanes { 52 public: 53 ImagePlanes(); 54 ImagePlanes(void* planes[3], size_t rowBytes[3]); 55 56 void* plane(int); 57 size_t rowBytes(int) const; 58 59 private: 60 void* m_planes[3]; 61 size_t m_rowBytes[3]; 62 }; 63 64 // ImageDecoder is a base for all format-specific decoders 65 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache. 66 // 67 class PLATFORM_EXPORT ImageDecoder { 68 WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED; 69 public: 70 enum SizeType { ActualSize, SizeForMemoryAllocation }; 71 72 static const size_t noDecodedImageByteLimit = blink::Platform::noDecodedImageByteLimit; 73 74 ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption, size_t maxDecodedBytes) 75 : m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied) 76 , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored) 77 , m_maxDecodedBytes(maxDecodedBytes) 78 , m_sizeAvailable(false) 79 , m_isAllDataReceived(false) 80 , m_failed(false) { } 81 82 virtual ~ImageDecoder() { } 83 84 // Returns a caller-owned decoder of the appropriate type. Returns 0 if 85 // we can't sniff a supported type from the provided data (possibly 86 // because there isn't enough data yet). 87 // Sets m_maxDecodedBytes to Platform::maxImageDecodedBytes(). 88 static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption); 89 90 // Returns a decoder with custom maxDecodedSize. 91 static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption, size_t maxDecodedSize); 92 93 virtual String filenameExtension() const = 0; 94 95 bool isAllDataReceived() const { return m_isAllDataReceived; } 96 97 virtual void setData(SharedBuffer* data, bool allDataReceived) 98 { 99 if (m_failed) 100 return; 101 m_data = data; 102 m_isAllDataReceived = allDataReceived; 103 } 104 105 virtual bool isSizeAvailable() 106 { 107 return !m_failed && m_sizeAvailable; 108 } 109 110 bool isSizeAvailable() const 111 { 112 return !m_failed && m_sizeAvailable; 113 } 114 115 virtual IntSize size() const { return m_size; } 116 117 // Decoders which downsample images should override this method to 118 // return the actual decoded size. 119 virtual IntSize decodedSize() const { return size(); } 120 121 // Decoders which support YUV decoding can override this to 122 // give potentially different sizes per component. 123 virtual IntSize decodedYUVSize(int component, SizeType) const { return decodedSize(); } 124 125 // This will only differ from size() for ICO (where each frame is a 126 // different icon) or other formats where different frames are different 127 // sizes. This does NOT differ from size() for GIF or WebP, since 128 // decoding GIF or WebP composites any smaller frames against previous 129 // frames to create full-size frames. 130 virtual IntSize frameSizeAtIndex(size_t) const 131 { 132 return size(); 133 } 134 135 // Returns whether the size is legal (i.e. not going to result in 136 // overflow elsewhere). If not, marks decoding as failed. 137 virtual bool setSize(unsigned width, unsigned height) 138 { 139 if (sizeCalculationMayOverflow(width, height)) 140 return setFailed(); 141 m_size = IntSize(width, height); 142 m_sizeAvailable = true; 143 return true; 144 } 145 146 // Lazily-decodes enough of the image to get the frame count (if 147 // possible), without decoding the individual frames. 148 // FIXME: Right now that has to be done by each subclass; factor the 149 // decode call out and use it here. 150 virtual size_t frameCount() { return 1; } 151 152 virtual int repetitionCount() const { return cAnimationNone; } 153 154 // Decodes as much of the requested frame as possible, and returns an 155 // ImageDecoder-owned pointer. 156 virtual ImageFrame* frameBufferAtIndex(size_t) = 0; 157 158 // Make the best effort guess to check if the requested frame has alpha channel. 159 virtual bool frameHasAlphaAtIndex(size_t) const; 160 161 // Whether or not the frame is fully received. 162 virtual bool frameIsCompleteAtIndex(size_t) const; 163 164 // Duration for displaying a frame in seconds. This method is used by animated images only. 165 virtual float frameDurationAtIndex(size_t) const { return 0; } 166 167 // Number of bytes in the decoded frame requested. Return 0 if not yet decoded. 168 virtual unsigned frameBytesAtIndex(size_t) const; 169 170 ImageOrientation orientation() const { return m_orientation; } 171 172 static bool deferredImageDecodingEnabled(); 173 174 void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; } 175 bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; } 176 177 virtual bool hasColorProfile() const { return false; } 178 179 #if USE(QCMSLIB) 180 enum { iccColorProfileHeaderLength = 128 }; 181 182 static bool rgbColorProfile(const char* profileData, unsigned profileLength) 183 { 184 ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength); 185 186 return !memcmp(&profileData[16], "RGB ", 4); 187 } 188 189 static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength) 190 { 191 ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength); 192 193 return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4); 194 } 195 196 class OutputDeviceProfile { 197 public: 198 OutputDeviceProfile() 199 : m_outputDeviceProfile(0) 200 { 201 ColorProfile profile = screenColorProfile(); 202 if (!profile.isEmpty()) 203 m_outputDeviceProfile = qcms_profile_from_memory(profile.data(), profile.size()); 204 205 if (m_outputDeviceProfile && qcms_profile_is_bogus(m_outputDeviceProfile)) { 206 qcms_profile_release(m_outputDeviceProfile); 207 m_outputDeviceProfile = 0; 208 } 209 210 if (!m_outputDeviceProfile) 211 m_outputDeviceProfile = qcms_profile_sRGB(); 212 if (m_outputDeviceProfile) 213 qcms_profile_precache_output_transform(m_outputDeviceProfile); 214 } 215 216 qcms_profile* profile() const { return m_outputDeviceProfile; } 217 218 private: 219 static ColorProfile screenColorProfile() 220 { 221 // FIXME: Add optional ICCv4 support and support for multiple monitors. 222 WebVector<char> profile; 223 Platform::current()->screenColorProfile(&profile); 224 225 ColorProfile colorProfile; 226 colorProfile.append(profile.data(), profile.size()); 227 return colorProfile; 228 } 229 230 qcms_profile* m_outputDeviceProfile; 231 }; 232 233 static qcms_profile* qcmsOutputDeviceProfile() 234 { 235 AtomicallyInitializedStatic(OutputDeviceProfile*, outputDeviceProfile = new OutputDeviceProfile()); 236 237 return outputDeviceProfile->profile(); 238 } 239 #endif 240 241 // Sets the "decode failure" flag. For caller convenience (since so 242 // many callers want to return false after calling this), returns false 243 // to enable easy tailcalling. Subclasses may override this to also 244 // clean up any local data. 245 virtual bool setFailed() 246 { 247 m_failed = true; 248 return false; 249 } 250 251 bool failed() const { return m_failed; } 252 253 // Clears decoded pixel data from all frames except the provided frame. 254 // Callers may pass WTF::kNotFound to clear all frames. 255 // Note: If |m_frameBufferCache| contains only one frame, it won't be cleared. 256 // Returns the number of bytes of frame data actually cleared. 257 virtual size_t clearCacheExceptFrame(size_t); 258 259 // If the image has a cursor hot-spot, stores it in the argument 260 // and returns true. Otherwise returns false. 261 virtual bool hotSpot(IntPoint&) const { return false; } 262 263 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator) 264 { 265 // FIXME: this doesn't work for images with multiple frames. 266 if (m_frameBufferCache.isEmpty()) { 267 m_frameBufferCache.resize(1); 268 m_frameBufferCache[0].setRequiredPreviousFrameIndex( 269 findRequiredPreviousFrame(0, false)); 270 } 271 m_frameBufferCache[0].setMemoryAllocator(allocator); 272 } 273 274 virtual bool canDecodeToYUV() const { return false; } 275 virtual bool decodeToYUV() { return false; } 276 virtual void setImagePlanes(PassOwnPtr<ImagePlanes>) { } 277 278 protected: 279 // Calculates the most recent frame whose image data may be needed in 280 // order to decode frame |frameIndex|, based on frame disposal methods 281 // and |frameRectIsOpaque|, where |frameRectIsOpaque| signifies whether 282 // the rectangle of frame at |frameIndex| is known to be opaque. 283 // If no previous frame's data is required, returns WTF::kNotFound. 284 // 285 // This function requires that the previous frame's 286 // |m_requiredPreviousFrameIndex| member has been set correctly. The 287 // easiest way to ensure this is for subclasses to call this method and 288 // store the result on the frame via setRequiredPreviousFrameIndex() 289 // as soon as the frame has been created and parsed sufficiently to 290 // determine the disposal method; assuming this happens for all frames 291 // in order, the required invariant will hold. 292 // 293 // Image formats which do not use more than one frame do not need to 294 // worry about this; see comments on 295 // ImageFrame::m_requiredPreviousFrameIndex. 296 size_t findRequiredPreviousFrame(size_t frameIndex, bool frameRectIsOpaque); 297 298 virtual void clearFrameBuffer(size_t frameIndex); 299 300 RefPtr<SharedBuffer> m_data; // The encoded data. 301 Vector<ImageFrame, 1> m_frameBufferCache; 302 bool m_premultiplyAlpha; 303 bool m_ignoreGammaAndColorProfile; 304 ImageOrientation m_orientation; 305 306 // The maximum amount of memory a decoded image should require. Ideally, 307 // image decoders should downsample large images to fit under this limit 308 // (and then return the downsampled size from decodedSize()). Ignoring 309 // this limit can cause excessive memory use or even crashes on low- 310 // memory devices. 311 size_t m_maxDecodedBytes; 312 313 private: 314 // Some code paths compute the size of the image as "width * height * 4" 315 // and return it as a (signed) int. Avoid overflow. 316 static bool sizeCalculationMayOverflow(unsigned width, unsigned height) 317 { 318 unsigned long long total_size = static_cast<unsigned long long>(width) 319 * static_cast<unsigned long long>(height); 320 return total_size > ((1 << 29) - 1); 321 } 322 323 IntSize m_size; 324 bool m_sizeAvailable; 325 bool m_isAllDataReceived; 326 bool m_failed; 327 }; 328 329 } // namespace blink 330 331 #endif 332