Diff
Modified: trunk/Source/WebCore/ChangeLog (215709 => 215710)
--- trunk/Source/WebCore/ChangeLog 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/ChangeLog 2017-04-25 01:23:55 UTC (rev 215710)
@@ -1,3 +1,81 @@
+2017-04-24 Said Abou-Hallawa <sabouhall...@apple.com>
+
+ [CG] Provide a type identifier hint to the CGImageSource so getting the type identifier is more accurate
+ https://bugs.webkit.org/show_bug.cgi?id=171042
+
+ Reviewed by Tim Horton.
+
+ The image URL can be used to get the type identifier hint. Without providing
+ this hint, the image type identifier is not accurate for image formats.
+
+ Also add a function to the ImageDecoder class to get the typeIdentifier. Add
+ all the pluming from the ImageDecoder till the Image class.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::destroyDecodedData):
+ (WebCore::BitmapImage::frameImageAtIndexCacheIfNeeded):
+ (WebCore::BitmapImage::draw):
+ (WebCore::BitmapImage::internalStartAnimation):
+ (WebCore::BitmapImage::advanceAnimation):
+ (WebCore::BitmapImage::internalAdvanceAnimation):
+ (WebCore::BitmapImage::newFrameNativeImageAvailableAtIndex):
+ * platform/graphics/BitmapImage.h:
+ * platform/graphics/Image.cpp:
+ (WebCore::Image::sourceURL):
+ * platform/graphics/Image.h: Change the sourceURL() to return a URL so CG can create CFURLRef from it.
+ (WebCore::Image::uti):
+ * platform/graphics/ImageFrameCache.cpp:
+ (WebCore::ImageFrameCache::cacheAsyncFrameNativeImageAtIndex):
+ (WebCore::ImageFrameCache::startAsyncDecodingQueue):
+ (WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex):
+ (WebCore::ImageFrameCache::stopAsyncDecodingQueue):
+ (WebCore::ImageFrameCache::clearMetadata):
+ (WebCore::ImageFrameCache::sourceURL):
+ (WebCore::ImageFrameCache::encodedDataStatus):
+ (WebCore::ImageFrameCache::uti):
+ (WebCore::ImageFrameCache::filenameExtension):
+ * platform/graphics/ImageFrameCache.h:
+ * platform/graphics/ImageSource.cpp:
+ (WebCore::ImageSource::ensureDecoderAvailable):
+ * platform/graphics/ImageSource.h:
+ (WebCore::ImageSource::uti):
+ * platform/graphics/cg/ImageDecoderCG.cpp:
+ (WebCore::ImageDecoder::ImageDecoder): Pass the type identifier hint to CGImageSourceCreateIncremental().
+ (WebCore::ImageDecoder::uti):
+ (WebCore::ImageDecoder::filenameExtension):
+ (WebCore::ImageDecoder::frameHasAlphaAtIndex):
+ (WebCore::ImageDecoder::createFrameImageAtIndex):
+ * platform/graphics/cg/ImageDecoderCG.h:
+ (WebCore::ImageDecoder::create):
+ * platform/graphics/win/ImageDecoderDirect2D.cpp:
+ (WebCore::ImageDecoder::encodedDataStatus):
+ * platform/graphics/win/ImageDecoderDirect2D.h:
+ (WebCore::ImageDecoder::create): Add an argument of type URL.
+ * platform/image-decoders/ImageDecoder.cpp:
+ (WebCore::ImageDecoder::create): Add an argument of type URL.
+ * platform/image-decoders/ImageDecoder.h:
+ (WebCore::ImageDecoder::encodedDataStatus): Make it const.
+ * platform/image-decoders/bmp/BMPImageDecoder.cpp:
+ (WebCore::BMPImageDecoder::encodedDataStatus):
+ * platform/image-decoders/bmp/BMPImageDecoder.h:
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::encodedDataStatus):
+ * platform/image-decoders/gif/GIFImageDecoder.h:
+ * platform/image-decoders/ico/ICOImageDecoder.cpp:
+ (WebCore::ICOImageDecoder::encodedDataStatus):
+ * platform/image-decoders/ico/ICOImageDecoder.h:
+ * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
+ (WebCore::JPEGImageDecoder::encodedDataStatus):
+ * platform/image-decoders/jpeg/JPEGImageDecoder.h:
+ * platform/image-decoders/png/PNGImageDecoder.cpp:
+ (WebCore::PNGImageDecoder::encodedDataStatus):
+ * platform/image-decoders/png/PNGImageDecoder.h:
+ * platform/image-decoders/webp/WEBPImageDecoder.cpp:
+ (WebCore::WEBPImageDecoder::encodedDataStatus):
+ * platform/image-decoders/webp/WEBPImageDecoder.h:
+ * platform/spi/cg/ImageIOSPI.h: Added.
+
2017-04-24 Ryan Haddad <ryanhad...@apple.com>
Unreviewed build fix.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (215709 => 215710)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-25 01:23:55 UTC (rev 215710)
@@ -2515,6 +2515,7 @@
5597F8271D91C3130066BC21 /* ImageFrameCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5597F8251D91C3130066BC21 /* ImageFrameCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 55B2BDD71EA923A400BFFCBD /* ImageIOSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B2BDD61EA923A400BFFCBD /* ImageIOSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
55AF14E51EAAC59B0026EEAA /* UTIRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55AF14E31EAAC59B0026EEAA /* UTIRegistry.cpp */; };
55AF14E61EAAC59B0026EEAA /* UTIRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 55AF14E41EAAC59B0026EEAA /* UTIRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
570440531E5278B200356601 /* CryptoAlgorithmAES_CFB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5712526A1E52527C008FF369 /* CryptoAlgorithmAES_CFB.cpp */; };
@@ -10238,6 +10239,7 @@
5597F8251D91C3130066BC21 /* ImageFrameCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrameCache.h; sourceTree = "<group>"; };
55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = "<group>"; };
+ 55B2BDD61EA923A400BFFCBD /* ImageIOSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageIOSPI.h; sourceTree = "<group>"; };
55AF14E31EAAC59B0026EEAA /* UTIRegistry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UTIRegistry.cpp; sourceTree = "<group>"; };
55AF14E41EAAC59B0026EEAA /* UTIRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTIRegistry.h; sourceTree = "<group>"; };
55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; };
@@ -17202,6 +17204,7 @@
isa = PBXGroup;
children = (
C24685131A148E1800811792 /* CoreGraphicsSPI.h */,
+ 55B2BDD61EA923A400BFFCBD /* ImageIOSPI.h */,
);
path = cg;
sourceTree = "<group>";
@@ -28364,6 +28367,7 @@
1A4DA4221CDD3A8300F4473C /* LinkIconCollector.h in Headers */,
1A250E0D1CDD632000D0BE63 /* LinkIconType.h in Headers */,
98CE432A129E00E5005821DC /* LinkLoader.h in Headers */,
+ 55B2BDD71EA923A400BFFCBD /* ImageIOSPI.h in Headers */,
984264F112D5280A000D88A4 /* LinkLoaderClient.h in Headers */,
CBB6B2D41CB7AE51009EDE1A /* LinkPreloadResourceClients.h in Headers */,
985BB96E13A94058007A0B69 /* LinkRelAttribute.h in Headers */,
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -65,7 +65,7 @@
void BitmapImage::destroyDecodedData(bool destroyAll)
{
- LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().utf8().data());
+ LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().string().utf8().data());
if (!destroyAll)
m_source.destroyDecodedDataBeforeFrame(m_currentFrame);
@@ -105,7 +105,7 @@
NativeImagePtr BitmapImage::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext)
{
if (!frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel)) {
- LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel was %d, resampling]", __FUNCTION__, this, sourceURL().utf8().data(), static_cast<int>(frameSubsamplingLevelAtIndex(index)));
+ LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel was %d, resampling]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(frameSubsamplingLevelAtIndex(index)));
invalidatePlatformData();
}
@@ -167,7 +167,7 @@
IntSize sizeForDrawing = expandedIntSize(size() * scaleFactorForDrawing);
m_currentSubsamplingLevel = allowSubsampling() ? m_source.subsamplingLevelForScaleFactor(context, scaleFactorForDrawing) : SubsamplingLevel::Default;
- LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel = %d scaleFactorForDrawing = (%.4f, %.4f)]", __FUNCTION__, this, sourceURL().utf8().data(), static_cast<int>(m_currentSubsamplingLevel), scaleFactorForDrawing.width(), scaleFactorForDrawing.height());
+ LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel = %d scaleFactorForDrawing = (%.4f, %.4f)]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(m_currentSubsamplingLevel), scaleFactorForDrawing.width(), scaleFactorForDrawing.height());
NativeImagePtr image;
if (decodingMode == DecodingMode::Asynchronous && shouldUseAsyncDecodingForLargeImages()) {
@@ -175,7 +175,7 @@
if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingOptions(sizeForDrawing))
&& !frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingOptions(sizeForDrawing))) {
- LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().utf8().data());
+ LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().string().utf8().data());
m_source.requestFrameAsyncDecodingAtIndex(0, m_currentSubsamplingLevel, sizeForDrawing);
}
@@ -186,7 +186,7 @@
}
image = frameImageAtIndex(m_currentFrame);
- LOG(Images, "BitmapImage::%s - %p - url: %s [a decoded image frame is available for drawing]", __FUNCTION__, this, sourceURL().utf8().data());
+ LOG(Images, "BitmapImage::%s - %p - url: %s [a decoded image frame is available for drawing]", __FUNCTION__, this, sourceURL().string().utf8().data());
} else {
StartAnimationStatus status = internalStartAnimation();
ASSERT_IMPLIES(status == StartAnimationStatus::DecodingActive, frameHasFullSizeNativeImageAtIndex(m_currentFrame, m_currentSubsamplingLevel));
@@ -200,7 +200,7 @@
// FIXME: instead of showing the yellow rectangle and returning we need to wait for this the frame to finish decoding.
if (showDebugBackground()) {
fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op);
- LOG(Images, "BitmapImage::%s - %p - url: %s [waiting for async decoding to finish]", __FUNCTION__, this, sourceURL().utf8().data());
+ LOG(Images, "BitmapImage::%s - %p - url: %s [waiting for async decoding to finish]", __FUNCTION__, this, sourceURL().string().utf8().data());
}
return;
}
@@ -304,7 +304,7 @@
// Don't start a new animation until we draw the frame that is currently being decoded.
size_t nextFrame = (m_currentFrame + 1) % frameCount();
if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(nextFrame, DecodingMode::Asynchronous)) {
- LOG(Images, "BitmapImage::%s - %p - url: %s [nextFrame = %ld is being decoded]", __FUNCTION__, this, sourceURL().utf8().data(), nextFrame);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [nextFrame = %ld is being decoded]", __FUNCTION__, this, sourceURL().string().utf8().data(), nextFrame);
return StartAnimationStatus::DecodingActive;
}
@@ -350,9 +350,9 @@
#if !LOG_DISABLED
if (isAsyncDecode)
- LOG(Images, "BitmapImage::%s - %p - url: %s [requesting async decoding for nextFrame = %ld]", __FUNCTION__, this, sourceURL().utf8().data(), nextFrame);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [requesting async decoding for nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), nextFrame);
else
- LOG(Images, "BitmapImage::%s - %p - url: %s [cachedFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().utf8().data(), ++m_cachedFrameCount, nextFrame);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [cachedFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), ++m_cachedFrameCount, nextFrame);
#else
UNUSED_PARAM(isAsyncDecode);
#endif
@@ -390,7 +390,7 @@
// Force repaint if showDebugBackground() is on.
if (showDebugBackground())
imageObserver()->changedInRect(this);
- LOG(Images, "BitmapImage::%s - %p - url: %s [lateFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().utf8().data(), ++m_lateFrameCount, nextFrame);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [lateFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), ++m_lateFrameCount, nextFrame);
}
}
@@ -404,7 +404,7 @@
if (imageObserver())
imageObserver()->animationAdvanced(this);
- LOG(Images, "BitmapImage::%s - %p - url: %s [m_currentFrame = %ld]", __FUNCTION__, this, sourceURL().utf8().data(), m_currentFrame);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [m_currentFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), m_currentFrame);
}
bool BitmapImage::isAnimating() const
@@ -436,7 +436,7 @@
void BitmapImage::newFrameNativeImageAvailableAtIndex(size_t index)
{
UNUSED_PARAM(index);
- LOG(Images, "BitmapImage::%s - %p - url: %s [requested frame %ld is now available]", __FUNCTION__, this, sourceURL().utf8().data(), index);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [requested frame %ld is now available]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
if (canAnimate()) {
ASSERT(index == (m_currentFrame + 1) % frameCount());
@@ -445,7 +445,7 @@
if (canAnimate() && !m_frameTimer)
internalAdvanceAnimation();
else
- LOG(Images, "BitmapImage::%s - %p - url: %s [earlyFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().utf8().data(), ++m_earlyFrameCount, index);
+ LOG(Images, "BitmapImage::%s - %p - url: %s [earlyFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), ++m_earlyFrameCount, index);
} else {
ASSERT(index == m_currentFrame && !m_currentFrame);
imageObserver()->changedInRect(this, nullptr);
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -74,6 +74,7 @@
EncodedDataStatus encodedDataStatus() const { return m_source.encodedDataStatus(); }
size_t frameCount() const { return m_source.frameCount(); }
RepetitionCount repetitionCount() const { return m_source.repetitionCount(); }
+ String uti() const override { return m_source.uti(); }
String filenameExtension() const override { return m_source.filenameExtension(); }
std::optional<IntPoint> hotSpot() const override { return m_source.hotSpot(); }
Modified: trunk/Source/WebCore/platform/graphics/Image.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/Image.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/Image.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -77,9 +77,9 @@
return dataChanged(allDataReceived);
}
-String Image::sourceURL() const
+URL Image::sourceURL() const
{
- return imageObserver() ? imageObserver()->sourceUrl().string() : emptyString();
+ return imageObserver() ? imageObserver()->sourceUrl() : URL();
}
void Image::fillWithSolidColor(GraphicsContext& ctxt, const FloatRect& dstRect, const Color& color, CompositeOperator op)
Modified: trunk/Source/WebCore/platform/graphics/Image.h (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/Image.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/Image.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -68,6 +68,7 @@
class FloatSize;
class GraphicsContext;
class SharedBuffer;
+class URL;
struct Length;
// This class gets notified when an image creates or destroys decoded frames and when it advances animation frames.
@@ -119,6 +120,7 @@
WEBCORE_EXPORT EncodedDataStatus setData(RefPtr<SharedBuffer>&& data, bool allDataReceived);
virtual EncodedDataStatus dataChanged(bool /*allDataReceived*/) { return EncodedDataStatus::Unknown; }
+ virtual String uti() const { return String(); } // null string if unknown
virtual String filenameExtension() const { return String(); } // null string if unknown
virtual void destroyDecodedData(bool destroyAll = true) = 0;
@@ -137,7 +139,7 @@
// Typically the CachedImage that owns us.
ImageObserver* imageObserver() const { return m_imageObserver; }
void setImageObserver(ImageObserver* observer) { m_imageObserver = observer; }
- String sourceURL() const;
+ URL sourceURL() const;
enum TileRule { StretchTile, RoundTile, SpaceTile, RepeatTile };
Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -29,6 +29,7 @@
#include "Image.h"
#include "ImageObserver.h"
#include "Logging.h"
+#include "URL.h"
#include <wtf/SystemTracing.h>
#if USE(CG)
@@ -250,7 +251,7 @@
// Clean the old native image and set a new one
cacheFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, decodingOptions);
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld has been cached]", __FUNCTION__, this, sourceURL().utf8().data(), index);
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld has been cached]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
// Notify the image with the readiness of the new frame NativeImage.
if (m_image)
@@ -286,9 +287,9 @@
// Get the frame NativeImage on the decoding thread.
NativeImagePtr nativeImage = protectedDecoder->createFrameImageAtIndex(frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions);
if (nativeImage)
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld has been decoded]", __FUNCTION__, this, sourceURL().utf8().data(), frameRequest.index);
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld has been decoded]", __FUNCTION__, this, sourceURL().string().utf8().data(), frameRequest.index);
else
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding for frame %ld has failed]", __FUNCTION__, this, sourceURL().utf8().data(), frameRequest.index);
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding for frame %ld has failed]", __FUNCTION__, this, sourceURL().string().utf8().data(), frameRequest.index);
// Update the cached frames on the main thread to avoid updating the MemoryCache from a different thread.
callOnMainThread([this, protectedQueue = protectedQueue.copyRef(), nativeImage, frameRequest] () mutable {
@@ -298,7 +299,7 @@
m_frameCommitQueue.removeFirst();
cacheAsyncFrameNativeImageAtIndex(WTFMove(nativeImage), frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions);
} else
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld will not cached]", __FUNCTION__, this, sourceURL().utf8().data(), frameRequest.index);
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld will not cached]", __FUNCTION__, this, sourceURL().string().utf8().data(), frameRequest.index);
});
}
});
@@ -323,7 +324,7 @@
if (!hasAsyncDecodingQueue())
startAsyncDecodingQueue();
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [enqueuing frame %ld for decoding]", __FUNCTION__, this, sourceURL().utf8().data(), index);
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [enqueuing frame %ld for decoding]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
m_frameRequestQueue.enqueue({ index, subsamplingLevel, sizeForDrawing });
m_frameCommitQueue.append({ index, subsamplingLevel, sizeForDrawing });
return true;
@@ -342,7 +343,7 @@
std::for_each(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [this](const ImageFrameRequest& frameRequest) {
ImageFrame& frame = m_frames[frameRequest.index];
if (!frame.isEmpty()) {
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding has been cancelled for frame %ld]", __FUNCTION__, this, sourceURL().utf8().data(), frameRequest.index);
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding has been cancelled for frame %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), frameRequest.index);
frame.clear();
}
});
@@ -350,7 +351,7 @@
m_frameRequestQueue.close();
m_frameCommitQueue.clear();
m_decodingQueue = nullptr;
- LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding has been stopped]", __FUNCTION__, this, sourceURL().utf8().data());
+ LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding has been stopped]", __FUNCTION__, this, sourceURL().string().utf8().data());
}
const ImageFrame& ImageFrameCache::frameAtIndexCacheIfNeeded(size_t index, ImageFrame::Caching caching, const std::optional<SubsamplingLevel>& subsamplingLevel)
@@ -388,11 +389,13 @@
{
m_frameCount = std::nullopt;
m_singlePixelSolidColor = std::nullopt;
+ m_encodedDataStatus = std::nullopt;
+ m_uti = std::nullopt;
}
-String ImageFrameCache::sourceURL() const
+URL ImageFrameCache::sourceURL() const
{
- return m_image ? m_image->sourceURL() : emptyString();
+ return m_image ? m_image->sourceURL() : URL();
}
template<typename T, T (ImageDecoder::*functor)() const>
@@ -437,22 +440,7 @@
EncodedDataStatus ImageFrameCache::encodedDataStatus()
{
- if (m_encodedDataStatus)
- return m_encodedDataStatus.value();
-
- if (!isDecoderAvailable())
- return EncodedDataStatus::Unknown;
-
- EncodedDataStatus status = m_decoder->encodedDataStatus();
- if (status < EncodedDataStatus::SizeAvailable)
- return status;
-
- didDecodeProperties(m_decoder->bytesDecodedToDetermineProperties());
- if (status < EncodedDataStatus::Complete)
- return status;
-
- m_encodedDataStatus = status;
- return status;
+ return metadata<EncodedDataStatus, (&ImageDecoder::encodedDataStatus)>(EncodedDataStatus::Unknown, &m_encodedDataStatus);
}
size_t ImageFrameCache::frameCount()
@@ -464,6 +452,15 @@
{
return metadata<RepetitionCount, (&ImageDecoder::repetitionCount)>(RepetitionCountNone, &m_repetitionCount);
}
+
+String ImageFrameCache::uti()
+{
+#if USE(CG)
+ return metadata<String, (&ImageDecoder::uti)>(String(), &m_uti);
+#else
+ return String();
+#endif
+}
String ImageFrameCache::filenameExtension()
{
Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.h (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -39,6 +39,7 @@
class GraphicsContext;
class Image;
class ImageDecoder;
+class URL;
class ImageFrameCache : public RefCounted<ImageFrameCache> {
friend class ImageSource;
@@ -66,7 +67,7 @@
void growFrames();
void clearMetadata();
- String sourceURL() const;
+ URL sourceURL() const;
// Asynchronous image decoding
void startAsyncDecodingQueue();
@@ -81,6 +82,7 @@
bool isSizeAvailable() { return encodedDataStatus() >= EncodedDataStatus::SizeAvailable; }
size_t frameCount();
RepetitionCount repetitionCount();
+ String uti();
String filenameExtension();
std::optional<IntPoint> hotSpot();
@@ -117,10 +119,10 @@
template<typename T, typename... Args>
T frameMetadataAtIndex(size_t, T (ImageFrame::*functor)(Args...) const, Args&&...);
-
+
template<typename T, typename... Args>
T frameMetadataAtIndexCacheIfNeeded(size_t, T (ImageFrame::*functor)() const, std::optional<T>* cachedValue, Args&&...);
-
+
bool isDecoderAvailable() const { return m_decoder; }
void destroyDecodedData(size_t frameCount, size_t excludeFrame);
void decodedSizeChanged(long long decodedSize);
@@ -166,6 +168,7 @@
std::optional<EncodedDataStatus> m_encodedDataStatus;
std::optional<size_t> m_frameCount;
std::optional<RepetitionCount> m_repetitionCount;
+ std::optional<String> m_uti;
std::optional<String> m_filenameExtension;
std::optional<std::optional<IntPoint>> m_hotSpot;
Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -82,7 +82,7 @@
if (!data || isDecoderAvailable())
return true;
- m_decoder = ImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption);
+ m_decoder = ImageDecoder::create(*data, m_frameCache->sourceURL(), m_alphaOption, m_gammaAndColorProfileOption);
if (!isDecoderAvailable())
return false;
Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/ImageSource.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -32,6 +32,7 @@
#include "IntPoint.h"
#include "NativeImage.h"
#include "TextStream.h"
+#include "URL.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/Optional.h>
@@ -78,6 +79,7 @@
EncodedDataStatus encodedDataStatus() { return m_frameCache->encodedDataStatus(); }
size_t frameCount() { return m_frameCache->frameCount(); }
RepetitionCount repetitionCount() { return m_frameCache->repetitionCount(); }
+ String uti() { return m_frameCache->uti(); }
String filenameExtension() { return m_frameCache->filenameExtension(); }
std::optional<IntPoint> hotSpot() { return m_frameCache->hotSpot(); }
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -28,11 +28,13 @@
#if USE(CG)
+#include "ImageIOSPI.h"
#include "ImageOrientation.h"
#include "IntPoint.h"
#include "IntSize.h"
#include "Logging.h"
#include "SharedBuffer.h"
+#include "URL.h"
#include <wtf/NeverDestroyed.h>
#if !PLATFORM(IOS)
@@ -42,13 +44,6 @@
#include <ImageIO/ImageIO.h>
#endif
-#if USE(APPLE_INTERNAL_SDK)
-#import <ImageIO/CGImageSourcePrivate.h>
-#else
-const CFStringRef kCGImageSourceSubsampleFactor = CFSTR("kCGImageSourceSubsampleFactor");
-const CFStringRef kCGImageSourceShouldCacheImmediately = CFSTR("kCGImageSourceShouldCacheImmediately");
-#endif
-
namespace WebCore {
const CFStringRef WebCoreCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime");
@@ -55,8 +50,12 @@
const CFStringRef WebCoreCGImagePropertyAPNGDelayTime = CFSTR("DelayTime");
const CFStringRef WebCoreCGImagePropertyAPNGLoopCount = CFSTR("LoopCount");
+#if PLATFORM(WIN)
const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
const CFStringRef kCGImageSourceSkipMetadata = CFSTR("kCGImageSourceSkipMetadata");
+const CFStringRef kCGImageSourceSubsampleFactor = CFSTR("kCGImageSourceSubsampleFactor");
+const CFStringRef kCGImageSourceShouldCacheImmediately = CFSTR("kCGImageSourceShouldCacheImmediately");
+#endif
static RetainPtr<CFMutableDictionaryRef> createImageSourceOptions()
{
@@ -153,9 +152,23 @@
}
#endif
-ImageDecoder::ImageDecoder(AlphaOption, GammaAndColorProfileOption)
+ImageDecoder::ImageDecoder(const URL& sourceURL, AlphaOption, GammaAndColorProfileOption)
{
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
+ RetainPtr<CFURLRef> url = ""
+ RetainPtr<CFStringRef> utiHint = adoptCF(CGImageSourceGetTypeWithURL(url.get(), nullptr));
+
+ if (utiHint) {
+ const void* key = kCGImageSourceTypeIdentifierHint;
+ const void* value = utiHint.get();
+ auto options = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ m_nativeDecoder = adoptCF(CGImageSourceCreateIncremental(options.get()));
+ } else
+ m_nativeDecoder = adoptCF(CGImageSourceCreateIncremental(nullptr));
+#else
+ UNUSED_PARAM(sourceURL);
m_nativeDecoder = adoptCF(CGImageSourceCreateIncremental(nullptr));
+#endif
}
size_t ImageDecoder::bytesDecodedToDetermineProperties()
@@ -168,11 +181,15 @@
// behavior is unchanged.
return 13088;
}
+
+String ImageDecoder::uti() const
+{
+ return CGImageSourceGetType(m_nativeDecoder.get());
+}
String ImageDecoder::filenameExtension() const
{
- CFStringRef imageSourceType = CGImageSourceGetType(m_nativeDecoder.get());
- return WebCore::preferredExtensionForImageSourceType(imageSourceType);
+ return WebCore::preferredExtensionForImageSourceType(uti());
}
EncodedDataStatus ImageDecoder::encodedDataStatus() const
@@ -367,11 +384,11 @@
if (!frameIsCompleteAtIndex(index))
return true;
- CFStringRef imageType = CGImageSourceGetType(m_nativeDecoder.get());
+ String uti = this->uti();
// Return false if there is no image type or the image type is JPEG, because
// JPEG does not support alpha transparency.
- if (!imageType || CFEqual(imageType, CFSTR("public.jpeg")))
+ if (uti.isEmpty() || uti == "public.jpeg")
return false;
// FIXME: Could return false for other non-transparent image formats.
@@ -435,15 +452,10 @@
#endif
#endif // PLATFORM(IOS)
- CFStringRef imageUTI = CGImageSourceGetType(m_nativeDecoder.get());
- static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image");
-
- if (!imageUTI)
+ String uti = this->uti();
+ if (uti.isEmpty() || uti != "public.xbitmap-image")
return image;
- if (!CFEqual(imageUTI, xbmUTI))
- return image;
-
// If it is an xbm image, mask out all the white areas to render them transparent.
const CGFloat maskingColors[6] = {255, 255, 255, 255, 255, 255};
RetainPtr<CGImageRef> maskedImage = adoptCF(CGImageCreateWithMaskingColors(image.get(), maskingColors));
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -38,11 +38,11 @@
class ImageDecoder : public RefCounted<ImageDecoder> {
WTF_MAKE_FAST_ALLOCATED;
public:
- ImageDecoder(AlphaOption, GammaAndColorProfileOption);
+ ImageDecoder(const URL& sourceURL, AlphaOption, GammaAndColorProfileOption);
- static Ref<ImageDecoder> create(const SharedBuffer&, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
+ static Ref<ImageDecoder> create(const SharedBuffer&, const URL& sourceURL, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
{
- return adoptRef(*new ImageDecoder(alphaOption, gammaAndColorProfileOption));
+ return adoptRef(*new ImageDecoder(sourceURL, alphaOption, gammaAndColorProfileOption));
}
static size_t bytesDecodedToDetermineProperties();
@@ -51,6 +51,7 @@
bool isSizeAvailable() { return encodedDataStatus() >= EncodedDataStatus::SizeAvailable; }
size_t frameCount() const;
RepetitionCount repetitionCount() const;
+ String uti() const;
String filenameExtension() const;
std::optional<IntPoint> hotSpot() const;
Modified: trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -73,6 +73,12 @@
return m_nativeDecoder ? true : false;
}
+EncodedDataStatus ImageDecoder::encodedDataStatus() const
+{
+ notImplemented();
+ return EncodedDataStatus::Unknown;
+}
+
IntSize ImageDecoder::size() const
{
if (!m_nativeDecoder)
Modified: trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h (215709 => 215710)
--- trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -41,7 +41,7 @@
public:
ImageDecoder();
- static Ref<ImageDecoder> create(const SharedBuffer&, AlphaOption, GammaAndColorProfileOption)
+ static Ref<ImageDecoder> create(const SharedBuffer&, const URL&, AlphaOption, GammaAndColorProfileOption)
{
return adoptRef(*new ImageDecoder());
}
@@ -49,6 +49,7 @@
static size_t bytesDecodedToDetermineProperties();
String filenameExtension() const;
+ EncodedDataStatus encodedDataStatus() const;
bool isSizeAvailable() const;
// Always original size, without subsampling.
Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -98,7 +98,7 @@
}
-RefPtr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
+RefPtr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, const URL&, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
{
static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP"
char contents[lengthOfLongestSignature];
Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -41,189 +41,191 @@
namespace WebCore {
- // ImageDecoder is a base for all format-specific decoders
- // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
- //
- // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
- // at decode time. Image decoders will downsample any images larger than
- // |m_maxNumPixels|. FIXME: Not yet supported by all decoders.
- class ImageDecoder : public RefCounted<ImageDecoder> {
- WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
- public:
- ImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
- : m_premultiplyAlpha(alphaOption == AlphaOption::Premultiplied)
- , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == GammaAndColorProfileOption::Ignored)
- {
- }
+class URL;
- virtual ~ImageDecoder()
- {
- }
+// ImageDecoder is a base for all format-specific decoders
+// (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
+//
+// ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
+// at decode time. Image decoders will downsample any images larger than
+// |m_maxNumPixels|. FIXME: Not yet supported by all decoders.
+class ImageDecoder : public RefCounted<ImageDecoder> {
+ WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
+public:
+ ImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
+ : m_premultiplyAlpha(alphaOption == AlphaOption::Premultiplied)
+ , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == GammaAndColorProfileOption::Ignored)
+ {
+ }
- // Returns nullptr if we can't sniff a supported type from the provided data (possibly
- // because there isn't enough data yet).
- static RefPtr<ImageDecoder> create(const SharedBuffer& data, AlphaOption, GammaAndColorProfileOption);
+ virtual ~ImageDecoder()
+ {
+ }
- virtual String filenameExtension() const = 0;
-
- bool premultiplyAlpha() const { return m_premultiplyAlpha; }
+ // Returns nullptr if we can't sniff a supported type from the provided data (possibly
+ // because there isn't enough data yet).
+ static RefPtr<ImageDecoder> create(const SharedBuffer& data, const URL&, AlphaOption, GammaAndColorProfileOption);
- bool isAllDataReceived() const { return m_isAllDataReceived; }
+ virtual String filenameExtension() const = 0;
+
+ bool premultiplyAlpha() const { return m_premultiplyAlpha; }
- virtual void setData(SharedBuffer& data, bool allDataReceived)
- {
- if (m_failed)
- return;
- m_data = &data;
- m_isAllDataReceived = allDataReceived;
- }
+ bool isAllDataReceived() const { return m_isAllDataReceived; }
- // Lazily-decodes enough of the image to get the size (if possible).
- // FIXME: Right now that has to be done by each subclass; factor the
- // decode call out and use it here.
- virtual EncodedDataStatus encodedDataStatus()
- {
- if (m_failed)
- return EncodedDataStatus::Error;
+ virtual void setData(SharedBuffer& data, bool allDataReceived)
+ {
+ if (m_failed)
+ return;
+ m_data = &data;
+ m_isAllDataReceived = allDataReceived;
+ }
- if (m_isAllDataReceived)
- return EncodedDataStatus::Complete;
+ // Lazily-decodes enough of the image to get the size (if possible).
+ // FIXME: Right now that has to be done by each subclass; factor the
+ // decode call out and use it here.
+ virtual EncodedDataStatus encodedDataStatus() const
+ {
+ if (m_failed)
+ return EncodedDataStatus::Error;
- if (m_sizeAvailable)
- return EncodedDataStatus::SizeAvailable;
+ if (m_isAllDataReceived)
+ return EncodedDataStatus::Complete;
- return EncodedDataStatus::TypeAvailable;
- }
+ if (m_sizeAvailable)
+ return EncodedDataStatus::SizeAvailable;
- bool isSizeAvailable() { return encodedDataStatus() >= EncodedDataStatus::SizeAvailable; }
+ return EncodedDataStatus::TypeAvailable;
+ }
- virtual IntSize size() { return isSizeAvailable() ? m_size : IntSize(); }
+ bool isSizeAvailable() { return encodedDataStatus() >= EncodedDataStatus::SizeAvailable; }
- IntSize scaledSize()
- {
- return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
- }
+ virtual IntSize size() { return isSizeAvailable() ? m_size : IntSize(); }
- // This will only differ from size() for ICO (where each frame is a
- // different icon) or other formats where different frames are different
- // sizes. This does NOT differ from size() for GIF, since decoding GIFs
- // composites any smaller frames against previous frames to create full-
- // size frames.
- virtual IntSize frameSizeAtIndex(size_t, SubsamplingLevel)
- {
- return size();
- }
+ IntSize scaledSize()
+ {
+ return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
+ }
- // Returns whether the size is legal (i.e. not going to result in
- // overflow elsewhere). If not, marks decoding as failed.
- virtual bool setSize(const IntSize& size)
- {
- if (ImageBackingStore::isOverSize(size))
- return setFailed();
- m_size = size;
- m_sizeAvailable = true;
- return true;
- }
+ // This will only differ from size() for ICO (where each frame is a
+ // different icon) or other formats where different frames are different
+ // sizes. This does NOT differ from size() for GIF, since decoding GIFs
+ // composites any smaller frames against previous frames to create full-
+ // size frames.
+ virtual IntSize frameSizeAtIndex(size_t, SubsamplingLevel)
+ {
+ return size();
+ }
- // Lazily-decodes enough of the image to get the frame count (if
- // possible), without decoding the individual frames.
- // FIXME: Right now that has to be done by each subclass; factor the
- // decode call out and use it here.
- virtual size_t frameCount() const { return 1; }
+ // Returns whether the size is legal (i.e. not going to result in
+ // overflow elsewhere). If not, marks decoding as failed.
+ virtual bool setSize(const IntSize& size)
+ {
+ if (ImageBackingStore::isOverSize(size))
+ return setFailed();
+ m_size = size;
+ m_sizeAvailable = true;
+ return true;
+ }
- virtual RepetitionCount repetitionCount() const { return RepetitionCountNone; }
+ // Lazily-decodes enough of the image to get the frame count (if
+ // possible), without decoding the individual frames.
+ // FIXME: Right now that has to be done by each subclass; factor the
+ // decode call out and use it here.
+ virtual size_t frameCount() const { return 1; }
- // Decodes as much of the requested frame as possible, and returns an
- // ImageDecoder-owned pointer.
- virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
+ virtual RepetitionCount repetitionCount() const { return RepetitionCountNone; }
- bool frameIsCompleteAtIndex(size_t);
+ // Decodes as much of the requested frame as possible, and returns an
+ // ImageDecoder-owned pointer.
+ virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
- // Make the best effort guess to check if the requested frame has alpha channel.
- bool frameHasAlphaAtIndex(size_t) const;
+ bool frameIsCompleteAtIndex(size_t);
- // Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
- unsigned frameBytesAtIndex(size_t) const;
-
- float frameDurationAtIndex(size_t);
-
- NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const DecodingOptions& = DecodingMode::Synchronous);
+ // Make the best effort guess to check if the requested frame has alpha channel.
+ bool frameHasAlphaAtIndex(size_t) const;
- void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
- bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
+ // Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
+ unsigned frameBytesAtIndex(size_t) const;
+
+ float frameDurationAtIndex(size_t);
+
+ NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const DecodingOptions& = DecodingMode::Synchronous);
- ImageOrientation frameOrientationAtIndex(size_t) const { return m_orientation; }
-
- bool frameAllowSubsamplingAtIndex(size_t) const { return false; }
+ void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
+ bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
- enum { iccColorProfileHeaderLength = 128 };
+ ImageOrientation frameOrientationAtIndex(size_t) const { return m_orientation; }
+
+ bool frameAllowSubsamplingAtIndex(size_t) const { return false; }
- static bool rgbColorProfile(const char* profileData, unsigned profileLength)
- {
- ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
+ enum { ICCColorProfileHeaderLength = 128 };
- return !memcmp(&profileData[16], "RGB ", 4);
- }
+ static bool rgbColorProfile(const char* profileData, unsigned profileLength)
+ {
+ ASSERT_UNUSED(profileLength, profileLength >= ICCColorProfileHeaderLength);
- static size_t bytesDecodedToDetermineProperties() { return 0; }
-
- static SubsamplingLevel subsamplingLevelForScale(float, SubsamplingLevel) { return SubsamplingLevel::Default; }
+ return !memcmp(&profileData[16], "RGB ", 4);
+ }
- static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
- {
- ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
+ static size_t bytesDecodedToDetermineProperties() { return 0; }
+
+ static SubsamplingLevel subsamplingLevelForScale(float, SubsamplingLevel) { return SubsamplingLevel::Default; }
- return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
- }
+ static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
+ {
+ ASSERT_UNUSED(profileLength, profileLength >= ICCColorProfileHeaderLength);
- // Sets the "decode failure" flag. For caller convenience (since so
- // many callers want to return false after calling this), returns false
- // to enable easy tailcalling. Subclasses may override this to also
- // clean up any local data.
- virtual bool setFailed()
- {
- m_failed = true;
- return false;
- }
+ return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
+ }
- bool failed() const { return m_failed; }
+ // Sets the "decode failure" flag. For caller convenience (since so
+ // many callers want to return false after calling this), returns false
+ // to enable easy tailcalling. Subclasses may override this to also
+ // clean up any local data.
+ virtual bool setFailed()
+ {
+ m_failed = true;
+ return false;
+ }
- // Clears decoded pixel data from before the provided frame unless that
- // data may be needed to decode future frames (e.g. due to GIF frame
- // compositing).
- virtual void clearFrameBufferCache(size_t) { }
+ bool failed() const { return m_failed; }
- // If the image has a cursor hot-spot, stores it in the argument
- // and returns true. Otherwise returns false.
- virtual std::optional<IntPoint> hotSpot() const { return std::nullopt; }
+ // Clears decoded pixel data from before the provided frame unless that
+ // data may be needed to decode future frames (e.g. due to GIF frame
+ // compositing).
+ virtual void clearFrameBufferCache(size_t) { }
- protected:
- void prepareScaleDataIfNecessary();
- int upperBoundScaledX(int origX, int searchStart = 0);
- int lowerBoundScaledX(int origX, int searchStart = 0);
- int upperBoundScaledY(int origY, int searchStart = 0);
- int lowerBoundScaledY(int origY, int searchStart = 0);
- int scaledY(int origY, int searchStart = 0);
+ // If the image has a cursor hot-spot, stores it in the argument
+ // and returns true. Otherwise returns false.
+ virtual std::optional<IntPoint> hotSpot() const { return std::nullopt; }
- RefPtr<SharedBuffer> m_data; // The encoded data.
- Vector<ImageFrame, 1> m_frameBufferCache;
- bool m_scaled { false };
- Vector<int> m_scaledColumns;
- Vector<int> m_scaledRows;
- bool m_premultiplyAlpha;
- bool m_ignoreGammaAndColorProfile;
- ImageOrientation m_orientation;
+protected:
+ void prepareScaleDataIfNecessary();
+ int upperBoundScaledX(int origX, int searchStart = 0);
+ int lowerBoundScaledX(int origX, int searchStart = 0);
+ int upperBoundScaledY(int origY, int searchStart = 0);
+ int lowerBoundScaledY(int origY, int searchStart = 0);
+ int scaledY(int origY, int searchStart = 0);
- private:
- IntSize m_size;
- bool m_sizeAvailable { false };
+ RefPtr<SharedBuffer> m_data; // The encoded data.
+ Vector<ImageFrame, 1> m_frameBufferCache;
+ bool m_scaled { false };
+ Vector<int> m_scaledColumns;
+ Vector<int> m_scaledRows;
+ bool m_premultiplyAlpha;
+ bool m_ignoreGammaAndColorProfile;
+ ImageOrientation m_orientation;
+
+private:
+ IntSize m_size;
+ bool m_sizeAvailable { false };
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- static const int m_maxNumPixels { 1024 * 1024 };
+ static const int m_maxNumPixels { 1024 * 1024 };
#else
- static const int m_maxNumPixels { -1 };
+ static const int m_maxNumPixels { -1 };
#endif
- bool m_isAllDataReceived { false };
- bool m_failed { false };
- };
+ bool m_isAllDataReceived { false };
+ bool m_failed { false };
+};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -56,10 +56,10 @@
m_reader->setData(&data);
}
-EncodedDataStatus BMPImageDecoder::encodedDataStatus()
+EncodedDataStatus BMPImageDecoder::encodedDataStatus() const
{
if (ImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
- decode(true);
+ const_cast<BMPImageDecoder*>(this)->decode(true);
return ImageDecoder::encodedDataStatus();
}
Modified: trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -40,9 +40,9 @@
BMPImageDecoder(AlphaOption, GammaAndColorProfileOption);
// ImageDecoder
- String filenameExtension() const override { return "bmp"; }
+ String filenameExtension() const override { return ASCIILiteral("bmp"); }
void setData(SharedBuffer&, bool allDataReceived) override;
- EncodedDataStatus encodedDataStatus() override;
+ EncodedDataStatus encodedDataStatus() const override;
ImageFrame* frameBufferAtIndex(size_t index) override;
// CAUTION: setFailed() deletes |m_reader|. Be careful to avoid
// accessing deleted memory, especially when calling this from inside
Modified: trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -50,10 +50,10 @@
m_reader->setData(&data);
}
-EncodedDataStatus GIFImageDecoder::encodedDataStatus()
+EncodedDataStatus GIFImageDecoder::encodedDataStatus() const
{
if (ImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
- decode(0, GIFSizeQuery);
+ const_cast<GIFImageDecoder*>(this)->decode(0, GIFSizeQuery);
return ImageDecoder::encodedDataStatus();
}
Modified: trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -41,9 +41,9 @@
enum GIFQuery { GIFFullQuery, GIFSizeQuery, GIFFrameCountQuery };
// ImageDecoder
- String filenameExtension() const override { return "gif"; }
+ String filenameExtension() const override { return ASCIILiteral("gif"); }
void setData(SharedBuffer& data, bool allDataReceived) override;
- EncodedDataStatus encodedDataStatus() override;
+ EncodedDataStatus encodedDataStatus() const override;
bool setSize(const IntSize&) override;
size_t frameCount() const override;
RepetitionCount repetitionCount() const override;
Modified: trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -69,10 +69,10 @@
setDataForPNGDecoderAtIndex(i);
}
-EncodedDataStatus ICOImageDecoder::encodedDataStatus()
+EncodedDataStatus ICOImageDecoder::encodedDataStatus() const
{
if (ImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
- decode(0, true);
+ const_cast<ICOImageDecoder*>(this)->decode(0, true);
return ImageDecoder::encodedDataStatus();
}
Modified: trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -43,9 +43,9 @@
virtual ~ICOImageDecoder();
// ImageDecoder
- String filenameExtension() const override { return "ico"; }
+ String filenameExtension() const override { return ASCIILiteral("ico"); }
void setData(SharedBuffer&, bool allDataReceived) override;
- EncodedDataStatus encodedDataStatus() override;
+ EncodedDataStatus encodedDataStatus() const override;
IntSize size() override;
IntSize frameSizeAtIndex(size_t, SubsamplingLevel) override;
bool setSize(const IntSize&) override;
Modified: trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -510,10 +510,10 @@
{
}
-EncodedDataStatus JPEGImageDecoder::encodedDataStatus()
+EncodedDataStatus JPEGImageDecoder::encodedDataStatus() const
{
if (ImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
- decode(true);
+ const_cast<JPEGImageDecoder*>(this)->decode(true);
return ImageDecoder::encodedDataStatus();
}
Modified: trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -47,8 +47,8 @@
virtual ~JPEGImageDecoder();
// ImageDecoder
- String filenameExtension() const override { return "jpg"; }
- EncodedDataStatus encodedDataStatus() override;
+ String filenameExtension() const override { return ASCIILiteral("jpg"); }
+ EncodedDataStatus encodedDataStatus() const override;
bool setSize(const IntSize&) override;
ImageFrame* frameBufferAtIndex(size_t index) override;
// CAUTION: setFailed() deletes |m_reader|. Be careful to avoid
Modified: trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -244,10 +244,10 @@
}
#endif
-EncodedDataStatus PNGImageDecoder::encodedDataStatus()
+EncodedDataStatus PNGImageDecoder::encodedDataStatus() const
{
if (ImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
- decode(true, 0);
+ const_cast<PNGImageDecoder*>(this)->decode(true, 0);
return ImageDecoder::encodedDataStatus();
}
Modified: trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -41,12 +41,12 @@
virtual ~PNGImageDecoder();
// ImageDecoder
- String filenameExtension() const override { return "png"; }
+ String filenameExtension() const override { return ASCIILiteral("png"); }
#if ENABLE(APNG)
size_t frameCount() const override { return m_frameCount; }
RepetitionCount repetitionCount() const override;
#endif
- EncodedDataStatus encodedDataStatus() override;
+ EncodedDataStatus encodedDataStatus() const override;
bool setSize(const IntSize&) override;
ImageFrame* frameBufferAtIndex(size_t index) override;
// CAUTION: setFailed() deletes |m_reader|. Be careful to avoid
Modified: trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp 2017-04-25 01:23:55 UTC (rev 215710)
@@ -64,10 +64,10 @@
m_decoder = 0;
}
-EncodedDataStatus WEBPImageDecoder::encodedDataStatus()
+EncodedDataStatus WEBPImageDecoder::encodedDataStatus() const
{
if (ImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
- decode(true);
+ const_cast<WEBPImageDecoder*>(this)->decode(true);
return ImageDecoder::encodedDataStatus();
}
Modified: trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h (215709 => 215710)
--- trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h 2017-04-25 00:43:36 UTC (rev 215709)
+++ trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -41,8 +41,8 @@
WEBPImageDecoder(AlphaOption, GammaAndColorProfileOption);
virtual ~WEBPImageDecoder();
- String filenameExtension() const override { return "webp"; }
- EncodedDataStatus encodedDataStatus() override;
+ String filenameExtension() const override { return ASCIILiteral("webp"); }
+ EncodedDataStatus encodedDataStatus() const override;
ImageFrame* frameBufferAtIndex(size_t index) override;
private:
Added: trunk/Source/WebCore/platform/spi/cg/ImageIOSPI.h (0 => 215710)
--- trunk/Source/WebCore/platform/spi/cg/ImageIOSPI.h (rev 0)
+++ trunk/Source/WebCore/platform/spi/cg/ImageIOSPI.h 2017-04-25 01:23:55 UTC (rev 215710)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <ImageIO/ImageIOBase.h>
+
+#if USE(APPLE_INTERNAL_SDK)
+#include <ImageIO/CGImageSourcePrivate.h>
+#endif
+
+#if !PLATFORM(WIN)
+IMAGEIO_EXTERN const CFStringRef kCGImageSourceShouldPreferRGB32;
+IMAGEIO_EXTERN const CFStringRef kCGImageSourceSkipMetadata;
+IMAGEIO_EXTERN const CFStringRef kCGImageSourceSubsampleFactor;
+IMAGEIO_EXTERN const CFStringRef kCGImageSourceShouldCacheImmediately;
+#endif
+
+WTF_EXTERN_C_BEGIN
+CFStringRef CGImageSourceGetTypeWithURL(CFURLRef, CFStringRef);
+WTF_EXTERN_C_END