Get the size from the shared buffer.
[WebKit-https.git] / WebCore / platform / graphics / cg / ImageSourceCG.cpp
index 2326d77..a8eaee4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 #include "ImageSource.h"
+#include "SharedBuffer.h"
 
 #if PLATFORM(CG)
 
@@ -40,8 +41,15 @@ ImageSource::ImageSource()
 
 ImageSource::~ImageSource()
 {
-    if (m_decoder)
+    clear();
+}
+
+void ImageSource::clear()
+{
+    if (m_decoder) {
         CFRelease(m_decoder);
+        m_decoder = 0;
+    }
 }
 
 const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
@@ -64,11 +72,21 @@ bool ImageSource::initialized() const
     return m_decoder;
 }
 
-void ImageSource::setData(NativeBytePtr data, bool allDataReceived)
+void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
 {
     if (!m_decoder)
-        m_decoder = CGImageSourceCreateIncremental(imageSourceOptions());
-    CGImageSourceUpdateData(m_decoder, data, allDataReceived);
+        m_decoder = CGImageSourceCreateIncremental(NULL);
+#if PLATFORM(MAC)
+    // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
+    // to wrap itself in an NSData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
+    CFDataRef cfData = (CFDataRef)data->createNSData();
+#else
+    // If no NSData is available, then we know SharedBuffer will always just be a vector.  That means no secret changes can occur to it behind the
+    // scenes.  We use CFDataCreateWithBytesNoCopy in that case.
+    CFDataRef cfData = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), kCFAllocatorNull);
+#endif
+    CGImageSourceUpdateData(m_decoder, cfData, allDataReceived);
+    CFRelease(cfData);
 }
 
 bool ImageSource::isSizeAvailable()
@@ -139,6 +157,20 @@ CGImageRef ImageSource::createFrameAtIndex(size_t index)
     return CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions());
 }
 
+void ImageSource::destroyFrameAtIndex(size_t index)
+{
+    // FIXME: Image I/O has no API for flushing frames from its internal cache.  The best we can do is tell it to create
+    // a new image with NULL options.  This will cause the cache/no-cache flags to mismatch, and it will then drop
+    // its reference to the old decoded image.
+    CGImageRef image = CGImageSourceCreateImageAtIndex(m_decoder, index, NULL);
+    CGImageRelease(image);
+}
+
+bool ImageSource::frameIsCompleteAtIndex(size_t index)
+{
+    return CGImageSourceGetStatusAtIndex(m_decoder, index) == kCGImageStatusComplete;
+}
+
 float ImageSource::frameDurationAtIndex(size_t index)
 {
     float duration = 0;