| Differences between
and this patch
- Source/WebCore/ChangeLog +86 lines
Lines 1-3 Source/WebCore/ChangeLog_sec1
1
2016-09-09  Said Abou-Hallawa  <sabouhallawa@apple.com>
2
3
        Move the pixel data of ImageFrame to a separate class named ImageBackingStore
4
        https://bugs.webkit.org/show_bug.cgi?id=159679
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Move the pixel data manipulation part in ImageFrame into a separate class
9
        and allocate it on demand.
10
 
11
        * PlatformEfl.cmake:
12
        * PlatformGTK.cmake:
13
        * PlatformWinCairo.cmake:
14
        * WebCore.xcodeproj/project.pbxproj:
15
        * platform/graphics/Color.cpp:
16
        (WebCore::premultipliedChannel):
17
        (WebCore::unpremultipliedChannel):
18
        (WebCore::makePremultipliedRGBA):
19
        (WebCore::makeUnPremultipliedRGBA):
20
        (WebCore::colorFromPremultipliedARGB):
21
        (WebCore::premultipliedARGBFromColor):
22
        * platform/graphics/Color.h:
23
        (WebCore::fastMultiplyBy255):
24
        * platform/graphics/ImageBackingStore.h: Added.
25
        (WebCore::ImageBackingStore::create):
26
        (WebCore::ImageBackingStore::ImageBackingStore):
27
        (WebCore::ImageBackingStore::setSize):
28
        (WebCore::ImageBackingStore::setFrameRect):
29
        (WebCore::ImageBackingStore::size):
30
        (WebCore::ImageBackingStore::frameRect):
31
        (WebCore::ImageBackingStore::clear):
32
        (WebCore::ImageBackingStore::clearRect):
33
        (WebCore::ImageBackingStore::repeatFirstRow):
34
        (WebCore::ImageBackingStore::at):
35
        (WebCore::ImageBackingStore::setRGBA):
36
        (WebCore::ImageBackingStore::overRGBA):
37
        (WebCore::ImageBackingStore::inBounds):
38
        (WebCore::ImageBackingStore::isOverSize):
39
        * platform/graphics/cg/NativeImageCG.cpp:
40
        (WebCore::nativeImageHasAlpha):
41
        * platform/image-decoders/ImageDecoder.cpp:
42
        (WebCore::ImageFrame::operator=):
43
        (WebCore::ImageFrame::clearPixelData):
44
        (WebCore::ImageFrame::zeroFillPixelData):
45
        (WebCore::ImageFrame::zeroFillFrameRect):
46
        (WebCore::ImageFrame::setBackingStore):
47
        (WebCore::ImageFrame::setSize):
48
        (WebCore::setOriginalFrameRect):
49
        (WebCore::ImageDecoder::frameBytesAtIndex):
50
        (WebCore::ImageFrame::copyBitmapData): Deleted.
51
        * platform/image-decoders/ImageDecoder.h:
52
        (WebCore::ImageFrame::copyRowNTimes):
53
        (WebCore::ImageFrame::size):
54
        (WebCore::ImageFrame::asNewNativeImage):
55
        (WebCore::ImageFrame::backingStore):
56
        (WebCore::ImageFrame::hasBackingStore):
57
        (WebCore::ImageFrame::originalFrameRect):
58
        (WebCore::ImageFrame::getAddr):
59
        (WebCore::ImageFrame::setRGBA):
60
        (WebCore::ImageFrame::overRGBA):
61
        (WebCore::ImageDecoder::setSize):
62
        (WebCore::ImageFrame::setOriginalFrameRect): Deleted.
63
        (WebCore::ImageFrame::hasPixelData): Deleted.
64
        (WebCore::ImageFrame::fixPointUnsignedMultiply): Deleted.
65
        (WebCore::ImageFrame::divide255): Deleted.
66
        (WebCore::ImageFrame::width): Deleted.
67
        (WebCore::ImageFrame::height): Deleted.
68
        (WebCore::ImageDecoder::isOverSize): Deleted.
69
        * platform/image-decoders/bmp/BMPImageReader.cpp:
70
        (WebCore::BMPImageReader::decodeBMP):
71
        * platform/image-decoders/cairo/ImageBackingStoreCairo.cpp: Added.
72
        (WebCore::ImageBackingStore::image):
73
        * platform/image-decoders/gif/GIFImageDecoder.cpp:
74
        (WebCore::GIFImageDecoder::haveDecodedRow):
75
        * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
76
        (WebCore::setPixel):
77
        (WebCore::JPEGImageDecoder::outputScanlines):
78
        * platform/image-decoders/png/PNGImageDecoder.cpp:
79
        (WebCore::setPixelRGB):
80
        (WebCore::setPixelRGBA):
81
        (WebCore::setPixelPremultipliedRGBA):
82
        (WebCore::PNGImageDecoder::rowAvailable):
83
        (WebCore::PNGImageDecoder::frameComplete):
84
        * platform/image-decoders/webp/WEBPImageDecoder.cpp:
85
        (WebCore::WEBPImageDecoder::decode):
86
1
2016-09-09  Brady Eidson  <beidson@apple.com>
87
2016-09-09  Brady Eidson  <beidson@apple.com>
2
88
3
        Soft-link GameController.framework.
89
        Soft-link GameController.framework.
- Source/WebCore/PlatformEfl.cmake -2 / +1 lines
Lines 183-192 list(APPEND WebCore_SOURCES Source/WebCore/PlatformEfl.cmake_sec1
183
    platform/graphics/x11/PlatformDisplayX11.cpp
183
    platform/graphics/x11/PlatformDisplayX11.cpp
184
    platform/graphics/x11/XUniqueResource.cpp
184
    platform/graphics/x11/XUniqueResource.cpp
185
185
186
    platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
186
    platform/image-encoders/JPEGImageEncoder.cpp
187
    platform/image-encoders/JPEGImageEncoder.cpp
187
188
188
    platform/image-decoders/cairo/ImageDecoderCairo.cpp
189
190
    platform/network/efl/NetworkStateNotifierEfl.cpp
189
    platform/network/efl/NetworkStateNotifierEfl.cpp
191
190
192
    platform/network/soup/AuthenticationChallengeSoup.cpp
191
    platform/network/soup/AuthenticationChallengeSoup.cpp
- Source/WebCore/PlatformGTK.cmake -1 / +1 lines
Lines 155-161 list(APPEND WebCore_SOURCES Source/WebCore/PlatformGTK.cmake_sec1
155
    platform/gtk/TemporaryLinkStubs.cpp
155
    platform/gtk/TemporaryLinkStubs.cpp
156
    platform/gtk/UserAgentGtk.cpp
156
    platform/gtk/UserAgentGtk.cpp
157
157
158
    platform/image-decoders/cairo/ImageDecoderCairo.cpp
158
    platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
159
159
160
    platform/mediastream/gtk/SDPProcessorScriptResourceGtk.cpp
160
    platform/mediastream/gtk/SDPProcessorScriptResourceGtk.cpp
161
161
- Source/WebCore/PlatformWinCairo.cmake -1 / +1 lines
Lines 46-52 list(APPEND WebCore_SOURCES Source/WebCore/PlatformWinCairo.cmake_sec1
46
    platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
46
    platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
47
    platform/graphics/win/SimpleFontDataCairoWin.cpp
47
    platform/graphics/win/SimpleFontDataCairoWin.cpp
48
48
49
    platform/image-decoders/cairo/ImageDecoderCairo.cpp
49
    platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
50
50
51
    platform/network/NetworkStorageSessionStub.cpp
51
    platform/network/NetworkStorageSessionStub.cpp
52
52
- Source/WebCore/WebCore.xcodeproj/project.pbxproj +4 lines
Lines 2275-2280 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec1
2275
		555B87EC1CAAF0AB00349425 /* ImageDecoderCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */; };
2275
		555B87EC1CAAF0AB00349425 /* ImageDecoderCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */; };
2276
		555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */; };
2276
		555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */; };
2277
		55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
2277
		55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
2278
		55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
2278
		5709E8CD1D413D47003244AC /* WebKitSubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */; };
2279
		5709E8CD1D413D47003244AC /* WebKitSubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */; };
2279
		5709E8CE1D413D5B003244AC /* JSWebKitSubtleCryptoCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F661807460800132674 /* JSWebKitSubtleCryptoCustom.cpp */; };
2280
		5709E8CE1D413D5B003244AC /* JSWebKitSubtleCryptoCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F661807460800132674 /* JSWebKitSubtleCryptoCustom.cpp */; };
2280
		5709E8CF1D413D9A003244AC /* WebKitSubtleCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 5709E8CB1D413CE3003244AC /* WebKitSubtleCrypto.h */; };
2281
		5709E8CF1D413D9A003244AC /* WebKitSubtleCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 5709E8CB1D413CE3003244AC /* WebKitSubtleCrypto.h */; };
Lines 9291-9296 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec2
9291
		555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = "<group>"; };
9292
		555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = "<group>"; };
9292
		555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = "<group>"; };
9293
		555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = "<group>"; };
9293
		55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
9294
		55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
9295
		55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = "<group>"; };
9294
		55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; };
9296
		55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; };
9295
		5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitSubtleCrypto.cpp; sourceTree = "<group>"; };
9297
		5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitSubtleCrypto.cpp; sourceTree = "<group>"; };
9296
		5709E8CB1D413CE3003244AC /* WebKitSubtleCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitSubtleCrypto.h; sourceTree = "<group>"; };
9298
		5709E8CB1D413CE3003244AC /* WebKitSubtleCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitSubtleCrypto.h; sourceTree = "<group>"; };
Lines 20769-20774 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec3
20769
				379919941200DDF400EA041C /* WOFFFileFormat.cpp */,
20771
				379919941200DDF400EA041C /* WOFFFileFormat.cpp */,
20770
				379919951200DDF400EA041C /* WOFFFileFormat.h */,
20772
				379919951200DDF400EA041C /* WOFFFileFormat.h */,
20771
				55A336F61D8209F40022C4C7 /* NativeImage.h */,
20773
				55A336F61D8209F40022C4C7 /* NativeImage.h */,
20774
				55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */,
20772
			);
20775
			);
20773
			path = graphics;
20776
			path = graphics;
20774
			sourceTree = "<group>";
20777
			sourceTree = "<group>";
Lines 26339-26344 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec4
26339
				582CB0531A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h in Headers */,
26342
				582CB0531A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h in Headers */,
26340
				C5A1EA7D152BCF08004D00B6 /* SimplifyMarkupCommand.h in Headers */,
26343
				C5A1EA7D152BCF08004D00B6 /* SimplifyMarkupCommand.h in Headers */,
26341
				572A7F211C6E5719009C6149 /* SimulatedClick.h in Headers */,
26344
				572A7F211C6E5719009C6149 /* SimulatedClick.h in Headers */,
26345
				55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */,
26342
				31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
26346
				31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
26343
				FD00D7A514A3F61900734011 /* SincResampler.h in Headers */,
26347
				FD00D7A514A3F61900734011 /* SincResampler.h in Headers */,
26344
				51327D6011A33A2B004F9D65 /* SinkDocument.h in Headers */,
26348
				51327D6011A33A2B004F9D65 /* SinkDocument.h in Headers */,
- Source/WebCore/platform/graphics/Color.cpp -16 / +27 lines
Lines 49-54 const RGBA32 Color::transparent; Source/WebCore/platform/graphics/Color.cpp_sec1
49
static const RGBA32 lightenedBlack = 0xFF545454;
49
static const RGBA32 lightenedBlack = 0xFF545454;
50
static const RGBA32 darkenedWhite = 0xFFABABAB;
50
static const RGBA32 darkenedWhite = 0xFFABABAB;
51
51
52
static inline unsigned premultipliedChannel(unsigned c, unsigned a)
53
{
54
    return fastDivideBy255(c * a + 254);
55
}
56
57
static inline unsigned unpremultipliedChannel(unsigned c, unsigned a)
58
{
59
    return (fastMultiplyBy255(c) + a - 1) / a;
60
}
61
52
RGBA32 makeRGB(int r, int g, int b)
62
RGBA32 makeRGB(int r, int g, int b)
53
{
63
{
54
    return 0xFF000000 | std::max(0, std::min(r, 255)) << 16 | std::max(0, std::min(g, 255)) << 8 | std::max(0, std::min(b, 255));
64
    return 0xFF000000 | std::max(0, std::min(r, 255)) << 16 | std::max(0, std::min(g, 255)) << 8 | std::max(0, std::min(b, 255));
Lines 59-64 RGBA32 makeRGBA(int r, int g, int b, int Source/WebCore/platform/graphics/Color.cpp_sec2
59
    return std::max(0, std::min(a, 255)) << 24 | std::max(0, std::min(r, 255)) << 16 | std::max(0, std::min(g, 255)) << 8 | std::max(0, std::min(b, 255));
69
    return std::max(0, std::min(a, 255)) << 24 | std::max(0, std::min(r, 255)) << 16 | std::max(0, std::min(g, 255)) << 8 | std::max(0, std::min(b, 255));
60
}
70
}
61
71
72
RGBA32 makePremultipliedRGBA(int r, int g, int b, int a)
73
{
74
    return makeRGBA(premultipliedChannel(r, a), premultipliedChannel(g, a), premultipliedChannel(b, a), a);
75
}
76
77
RGBA32 makeUnPremultipliedRGBA(int r, int g, int b, int a)
78
{
79
    return makeRGBA(unpremultipliedChannel(r, a), unpremultipliedChannel(g, a), unpremultipliedChannel(b, a), a);
80
}
81
62
static int colorFloatToRGBAByte(float f)
82
static int colorFloatToRGBAByte(float f)
63
{
83
{
64
    // We use lroundf and 255 instead of nextafterf(256, 0) to match CG's rounding
84
    // We use lroundf and 255 instead of nextafterf(256, 0) to match CG's rounding
Lines 482-495 void Color::getHSV(double& hue, double& Source/WebCore/platform/graphics/Color.cpp_sec3
482
Color colorFromPremultipliedARGB(RGBA32 pixelColor)
502
Color colorFromPremultipliedARGB(RGBA32 pixelColor)
483
{
503
{
484
    int alpha = alphaChannel(pixelColor);
504
    int alpha = alphaChannel(pixelColor);
485
    if (alpha && alpha < 255) {
505
    if (alpha && alpha < 255)
486
        return Color::createUnchecked(
506
        pixelColor = makeUnPremultipliedRGBA(redChannel(pixelColor), greenChannel(pixelColor), blueChannel(pixelColor), alpha);
487
            redChannel(pixelColor) * 255 / alpha,
507
    return Color(pixelColor);
488
            greenChannel(pixelColor) * 255 / alpha,
489
            blueChannel(pixelColor) * 255 / alpha,
490
            alpha);
491
    } else
492
        return Color(pixelColor);
493
}
508
}
494
509
495
RGBA32 premultipliedARGBFromColor(const Color& color)
510
RGBA32 premultipliedARGBFromColor(const Color& color)
Lines 497-510 RGBA32 premultipliedARGBFromColor(const Source/WebCore/platform/graphics/Color.cpp_sec4
497
    unsigned pixelColor;
512
    unsigned pixelColor;
498
513
499
    unsigned alpha = color.alpha();
514
    unsigned alpha = color.alpha();
500
    if (alpha < 255) {
515
    if (alpha < 255)
501
        pixelColor = Color::createUnchecked(
516
        pixelColor = makePremultipliedRGBA(color.red(), color.green(), color.blue(), alpha);
502
            fastDivideBy255(color.red() * alpha + 254),
517
    else
503
            fastDivideBy255(color.green() * alpha + 254),
518
        pixelColor = color.rgb();
504
            fastDivideBy255(color.blue() * alpha + 254),
505
            alpha).rgb();
506
    } else
507
         pixelColor = color.rgb();
508
519
509
    return pixelColor;
520
    return pixelColor;
510
}
521
}
- Source/WebCore/platform/graphics/Color.h +9 lines
Lines 55-60 typedef unsigned RGBA32; // Deprecated: Source/WebCore/platform/graphics/Color.h_sec1
55
WEBCORE_EXPORT RGBA32 makeRGB(int r, int g, int b);
55
WEBCORE_EXPORT RGBA32 makeRGB(int r, int g, int b);
56
WEBCORE_EXPORT RGBA32 makeRGBA(int r, int g, int b, int a);
56
WEBCORE_EXPORT RGBA32 makeRGBA(int r, int g, int b, int a);
57
57
58
RGBA32 makePremultipliedRGBA(int r, int g, int b, int a);
59
RGBA32 makeUnPremultipliedRGBA(int r, int g, int b, int a);
60
58
WEBCORE_EXPORT RGBA32 colorWithOverrideAlpha(RGBA32 color, float overrideAlpha);
61
WEBCORE_EXPORT RGBA32 colorWithOverrideAlpha(RGBA32 color, float overrideAlpha);
59
WEBCORE_EXPORT RGBA32 colorWithOverrideAlpha(RGBA32 color, Optional<float> overrideAlpha);
62
WEBCORE_EXPORT RGBA32 colorWithOverrideAlpha(RGBA32 color, Optional<float> overrideAlpha);
60
63
Lines 218-223 Color blend(const Color& from, const Col Source/WebCore/platform/graphics/Color.h_sec2
218
221
219
int differenceSquared(const Color&, const Color&);
222
int differenceSquared(const Color&, const Color&);
220
223
224
uint16_t fastMultiplyBy255(uint16_t value);
221
uint16_t fastDivideBy255(uint16_t);
225
uint16_t fastDivideBy255(uint16_t);
222
226
223
#if USE(CG)
227
#if USE(CG)
Lines 290-295 inline uint8_t roundAndClampColorChannel Source/WebCore/platform/graphics/Color.h_sec3
290
    return std::max(0.f, std::min(255.f, std::round(value)));
294
    return std::max(0.f, std::min(255.f, std::round(value)));
291
}
295
}
292
296
297
inline uint16_t fastMultiplyBy255(uint16_t value)
298
{
299
    return (value << 8) - value;
300
}
301
293
inline uint16_t fastDivideBy255(uint16_t value)
302
inline uint16_t fastDivideBy255(uint16_t value)
294
{
303
{
295
    // While this is an approximate algorithm for division by 255, it gives perfectly accurate results for 16-bit values.
304
    // While this is an approximate algorithm for division by 255, it gives perfectly accurate results for 16-bit values.
- Source/WebCore/platform/graphics/ImageBackingStore.h +190 lines
Line 0 Source/WebCore/platform/graphics/ImageBackingStore.h_sec1
1
/*
2
 * Copyright (C) 2016 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#pragma once
27
28
#include "Color.h"
29
#include "IntRect.h"
30
#include "IntSize.h"
31
#include "NativeImagePtr.h"
32
33
#include <wtf/Vector.h>
34
35
namespace WebCore {
36
37
class ImageBackingStore {
38
public:
39
    static std::unique_ptr<ImageBackingStore> create(const IntSize& size, bool premultiplyAlpha)
40
    {
41
        return std::make_unique<ImageBackingStore>(size, premultiplyAlpha);
42
    }
43
44
    static std::unique_ptr<ImageBackingStore> create(const ImageBackingStore& other)
45
    {
46
        return std::make_unique<ImageBackingStore>(other);
47
    }
48
49
    ImageBackingStore(const IntSize& size, bool premultiplyAlpha = true)
50
        : m_premultiplyAlpha(premultiplyAlpha)
51
    {
52
        ASSERT(!size.isEmpty());
53
        setSize(size);
54
    }
55
56
    ImageBackingStore(const ImageBackingStore& other)
57
    {
58
        if (this == &other)
59
            return;
60
61
        m_pixels = other.m_pixels;
62
        m_pixelsPtr = m_pixels.data();
63
        m_size = other.m_size;
64
        m_premultiplyAlpha = other.m_premultiplyAlpha;
65
    }
66
67
    NativeImagePtr image() const;
68
69
    bool setSize(const IntSize& size)
70
    {
71
        if (!m_pixels.tryReserveCapacity(size.area()))
72
            return false;
73
74
        m_pixels.resize(size.area());
75
        m_pixelsPtr = m_pixels.data();
76
        m_size = size;
77
        m_frameRect = IntRect(IntPoint(), m_size);
78
        clear();
79
        return true;
80
    }
81
82
    void setFrameRect(const IntRect& frameRect)
83
    {
84
        ASSERT(!m_size.isEmpty());
85
        ASSERT(inBounds(frameRect));
86
        m_frameRect = frameRect;
87
    }
88
89
    IntSize size() const { return m_size; }
90
    IntRect frameRect() const { return m_frameRect; }
91
92
    void clear()
93
    {
94
        memset(m_pixelsPtr, 0, m_size.area() * sizeof(RGBA32));
95
    }
96
97
    void clearRect(const IntRect& rect)
98
    {
99
        if (rect.isEmpty() || !inBounds(rect))
100
            return;
101
102
        size_t rectWidthInBytes = rect.width() * sizeof(RGBA32);
103
        RGBA32* start = at(rect.x(), rect.y());
104
        for (int i = 0; i < rect.height(); ++i) {
105
            memset(start, 0, rectWidthInBytes);
106
            start += m_size.width();
107
        }
108
    }
109
110
    void repeatFirstRow(const IntRect& rect)
111
    {
112
        if (rect.isEmpty() || !inBounds(rect))
113
            return;
114
115
        size_t rectWidthInBytes = rect.width() * sizeof(RGBA32);
116
        RGBA32* src = at(rect.x(), rect.y());
117
        RGBA32* dest = src + m_size.width();
118
        for (int i = 1; i < rect.height(); ++i) {
119
            memcpy(dest, src, rectWidthInBytes);
120
            dest += m_size.width();
121
        }
122
    }
123
124
    RGBA32* at(int x, int y) const
125
    {
126
        return m_pixelsPtr + y * m_size.width() + x;
127
    }
128
129
    void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
130
    {
131
        setRGBA(at(x, y), r, g, b, a);
132
    }
133
134
    void setRGBA(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
135
    {
136
        if (m_premultiplyAlpha && !a)
137
            *dest = 0;
138
        else if (m_premultiplyAlpha && a < 255)
139
            *dest = makePremultipliedRGBA(r, g, b, a);
140
        else
141
            *dest = makeRGBA(r, g, b, a);
142
    }
143
144
    void overRGBA(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
145
    {
146
        if (!a)
147
            return;
148
149
        if (a >= 255 || !alphaChannel(*dest)) {
150
            setRGBA(dest, r, g, b, a);
151
            return;
152
        }
153
154
        if (!m_premultiplyAlpha)
155
            *dest = makePremultipliedRGBA(redChannel(*dest), greenChannel(*dest), blueChannel(*dest), alphaChannel(*dest));
156
157
        unsigned d = 255 - a;
158
159
        r = fastDivideBy255(r * a + redChannel(*dest) * d);
160
        g = fastDivideBy255(g * a + greenChannel(*dest) * d);
161
        b = fastDivideBy255(b * a + blueChannel(*dest) * d);
162
        a += fastDivideBy255(d * alphaChannel(*dest));
163
164
        if (m_premultiplyAlpha)
165
            *dest = makeRGBA(r, g, b, a);
166
        else
167
            *dest = makeUnPremultipliedRGBA(r, g, b, a);
168
    }
169
170
    bool inBounds(const IntRect& rect) const
171
    {
172
        return IntRect(IntPoint(), m_size).contains(rect);
173
    }
174
175
    static bool isOverSize(const IntSize& size)
176
    {
177
        static unsigned long long MaxPixels = ((1 << 29) - 1);
178
        unsigned long long pixels = static_cast<unsigned long long>(size.width()) * static_cast<unsigned long long>(size.height());
179
        return pixels > MaxPixels;
180
    }
181
182
private:
183
    Vector<RGBA32> m_pixels;
184
    RGBA32* m_pixelsPtr { nullptr };
185
    IntSize m_size;
186
    IntRect m_frameRect; // This will always just be the entire buffer except for GIF and PNG frames
187
    bool m_premultiplyAlpha { true };
188
};
189
190
}
- Source/WebCore/platform/graphics/cg/NativeImageCG.cpp -3 / +3 lines
Lines 47-56 IntSize nativeImageSize(const NativeImag Source/WebCore/platform/graphics/cg/NativeImageCG.cpp_sec1
47
    return image ? IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get())) : IntSize();
47
    return image ? IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get())) : IntSize();
48
}
48
}
49
49
50
bool nativeImageHasAlpha(const NativeImagePtr&)
50
bool nativeImageHasAlpha(const NativeImagePtr& image)
51
{
51
{
52
    // FIXME: Answer correctly the question: does the CGImageRef have alpha channnel?
52
    CGImageAlphaInfo info = CGImageGetAlphaInfo(image.get());
53
    return true;
53
    return (info >= kCGImageAlphaPremultipliedLast) && (info <= kCGImageAlphaFirst);
54
}
54
}
55
55
56
Color nativeImageSinglePixelSolidColor(const NativeImagePtr& image)
56
Color nativeImageSinglePixelSolidColor(const NativeImagePtr& image)
- Source/WebCore/platform/image-decoders/ImageDecoder.cpp -34 / +19 lines
Lines 141-148 ImageFrame& ImageFrame::operator=(const Source/WebCore/platform/image-decoders/ImageDecoder.cpp_sec1
141
    if (this == &other)
141
    if (this == &other)
142
        return *this;
142
        return *this;
143
143
144
    copyBitmapData(other);
144
    setBackingStore(other.backingStore());
145
    setOriginalFrameRect(other.originalFrameRect());
145
    setHasAlpha(other.m_hasAlpha);
146
    setStatus(other.status());
146
    setStatus(other.status());
147
    setDuration(other.duration());
147
    setDuration(other.duration());
148
    setDisposalMethod(other.disposalMethod());
148
    setDisposalMethod(other.disposalMethod());
Lines 152-159 ImageFrame& ImageFrame::operator=(const Source/WebCore/platform/image-decoders/ImageDecoder.cpp_sec2
152
152
153
void ImageFrame::clearPixelData()
153
void ImageFrame::clearPixelData()
154
{
154
{
155
    m_backingStore.clear();
155
    m_backingStore = nullptr;
156
    m_bytes = 0;
157
    m_status = FrameEmpty;
156
    m_status = FrameEmpty;
158
    // NOTE: Do not reset other members here; clearFrameBufferCache() calls this
157
    // NOTE: Do not reset other members here; clearFrameBufferCache() calls this
159
    // to free the bitmap data, but other functions like initFrameBuffer() and
158
    // to free the bitmap data, but other functions like initFrameBuffer() and
Lines 163-213 void ImageFrame::clearPixelData() Source/WebCore/platform/image-decoders/ImageDecoder.cpp_sec3
163
162
164
void ImageFrame::zeroFillPixelData()
163
void ImageFrame::zeroFillPixelData()
165
{
164
{
166
    memset(m_bytes, 0, m_size.width() * m_size.height() * sizeof(PixelData));
165
    m_backingStore->clear();
167
    m_hasAlpha = true;
166
    m_hasAlpha = true;
168
}
167
}
169
168
170
void ImageFrame::zeroFillFrameRect(const IntRect& rect)
169
void ImageFrame::zeroFillFrameRect(const IntRect& rect)
171
{
170
{
172
    ASSERT(IntRect(IntPoint(), m_size).contains(rect));
173
174
    if (rect.isEmpty())
171
    if (rect.isEmpty())
175
        return;
172
        return;
176
173
177
    size_t rectWidthInBytes = rect.width() * sizeof(PixelData);
174
    m_backingStore->clearRect(rect);
178
    PixelData* start = m_bytes + (rect.y() * width()) + rect.x();
179
    for (int i = 0; i < rect.height(); ++i) {
180
        memset(start, 0, rectWidthInBytes);
181
        start += width();
182
    }
183
184
    setHasAlpha(true);
175
    setHasAlpha(true);
185
}
176
}
186
177
187
bool ImageFrame::copyBitmapData(const ImageFrame& other)
178
void ImageFrame::setBackingStore(const ImageBackingStore* backingStore)
188
{
179
{
189
    if (this == &other)
180
    if (backingStore == m_backingStore)
190
        return true;
181
        return;
191
182
    m_backingStore = backingStore ? ImageBackingStore::create(*backingStore) : nullptr;
192
    m_backingStore = other.m_backingStore;
193
    m_bytes = m_backingStore.data();
194
    m_size = other.m_size;
195
    setHasAlpha(other.m_hasAlpha);
196
    return true;
197
}
183
}
198
184
199
bool ImageFrame::setSize(int newWidth, int newHeight)
185
bool ImageFrame::setSize(int newWidth, int newHeight)
200
{
186
{
201
    ASSERT(!width() && !height());
187
    ASSERT(!m_backingStore);
202
    size_t backingStoreSize = newWidth * newHeight;
188
    m_backingStore = ImageBackingStore::create(IntSize(newWidth, newHeight), m_premultiplyAlpha);
203
    if (!m_backingStore.tryReserveCapacity(backingStoreSize))
189
    return m_backingStore;
204
        return false;
205
    m_backingStore.resize(backingStoreSize);
206
    m_bytes = m_backingStore.data();
207
    m_size = IntSize(newWidth, newHeight);
208
209
    zeroFillPixelData();
210
    return true;
211
}
190
}
212
191
213
bool ImageFrame::hasAlpha() const
192
bool ImageFrame::hasAlpha() const
Lines 220-225 void ImageFrame::setHasAlpha(bool alpha) Source/WebCore/platform/image-decoders/ImageDecoder.cpp_sec4
220
    m_hasAlpha = alpha;
199
    m_hasAlpha = alpha;
221
}
200
}
222
201
202
void setOriginalFrameRect(const IntRect& frameRect)
203
{
204
    if (m_backingStore)
205
        m_backingStore->setFrameRect(frameRect);
206
}
207
223
void ImageFrame::setStatus(FrameStatus status)
208
void ImageFrame::setStatus(FrameStatus status)
224
{
209
{
225
    m_status = status;
210
    m_status = status;
Lines 286-292 unsigned ImageDecoder::frameBytesAtIndex Source/WebCore/platform/image-decoders/ImageDecoder.cpp_sec5
286
    if (m_frameBufferCache.size() <= index)
271
    if (m_frameBufferCache.size() <= index)
287
        return 0;
272
        return 0;
288
    // FIXME: Use the dimension of the requested frame.
273
    // FIXME: Use the dimension of the requested frame.
289
    return m_size.area() * sizeof(ImageFrame::PixelData);
274
    return m_size.area() * sizeof(RGBA32);
290
}
275
}
291
276
292
float ImageDecoder::frameDurationAtIndex(size_t index)
277
float ImageDecoder::frameDurationAtIndex(size_t index)
- Source/WebCore/platform/image-decoders/ImageDecoder.h -118 / +27 lines
Lines 28-35 Source/WebCore/platform/image-decoders/ImageDecoder.h_sec1
28
28
29
#pragma once
29
#pragma once
30
30
31
#include "IntRect.h"
31
#include "ImageBackingStore.h"
32
#include "ImageSource.h"
32
#include "ImageSource.h"
33
#include "IntRect.h"
34
#include "IntSize.h"
33
#include "PlatformScreen.h"
35
#include "PlatformScreen.h"
34
#include "SharedBuffer.h"
36
#include "SharedBuffer.h"
35
#include <wtf/Assertions.h>
37
#include <wtf/Assertions.h>
Lines 57-63 using ColorProfile = Vector<char>; Source/WebCore/platform/image-decoders/ImageDecoder.h_sec2
57
            DisposeOverwritePrevious  // Clear frame to previous framebuffer
59
            DisposeOverwritePrevious  // Clear frame to previous framebuffer
58
                                      // contents
60
                                      // contents
59
        };
61
        };
60
        typedef unsigned PixelData;
61
62
62
        ImageFrame();
63
        ImageFrame();
63
64
Lines 72-223 using ColorProfile = Vector<char>; Source/WebCore/platform/image-decoders/ImageDecoder.h_sec3
72
        void zeroFillPixelData();
73
        void zeroFillPixelData();
73
        void zeroFillFrameRect(const IntRect&);
74
        void zeroFillFrameRect(const IntRect&);
74
75
75
        // Makes this frame have an independent copy of the provided image's
76
        // pixel data, so that modifications in one frame are not reflected in
77
        // the other.  Returns whether the copy succeeded.
78
        bool copyBitmapData(const ImageFrame&);
79
80
        // Copies the pixel data at [(startX, startY), (endX, startY)) to the
76
        // Copies the pixel data at [(startX, startY), (endX, startY)) to the
81
        // same X-coordinates on each subsequent row up to but not including
77
        // same X-coordinates on each subsequent row up to but not including
82
        // endY.
78
        // endY.
83
        void copyRowNTimes(int startX, int endX, int startY, int endY)
79
        void copyRowNTimes(int startX, int endX, int startY, int endY)
84
        {
80
        {
85
            ASSERT(startX < width());
81
            m_backingStore->repeatFirstRow(IntRect(startX, startY, endX -startX , endY - startY));
86
            ASSERT(endX <= width());
87
            ASSERT(startY < height());
88
            ASSERT(endY <= height());
89
            const int rowBytes = (endX - startX) * sizeof(PixelData);
90
            const PixelData* const startAddr = getAddr(startX, startY);
91
            for (int destY = startY + 1; destY < endY; ++destY)
92
                memcpy(getAddr(startX, destY), startAddr, rowBytes);
93
        }
82
        }
94
83
95
        // Allocates space for the pixel data.  Must be called before any pixels
84
        // Allocates space for the pixel data.  Must be called before any pixels
96
        // are written.  Must only be called once.  Returns whether allocation
85
        // are written.  Must only be called once.  Returns whether allocation
97
        // succeeded.
86
        // succeeded.
98
        bool setSize(int newWidth, int newHeight);
87
        bool setSize(const IntSize&, bool premultiplyAlpha);
88
        IntSize size() const { return m_backingStore->size(); }
99
89
100
        // Returns a caller-owned pointer to the underlying native image data.
90
        // Returns a caller-owned pointer to the underlying native image data.
101
        // (Actual use: This pointer will be owned by BitmapImage and freed in
91
        // (Actual use: This pointer will be owned by BitmapImage and freed in
102
        // FrameData::clear()).
92
        // FrameData::clear()).
103
        NativeImagePtr asNewNativeImage() const;
93
        NativeImagePtr asNewNativeImage() const { return m_backingStore->image(); }
104
94
95
        inline ImageBackingStore* backingStore() const { return m_backingStore ? m_backingStore.get() : nullptr; }
96
        inline bool hasBackingStore() const { return backingStore(); }
97
        
105
        bool hasAlpha() const;
98
        bool hasAlpha() const;
106
        const IntRect& originalFrameRect() const { return m_originalFrameRect; }
99
        const IntRect& originalFrameRect() const { return m_backingStore ? m_backingStore->frameRect() : IntRect(); }
107
        FrameStatus status() const { return m_status; }
100
        FrameStatus status() const { return m_status; }
108
        unsigned duration() const { return m_duration; }
101
        unsigned duration() const { return m_duration; }
109
        FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
102
        FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
110
        bool premultiplyAlpha() const { return m_premultiplyAlpha; }
103
        bool premultiplyAlpha() const { return m_premultiplyAlpha; }
111
104
105
        void setBackingStore(const ImageBackingStore*);
106
        
112
        void setHasAlpha(bool alpha);
107
        void setHasAlpha(bool alpha);
113
        void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
108
        void setOriginalFrameRect(const IntRect&);
114
        void setStatus(FrameStatus status);
109
        void setStatus(FrameStatus status);
115
        void setDuration(unsigned duration) { m_duration = duration; }
110
        void setDuration(unsigned duration) { m_duration = duration; }
116
        void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
111
        void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
117
        void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
112
        void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
118
113
119
        inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
114
        inline RGBA32* getAddr(int x, int y)
120
        {
115
        {
121
            setRGBA(getAddr(x, y), r, g, b, a);
116
            return m_backingStore->at(x, y);
122
        }
117
        }
123
118
124
        inline PixelData* getAddr(int x, int y)
119
        inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
125
        {
126
            return m_bytes + (y * width()) + x;
127
        }
128
129
        inline bool hasPixelData() const
130
        {
131
            return m_bytes;
132
        }
133
134
        // Use fix point multiplier instead of integer division or floating point math.
135
        // This multipler produces exactly the same result for all values in range 0 - 255.
136
        static const unsigned fixPointShift = 24;
137
        static const unsigned fixPointMult = static_cast<unsigned>(1.0 / 255.0 * (1 << fixPointShift)) + 1;
138
        // Multiplies unsigned value by fixpoint value and converts back to unsigned.
139
        static unsigned fixPointUnsignedMultiply(unsigned fixed, unsigned v)
140
        {
120
        {
141
            return  (fixed * v) >> fixPointShift;
121
            m_backingStore->setRGBA(x, y, r, g, b, a);
142
        }
122
        }
143
123
        
144
        inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
124
        inline void setRGBA(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
145
        {
125
        {
146
            if (m_premultiplyAlpha && a < 255) {
126
            m_backingStore->setRGBA(dest, r, g, b, a);
147
                if (!a) {
148
                    *dest = 0;
149
                    return;
150
                }
151
152
                unsigned alphaMult = a * fixPointMult;
153
                r = fixPointUnsignedMultiply(r, alphaMult);
154
                g = fixPointUnsignedMultiply(g, alphaMult);
155
                b = fixPointUnsignedMultiply(b, alphaMult);
156
            }
157
            *dest = (a << 24 | r << 16 | g << 8 | b);
158
        }
127
        }
159
128
160
#if ENABLE(APNG)
129
#if ENABLE(APNG)
161
        static inline unsigned divide255(unsigned a)
130
        inline void overRGBA(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
162
        {
163
            return (a + (a >> 8) + 1) >> 8;
164
        }
165
166
        inline void overRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
167
        {
131
        {
168
            if (!a)
132
            m_backingStore->overRGBA(dest, r, g, b, a);
169
                return;
170
171
            if (a < 255) {
172
                unsigned aDest = ((*dest) >> 24) & 255;
173
                if (aDest) {
174
                    unsigned rDest = ((*dest) >> 16) & 255;
175
                    unsigned gDest = ((*dest) >> 8) & 255;
176
                    unsigned bDest = (*dest) & 255;
177
                    unsigned aAux = 255 - a;
178
                    if (!m_premultiplyAlpha) {
179
                        rDest = divide255(rDest * aDest);
180
                        gDest = divide255(gDest * aDest);
181
                        bDest = divide255(bDest * aDest);
182
                    }
183
                    r = divide255(r * a + rDest * aAux);
184
                    g = divide255(g * a + gDest * aAux);
185
                    b = divide255(b * a + bDest * aAux);
186
                    a += divide255(aDest * aAux);
187
                    if (!m_premultiplyAlpha) {
188
                        r = (r * 255 + a - 1) / a;
189
                        g = (g * 255 + a - 1) / a;
190
                        b = (b * 255 + a - 1) / a;
191
                    }
192
                } else if (m_premultiplyAlpha) {
193
                    r = divide255(r * a);
194
                    g = divide255(g * a);
195
                    b = divide255(b * a);
196
                }
197
            }
198
            *dest = (a << 24 | r << 16 | g << 8 | b);
199
        }
133
        }
200
#endif
134
#endif
201
135
202
    private:
136
    private:
203
        int width() const
137
        std::unique_ptr<ImageBackingStore> m_backingStore;
204
        {
205
            return m_size.width();
206
        }
207
208
        int height() const
209
        {
210
            return m_size.height();
211
        }
212
213
        Vector<PixelData> m_backingStore;
214
        PixelData* m_bytes; // The memory is backed by m_backingStore.
215
        IntSize m_size;
216
        bool m_hasAlpha;
138
        bool m_hasAlpha;
217
        IntRect m_originalFrameRect; // This will always just be the entire
218
                                     // buffer except for GIF frames whose
219
                                     // original rect was smaller than the
220
                                     // overall image size.
221
        FrameStatus m_status;
139
        FrameStatus m_status;
222
        unsigned m_duration;
140
        unsigned m_duration;
223
        FrameDisposalMethod m_disposalMethod;
141
        FrameDisposalMethod m_disposalMethod;
Lines 287-297 using ColorProfile = Vector<char>; Source/WebCore/platform/image-decoders/ImageDecoder.h_sec4
287
205
288
        // Returns whether the size is legal (i.e. not going to result in
206
        // Returns whether the size is legal (i.e. not going to result in
289
        // overflow elsewhere).  If not, marks decoding as failed.
207
        // overflow elsewhere).  If not, marks decoding as failed.
290
        virtual bool setSize(unsigned width, unsigned height)
208
        virtual bool setSize(const IntSize& size)
291
        {
209
        {
292
            if (isOverSize(width, height))
210
            if (ImageBackingStore::isOverSize(size))
293
                return setFailed();
211
                return setFailed();
294
            m_size = IntSize(width, height);
212
            m_size = size;
295
            m_sizeAvailable = true;
213
            m_sizeAvailable = true;
296
            return true;
214
            return true;
297
        }
215
        }
Lines 386-400 using ColorProfile = Vector<char>; Source/WebCore/platform/image-decoders/ImageDecoder.h_sec5
386
        ImageOrientation m_orientation;
304
        ImageOrientation m_orientation;
387
305
388
    private:
306
    private:
389
        // Some code paths compute the size of the image as "width * height * 4"
390
        // and return it as a (signed) int.  Avoid overflow.
391
        static bool isOverSize(unsigned width, unsigned height)
392
        {
393
            unsigned long long total_size = static_cast<unsigned long long>(width)
394
                                          * static_cast<unsigned long long>(height);
395
            return total_size > ((1 << 29) - 1);
396
        }
397
398
        IntSize m_size;
307
        IntSize m_size;
399
        bool m_sizeAvailable { false };
308
        bool m_sizeAvailable { false };
400
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
309
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp -3 lines
Lines 86-94 bool BMPImageReader::decodeBMP(bool only Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp_sec1
86
        // these 0s could actually show through.
86
        // these 0s could actually show through.
87
        m_buffer->setHasAlpha(false);
87
        m_buffer->setHasAlpha(false);
88
88
89
        // For BMPs, the frame always fills the entire image.
90
        m_buffer->setOriginalFrameRect(IntRect(IntPoint(), m_parent->size()));
91
92
        if (!m_isTopDown)
89
        if (!m_isTopDown)
93
            m_coord.setY(m_parent->size().height() - 1);
90
            m_coord.setY(m_parent->size().height() - 1);
94
    }
91
    }
- Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp +40 lines
Line 0 Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp_sec1
1
/*
2
 * Copyright (C) 2016 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "ImageBackingStore.h"
28
29
#include <cairo.h>
30
31
namespace WebCore {
32
33
NativeImagePtr ImageBackingStore::image() const
34
{
35
    return adoptRef(cairo_image_surface_create_for_data(
36
        reinterpret_cast<unsigned char*>(const_cast<RGBA32*>(m_pixelsPtr)),
37
        CAIRO_FORMAT_ARGB32, size().width(), size().height(), size().width() * sizeof(RGBA32)));
38
}
39
40
} // namespace WebCore
- Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp -2 / +2 lines
Lines 213-222 bool GIFImageDecoder::haveDecodedRow(uns Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp_sec1
213
213
214
    // Initialize the frame if necessary.
214
    // Initialize the frame if necessary.
215
    ImageFrame& buffer = m_frameBufferCache[frameIndex];
215
    ImageFrame& buffer = m_frameBufferCache[frameIndex];
216
    if (((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex)) || !buffer.hasPixelData())
216
    if (((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex)) || !buffer.hasBackingStore())
217
        return false;
217
        return false;
218
218
219
    ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin);
219
    RGBA32* currentAddress = buffer.getAddr(xBegin, yBegin);
220
    // Write one row's worth of data into the frame.  
220
    // Write one row's worth of data into the frame.  
221
    for (int x = xBegin; x < xEnd; ++x) {
221
    for (int x = xBegin; x < xEnd; ++x) {
222
        const unsigned char sourceValue = rowBuffer[(m_scaled ? m_scaledColumns[x] : x) - frameContext->xOffset];
222
        const unsigned char sourceValue = rowBuffer[(m_scaled ? m_scaledColumns[x] : x) - frameContext->xOffset];
- Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp -5 / +2 lines
Lines 551-557 bool JPEGImageDecoder::setFailed() Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp_sec1
551
}
551
}
552
552
553
template <J_COLOR_SPACE colorSpace>
553
template <J_COLOR_SPACE colorSpace>
554
void setPixel(ImageFrame& buffer, ImageFrame::PixelData* currentAddress, JSAMPARRAY samples, int column)
554
void setPixel(ImageFrame& buffer, RGBA32* currentAddress, JSAMPARRAY samples, int column)
555
{
555
{
556
    JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4);
556
    JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4);
557
557
Lines 594-600 bool JPEGImageDecoder::outputScanlines(I Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp_sec2
594
        if (destY < 0)
594
        if (destY < 0)
595
            continue;
595
            continue;
596
596
597
        ImageFrame::PixelData* currentAddress = buffer.getAddr(0, destY);
597
        RGBA32* currentAddress = buffer.getAddr(0, destY);
598
        for (int x = 0; x < width; ++x) {
598
        for (int x = 0; x < width; ++x) {
599
            setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x);
599
            setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x);
600
            ++currentAddress;
600
            ++currentAddress;
Lines 623-631 bool JPEGImageDecoder::outputScanlines() Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp_sec3
623
        // The buffer is transparent outside the decoded area while the image is
623
        // The buffer is transparent outside the decoded area while the image is
624
        // loading. The completed image will be marked fully opaque in jpegComplete().
624
        // loading. The completed image will be marked fully opaque in jpegComplete().
625
        buffer.setHasAlpha(true);
625
        buffer.setHasAlpha(true);
626
627
        // For JPEGs, the frame always fills the entire image.
628
        buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
629
    }
626
    }
630
627
631
    jpeg_decompress_struct* info = m_reader->info();
628
    jpeg_decompress_struct* info = m_reader->info();
- Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp -8 / +6 lines
Lines 411-429 void PNGImageDecoder::headerAvailable() Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp_sec1
411
    }
411
    }
412
}
412
}
413
413
414
static inline void setPixelRGB(ImageFrame::PixelData* dest, png_bytep pixel)
414
static inline void setPixelRGB(RGBA32* dest, png_bytep pixel)
415
{
415
{
416
    *dest = 0xFF000000U | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
416
    *dest = 0xFF000000U | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
417
}
417
}
418
418
419
static inline void setPixelRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
419
static inline void setPixelRGBA(RGBA32* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
420
{
420
{
421
    unsigned char a = pixel[3];
421
    unsigned char a = pixel[3];
422
    *dest = a << 24 | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
422
    *dest = a << 24 | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
423
    nonTrivialAlphaMask |= (255 - a);
423
    nonTrivialAlphaMask |= (255 - a);
424
}
424
}
425
425
426
static inline void setPixelPremultipliedRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
426
static inline void setPixelPremultipliedRGBA(RGBA32* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
427
{
427
{
428
    unsigned char a = pixel[3];
428
    unsigned char a = pixel[3];
429
    unsigned char r = fastDivideBy255(pixel[0] * a);
429
    unsigned char r = fastDivideBy255(pixel[0] * a);
Lines 471-478 void PNGImageDecoder::rowAvailable(unsig Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp_sec2
471
            initFrameBuffer(m_currentFrame);
471
            initFrameBuffer(m_currentFrame);
472
        else
472
        else
473
#endif
473
#endif
474
        // For PNGs, the frame always fills the entire image.
475
        buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
476
    }
474
    }
477
475
478
    /* libpng comments (here to explain what follows).
476
    /* libpng comments (here to explain what follows).
Lines 531-537 void PNGImageDecoder::rowAvailable(unsig Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp_sec3
531
    }
529
    }
532
530
533
    // Write the decoded row pixels to the frame buffer.
531
    // Write the decoded row pixels to the frame buffer.
534
    ImageFrame::PixelData* address = buffer.getAddr(0, y);
532
    RGBA32* address = buffer.getAddr(0, y);
535
    int width = scaledSize().width();
533
    int width = scaledSize().width();
536
    unsigned char nonTrivialAlphaMask = 0;
534
    unsigned char nonTrivialAlphaMask = 0;
537
535
Lines 854-860 void PNGImageDecoder::frameComplete() Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp_sec4
854
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
852
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
855
        for (int y = 0; y < rect.maxY() - rect.y(); ++y) {
853
        for (int y = 0; y < rect.maxY() - rect.y(); ++y) {
856
            png_bytep row = interlaceBuffer + (m_scaled ? m_scaledRows[y] : y) * colorChannels * size().width();
854
            png_bytep row = interlaceBuffer + (m_scaled ? m_scaledRows[y] : y) * colorChannels * size().width();
857
            ImageFrame::PixelData* address = buffer.getAddr(rect.x(), y + rect.y());
855
            RGBA32* address = buffer.getAddr(rect.x(), y + rect.y());
858
            for (int x = 0; x < rect.maxX() - rect.x(); ++x) {
856
            for (int x = 0; x < rect.maxX() - rect.x(); ++x) {
859
                png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
857
                png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
860
                unsigned alpha = hasAlpha ? pixel[3] : 255;
858
                unsigned alpha = hasAlpha ? pixel[3] : 255;
Lines 870-876 void PNGImageDecoder::frameComplete() Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp_sec5
870
        png_bytep row = interlaceBuffer;
868
        png_bytep row = interlaceBuffer;
871
        for (int y = rect.y(); y < rect.maxY(); ++y, row += colorChannels * size().width()) {
869
        for (int y = rect.y(); y < rect.maxY(); ++y, row += colorChannels * size().width()) {
872
            png_bytep pixel = row;
870
            png_bytep pixel = row;
873
            ImageFrame::PixelData* address = buffer.getAddr(rect.x(), y);
871
            RGBA32* address = buffer.getAddr(rect.x(), y);
874
            for (int x = rect.x(); x < rect.maxX(); ++x, pixel += colorChannels) {
872
            for (int x = rect.x(); x < rect.maxX(); ++x, pixel += colorChannels) {
875
                unsigned alpha = hasAlpha ? pixel[3] : 255;
873
                unsigned alpha = hasAlpha ? pixel[3] : 255;
876
                nonTrivialAlpha |= alpha < 255;
874
                nonTrivialAlpha |= alpha < 255;
- Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp -2 / +1 lines
Lines 132-145 bool WEBPImageDecoder::decode(bool onlyS Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp_sec1
132
            return setFailed();
132
            return setFailed();
133
        buffer.setStatus(ImageFrame::FramePartial);
133
        buffer.setStatus(ImageFrame::FramePartial);
134
        buffer.setHasAlpha(m_hasAlpha);
134
        buffer.setHasAlpha(m_hasAlpha);
135
        buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
136
    }
135
    }
137
136
138
    if (!m_decoder) {
137
    if (!m_decoder) {
139
        WEBP_CSP_MODE mode = outputMode(m_hasAlpha);
138
        WEBP_CSP_MODE mode = outputMode(m_hasAlpha);
140
        if (!m_premultiplyAlpha)
139
        if (!m_premultiplyAlpha)
141
            mode = outputMode(false);
140
            mode = outputMode(false);
142
        int rowStride = size().width() * sizeof(ImageFrame::PixelData);
141
        int rowStride = size().width() * sizeof(RGBA32);
143
        uint8_t* output = reinterpret_cast<uint8_t*>(buffer.getAddr(0, 0));
142
        uint8_t* output = reinterpret_cast<uint8_t*>(buffer.getAddr(0, 0));
144
        int outputSize = size().height() * rowStride;
143
        int outputSize = size().height() * rowStride;
145
        m_decoder = WebPINewRGB(mode, output, outputSize, rowStride);
144
        m_decoder = WebPINewRGB(mode, output, outputSize, rowStride);

Return to Bug 159679