Title: [254900] trunk/Source/WebCore
Revision
254900
Author
[email protected]
Date
2020-01-21 23:00:16 -0800 (Tue, 21 Jan 2020)

Log Message

Move ImageBuffer utilities function to separate files
https://bugs.webkit.org/show_bug.cgi?id=206519

Patch by Said Abou-Hallawa <[email protected]> on 2020-01-21
Reviewed by Tim Horton.

These utilities function are merely related to the ImageData.

* SourcesGTK.txt:
* html/HTMLCanvasElement.cpp:
* platform/SourcesCairo.txt:
* platform/graphics/ImageBuffer.h:
* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::ImageBuffer::toData const):
(WebCore::writeFunction): Deleted.
(WebCore::encodeImage): Deleted.
* platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp: Added.
(WebCore::writeFunction):
(WebCore::encodeImage):
(WebCore::data):
* platform/graphics/cairo/ImageBufferUtilitiesCairo.h: Added.
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::jpegUTI): Deleted.
(WebCore::utiFromImageBufferMIMEType): Deleted.
(WebCore::encodeImage): Deleted.
(WebCore::dataURL): Deleted.
(WebCore::dataVector): Deleted.
(WebCore::cfData): Deleted.
(WebCore::data): Deleted.
* platform/graphics/cg/ImageBufferDataCG.h:
* platform/graphics/cg/ImageBufferUtilitiesCG.cpp:
(WebCore::jpegUTI):
(WebCore::utiFromImageBufferMIMEType):
(WebCore::encodeImage):
(WebCore::cfData):
(WebCore::dataURL):
(WebCore::dataVector):
(WebCore::data):
* platform/graphics/cg/ImageBufferUtilitiesCG.h:
* platform/graphics/gtk/ImageBufferGtk.cpp: Removed.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (254899 => 254900)


--- trunk/Source/WebCore/ChangeLog	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/ChangeLog	2020-01-22 07:00:16 UTC (rev 254900)
@@ -1,3 +1,45 @@
+2020-01-21  Said Abou-Hallawa  <[email protected]>
+
+        Move ImageBuffer utilities function to separate files
+        https://bugs.webkit.org/show_bug.cgi?id=206519
+
+        Reviewed by Tim Horton.
+
+        These utilities function are merely related to the ImageData.
+
+        * SourcesGTK.txt:
+        * html/HTMLCanvasElement.cpp:
+        * platform/SourcesCairo.txt:
+        * platform/graphics/ImageBuffer.h:
+        * platform/graphics/cairo/ImageBufferCairo.cpp:
+        (WebCore::ImageBuffer::toData const):
+        (WebCore::writeFunction): Deleted.
+        (WebCore::encodeImage): Deleted.
+        * platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp: Added.
+        (WebCore::writeFunction):
+        (WebCore::encodeImage):
+        (WebCore::data):
+        * platform/graphics/cairo/ImageBufferUtilitiesCairo.h: Added.
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::jpegUTI): Deleted.
+        (WebCore::utiFromImageBufferMIMEType): Deleted.
+        (WebCore::encodeImage): Deleted.
+        (WebCore::dataURL): Deleted.
+        (WebCore::dataVector): Deleted.
+        (WebCore::cfData): Deleted.
+        (WebCore::data): Deleted.
+        * platform/graphics/cg/ImageBufferDataCG.h:
+        * platform/graphics/cg/ImageBufferUtilitiesCG.cpp:
+        (WebCore::jpegUTI):
+        (WebCore::utiFromImageBufferMIMEType):
+        (WebCore::encodeImage):
+        (WebCore::cfData):
+        (WebCore::dataURL):
+        (WebCore::dataVector):
+        (WebCore::data):
+        * platform/graphics/cg/ImageBufferUtilitiesCG.h:
+        * platform/graphics/gtk/ImageBufferGtk.cpp: Removed.
+
 2020-01-21  Fujii Hironori  <[email protected]>
 
         A partially selected RTL text is placed at a wrong vertical position if it has a vertical initial advance

Modified: trunk/Source/WebCore/SourcesGTK.txt (254899 => 254900)


--- trunk/Source/WebCore/SourcesGTK.txt	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/SourcesGTK.txt	2020-01-22 07:00:16 UTC (rev 254900)
@@ -84,7 +84,6 @@
 platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp
 platform/graphics/gtk/GdkCairoUtilities.cpp
 platform/graphics/gtk/IconGtk.cpp
-platform/graphics/gtk/ImageBufferGtk.cpp
 platform/graphics/gtk/ImageGtk.cpp
 
 platform/graphics/gstreamer/ImageGStreamerCairo.cpp

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (254899 => 254900)


--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp	2020-01-22 07:00:16 UTC (rev 254900)
@@ -83,6 +83,10 @@
 #include <pal/cf/CoreMediaSoftLink.h>
 #endif
 
+#if USE(CG)
+#include "ImageBufferUtilitiesCG.h"
+#endif
+
 namespace WebCore {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLCanvasElement);

Modified: trunk/Source/WebCore/platform/SourcesCairo.txt (254899 => 254900)


--- trunk/Source/WebCore/platform/SourcesCairo.txt	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/SourcesCairo.txt	2020-01-22 07:00:16 UTC (rev 254900)
@@ -31,6 +31,7 @@
 platform/graphics/cairo/GraphicsContextCairo.cpp
 platform/graphics/cairo/GraphicsContextImplCairo.cpp
 platform/graphics/cairo/ImageBufferCairo.cpp
+platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp
 platform/graphics/cairo/IntRectCairo.cpp
 platform/graphics/cairo/NativeImageCairo.cpp
 platform/graphics/cairo/PathCairo.cpp

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (254899 => 254900)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-01-22 07:00:16 UTC (rev 254900)
@@ -190,9 +190,4 @@
 #endif
 };
 
-#if USE(CG)
-String dataURL(const ImageData&, const String& mimeType, Optional<double> quality);
-Vector<uint8_t> data(const ImageData&, const String& mimeType, Optional<double> quality);
-#endif
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp (254899 => 254900)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp	2020-01-22 07:00:16 UTC (rev 254900)
@@ -37,6 +37,7 @@
 #include "Color.h"
 #include "GraphicsContext.h"
 #include "GraphicsContextImplCairo.h"
+#include "ImageBufferUtilitiesCairo.h"
 #include "MIMETypeRegistry.h"
 #include "NotImplemented.h"
 #include "Pattern.h"
@@ -76,7 +77,6 @@
 #endif
 #endif
 
-
 namespace WebCore {
 
 ImageBufferData::ImageBufferData(const IntSize& size, RenderingMode renderingMode)
@@ -654,21 +654,6 @@
     }
 }
 
-#if !PLATFORM(GTK)
-static cairo_status_t writeFunction(void* output, const unsigned char* data, unsigned int length)
-{
-    if (!reinterpret_cast<Vector<uint8_t>*>(output)->tryAppend(data, length))
-        return CAIRO_STATUS_WRITE_ERROR;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static bool encodeImage(cairo_surface_t* image, const String& mimeType, Vector<uint8_t>* output)
-{
-    ASSERT_UNUSED(mimeType, mimeType == "image/png"); // Only PNG output is supported for now.
-
-    return cairo_surface_write_to_png_stream(image, writeFunction, output) == CAIRO_STATUS_SUCCESS;
-}
-
 String ImageBuffer::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const
 {
     Vector<uint8_t> encodedImage = toData(mimeType, quality);
@@ -681,21 +666,13 @@
     return "data:" + mimeType + ";base64," + base64Data;
 }
 
-Vector<uint8_t> ImageBuffer::toData(const String& mimeType, Optional<double>) const
+Vector<uint8_t> ImageBuffer::toData(const String& mimeType, Optional<double> quality) const
 {
     ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
-
     cairo_surface_t* image = cairo_get_target(context().platformContext()->cr());
-
-    Vector<uint8_t> encodedImage;
-    if (!image || !encodeImage(image, mimeType, &encodedImage))
-        return { };
-
-    return encodedImage;
+    return data(image, mimeType, quality);
 }
 
-#endif
-
 #if ENABLE(ACCELERATED_2D_CANVAS) && !USE(COORDINATED_GRAPHICS)
 void ImageBufferData::paintToTextureMapper(TextureMapper& textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
 {

Copied: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp (from rev 254899, trunk/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp) (0 => 254900)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp	2020-01-22 07:00:16 UTC (rev 254900)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <[email protected]>
+ * Copyright (C) 2007 Holger Hans Peter Freyther <[email protected]>
+ * Copyright (C) 2008, 2009 Dirk Schulze <[email protected]>
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ * Copyright (C) 2010 Igalia S.L.
+ * Copyright (C) 2020 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.
+ */
+
+#include "config.h"
+#include "ImageBufferUtilitiesCairo.h"
+
+#if USE(CAIRO)
+
+#include "CairoUtilities.h"
+#include "MIMETypeRegistry.h"
+#include <cairo.h>
+#include <wtf/text/Base64.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(GTK)
+#include "GRefPtrGtk.h"
+#include "GdkCairoUtilities.h"
+#include <gtk/gtk.h>
+#include <wtf/glib/GUniquePtr.h>
+#endif
+
+namespace WebCore {
+
+#if !PLATFORM(GTK)
+static cairo_status_t writeFunction(void* output, const unsigned char* data, unsigned length)
+{
+    if (!reinterpret_cast<Vector<uint8_t>*>(output)->tryAppend(data, length))
+        return CAIRO_STATUS_WRITE_ERROR;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static bool encodeImage(cairo_surface_t* image, const String& mimeType, Vector<uint8_t>* output)
+{
+    ASSERT_UNUSED(mimeType, mimeType == "image/png"); // Only PNG output is supported for now.
+
+    return cairo_surface_write_to_png_stream(image, writeFunction, output) == CAIRO_STATUS_SUCCESS;
+}
+
+Vector<uint8_t> data(cairo_surface_t* image, const String& mimeType, Optional<double>)
+{
+    Vector<uint8_t> encodedImage;
+    if (!image || !encodeImage(image, mimeType, &encodedImage))
+        return { };
+    return encodedImage;
+}
+#else
+static bool encodeImage(cairo_surface_t* surface, const String& mimeType, Optional<double> quality, GUniqueOutPtr<gchar>& buffer, gsize& bufferSize)
+{
+    // List of supported image encoding types comes from the GdkPixbuf documentation.
+    // http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-File-saving.html#gdk-pixbuf-save-to-bufferv
+
+    String type = mimeType.substring(sizeof "image");
+    if (type != "jpeg" && type != "png" && type != "tiff" && type != "ico" && type != "bmp")
+        return false;
+
+    GRefPtr<GdkPixbuf> pixbuf;
+    if (type == "jpeg") {
+        // JPEG doesn't support alpha channel. The <canvas> spec states that toDataURL() must encode a Porter-Duff
+        // composite source-over black for image types that do not support alpha.
+        RefPtr<cairo_surface_t> newSurface;
+        if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE) {
+            newSurface = adoptRef(cairo_image_surface_create_for_data(cairo_image_surface_get_data(surface),
+                CAIRO_FORMAT_RGB24,
+                cairo_image_surface_get_width(surface),
+                cairo_image_surface_get_height(surface),
+                cairo_image_surface_get_stride(surface)));
+        } else {
+            IntSize size = cairoSurfaceSize(surface);
+            newSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_RGB24, size.width(), size.height()));
+            RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
+            cairo_set_source_surface(cr.get(), surface, 0, 0);
+            cairo_paint(cr.get());
+        }
+        pixbuf = adoptGRef(cairoSurfaceToGdkPixbuf(newSurface.get()));
+    } else
+        pixbuf = adoptGRef(cairoSurfaceToGdkPixbuf(surface));
+    if (!pixbuf)
+        return false;
+
+    GUniqueOutPtr<GError> error;
+    if (type == "jpeg" && quality && *quality >= 0.0 && *quality <= 1.0) {
+        String qualityString = String::number(static_cast<int>(*quality * 100.0 + 0.5));
+        gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize, type.utf8().data(), &error.outPtr(), "quality", qualityString.utf8().data(), NULL);
+    } else
+        gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize, type.utf8().data(), &error.outPtr(), NULL);
+
+    return !error;
+}
+
+Vector<uint8_t> data(cairo_surface_t* image, const String& mimeType, Optional<double> quality)
+{
+    GUniqueOutPtr<gchar> buffer;
+    gsize bufferSize;
+    if (!encodeImage(image, mimeType, quality, buffer, bufferSize))
+        return { };
+
+    Vector<uint8_t> imageData;
+    imageData.append(buffer.get(), bufferSize);
+    return imageData;
+}
+#endif // !PLATFORM(GTK)
+
+} // namespace WebCore
+
+#endif // USE(CAIRO)

Added: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.h (0 => 254900)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.h	2020-01-22 07:00:16 UTC (rev 254900)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <[email protected]>
+ * Copyright (C) 2007 Holger Hans Peter Freyther <[email protected]>
+ * Copyright (C) 2008, 2009 Dirk Schulze <[email protected]>
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ * Copyright (C) 2020 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
+
+#if USE(CAIRO)
+
+#include <cairo.h>
+#include <wtf/Optional.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+Vector<uint8_t> data(cairo_surface_t*, const String& mimeType, Optional<double> quality);
+
+} // namespace WebCore
+
+#endif // USE(CAIRO)

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (254899 => 254900)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp	2020-01-22 07:00:16 UTC (rev 254900)
@@ -445,79 +445,6 @@
         context().fillRect(FloatRect(1, 1, 0, 0));
 }
 
-static inline CFStringRef jpegUTI()
-{
-#if PLATFORM(IOS_FAMILY) || PLATFORM(WIN)
-    static const CFStringRef kUTTypeJPEG = CFSTR("public.jpeg");
-#endif
-    return kUTTypeJPEG;
-}
-    
-static RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String& mimeType)
-{
-    // FIXME: Why doesn't iOS use the CoreServices version?
-#if PLATFORM(MAC)
-    return UTIFromMIMEType(mimeType).createCFString();
-#else
-    ASSERT(isMainThread()); // It is unclear if CFSTR is threadsafe.
-
-    // FIXME: Add Windows support for all the supported UTIs when a way to convert from MIMEType to UTI reliably is found.
-    // For now, only support PNG, JPEG, and GIF. See <rdar://problem/6095286>.
-    static const CFStringRef kUTTypePNG = CFSTR("public.png");
-    static const CFStringRef kUTTypeGIF = CFSTR("com.compuserve.gif");
-
-    if (equalLettersIgnoringASCIICase(mimeType, "image/png"))
-        return kUTTypePNG;
-    if (equalLettersIgnoringASCIICase(mimeType, "image/jpeg"))
-        return jpegUTI();
-    if (equalLettersIgnoringASCIICase(mimeType, "image/gif"))
-        return kUTTypeGIF;
-
-    ASSERT_NOT_REACHED();
-    return kUTTypePNG;
-#endif
-}
-
-static bool encodeImage(CGImageRef image, CFStringRef uti, Optional<double> quality, CFMutableDataRef data)
-{
-    if (!image || !uti || !data)
-        return false;
-
-    auto destination = adoptCF(CGImageDestinationCreateWithData(data, uti, 1, 0));
-    if (!destination)
-        return false;
-
-    RetainPtr<CFDictionaryRef> imageProperties;
-    if (CFEqual(uti, jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) {
-        // Apply the compression quality to the JPEG image destination.
-        auto compressionQuality = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &*quality));
-        const void* key = kCGImageDestinationLossyCompressionQuality;
-        const void* value = compressionQuality.get();
-        imageProperties = adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-    }
-
-    // Setting kCGImageDestinationBackgroundColor to black for JPEG images in imageProperties would save some math
-    // in the calling functions, but it doesn't seem to work.
-
-    CGImageDestinationAddImage(destination.get(), image, imageProperties.get());
-    return CGImageDestinationFinalize(destination.get());
-}
-
-static String dataURL(CFDataRef data, const String& mimeType)
-{
-    Vector<char> base64Data;
-    base64Encode(CFDataGetBytePtr(data), CFDataGetLength(data), base64Data);
-
-    return "data:" + mimeType + ";base64," + base64Data;
-}
-
-static Vector<uint8_t> dataVector(CFDataRef cfData)
-{
-    Vector<uint8_t> data;
-    data.append(CFDataGetBytePtr(cfData), CFDataGetLength(cfData));
-    return data;
-}
-
 String ImageBuffer::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution preserveResolution) const
 {
     if (auto data = "" quality, preserveResolution))
@@ -578,70 +505,6 @@
     return WTFMove(cfData);
 }
 
-static RetainPtr<CFDataRef> cfData(const ImageData& source, const String& mimeType, Optional<double> quality)
-{
-    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
-
-    auto uti = utiFromImageBufferMIMEType(mimeType);
-    ASSERT(uti);
-
-    CGImageAlphaInfo dataAlphaInfo = kCGImageAlphaLast;
-    unsigned char* data = ""
-    Vector<uint8_t> premultipliedData;
-
-    if (CFEqual(uti.get(), jpegUTI())) {
-        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
-        size_t size = 4 * source.width() * source.height();
-        if (!premultipliedData.tryReserveCapacity(size))
-            return nullptr;
-
-        premultipliedData.grow(size);
-        unsigned char *buffer = premultipliedData.data();
-        for (size_t i = 0; i < size; i += 4) {
-            unsigned alpha = data[i + 3];
-            if (alpha != 255) {
-                buffer[i + 0] = data[i + 0] * alpha / 255;
-                buffer[i + 1] = data[i + 1] * alpha / 255;
-                buffer[i + 2] = data[i + 2] * alpha / 255;
-            } else {
-                buffer[i + 0] = data[i + 0];
-                buffer[i + 1] = data[i + 1];
-                buffer[i + 2] = data[i + 2];
-            }
-        }
-
-        dataAlphaInfo = kCGImageAlphaNoneSkipLast; // Ignore the alpha channel.
-        data = ""
-    }
-
-    verifyImageBufferIsBigEnough(data, 4 * source.width() * source.height());
-    auto dataProvider = adoptCF(CGDataProviderCreateWithData(0, data, 4 * source.width() * source.height(), 0));
-    if (!dataProvider)
-        return nullptr;
-
-    auto image = adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(), sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | dataAlphaInfo, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
-
-    auto cfData = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
-    if (!encodeImage(image.get(), uti.get(), quality, cfData.get()))
-        return nullptr;
-
-    return WTFMove(cfData);
-}
-
-String dataURL(const ImageData& source, const String& mimeType, Optional<double> quality)
-{
-    if (auto data = "" mimeType, quality))
-        return dataURL(data.get(), mimeType);
-    return "data:,"_s;
-}
-
-Vector<uint8_t> data(const ImageData& source, const String& mimeType, Optional<double> quality)
-{
-    if (auto data = "" mimeType, quality))
-        return dataVector(data.get());
-    return { };
-}
-
 Vector<uint8_t> ImageBuffer::toBGRAData() const
 {
     if (context().isAcceleratedContext())

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.cpp (254899 => 254900)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.cpp	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.cpp	2020-01-22 07:00:16 UTC (rev 254900)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,19 @@
 #include "config.h"
 #include "ImageBufferUtilitiesCG.h"
 
+#if USE(CG)
+
+#include "GraphicsContextCG.h"
+#include "ImageData.h"
+#include "MIMETypeRegistry.h"
+#include <ImageIO/ImageIO.h>
 #include <wtf/CheckedArithmetic.h>
+#include <wtf/text/Base64.h>
 
+#if PLATFORM(COCOA)
+#include "UTIUtilities.h"
+#endif
+
 namespace WebCore {
 
 uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t bufferSize)
@@ -41,4 +52,143 @@
     return *(uint8_t*)lastByte;
 }
 
+CFStringRef jpegUTI()
+{
+#if PLATFORM(IOS_FAMILY) || PLATFORM(WIN)
+    static const CFStringRef kUTTypeJPEG = CFSTR("public.jpeg");
+#endif
+    return kUTTypeJPEG;
 }
+
+RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String& mimeType)
+{
+    // FIXME: Why doesn't iOS use the CoreServices version?
+#if PLATFORM(MAC)
+    return UTIFromMIMEType(mimeType).createCFString();
+#else
+    ASSERT(isMainThread()); // It is unclear if CFSTR is threadsafe.
+
+    // FIXME: Add Windows support for all the supported UTIs when a way to convert from MIMEType to UTI reliably is found.
+    // For now, only support PNG, JPEG, and GIF. See <rdar://problem/6095286>.
+    static const CFStringRef kUTTypePNG = CFSTR("public.png");
+    static const CFStringRef kUTTypeGIF = CFSTR("com.compuserve.gif");
+
+    if (equalLettersIgnoringASCIICase(mimeType, "image/png"))
+        return kUTTypePNG;
+    if (equalLettersIgnoringASCIICase(mimeType, "image/jpeg"))
+        return jpegUTI();
+    if (equalLettersIgnoringASCIICase(mimeType, "image/gif"))
+        return kUTTypeGIF;
+
+    ASSERT_NOT_REACHED();
+    return kUTTypePNG;
+#endif
+}
+
+bool encodeImage(CGImageRef image, CFStringRef uti, Optional<double> quality, CFMutableDataRef data)
+{
+    if (!image || !uti || !data)
+        return false;
+
+    auto destination = adoptCF(CGImageDestinationCreateWithData(data, uti, 1, 0));
+    if (!destination)
+        return false;
+
+    RetainPtr<CFDictionaryRef> imageProperties;
+    if (CFEqual(uti, jpegUTI()) && quality && *quality >= 0.0 && *quality <= 1.0) {
+        // Apply the compression quality to the JPEG image destination.
+        auto compressionQuality = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &*quality));
+        const void* key = kCGImageDestinationLossyCompressionQuality;
+        const void* value = compressionQuality.get();
+        imageProperties = adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+    }
+
+    // Setting kCGImageDestinationBackgroundColor to black for JPEG images in imageProperties would save some math
+    // in the calling functions, but it doesn't seem to work.
+
+    CGImageDestinationAddImage(destination.get(), image, imageProperties.get());
+    return CGImageDestinationFinalize(destination.get());
+}
+
+static RetainPtr<CFDataRef> cfData(const ImageData& source, const String& mimeType, Optional<double> quality)
+{
+    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
+
+    auto uti = utiFromImageBufferMIMEType(mimeType);
+    ASSERT(uti);
+
+    CGImageAlphaInfo dataAlphaInfo = kCGImageAlphaLast;
+    unsigned char* data = ""
+    Vector<uint8_t> premultipliedData;
+
+    if (CFEqual(uti.get(), jpegUTI())) {
+        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
+        size_t size = 4 * source.width() * source.height();
+        if (!premultipliedData.tryReserveCapacity(size))
+            return nullptr;
+
+        premultipliedData.grow(size);
+        unsigned char* buffer = premultipliedData.data();
+        for (size_t i = 0; i < size; i += 4) {
+            unsigned alpha = data[i + 3];
+            if (alpha != 255) {
+                buffer[i + 0] = data[i + 0] * alpha / 255;
+                buffer[i + 1] = data[i + 1] * alpha / 255;
+                buffer[i + 2] = data[i + 2] * alpha / 255;
+            } else {
+                buffer[i + 0] = data[i + 0];
+                buffer[i + 1] = data[i + 1];
+                buffer[i + 2] = data[i + 2];
+            }
+        }
+
+        dataAlphaInfo = kCGImageAlphaNoneSkipLast; // Ignore the alpha channel.
+        data = ""
+    }
+
+    verifyImageBufferIsBigEnough(data, 4 * source.width() * source.height());
+    auto dataProvider = adoptCF(CGDataProviderCreateWithData(0, data, 4 * source.width() * source.height(), 0));
+    if (!dataProvider)
+        return nullptr;
+
+    auto image = adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(), sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | dataAlphaInfo, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
+
+    auto cfData = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
+    if (!encodeImage(image.get(), uti.get(), quality, cfData.get()))
+        return nullptr;
+
+    return WTFMove(cfData);
+}
+
+String dataURL(CFDataRef data, const String& mimeType)
+{
+    Vector<char> base64Data;
+    base64Encode(CFDataGetBytePtr(data), CFDataGetLength(data), base64Data);
+
+    return "data:" + mimeType + ";base64," + base64Data;
+}
+
+String dataURL(const ImageData& source, const String& mimeType, Optional<double> quality)
+{
+    if (auto data = "" mimeType, quality))
+        return dataURL(data.get(), mimeType);
+    return "data:,"_s;
+}
+
+Vector<uint8_t> dataVector(CFDataRef cfData)
+{
+    Vector<uint8_t> data;
+    data.append(CFDataGetBytePtr(cfData), CFDataGetLength(cfData));
+    return data;
+}
+
+Vector<uint8_t> data(const ImageData& source, const String& mimeType, Optional<double> quality)
+{
+    if (auto data = "" mimeType, quality))
+        return dataVector(data.get());
+    return { };
+}
+
+} // namespace WebCore
+
+#endif // USE(CG)

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h (254899 => 254900)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h	2020-01-22 07:00:16 UTC (rev 254900)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,8 +25,31 @@
 
 #pragma once
 
+#if USE(CG)
+
+#include <wtf/Forward.h>
+#include <wtf/Optional.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
 namespace WebCore {
 
+class ImageData;
+
 WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t bufferSize);
 
-}
+CFStringRef jpegUTI();
+RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String&);
+
+bool encodeImage(CGImageRef, CFStringRef uti, Optional<double> quality, CFMutableDataRef);
+
+String dataURL(CFDataRef, const String& mimeType);
+String dataURL(const ImageData&, const String& mimeType, Optional<double> quality);
+
+Vector<uint8_t> dataVector(CFDataRef);
+Vector<uint8_t> data(const ImageData&, const String& mimeType, Optional<double> quality);
+
+} // namespace WebCore
+
+#endif // USE(CG)

Deleted: trunk/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp (254899 => 254900)


--- trunk/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp	2020-01-22 03:11:39 UTC (rev 254899)
+++ trunk/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp	2020-01-22 07:00:16 UTC (rev 254900)
@@ -1,104 +0,0 @@
-/*
- *  Copyright (C) 2010 Igalia S.L.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "config.h"
-#include "ImageBuffer.h"
-
-#include "CairoUtilities.h"
-#include "GRefPtrGtk.h"
-#include "GdkCairoUtilities.h"
-#include "MIMETypeRegistry.h"
-#include <cairo.h>
-#include <gtk/gtk.h>
-#include <wtf/glib/GUniquePtr.h>
-#include <wtf/text/Base64.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-static bool encodeImage(cairo_surface_t* surface, const String& mimeType, Optional<double> quality, GUniqueOutPtr<gchar>& buffer, gsize& bufferSize)
-{
-    // List of supported image encoding types comes from the GdkPixbuf documentation.
-    // http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-File-saving.html#gdk-pixbuf-save-to-bufferv
-
-    String type = mimeType.substring(sizeof "image");
-    if (type != "jpeg" && type != "png" && type != "tiff" && type != "ico" && type != "bmp")
-        return false;
-
-    GRefPtr<GdkPixbuf> pixbuf;
-    if (type == "jpeg") {
-        // JPEG doesn't support alpha channel. The <canvas> spec states that toDataURL() must encode a Porter-Duff
-        // composite source-over black for image types that do not support alpha.
-        RefPtr<cairo_surface_t> newSurface;
-        if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE) {
-            newSurface = adoptRef(cairo_image_surface_create_for_data(cairo_image_surface_get_data(surface),
-                CAIRO_FORMAT_RGB24,
-                cairo_image_surface_get_width(surface),
-                cairo_image_surface_get_height(surface),
-                cairo_image_surface_get_stride(surface)));
-        } else {
-            IntSize size = cairoSurfaceSize(surface);
-            newSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_RGB24, size.width(), size.height()));
-            RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
-            cairo_set_source_surface(cr.get(), surface, 0, 0);
-            cairo_paint(cr.get());
-        }
-        pixbuf = adoptGRef(cairoSurfaceToGdkPixbuf(newSurface.get()));
-    } else
-        pixbuf = adoptGRef(cairoSurfaceToGdkPixbuf(surface));
-    if (!pixbuf)
-        return false;
-
-    GUniqueOutPtr<GError> error;
-    if (type == "jpeg" && quality && *quality >= 0.0 && *quality <= 1.0) {
-        String qualityString = String::number(static_cast<int>(*quality * 100.0 + 0.5));
-        gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize, type.utf8().data(), &error.outPtr(), "quality", qualityString.utf8().data(), NULL);
-    } else
-        gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize, type.utf8().data(), &error.outPtr(), NULL);
-
-    return !error;
-}
-
-String ImageBuffer::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const
-{
-    Vector<uint8_t> imageData = toData(mimeType, quality);
-    if (imageData.isEmpty())
-        return "data:,";
-
-    Vector<char> base64Data;
-    base64Encode(imageData.data(), imageData.size(), base64Data);
-
-    return "data:" + mimeType + ";base64," + base64Data;
-}
-
-Vector<uint8_t> ImageBuffer::toData(const String& mimeType, Optional<double> quality) const
-{
-    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
-
-    GUniqueOutPtr<gchar> buffer;
-    gsize bufferSize;
-    if (!encodeImage(m_data.m_surface.get(), mimeType, quality, buffer, bufferSize))
-        return { };
-
-    Vector<uint8_t> imageData;
-    imageData.append(buffer.get(), bufferSize);
-    return imageData;
-}
-
-}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to