2009-11-19 Avi Drissman <avi@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Nov 2009 23:12:56 +0000 (23:12 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Nov 2009 23:12:56 +0000 (23:12 +0000)
        Reviewed by Darin Adler.

        Properly create a CGImageRef on non-PLATFORM(MAC).
        https://bugs.webkit.org/show_bug.cgi?id=27777

        * platform/graphics/cg/ImageSourceCG.cpp:
        (WebCore::sharedBufferGetBytesAtPosition):
        (WebCore::sharedBufferRelease):
        (WebCore::ImageSource::setData):
        * platform/graphics/cg/ImageSourceCG.h:
        * platform/graphics/cg/PDFDocumentImage.cpp:
        (WebCore::PDFDocumentImage::dataChanged):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51207 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/graphics/cg/ImageSourceCG.cpp
WebCore/platform/graphics/cg/ImageSourceCG.h
WebCore/platform/graphics/cg/PDFDocumentImage.cpp

index 741b8ee..c036d0a 100644 (file)
@@ -1,3 +1,18 @@
+2009-11-19  Avi Drissman  <avi@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Properly create a CGImageRef on non-PLATFORM(MAC).
+        https://bugs.webkit.org/show_bug.cgi?id=27777
+
+        * platform/graphics/cg/ImageSourceCG.cpp:
+        (WebCore::sharedBufferGetBytesAtPosition):
+        (WebCore::sharedBufferRelease):
+        (WebCore::ImageSource::setData):
+        * platform/graphics/cg/ImageSourceCG.h:
+        * platform/graphics/cg/PDFDocumentImage.cpp:
+        (WebCore::PDFDocumentImage::dataChanged):
+
 2009-11-19  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Dave Hyatt.
index 66246fe..2b2c6b0 100644 (file)
 #include <ApplicationServices/ApplicationServices.h>
 #include <wtf/UnusedParam.h>
 
+using namespace std;
+
 namespace WebCore {
 
 static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
 
 #if !PLATFORM(MAC)
-static void sharedBufferDerefCallback(void*, void* info)
+size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count)
+{
+    SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
+    size_t sourceSize = sharedBuffer->size();
+    if (position >= sourceSize)
+        return 0;
+
+    const char* source = sharedBuffer->data() + position;
+    size_t amount = min<size_t>(count, sourceSize - position);
+    memcpy(buffer, source, amount);
+    return amount;
+}
+
+void sharedBufferRelease(void* info)
 {
     SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
     sharedBuffer->deref();
@@ -110,15 +125,17 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
     // 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 inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
     RetainPtr<CFDataRef> cfData(AdoptCF, data->createCFData());
+    CGImageSourceUpdateData(m_decoder, cfData.get(), allDataReceived);
 #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. Ensure that the SharedBuffer lives as long as the CFDataRef.
+    // Create a CGDataProvider to wrap the SharedBuffer.
     data->ref();
-    CFAllocatorContext context = {0, data, 0, 0, 0, 0, 0, &sharedBufferDerefCallback, 0};
-    RetainPtr<CFAllocatorRef> derefAllocator(AdoptCF, CFAllocatorCreate(kCFAllocatorDefault, &context));
-    RetainPtr<CFDataRef> cfData(AdoptCF, CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), derefAllocator.get()));
+    // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
+    // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
+    // is a requirement for using the GetBytePointer callback.
+    CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, sharedBufferRelease };
+    RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateDirect(data, data->size(), &providerCallbacks));
+    CGImageSourceUpdateDataProvider(m_decoder, dataProvider.get(), allDataReceived);
 #endif
-    CGImageSourceUpdateData(m_decoder, cfData.get(), allDataReceived);
 }
 
 String ImageSource::filenameExtension() const
index d5b4b5a..76b4160 100644 (file)
@@ -36,6 +36,10 @@ String preferredExtensionForImageSourceType(const String& type);
 
 String MIMETypeForImageSourceType(const String& type);
 
+#if !PLATFORM(MAC)
+size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count);
+#endif
+
 }
 
 #endif // ImageSourceCG_h
index 2f5c15e..ee332c6 100644 (file)
@@ -31,6 +31,9 @@
 
 #include "GraphicsContext.h"
 #include "ImageObserver.h"
+#if !PLATFORM(MAC)
+#include "ImageSourceCG.h"
+#endif
 #include <wtf/MathExtras.h>
 
 using namespace std;
@@ -69,12 +72,15 @@ bool PDFDocumentImage::dataChanged(bool allDataReceived)
         // 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 inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
         RetainPtr<CFDataRef> data(AdoptCF, this->data()->createCFData());
+        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
 #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.
-        RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(this->data()->data()), this->data()->size(), kCFAllocatorNull));
+        // Create a CGDataProvider to wrap the SharedBuffer.
+        // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
+        // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
+        // is a requirement for using the GetBytePointer callback.
+        CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 };
+        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks));
 #endif
-        RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
         m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
         setCurrentPage(0);
     }