Changeset 213412 in webkit


Ignore:
Timestamp:
Mar 3, 2017 6:16:58 PM (7 years ago)
Author:
aestes@apple.com
Message:

Add support for canvas.toBlob
https://bugs.webkit.org/show_bug.cgi?id=148878
<rdar://problem/22590406>

Reviewed by Tim Horton.

LayoutTests/imported/w3c:

  • web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg-expected.txt:
  • web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.png-expected.txt:

Source/WebCore:

These tests now pass:
imported/w3c/web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg.html
imported/w3c/web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.png.html

  • CMakeLists.txt:
  • DerivedSources.make:
  • WebCore.xcodeproj/project.pbxproj:
  • fileapi/BlobCallback.cpp: Added.

(WebCore::BlobCallback::scheduleCallback):

  • fileapi/BlobCallback.h: Added.

(WebCore::BlobCallback::~BlobCallback):

  • fileapi/BlobCallback.idl: Added.
  • html/HTMLCanvasElement.cpp:

(WebCore::HTMLCanvasElement::toBlob):

  • html/HTMLCanvasElement.h:
  • html/HTMLCanvasElement.idl:
  • platform/graphics/ImageBuffer.h:
  • platform/graphics/cairo/ImageBufferCairo.cpp:

(WebCore::writeFunction):
(WebCore::encodeImage):
(WebCore::ImageBuffer::toDataURL):
(WebCore::ImageBuffer::toData):

  • platform/graphics/cg/ImageBufferCG.cpp:

(WebCore::data):
(WebCore::ImageBuffer::toDataURL):
(WebCore::ImageBuffer::toData):
(WebCore::ImageBuffer::toCGImage):
(WebCore::cgImage):
(WebCore::dataURL):

  • platform/graphics/gtk/ImageBufferGtk.cpp:

(WebCore::ImageBuffer::toDataURL):
(WebCore::ImageBuffer::toData):

  • platform/graphics/win/ImageBufferDirect2D.cpp:

(WebCore::ImageBuffer::toData):

Location:
trunk
Files:
3 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r213378 r213412  
     12017-03-03  Andy Estes  <aestes@apple.com>
     2
     3        Add support for canvas.toBlob
     4        https://bugs.webkit.org/show_bug.cgi?id=148878
     5        <rdar://problem/22590406>
     6
     7        Reviewed by Tim Horton.
     8
     9        * web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg-expected.txt:
     10        * web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.png-expected.txt:
     11
    1122017-03-03  Ryan Haddad  <ryanhaddad@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg-expected.txt

    r213378 r213412  
    11
    2 FAIL toBlob with image/jpeg returns a JPEG Blob canvas.toBlob is not a function. (In 'canvas.toBlob(this.step_func_done(function(data) {
    3             assert_equals(data.type, "image/jpeg");
    4         }), 'image/jpeg')', 'canvas.toBlob' is undefined)
     2PASS toBlob with image/jpeg returns a JPEG Blob
    53
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.png-expected.txt

    r213378 r213412  
    11
    2 FAIL toBlob with image/png returns a PNG Blob canvas.toBlob is not a function. (In 'canvas.toBlob(this.step_func_done(function(data) {
    3             assert_equals(data.type, "image/png");
    4         }), 'image/png')', 'canvas.toBlob' is undefined)
     2PASS toBlob with image/png returns a PNG Blob
    53
  • trunk/Source/WebCore/CMakeLists.txt

    r213379 r213412  
    476476
    477477    fileapi/Blob.idl
     478    fileapi/BlobCallback.idl
    478479    fileapi/BlobLineEndings.idl
    479480    fileapi/BlobPropertyBag.idl
     
    16061607    fileapi/Blob.cpp
    16071608    fileapi/BlobBuilder.cpp
     1609    fileapi/BlobCallback.cpp
    16081610    fileapi/BlobURL.cpp
    16091611    fileapi/File.cpp
  • trunk/Source/WebCore/ChangeLog

    r213410 r213412  
     12017-03-03  Andy Estes  <aestes@apple.com>
     2
     3        Add support for canvas.toBlob
     4        https://bugs.webkit.org/show_bug.cgi?id=148878
     5        <rdar://problem/22590406>
     6
     7        Reviewed by Tim Horton.
     8
     9        These tests now pass:
     10        imported/w3c/web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg.html
     11        imported/w3c/web-platform-tests/html/semantics/embedded-content/the-canvas-element/toBlob.png.html
     12
     13        * CMakeLists.txt:
     14        * DerivedSources.make:
     15        * WebCore.xcodeproj/project.pbxproj:
     16        * fileapi/BlobCallback.cpp: Added.
     17        (WebCore::BlobCallback::scheduleCallback):
     18        * fileapi/BlobCallback.h: Added.
     19        (WebCore::BlobCallback::~BlobCallback):
     20        * fileapi/BlobCallback.idl: Added.
     21        * html/HTMLCanvasElement.cpp:
     22        (WebCore::HTMLCanvasElement::toBlob):
     23        * html/HTMLCanvasElement.h:
     24        * html/HTMLCanvasElement.idl:
     25        * platform/graphics/ImageBuffer.h:
     26        * platform/graphics/cairo/ImageBufferCairo.cpp:
     27        (WebCore::writeFunction):
     28        (WebCore::encodeImage):
     29        (WebCore::ImageBuffer::toDataURL):
     30        (WebCore::ImageBuffer::toData):
     31        * platform/graphics/cg/ImageBufferCG.cpp:
     32        (WebCore::data):
     33        (WebCore::ImageBuffer::toDataURL):
     34        (WebCore::ImageBuffer::toData):
     35        (WebCore::ImageBuffer::toCGImage):
     36        (WebCore::cgImage):
     37        (WebCore::dataURL):
     38        * platform/graphics/gtk/ImageBufferGtk.cpp:
     39        (WebCore::ImageBuffer::toDataURL):
     40        (WebCore::ImageBuffer::toData):
     41        * platform/graphics/win/ImageBufferDirect2D.cpp:
     42        (WebCore::ImageBuffer::toData):
     43
    1442017-03-03  Dean Jackson  <dino@apple.com>
    245
  • trunk/Source/WebCore/DerivedSources.make

    r213378 r213412  
    405405    $(WebCore)/dom/XMLDocument.idl \
    406406    $(WebCore)/fileapi/Blob.idl \
     407    $(WebCore)/fileapi/BlobCallback.idl \
    407408    $(WebCore)/fileapi/BlobLineEndings.idl \
    408409    $(WebCore)/fileapi/BlobPropertyBag.idl \
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r213392 r213412  
    40344034                A149786F1ABAF33800CEF7E4 /* ContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A149786D1ABAF33800CEF7E4 /* ContentFilter.h */; };
    40354035                A14978711ABAF3A500CEF7E4 /* PlatformContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A14978701ABAF3A500CEF7E4 /* PlatformContentFilter.h */; };
     4036                A15D75151E68F7C400A35FBC /* BlobCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A15D75121E68F7B100A35FBC /* BlobCallback.cpp */; };
     4037                A15D75161E68F7C800A35FBC /* BlobCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = A15D75131E68F7B100A35FBC /* BlobCallback.h */; };
     4038                A15D751A1E68F89E00A35FBC /* JSBlobCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A15D75171E68F83600A35FBC /* JSBlobCallback.cpp */; };
     4039                A15D751B1E68F8A300A35FBC /* JSBlobCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = A15D75181E68F83600A35FBC /* JSBlobCallback.h */; };
    40364040                A15E31F31E0CB0B2004B371C /* QuickLook.mm in Sources */ = {isa = PBXBuildFile; fileRef = A15E31F21E0CB0AA004B371C /* QuickLook.mm */; };
    40374041                A15E31F41E0CB0B5004B371C /* QuickLook.h in Headers */ = {isa = PBXBuildFile; fileRef = A15E31F11E0CB0AA004B371C /* QuickLook.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1189511899                A149786D1ABAF33800CEF7E4 /* ContentFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentFilter.h; sourceTree = "<group>"; };
    1189611900                A14978701ABAF3A500CEF7E4 /* PlatformContentFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformContentFilter.h; sourceTree = "<group>"; };
     11901                A15D75121E68F7B100A35FBC /* BlobCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlobCallback.cpp; sourceTree = "<group>"; };
     11902                A15D75131E68F7B100A35FBC /* BlobCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobCallback.h; sourceTree = "<group>"; };
     11903                A15D75141E68F7B100A35FBC /* BlobCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BlobCallback.idl; sourceTree = "<group>"; };
     11904                A15D75171E68F83600A35FBC /* JSBlobCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBlobCallback.cpp; sourceTree = "<group>"; };
     11905                A15D75181E68F83600A35FBC /* JSBlobCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBlobCallback.h; sourceTree = "<group>"; };
    1189711906                A15E31F11E0CB0AA004B371C /* QuickLook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuickLook.h; sourceTree = "<group>"; };
    1189811907                A15E31F21E0CB0AA004B371C /* QuickLook.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickLook.mm; sourceTree = "<group>"; };
     
    1894818957                                2E2D99CB10E2BBDA00496337 /* JSBlob.cpp */,
    1894918958                                2E2D99CC10E2BBDA00496337 /* JSBlob.h */,
     18959                                A15D75171E68F83600A35FBC /* JSBlobCallback.cpp */,
     18960                                A15D75181E68F83600A35FBC /* JSBlobCallback.h */,
    1895018961                                7C77C3D91DEF86D700A50BFA /* JSBlobLineEndings.cpp */,
    1895118962                                7C77C3DA1DEF86D700A50BFA /* JSBlobLineEndings.h */,
     
    1988219893                                976D6C5C122B8A3D001FD1F7 /* BlobBuilder.cpp */,
    1988319894                                976D6C5D122B8A3D001FD1F7 /* BlobBuilder.h */,
     19895                                A15D75121E68F7B100A35FBC /* BlobCallback.cpp */,
     19896                                A15D75131E68F7B100A35FBC /* BlobCallback.h */,
     19897                                A15D75141E68F7B100A35FBC /* BlobCallback.idl */,
    1988419898                                7C77C3D61DEF850A00A50BFA /* BlobLineEndings.h */,
    1988519899                                7C77C3D81DEF854000A50BFA /* BlobLineEndings.idl */,
     
    2691326927                                A4226E5C1163D695008B8397 /* JSHTMLProgressElement.h in Headers */,
    2691426928                                1AE2AEC80A1D297B00B42B25 /* JSHTMLQuoteElement.h in Headers */,
     26929                                A15D751B1E68F8A300A35FBC /* JSBlobCallback.h in Headers */,
    2691526930                                1AE2ABAD0A1CE90500B42B25 /* JSHTMLScriptElement.h in Headers */,
    2691626931                                E1E6EEA80B628DB3005F2F70 /* JSHTMLSelectElement.h in Headers */,
     
    2830728322                                97BC6A521505F081001B74AC /* SQLTransactionCallback.h in Headers */,
    2830828323                                97BC6A571505F081001B74AC /* SQLTransactionCoordinator.h in Headers */,
     28324                                A15D75161E68F7C800A35FBC /* BlobCallback.h in Headers */,
    2830928325                                97BC6A581505F081001B74AC /* SQLTransactionErrorCallback.h in Headers */,
    2831028326                                FE36FD1816C7826500F887C1 /* SQLTransactionState.h in Headers */,
     
    3110431120                                B2FA3E0A0AB75A6F000E5AC4 /* JSSVGTransform.cpp in Sources */,
    3110531121                                B2FA3E0C0AB75A6F000E5AC4 /* JSSVGTransformList.cpp in Sources */,
     31122                                A15D75151E68F7C400A35FBC /* BlobCallback.cpp in Sources */,
    3110631123                                B2FA3E0E0AB75A6F000E5AC4 /* JSSVGTRefElement.cpp in Sources */,
    3110731124                                B2FA3E100AB75A6F000E5AC4 /* JSSVGTSpanElement.cpp in Sources */,
     
    3245432471                                93F19B0708245E59001E9ABC /* WebCoreView.m in Sources */,
    3245532472                                A5E616731894581F009ADF50 /* WebDebuggerAgent.cpp in Sources */,
     32473                                A15D751A1E68F89E00A35FBC /* JSBlobCallback.cpp in Sources */,
    3245632474                                FE0D84EB1048436E001A179E /* WebEvent.mm in Sources */,
    3245732475                                225A16B60D5C11E900090295 /* WebEventRegion.mm in Sources */,
  • trunk/Source/WebCore/html/HTMLCanvasElement.cpp

    r213378 r213412  
    2929#include "HTMLCanvasElement.h"
    3030
     31#include "Blob.h"
     32#include "BlobCallback.h"
    3133#include "CanvasGradient.h"
    3234#include "CanvasPattern.h"
     
    486488}
    487489
     490ExceptionOr<void> HTMLCanvasElement::toBlob(ScriptExecutionContext& context, Ref<BlobCallback>&& callback, const String& mimeType, JSC::JSValue qualityValue)
     491{
     492    if (!m_originClean)
     493        return Exception { SECURITY_ERR };
     494
     495    if (m_size.isEmpty() || !buffer()) {
     496        callback->scheduleCallback(context, nullptr);
     497        return { };
     498    }
     499
     500    String encodingMIMEType = toEncodingMimeType(mimeType);
     501    std::optional<double> quality;
     502    if (qualityValue.isNumber())
     503        quality = qualityValue.toNumber(context.execState());
     504
     505#if USE(CG)
     506    if (auto imageData = getImageData()) {
     507        Vector<uint8_t> blobData = data(*imageData, encodingMIMEType, quality);
     508        callback->scheduleCallback(context, Blob::create(WTFMove(blobData), encodingMIMEType));
     509        return { };
     510    }
     511#endif
     512
     513    makeRenderingResultsAvailable();
     514
     515    Vector<uint8_t> blobData = buffer()->toData(encodingMIMEType, quality);
     516    callback->scheduleCallback(context, Blob::create(WTFMove(blobData), encodingMIMEType));
     517    return { };
     518}
     519
    488520RefPtr<ImageData> HTMLCanvasElement::getImageData()
    489521{
  • trunk/Source/WebCore/html/HTMLCanvasElement.h

    r213378 r213412  
    4040namespace WebCore {
    4141
     42class BlobCallback;
    4243class CanvasRenderingContext;
    4344class GraphicsContext;
     
    102103    WEBCORE_EXPORT ExceptionOr<String> toDataURL(const String& mimeType, std::optional<double> quality);
    103104    ExceptionOr<String> toDataURL(const String& mimeType) { return toDataURL(mimeType, std::nullopt); }
     105    ExceptionOr<void> toBlob(ScriptExecutionContext&, Ref<BlobCallback>&&, const String& mimeType, JSC::JSValue qualityValue);
    104106
    105107    // Used for rendering
  • trunk/Source/WebCore/html/HTMLCanvasElement.idl

    r213378 r213412  
    3838
    3939    [Custom, MayThrowException] DOMString toDataURL(optional DOMString? type);
     40    [CallWith=ScriptExecutionContext, MayThrowException] void toBlob(BlobCallback callback, optional DOMString type, optional any quality);
    4041};
  • trunk/Source/WebCore/platform/graphics/ImageBuffer.h

    r213378 r213412  
    113113   
    114114    String toDataURL(const String& mimeType, std::optional<double> quality = std::nullopt, CoordinateSystem = LogicalCoordinateSystem) const;
     115    Vector<uint8_t> toData(const String& mimeType, std::optional<double> quality = std::nullopt) const;
    115116#if !USE(CG)
    116117    AffineTransform baseTransform() const { return AffineTransform(); }
     
    175176#if USE(CG)
    176177    ImageBuffer(const FloatSize&, float resolutionScale, CGColorSpaceRef, RenderingMode, bool& success);
     178    RetainPtr<CGImageRef> toCGImage(const String& mimeType) const;
    177179#elif USE(DIRECT2D)
    178180    ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, const GraphicsContext*, bool& success);
     
    182184#if USE(CG)
    183185String dataURL(const ImageData&, const String& mimeType, std::optional<double> quality);
     186Vector<uint8_t> data(const ImageData&, const String& mimeType, std::optional<double> quality);
    184187#endif
    185188
  • trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp

    r213378 r213412  
    540540static cairo_status_t writeFunction(void* output, const unsigned char* data, unsigned int length)
    541541{
    542     if (!reinterpret_cast<Vector<unsigned char>*>(output)->tryAppend(data, length))
     542    if (!reinterpret_cast<Vector<uint8_t>*>(output)->tryAppend(data, length))
    543543        return CAIRO_STATUS_WRITE_ERROR;
    544544    return CAIRO_STATUS_SUCCESS;
    545545}
    546546
    547 static bool encodeImage(cairo_surface_t* image, const String& mimeType, Vector<char>* output)
     547static bool encodeImage(cairo_surface_t* image, const String& mimeType, Vector<uint8_t>* output)
    548548{
    549549    ASSERT_UNUSED(mimeType, mimeType == "image/png"); // Only PNG output is supported for now.
     
    554554String ImageBuffer::toDataURL(const String& mimeType, std::optional<double>, CoordinateSystem) const
    555555{
     556    Vector<uint8_t> encodedImage = toData(mimeType, quality);
     557    if (encodedImage.isEmpty())
     558        return "data:,";
     559
     560    Vector<char> base64Data;
     561    base64Encode(encodedImage.data(), encodedImage.size(), base64Data);
     562
     563    return "data:" + mimeType + ";base64," + base64Data;
     564}
     565
     566Vector<uint8_t> ImageBuffer::toData(const String& mimeType, std::optional<double> quality) const
     567{
    556568    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
    557569
    558570    cairo_surface_t* image = cairo_get_target(context().platformContext()->cr());
    559571
    560     Vector<char> encodedImage;
     572    Vector<uint8_t> encodedImage;
    561573    if (!image || !encodeImage(image, mimeType, &encodedImage))
    562         return "data:,";
    563 
    564     Vector<char> base64Data;
    565     base64Encode(encodedImage, base64Data);
    566 
    567     return "data:" + mimeType + ";base64," + base64Data;
    568 }
     574        return { };
     575
     576    return encodedImage;
     577}
     578
    569579#endif
    570580
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp

    r213378 r213412  
    499499}
    500500
     501static Vector<uint8_t> data(CGImageRef image, const String& mimeType, std::optional<double> quality)
     502{
     503    auto uti = utiFromMIMEType(mimeType);
     504    ASSERT(uti);
     505
     506    auto cfData = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
     507    if (!encodeImage(image, uti.get(), quality, cfData.get()))
     508        return { };
     509
     510    Vector<uint8_t> data;
     511    data.append(CFDataGetBytePtr(cfData.get()), CFDataGetLength(cfData.get()));
     512    return data;
     513}
     514
    501515String ImageBuffer::toDataURL(const String& mimeType, std::optional<double> quality, CoordinateSystem) const
     516{
     517    if (auto image = toCGImage(mimeType))
     518        return dataURL(image.get(), mimeType, quality);
     519    return ASCIILiteral("data:,");
     520}
     521
     522Vector<uint8_t> ImageBuffer::toData(const String& mimeType, std::optional<double> quality) const
     523{
     524    if (auto image = toCGImage(mimeType))
     525        return data(image.get(), mimeType, quality);
     526    return { };
     527}
     528
     529RetainPtr<CGImageRef> ImageBuffer::toCGImage(const String& mimeType) const
    502530{
    503531    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
     
    509537    ASSERT(uti);
    510538
    511     RefPtr<Uint8ClampedArray> premultipliedData;
    512539    RetainPtr<CGImageRef> image;
    513540
    514541    if (CFEqual(uti.get(), jpegUTI())) {
    515542        // JPEGs don't have an alpha channel, so we have to manually composite on top of black.
    516         premultipliedData = getPremultipliedImageData(IntRect(IntPoint(0, 0), logicalSize()));
     543        // premultipliedData is leaked here, then adopted in the releaseData lambda passed to CGDataProviderCreateWithData().
     544        Uint8ClampedArray* premultipliedData = getPremultipliedImageData(IntRect(IntPoint(0, 0), logicalSize())).leakRef();
    517545        if (!premultipliedData)
    518             return ASCIILiteral("data:,");
    519 
    520         auto dataProvider = adoptCF(CGDataProviderCreateWithData(0, premultipliedData->data(), 4 * logicalSize().width() * logicalSize().height(), 0));
     546            return nullptr;
     547
     548        size_t dataSize = 4 * logicalSize().width() * logicalSize().height();
     549        auto dataProvider = adoptCF(CGDataProviderCreateWithData(premultipliedData, premultipliedData->data(), dataSize, [](void* info, const void*, size_t) {
     550            ASSERT(info);
     551            adoptRef(reinterpret_cast<Uint8ClampedArray*>(info));
     552        }));
    521553        if (!dataProvider)
    522             return ASCIILiteral("data:,");
    523 
    524         image = adoptCF(CGImageCreate(logicalSize().width(), logicalSize().height(), 8, 32, 4 * logicalSize().width(),
    525             sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
     554            return nullptr;
     555
     556        image = adoptCF(CGImageCreate(logicalSize().width(), logicalSize().height(), 8, 32, 4 * logicalSize().width(), sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
    526557    } else if (m_resolutionScale == 1) {
    527558        image = copyNativeImage(CopyBackingStore);
     
    537568    }
    538569
    539     return dataURL(image.get(), mimeType, quality);
    540 }
    541 
    542 String dataURL(const ImageData& source, const String& mimeType, std::optional<double> quality)
     570    return image;
     571}
     572
     573static RetainPtr<CGImageRef> cgImage(const ImageData& source, const String& mimeType)
    543574{
    544575    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
     
    555586        size_t size = 4 * source.width() * source.height();
    556587        if (!premultipliedData.tryReserveCapacity(size))
    557             return ASCIILiteral("data:,");
     588            return nullptr;
    558589
    559590        premultipliedData.resize(size);
     
    578609    auto dataProvider = adoptCF(CGDataProviderCreateWithData(0, data, 4 * source.width() * source.height(), 0));
    579610    if (!dataProvider)
    580         return ASCIILiteral("data:,");
    581 
    582     auto image = adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(),
    583         sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | dataAlphaInfo, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
    584     return dataURL(image.get(), mimeType, quality);
     611        return nullptr;
     612
     613    auto image = adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(), sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | dataAlphaInfo, dataProvider.get(), 0, false, kCGRenderingIntentDefault));
     614    return image;
     615}
     616
     617String dataURL(const ImageData& source, const String& mimeType, std::optional<double> quality)
     618{
     619    if (auto image = cgImage(source, mimeType))
     620        return dataURL(image.get(), mimeType, quality);
     621    return ASCIILiteral("data:,");
     622}
     623
     624Vector<uint8_t> data(const ImageData& source, const String& mimeType, std::optional<double> quality)
     625{
     626    if (auto image = cgImage(source, mimeType))
     627        return data(image.get(), mimeType, quality);
     628    return { };
    585629}
    586630
  • trunk/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp

    r213378 r213412  
    7878String ImageBuffer::toDataURL(const String& mimeType, std::optional<double> quality, CoordinateSystem) const
    7979{
     80    Vector<uint8_t> imageData = toData(mimeType, quality);
     81    if (imageData.isEmpty())
     82        return "data:,";
     83
     84    Vector<char> base64Data;
     85    base64Encode(imageData.data(), imageData.size(), base64Data);
     86
     87    return "data:" + mimeType + ";base64," + base64Data;
     88}
     89
     90Vector<uint8_t> ImageBuffer::toData(const String& mimeType, std::optional<double> quality) const
     91{
    8092    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
    8193
     
    8395    gsize bufferSize;
    8496    if (!encodeImage(m_data.m_surface.get(), mimeType, quality, buffer, bufferSize))
    85         return "data:,";
     97        return { };
    8698
    87     Vector<char> base64Data;
    88     base64Encode(buffer.get(), bufferSize, base64Data);
    89 
    90     return "data:" + mimeType + ";base64," + base64Data;
     99    Vector<uint8_t> imageData;
     100    imageData.append(buffer.get(), bufferSize);
     101    return imageData;
    91102}
    92103
  • trunk/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp

    r213378 r213412  
    261261}
    262262
     263Vector<uint8_t> ImageBuffer::toData(const String& mimeType, std::optional<double> quality) const
     264{
     265    notImplemented();
     266    return { };
     267}
     268
    263269String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality)
    264270{
Note: See TracChangeset for help on using the changeset viewer.