⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 284804 in webkit


Ignore:
Timestamp:
Oct 25, 2021, 12:09:47 PM (5 years ago)
Author:
Alan Coon
Message:

Cherry-pick r284436. rdar://problem/83753956

Make createImageBitmap() take EXIF orientation into account correctly
https://bugs.webkit.org/show_bug.cgi?id=231063
<rdar://problem/83753956>

Reviewed by Myles Maxfield and Said Abou-Hallawa.

LayoutTests/imported/w3c:

  • web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation-expected.txt: Added.
  • web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html: Added.
  • web-platform-tests/html/canvas/element/manual/imagebitmap/resources/squares.jpg: Added.

Source/WebCore:

Test: imported/w3c/web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html

This makes us treat {imageOrientation:"none"} as meaning "apply EXIF
orientation without any additional transformation", and
{imageOrientation:"flipY"} as meaning "apply EXIF orientation and then
apply an additional vertical flip". This behavior matches Firefox;
https://github.com/whatwg/html/issues/7210 is open on clarifying this
behavior in the HTML spec.

  • html/ImageBitmap.cpp: (WebCore::ImageBitmap::createPromise): (WebCore::ImageBitmap::createFromBuffer): (WebCore::imageOrientationForOrientation): Deleted.
  • html/ImageBitmapOptions.h: (WebCore::ImageBitmapOptions::resolvedImageOrientation const):
  • html/ImageBitmapOptions.idl:
  • platform/graphics/ImageOrientation.h: (WebCore::ImageOrientation::withFlippedY const):

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

Location:
branches/safari-612-branch
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-612-branch/LayoutTests/imported/w3c/ChangeLog

    r284482 r284804  
     12021-10-25  Null  <null@apple.com>
     2
     3        Cherry-pick r284436. rdar://problem/83753956
     4
     5    Make createImageBitmap() take EXIF orientation into account correctly
     6    https://bugs.webkit.org/show_bug.cgi?id=231063
     7    <rdar://problem/83753956>
     8   
     9    Reviewed by Myles Maxfield and Said Abou-Hallawa.
     10   
     11    LayoutTests/imported/w3c:
     12   
     13    * web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation-expected.txt: Added.
     14    * web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html: Added.
     15    * web-platform-tests/html/canvas/element/manual/imagebitmap/resources/squares.jpg: Added.
     16   
     17    Source/WebCore:
     18   
     19    Test: imported/w3c/web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html
     20   
     21    This makes us treat {imageOrientation:"none"} as meaning "apply EXIF
     22    orientation without any additional transformation", and
     23    {imageOrientation:"flipY"} as meaning "apply EXIF orientation and then
     24    apply an additional vertical flip". This behavior matches Firefox;
     25    https://github.com/whatwg/html/issues/7210 is open on clarifying this
     26    behavior in the HTML spec.
     27   
     28    * html/ImageBitmap.cpp:
     29    (WebCore::ImageBitmap::createPromise):
     30    (WebCore::ImageBitmap::createFromBuffer):
     31    (WebCore::imageOrientationForOrientation): Deleted.
     32    * html/ImageBitmapOptions.h:
     33    (WebCore::ImageBitmapOptions::resolvedImageOrientation const):
     34    * html/ImageBitmapOptions.idl:
     35    * platform/graphics/ImageOrientation.h:
     36    (WebCore::ImageOrientation::withFlippedY const):
     37   
     38   
     39    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@284436 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     40
     41    2021-10-18  Cameron McCormack  <heycam@apple.com>
     42
     43            Make createImageBitmap() take EXIF orientation into account correctly
     44            https://bugs.webkit.org/show_bug.cgi?id=231063
     45            <rdar://problem/83753956>
     46
     47            Reviewed by Myles Maxfield and Said Abou-Hallawa.
     48
     49            * web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation-expected.txt: Added.
     50            * web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html: Added.
     51            * web-platform-tests/html/canvas/element/manual/imagebitmap/resources/squares.jpg: Added.
     52
    1532021-10-19  Russell Epstein  <repstein@apple.com>
    254
  • branches/safari-612-branch/Source/WebCore/ChangeLog

    r284803 r284804  
     12021-10-25  Null  <null@apple.com>
     2
     3        Cherry-pick r284436. rdar://problem/83753956
     4
     5    Make createImageBitmap() take EXIF orientation into account correctly
     6    https://bugs.webkit.org/show_bug.cgi?id=231063
     7    <rdar://problem/83753956>
     8   
     9    Reviewed by Myles Maxfield and Said Abou-Hallawa.
     10   
     11    LayoutTests/imported/w3c:
     12   
     13    * web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation-expected.txt: Added.
     14    * web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html: Added.
     15    * web-platform-tests/html/canvas/element/manual/imagebitmap/resources/squares.jpg: Added.
     16   
     17    Source/WebCore:
     18   
     19    Test: imported/w3c/web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html
     20   
     21    This makes us treat {imageOrientation:"none"} as meaning "apply EXIF
     22    orientation without any additional transformation", and
     23    {imageOrientation:"flipY"} as meaning "apply EXIF orientation and then
     24    apply an additional vertical flip". This behavior matches Firefox;
     25    https://github.com/whatwg/html/issues/7210 is open on clarifying this
     26    behavior in the HTML spec.
     27   
     28    * html/ImageBitmap.cpp:
     29    (WebCore::ImageBitmap::createPromise):
     30    (WebCore::ImageBitmap::createFromBuffer):
     31    (WebCore::imageOrientationForOrientation): Deleted.
     32    * html/ImageBitmapOptions.h:
     33    (WebCore::ImageBitmapOptions::resolvedImageOrientation const):
     34    * html/ImageBitmapOptions.idl:
     35    * platform/graphics/ImageOrientation.h:
     36    (WebCore::ImageOrientation::withFlippedY const):
     37   
     38   
     39    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@284436 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     40
     41    2021-10-18  Cameron McCormack  <heycam@apple.com>
     42
     43            Make createImageBitmap() take EXIF orientation into account correctly
     44            https://bugs.webkit.org/show_bug.cgi?id=231063
     45            <rdar://problem/83753956>
     46
     47            Reviewed by Myles Maxfield and Said Abou-Hallawa.
     48
     49            Test: imported/w3c/web-platform-tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html
     50
     51            This makes us treat {imageOrientation:"none"} as meaning "apply EXIF
     52            orientation without any additional transformation", and
     53            {imageOrientation:"flipY"} as meaning "apply EXIF orientation and then
     54            apply an additional vertical flip". This behavior matches Firefox;
     55            https://github.com/whatwg/html/issues/7210 is open on clarifying this
     56            behavior in the HTML spec.
     57
     58            * html/ImageBitmap.cpp:
     59            (WebCore::ImageBitmap::createPromise):
     60            (WebCore::ImageBitmap::createFromBuffer):
     61            (WebCore::imageOrientationForOrientation): Deleted.
     62            * html/ImageBitmapOptions.h:
     63            (WebCore::ImageBitmapOptions::resolvedImageOrientation const):
     64            * html/ImageBitmapOptions.idl:
     65            * platform/graphics/ImageOrientation.h:
     66            (WebCore::ImageOrientation::withFlippedY const):
     67
    1682021-10-25  Null  <null@apple.com>
    269
  • branches/safari-612-branch/Source/WebCore/html/ImageBitmap.cpp

    r283830 r284804  
    236236}
    237237
    238 static ImageOrientation imageOrientationForOrientation(ImageBitmapOptions::Orientation orientation)
    239 {
    240     if (orientation == ImageBitmapOptions::Orientation::FlipY)
    241         return ImageOrientation(ImageOrientation::OriginBottomLeft);
    242     return ImageOrientation();
    243 }
    244 
    245238static AlphaPremultiplication alphaPremultiplicationForPremultiplyAlpha(ImageBitmapOptions::PremultiplyAlpha premultiplyAlpha)
    246239{
     
    374367    }
    375368
    376     auto imageForRender = cachedImage->imageForRenderer(imageElement->renderer());
    377     if (!imageForRender) {
     369    auto imageForRenderer = cachedImage->imageForRenderer(imageElement->renderer());
     370    if (!imageForRenderer) {
    378371        promise.reject(InvalidStateError, "Cannot create ImageBitmap from image that can't be rendered");
    379372        return;
     
    381374
    382375    auto outputSize = outputSizeForSourceRectangle(sourceRectangle.returnValue(), options);
    383     auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, imageForRender->colorSpace());
     376    auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, imageForRenderer->colorSpace());
    384377    if (!bitmapData) {
    385378        resolveWithBlankImageBuffer(scriptExecutionContext, !taintsOrigin(*cachedImage), WTFMove(promise));
     
    387380    }
    388381
     382    auto orientation = imageForRenderer->orientation();
     383    if (orientation == ImageOrientation::FromImage)
     384        orientation = ImageOrientation::None;
     385
    389386    FloatRect destRect(FloatPoint(), outputSize);
    390     bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
     387    bitmapData->context().drawImage(*imageForRenderer, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(orientation) });
    391388
    392389    // 9. If the origin of image's image is not the same origin as the origin specified by the
     
    456453
    457454    FloatRect destRect(FloatPoint(), outputSize);
    458     bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
     455    bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });
    459456
    460457    // 5. Set the origin-clean flag of the ImageBitmap object's bitmap to the same value as
     
    526523        auto scaleX = float(outputSize.width()) / float(sourceRectangle.width());
    527524        auto scaleY = float(outputSize.height()) / float(sourceRectangle.height());
    528         if (options.imageOrientation == ImageBitmapOptions::Orientation::FlipY) {
     525        if (options.orientation == ImageBitmapOptions::Orientation::FlipY) {
    529526            c.scale(FloatSize(scaleX, -scaleY));
    530527            c.translate(IntPoint(-sourceRectangle.location().x(), sourceRectangle.location().y() - outputSize.height()));
     
    589586
    590587    FloatRect destRect(FloatPoint(), outputSize);
    591     bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
     588    bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });
    592589
    593590    // 5. Set the origin-clean flag of the ImageBitmap object's bitmap to the same
     
    769766
    770767    FloatRect destRect(FloatPoint(), outputSize);
    771     bitmapData->context().drawImage(image, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
     768    bitmapData->context().drawImage(image, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });
    772769
    773770    OptionSet<SerializationState> serializationState = SerializationState::OriginClean;
     
    816813    // resulting ImageBuffer directly.
    817814    auto alphaPremultiplication = alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha);
    818     if (sourceRectangle.returnValue().location().isZero() && sourceRectangle.returnValue().size() == imageData->size() && sourceRectangle.returnValue().size() == outputSize && options.imageOrientation == ImageBitmapOptions::Orientation::None) {
     815    if (sourceRectangle.returnValue().location().isZero() && sourceRectangle.returnValue().size() == imageData->size() && sourceRectangle.returnValue().size() == outputSize && options.orientation == ImageBitmapOptions::Orientation::None) {
    819816        bitmapData->putPixelBuffer(imageData->pixelBuffer(), sourceRectangle.releaseReturnValue(), { }, alphaPremultiplication);
    820817       
     
    834831    tempBitmapData->putPixelBuffer(imageData->pixelBuffer(), IntRect(0, 0, imageData->width(), imageData->height()), { }, alphaPremultiplication);
    835832    FloatRect destRect(FloatPoint(), outputSize);
    836     bitmapData->context().drawImageBuffer(*tempBitmapData, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), imageOrientationForOrientation(options.imageOrientation) });
     833    bitmapData->context().drawImageBuffer(*tempBitmapData, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });
    837834
    838835    // 6.4.1. Resolve p with ImageBitmap.
  • branches/safari-612-branch/Source/WebCore/html/ImageBitmapOptions.h

    r278340 r284804  
    2626#pragma once
    2727
     28#include "ImageOrientation.h"
    2829#include <optional>
    2930
     
    3637    enum class ResizeQuality { Pixelated, Low, Medium, High };
    3738
    38     Orientation imageOrientation { Orientation::None };
     39    Orientation orientation { Orientation::None };
    3940    PremultiplyAlpha premultiplyAlpha { PremultiplyAlpha::Default };
    4041    ColorSpaceConversion colorSpaceConversion { ColorSpaceConversion::Default };
     
    4243    std::optional<unsigned> resizeHeight;
    4344    ResizeQuality resizeQuality { ResizeQuality::Low };
     45
     46    ImageOrientation resolvedImageOrientation(ImageOrientation imageOrientation) const
     47    {
     48        return orientation == Orientation::FlipY ? imageOrientation.withFlippedY() : imageOrientation;
     49    }
    4450};
    4551
  • branches/safari-612-branch/Source/WebCore/html/ImageBitmapOptions.idl

    r222986 r284804  
    3030
    3131dictionary ImageBitmapOptions {
    32     ImageOrientation imageOrientation = "none";
     32    [ImplementedAs=orientation] ImageOrientation imageOrientation = "none";
    3333    PremultiplyAlpha premultiplyAlpha = "default";
    3434    ColorSpaceConversion colorSpaceConversion = "default";
  • branches/safari-612-branch/Source/WebCore/platform/graphics/ImageOrientation.h

    r253249 r284804  
    103103    }
    104104
     105    ImageOrientation withFlippedY() const
     106    {
     107        ASSERT(isValidEXIFOrientation(m_orientation));
     108
     109        switch (m_orientation) {
     110        case FromImage:
     111            ASSERT_NOT_REACHED();
     112            return None;
     113        case OriginTopLeft:
     114            return OriginBottomLeft;
     115        case OriginTopRight:
     116            return OriginBottomRight;
     117        case OriginBottomRight:
     118            return OriginTopRight;
     119        case OriginBottomLeft:
     120            return OriginTopLeft;
     121        case OriginLeftTop:
     122            return OriginLeftBottom;
     123        case OriginRightTop:
     124            return OriginRightBottom;
     125        case OriginRightBottom:
     126            return OriginRightTop;
     127        case OriginLeftBottom:
     128            return OriginLeftTop;
     129        }
     130
     131        ASSERT_NOT_REACHED();
     132        return None;
     133    }
     134
    105135private:
    106136    static const Orientation EXIFFirst = OriginTopLeft;
Note: See TracChangeset for help on using the changeset viewer.