Source/WebCore/ChangeLog

 12016-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::ImageFrame::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 (WebCore::BMPImageReader::processInfoHeader):
 72 * platform/image-decoders/cairo/ImageBackingStoreCairo.cpp: Added.
 73 (WebCore::ImageBackingStore::image):
 74 * platform/image-decoders/gif/GIFImageDecoder.cpp:
 75 (WebCore::GIFImageDecoder::setSize):
 76 (WebCore::GIFImageDecoder::haveDecodedRow):
 77 (WebCore::GIFImageDecoder::initFrameBuffer):
 78 * platform/image-decoders/gif/GIFImageDecoder.h:
 79 * platform/image-decoders/gif/GIFImageReader.cpp:
 80 (GIFImageReader::parse):
 81 * platform/image-decoders/ico/ICOImageDecoder.cpp:
 82 (WebCore::ICOImageDecoder::setSize):
 83 (WebCore::ICOImageDecoder::processDirectoryEntries): Deleted.
 84 * platform/image-decoders/ico/ICOImageDecoder.h:
 85 * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
 86 (WebCore::JPEGImageReader::decode):
 87 (WebCore::JPEGImageDecoder::setSize):
 88 (WebCore::setPixel):
 89 (WebCore::JPEGImageDecoder::outputScanlines):
 90 * platform/image-decoders/jpeg/JPEGImageDecoder.h:
 91 * platform/image-decoders/png/PNGImageDecoder.cpp:
 92 (WebCore::PNGImageDecoder::setSize):
 93 (WebCore::PNGImageDecoder::headerAvailable):
 94 (WebCore::setPixelRGB):
 95 (WebCore::setPixelRGBA):
 96 (WebCore::setPixelPremultipliedRGBA):
 97 (WebCore::PNGImageDecoder::rowAvailable):
 98 (WebCore::PNGImageDecoder::initFrameBuffer):
 99 (WebCore::PNGImageDecoder::frameComplete):
 100 * platform/image-decoders/png/PNGImageDecoder.h:
 101 * platform/image-decoders/webp/WEBPImageDecoder.cpp:
 102 (WebCore::WEBPImageDecoder::decode):
 103
11042016-09-09 Alex Christensen <achristensen@webkit.org>
2105
3106 URLParser should convert ASCII hosts to lowercase
205774

Source/WebCore/PlatformEfl.cmake

@@list(APPEND WebCore_SOURCES
183183 platform/graphics/x11/PlatformDisplayX11.cpp
184184 platform/graphics/x11/XUniqueResource.cpp
185185
 186 platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
186187 platform/image-encoders/JPEGImageEncoder.cpp
187188
188  platform/image-decoders/cairo/ImageDecoderCairo.cpp
189 
190189 platform/network/efl/NetworkStateNotifierEfl.cpp
191190
192191 platform/network/soup/AuthenticationChallengeSoup.cpp
205684

Source/WebCore/PlatformGTK.cmake

@@list(APPEND WebCore_SOURCES
155155 platform/gtk/TemporaryLinkStubs.cpp
156156 platform/gtk/UserAgentGtk.cpp
157157
158  platform/image-decoders/cairo/ImageDecoderCairo.cpp
 158 platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
159159
160160 platform/mediastream/gtk/SDPProcessorScriptResourceGtk.cpp
161161
205684

Source/WebCore/PlatformWinCairo.cmake

@@list(APPEND WebCore_SOURCES
4646 platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
4747 platform/graphics/win/SimpleFontDataCairoWin.cpp
4848
49  platform/image-decoders/cairo/ImageDecoderCairo.cpp
 49 platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
5050
5151 platform/network/NetworkStorageSessionStub.cpp
5252
205684

Source/WebCore/WebCore.xcodeproj/project.pbxproj

22752275 555B87EC1CAAF0AB00349425 /* ImageDecoderCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */; };
22762276 555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */; };
22772277 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, ); }; };
22782279 5709E8CD1D413D47003244AC /* WebKitSubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */; };
22792280 5709E8CE1D413D5B003244AC /* JSWebKitSubtleCryptoCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F661807460800132674 /* JSWebKitSubtleCryptoCustom.cpp */; };
22802281 5709E8CF1D413D9A003244AC /* WebKitSubtleCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 5709E8CB1D413CE3003244AC /* WebKitSubtleCrypto.h */; };

92919292 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = "<group>"; };
92929293 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = "<group>"; };
92939294 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>"; };
92949296 55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; };
92959297 5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitSubtleCrypto.cpp; sourceTree = "<group>"; };
92969298 5709E8CB1D413CE3003244AC /* WebKitSubtleCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitSubtleCrypto.h; sourceTree = "<group>"; };

2076920771 379919941200DDF400EA041C /* WOFFFileFormat.cpp */,
2077020772 379919951200DDF400EA041C /* WOFFFileFormat.h */,
2077120773 55A336F61D8209F40022C4C7 /* NativeImage.h */,
 20774 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */,
2077220775 );
2077320776 path = graphics;
2077420777 sourceTree = "<group>";

2633926342 582CB0531A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h in Headers */,
2634026343 C5A1EA7D152BCF08004D00B6 /* SimplifyMarkupCommand.h in Headers */,
2634126344 572A7F211C6E5719009C6149 /* SimulatedClick.h in Headers */,
 26345 55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */,
2634226346 31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
2634326347 FD00D7A514A3F61900734011 /* SincResampler.h in Headers */,
2634426348 51327D6011A33A2B004F9D65 /* SinkDocument.h in Headers */,
205684

Source/WebCore/platform/graphics/Color.cpp

@@const RGBA32 Color::transparent;
4949static const RGBA32 lightenedBlack = 0xFF545454;
5050static const RGBA32 darkenedWhite = 0xFFABABAB;
5151
 52static inline unsigned premultipliedChannel(unsigned c, unsigned a)
 53{
 54 return fastDivideBy255(c * a + 254);
 55}
 56
 57static inline unsigned unpremultipliedChannel(unsigned c, unsigned a)
 58{
 59 return (fastMultiplyBy255(c) + a - 1) / a;
 60}
 61
5262RGBA32 makeRGB(int r, int g, int b)
5363{
5464 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));

@@RGBA32 makeRGBA(int r, int g, int b, int
5969 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));
6070}
6171
 72RGBA32 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
 77RGBA32 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
6282static int colorFloatToRGBAByte(float f)
6383{
6484 // We use lroundf and 255 instead of nextafterf(256, 0) to match CG's rounding

@@void Color::getHSV(double& hue, double&
482502Color colorFromPremultipliedARGB(RGBA32 pixelColor)
483503{
484504 int alpha = alphaChannel(pixelColor);
485  if (alpha && alpha < 255) {
486  return Color::createUnchecked(
487  redChannel(pixelColor) * 255 / alpha,
488  greenChannel(pixelColor) * 255 / alpha,
489  blueChannel(pixelColor) * 255 / alpha,
490  alpha);
491  } else
492  return Color(pixelColor);
 505 if (alpha && alpha < 255)
 506 pixelColor = makeUnPremultipliedRGBA(redChannel(pixelColor), greenChannel(pixelColor), blueChannel(pixelColor), alpha);
 507 return Color(pixelColor);
493508}
494509
495510RGBA32 premultipliedARGBFromColor(const Color& color)

@@RGBA32 premultipliedARGBFromColor(const
497512 unsigned pixelColor;
498513
499514 unsigned alpha = color.alpha();
500  if (alpha < 255) {
501  pixelColor = Color::createUnchecked(
502  fastDivideBy255(color.red() * alpha + 254),
503  fastDivideBy255(color.green() * alpha + 254),
504  fastDivideBy255(color.blue() * alpha + 254),
505  alpha).rgb();
506  } else
507  pixelColor = color.rgb();
 515 if (alpha < 255)
 516 pixelColor = makePremultipliedRGBA(color.red(), color.green(), color.blue(), alpha);
 517 else
 518 pixelColor = color.rgb();
508519
509520 return pixelColor;
510521}
205684

Source/WebCore/platform/graphics/Color.h

@@typedef unsigned RGBA32; // Deprecated:
5555WEBCORE_EXPORT RGBA32 makeRGB(int r, int g, int b);
5656WEBCORE_EXPORT RGBA32 makeRGBA(int r, int g, int b, int a);
5757
 58RGBA32 makePremultipliedRGBA(int r, int g, int b, int a);
 59RGBA32 makeUnPremultipliedRGBA(int r, int g, int b, int a);
 60
5861WEBCORE_EXPORT RGBA32 colorWithOverrideAlpha(RGBA32 color, float overrideAlpha);
5962WEBCORE_EXPORT RGBA32 colorWithOverrideAlpha(RGBA32 color, Optional<float> overrideAlpha);
6063

@@Color blend(const Color& from, const Col
218221
219222int differenceSquared(const Color&, const Color&);
220223
 224uint16_t fastMultiplyBy255(uint16_t value);
221225uint16_t fastDivideBy255(uint16_t);
222226
223227#if USE(CG)

@@inline uint8_t roundAndClampColorChannel
290294 return std::max(0.f, std::min(255.f, std::round(value)));
291295}
292296
 297inline uint16_t fastMultiplyBy255(uint16_t value)
 298{
 299 return (value << 8) - value;
 300}
 301
293302inline uint16_t fastDivideBy255(uint16_t value)
294303{
295304 // While this is an approximate algorithm for division by 255, it gives perfectly accurate results for 16-bit values.
205684

Source/WebCore/platform/graphics/ImageBackingStore.h

 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 "NativeImage.h"
 32
 33#include <wtf/Vector.h>
 34
 35namespace WebCore {
 36
 37class ImageBackingStore {
 38public:
 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
 182private:
 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}
nonexistent

Source/WebCore/platform/graphics/cg/NativeImageCG.cpp

@@IntSize nativeImageSize(const NativeImag
4747 return image ? IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get())) : IntSize();
4848}
4949
50 bool nativeImageHasAlpha(const NativeImagePtr&)
 50bool nativeImageHasAlpha(const NativeImagePtr& image)
5151{
52  // FIXME: Answer correctly the question: does the CGImageRef have alpha channnel?
53  return true;
 52 CGImageAlphaInfo info = CGImageGetAlphaInfo(image.get());
 53 return (info >= kCGImageAlphaPremultipliedLast) && (info <= kCGImageAlphaFirst);
5454}
5555
5656Color nativeImageSinglePixelSolidColor(const NativeImagePtr& image)
205684

Source/WebCore/platform/image-decoders/ImageDecoder.cpp

@@ImageFrame& ImageFrame::operator=(const
141141 if (this == &other)
142142 return *this;
143143
144  copyBitmapData(other);
145  setOriginalFrameRect(other.originalFrameRect());
 144 setBackingStore(other.backingStore());
 145 setHasAlpha(other.m_hasAlpha);
146146 setStatus(other.status());
147147 setDuration(other.duration());
148148 setDisposalMethod(other.disposalMethod());

@@ImageFrame& ImageFrame::operator=(const
152152
153153void ImageFrame::clearPixelData()
154154{
155  m_backingStore.clear();
156  m_bytes = 0;
 155 m_backingStore = nullptr;
157156 m_status = FrameEmpty;
158157 // NOTE: Do not reset other members here; clearFrameBufferCache() calls this
159158 // to free the bitmap data, but other functions like initFrameBuffer() and

@@void ImageFrame::clearPixelData()
163162
164163void ImageFrame::zeroFillPixelData()
165164{
166  memset(m_bytes, 0, m_size.width() * m_size.height() * sizeof(PixelData));
 165 m_backingStore->clear();
167166 m_hasAlpha = true;
168167}
169168
170169void ImageFrame::zeroFillFrameRect(const IntRect& rect)
171170{
172  ASSERT(IntRect(IntPoint(), m_size).contains(rect));
173 
174171 if (rect.isEmpty())
175172 return;
176173
177  size_t rectWidthInBytes = rect.width() * sizeof(PixelData);
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 
 174 m_backingStore->clearRect(rect);
184175 setHasAlpha(true);
185176}
186177
187 bool ImageFrame::copyBitmapData(const ImageFrame& other)
 178void ImageFrame::setBackingStore(const ImageBackingStore* backingStore)
188179{
189  if (this == &other)
190  return true;
191 
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;
 180 if (m_backingStore && backingStore == m_backingStore.get())
 181 return;
 182 m_backingStore = backingStore ? ImageBackingStore::create(*backingStore) : nullptr;
197183}
198184
199 bool ImageFrame::setSize(int newWidth, int newHeight)
 185bool ImageFrame::setSize(const IntSize& size)
200186{
201  ASSERT(!width() && !height());
202  size_t backingStoreSize = newWidth * newHeight;
203  if (!m_backingStore.tryReserveCapacity(backingStoreSize))
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;
 187 ASSERT(!m_backingStore);
 188 m_backingStore = ImageBackingStore::create(size, m_premultiplyAlpha);
 189 return m_backingStore;
211190}
212191
213192bool ImageFrame::hasAlpha() const

@@void ImageFrame::setHasAlpha(bool alpha)
220199 m_hasAlpha = alpha;
221200}
222201
 202void ImageFrame::setOriginalFrameRect(const IntRect& frameRect)
 203{
 204 if (m_backingStore)
 205 m_backingStore->setFrameRect(frameRect);
 206}
 207
223208void ImageFrame::setStatus(FrameStatus status)
224209{
225210 m_status = status;

@@unsigned ImageDecoder::frameBytesAtIndex
286271 if (m_frameBufferCache.size() <= index)
287272 return 0;
288273 // FIXME: Use the dimension of the requested frame.
289  return m_size.area() * sizeof(ImageFrame::PixelData);
 274 return m_size.area() * sizeof(RGBA32);
290275}
291276
292277float ImageDecoder::frameDurationAtIndex(size_t index)
205684

Source/WebCore/platform/image-decoders/ImageDecoder.h

2828
2929#pragma once
3030
31 #include "IntRect.h"
 31#include "ImageBackingStore.h"
3232#include "ImageSource.h"
 33#include "IntRect.h"
 34#include "IntSize.h"
3335#include "PlatformScreen.h"
3436#include "SharedBuffer.h"
3537#include <wtf/Assertions.h>

@@using ColorProfile = Vector<char>;
5759 DisposeOverwritePrevious // Clear frame to previous framebuffer
5860 // contents
5961 };
60  typedef unsigned PixelData;
6162
6263 ImageFrame();
6364

@@using ColorProfile = Vector<char>;
7273 void zeroFillPixelData();
7374 void zeroFillFrameRect(const IntRect&);
7475
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 
8076 // Copies the pixel data at [(startX, startY), (endX, startY)) to the
8177 // same X-coordinates on each subsequent row up to but not including
8278 // endY.
8379 void copyRowNTimes(int startX, int endX, int startY, int endY)
8480 {
85  ASSERT(startX < width());
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);
 81 m_backingStore->repeatFirstRow(IntRect(startX, startY, endX -startX , endY - startY));
9382 }
9483
9584 // Allocates space for the pixel data. Must be called before any pixels
9685 // are written. Must only be called once. Returns whether allocation
9786 // succeeded.
98  bool setSize(int newWidth, int newHeight);
 87 bool setSize(const IntSize&);
 88 IntSize size() const { return m_backingStore->size(); }
9989
10090 // Returns a caller-owned pointer to the underlying native image data.
10191 // (Actual use: This pointer will be owned by BitmapImage and freed in
10292 // FrameData::clear()).
103  NativeImagePtr asNewNativeImage() const;
 93 NativeImagePtr asNewNativeImage() const { return m_backingStore->image(); }
10494
 95 inline ImageBackingStore* backingStore() const { return m_backingStore ? m_backingStore.get() : nullptr; }
 96 inline bool hasBackingStore() const { return backingStore(); }
 97
10598 bool hasAlpha() const;
106  const IntRect& originalFrameRect() const { return m_originalFrameRect; }
 99 IntRect originalFrameRect() const { return m_backingStore ? m_backingStore->frameRect() : IntRect(); }
107100 FrameStatus status() const { return m_status; }
108101 unsigned duration() const { return m_duration; }
109102 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
110103 bool premultiplyAlpha() const { return m_premultiplyAlpha; }
111104
 105 void setBackingStore(const ImageBackingStore*);
 106
112107 void setHasAlpha(bool alpha);
113  void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
 108 void setOriginalFrameRect(const IntRect&);
114109 void setStatus(FrameStatus status);
115110 void setDuration(unsigned duration) { m_duration = duration; }
116111 void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
117112 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
118113
119  inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
120  {
121  setRGBA(getAddr(x, y), r, g, b, a);
122  }
123 
124  inline PixelData* getAddr(int x, int y)
 114 inline RGBA32* getAddr(int x, int y)
125115 {
126  return m_bytes + (y * width()) + x;
 116 return m_backingStore->at(x, y);
127117 }
128118
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)
 119 inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
140120 {
141  return (fixed * v) >> fixPointShift;
 121 m_backingStore->setRGBA(x, y, r, g, b, a);
142122 }
143123
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)
145125 {
146  if (m_premultiplyAlpha && a < 255) {
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);
 126 m_backingStore->setRGBA(dest, r, g, b, a);
158127 }
159128
160129#if ENABLE(APNG)
161  static inline unsigned divide255(unsigned a)
 130 inline void overRGBA(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
162131 {
163  return (a + (a >> 8) + 1) >> 8;
164  }
165 
166  inline void overRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
167  {
168  if (!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);
 132 m_backingStore->overRGBA(dest, r, g, b, a);
199133 }
200134#endif
201135
202136 private:
203  int width() const
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;
 137 std::unique_ptr<ImageBackingStore> m_backingStore;
216138 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.
221139 FrameStatus m_status;
222140 unsigned m_duration;
223141 FrameDisposalMethod m_disposalMethod;

@@using ColorProfile = Vector<char>;
287205
288206 // Returns whether the size is legal (i.e. not going to result in
289207 // overflow elsewhere). If not, marks decoding as failed.
290  virtual bool setSize(unsigned width, unsigned height)
 208 virtual bool setSize(const IntSize& size)
291209 {
292  if (isOverSize(width, height))
 210 if (ImageBackingStore::isOverSize(size))
293211 return setFailed();
294  m_size = IntSize(width, height);
 212 m_size = size;
295213 m_sizeAvailable = true;
296214 return true;
297215 }

@@using ColorProfile = Vector<char>;
386304 ImageOrientation m_orientation;
387305
388306 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 
398307 IntSize m_size;
399308 bool m_sizeAvailable { false };
400309#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
205684

Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp

@@bool BMPImageReader::decodeBMP(bool only
7878 // Initialize the framebuffer if needed.
7979 ASSERT(m_buffer); // Parent should set this before asking us to decode!
8080 if (m_buffer->status() == ImageFrame::FrameEmpty) {
81  if (!m_buffer->setSize(m_parent->size().width(), m_parent->size().height()))
 81 if (!m_buffer->setSize(m_parent->size()))
8282 return m_parent->setFailed(); // Unable to allocate.
8383 m_buffer->setStatus(ImageFrame::FramePartial);
8484 // setSize() calls eraseARGB(), which resets the alpha flag, so we force

@@bool BMPImageReader::decodeBMP(bool only
8686 // these 0s could actually show through.
8787 m_buffer->setHasAlpha(false);
8888
89  // For BMPs, the frame always fills the entire image.
90  m_buffer->setOriginalFrameRect(IntRect(IntPoint(), m_parent->size()));
91 
9289 if (!m_isTopDown)
9390 m_coord.setY(m_parent->size().height() - 1);
9491 }

@@bool BMPImageReader::processInfoHeader()
171168 return m_parent->setFailed();
172169
173170 // Set our size.
174  if (!m_parent->setSize(m_infoHeader.biWidth, m_infoHeader.biHeight))
 171 if (!m_parent->setSize(IntSize(m_infoHeader.biWidth, m_infoHeader.biHeight)))
175172 return false;
176173
177174 // For paletted images, bitmaps can set biClrUsed to 0 to mean "all
205684

Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp

 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
 31namespace WebCore {
 32
 33NativeImagePtr 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
nonexistent

Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp

@@bool GIFImageDecoder::isSizeAvailable()
6060 return ImageDecoder::isSizeAvailable();
6161}
6262
63 bool GIFImageDecoder::setSize(unsigned width, unsigned height)
 63bool GIFImageDecoder::setSize(const IntSize& size)
6464{
65  if (ImageDecoder::isSizeAvailable() && size() == IntSize(width, height))
 65 if (ImageDecoder::isSizeAvailable() && this->size() == size)
6666 return true;
6767
68  if (!ImageDecoder::setSize(width, height))
 68 if (!ImageDecoder::setSize(size))
6969 return false;
7070
7171 prepareScaleDataIfNecessary();

@@bool GIFImageDecoder::haveDecodedRow(uns
213213
214214 // Initialize the frame if necessary.
215215 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())
217217 return false;
218218
219  ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin);
 219 RGBA32* currentAddress = buffer.getAddr(xBegin, yBegin);
220220 // Write one row's worth of data into the frame.
221221 for (int x = xBegin; x < xEnd; ++x) {
222222 const unsigned char sourceValue = rowBuffer[(m_scaled ? m_scaledColumns[x] : x) - frameContext->xOffset];

@@bool GIFImageDecoder::initFrameBuffer(un
361361
362362 if (!frameIndex) {
363363 // This is the first frame, so we're not relying on any previous data.
364  if (!buffer->setSize(scaledSize().width(), scaledSize().height()))
 364 if (!buffer->setSize(scaledSize()))
365365 return setFailed();
366366 } else {
367367 // The starting state for this frame depends on the previous frame's

@@bool GIFImageDecoder::initFrameBuffer(un
387387 } else {
388388 // We want to clear the previous frame to transparent, without
389389 // affecting pixels in the image outside of the frame.
390  const IntRect& prevRect = prevBuffer->originalFrameRect();
 390 IntRect prevRect = prevBuffer->originalFrameRect();
391391 const IntSize& bufferSize = scaledSize();
392392 if (!frameIndex || prevRect.contains(IntRect(IntPoint(), scaledSize()))) {
393393 // Clearing the first frame, or a frame the size of the whole
394394 // image, results in a completely empty image.
395  if (!buffer->setSize(bufferSize.width(), bufferSize.height()))
 395 if (!buffer->setSize(bufferSize))
396396 return setFailed();
397397 } else {
398398 // Copy the whole previous buffer, then clear just its frame.
205684

Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h

@@namespace WebCore {
4444 String filenameExtension() const override { return "gif"; }
4545 void setData(SharedBuffer& data, bool allDataReceived) override;
4646 bool isSizeAvailable() override;
47  bool setSize(unsigned width, unsigned height) override;
 47 bool setSize(const IntSize&) override;
4848 size_t frameCount() override;
4949 int repetitionCount() const override;
5050 ImageFrame* frameBufferAtIndex(size_t index) override;
205684

Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp

@@bool GIFImageReader::parse(size_t dataPo
447447
448448 // CALLBACK: Inform the decoderplugin of our size.
449449 // Note: A subsequent frame might have dimensions larger than the "screen" dimensions.
450  if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight))
 450 if (m_client && !m_client->setSize(WebCore::IntSize(m_screenWidth, m_screenHeight)))
451451 return false;
452452
453453 m_screenBgcolor = currentComponent[5];

@@bool GIFImageReader::parse(size_t dataPo
664664 yOffset = 0;
665665
666666 // CALLBACK: Inform the decoderplugin of our size.
667  if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight))
 667 if (m_client && !m_client->setSize(WebCore::IntSize(m_screenWidth, m_screenHeight)))
668668 return false;
669669 }
670670
205684

Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp

@@IntSize ICOImageDecoder::frameSizeAtInde
8888 return (index && (index < m_dirEntries.size())) ? m_dirEntries[index].m_size : size();
8989}
9090
91 bool ICOImageDecoder::setSize(unsigned width, unsigned height)
 91bool ICOImageDecoder::setSize(const IntSize& size)
9292{
9393 // The size calculated inside the BMPImageReader had better match the one in
9494 // the icon directory.
95  return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntSize(width, height) == m_frameSize) || setFailed());
 95 return m_frameSize.isEmpty() ? ImageDecoder::setSize(size) : (size == m_frameSize) || setFailed());
9696}
9797
9898size_t ICOImageDecoder::frameCount()

@@bool ICOImageDecoder::processDirectoryEn
279279 const IconDirectoryEntry& dirEntry = m_dirEntries.first();
280280 // Technically, this next call shouldn't be able to fail, since the width
281281 // and height here are each <= 256, and |m_frameSize| is empty.
282  return setSize(dirEntry.m_size.width(), dirEntry.m_size.height());
 282 return setSize(dirEntry.m_size);
283283}
284284
285285ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry()
205684

Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h

@@namespace WebCore {
4949 bool isSizeAvailable() override;
5050 IntSize size() override;
5151 IntSize frameSizeAtIndex(size_t, SubsamplingLevel) override;
52  bool setSize(unsigned width, unsigned height) override;
 52 bool setSize(const IntSize&) override;
5353 size_t frameCount() override;
5454 ImageFrame* frameBufferAtIndex(size_t) override;
5555 // CAUTION: setFailed() deletes all readers and decoders. Be careful to
205684

Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

@@public:
322322 m_state = JPEG_START_DECOMPRESS;
323323
324324 // We can fill in the size now that the header is available.
325  if (!m_decoder->setSize(m_info.image_width, m_info.image_height))
 325 if (!m_decoder->setSize(IntSize(m_info.image_width, m_info.image_height)))
326326 return false;
327327
328328 m_decoder->setOrientation(readImageOrientation(info()));

@@bool JPEGImageDecoder::isSizeAvailable()
519519 return ImageDecoder::isSizeAvailable();
520520}
521521
522 bool JPEGImageDecoder::setSize(unsigned width, unsigned height)
 522bool JPEGImageDecoder::setSize(const IntSize& size)
523523{
524  if (!ImageDecoder::setSize(width, height))
 524 if (!ImageDecoder::setSize(size))
525525 return false;
526526
527527 prepareScaleDataIfNecessary();

@@bool JPEGImageDecoder::setFailed()
551551}
552552
553553template <J_COLOR_SPACE colorSpace>
554 void setPixel(ImageFrame& buffer, ImageFrame::PixelData* currentAddress, JSAMPARRAY samples, int column)
 554void setPixel(ImageFrame& buffer, RGBA32* currentAddress, JSAMPARRAY samples, int column)
555555{
556556 JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4);
557557

@@bool JPEGImageDecoder::outputScanlines(I
594594 if (destY < 0)
595595 continue;
596596
597  ImageFrame::PixelData* currentAddress = buffer.getAddr(0, destY);
 597 RGBA32* currentAddress = buffer.getAddr(0, destY);
598598 for (int x = 0; x < width; ++x) {
599599 setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x);
600600 ++currentAddress;

@@bool JPEGImageDecoder::outputScanlines()
617617 // Initialize the framebuffer if needed.
618618 ImageFrame& buffer = m_frameBufferCache[0];
619619 if (buffer.status() == ImageFrame::FrameEmpty) {
620  if (!buffer.setSize(scaledSize().width(), scaledSize().height()))
 620 if (!buffer.setSize(scaledSize()))
621621 return setFailed();
622622 buffer.setStatus(ImageFrame::FramePartial);
623623 // The buffer is transparent outside the decoded area while the image is
624624 // loading. The completed image will be marked fully opaque in jpegComplete().
625625 buffer.setHasAlpha(true);
626 
627  // For JPEGs, the frame always fills the entire image.
628  buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
629626 }
630627
631628 jpeg_decompress_struct* info = m_reader->info();
205684

Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h

@@namespace WebCore {
5050 // ImageDecoder
5151 String filenameExtension() const override { return "jpg"; }
5252 bool isSizeAvailable() override;
53  bool setSize(unsigned width, unsigned height) override;
 53 bool setSize(const IntSize&) override;
5454 ImageFrame* frameBufferAtIndex(size_t index) override;
5555 // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid
5656 // accessing deleted memory, especially when calling this from inside
205684

Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp

@@bool PNGImageDecoder::isSizeAvailable()
235235 return ImageDecoder::isSizeAvailable();
236236}
237237
238 bool PNGImageDecoder::setSize(unsigned width, unsigned height)
 238bool PNGImageDecoder::setSize(const IntSize& size)
239239{
240  if (!ImageDecoder::setSize(width, height))
 240 if (!ImageDecoder::setSize(size))
241241 return false;
242242
243243 prepareScaleDataIfNecessary();

@@void PNGImageDecoder::headerAvailable()
295295 // will cease to exist. Note that we'll still properly set the failure flag
296296 // in this case as soon as we longjmp().
297297 m_doNothingOnFailure = true;
298  bool result = setSize(width, height);
 298 bool result = setSize(IntSize(width, height));
299299 m_doNothingOnFailure = false;
300300 if (!result) {
301301 longjmp(JMPBUF(png), 1);

@@void PNGImageDecoder::headerAvailable()
411411 }
412412}
413413
414 static inline void setPixelRGB(ImageFrame::PixelData* dest, png_bytep pixel)
 414static inline void setPixelRGB(RGBA32* dest, png_bytep pixel)
415415{
416416 *dest = 0xFF000000U | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
417417}
418418
419 static inline void setPixelRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
 419static inline void setPixelRGBA(RGBA32* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
420420{
421421 unsigned char a = pixel[3];
422422 *dest = a << 24 | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
423423 nonTrivialAlphaMask |= (255 - a);
424424}
425425
426 static inline void setPixelPremultipliedRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
 426static inline void setPixelPremultipliedRGBA(RGBA32* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask)
427427{
428428 unsigned char a = pixel[3];
429429 unsigned char r = fastDivideBy255(pixel[0] * a);

@@void PNGImageDecoder::rowAvailable(unsig
447447 ImageFrame& buffer = m_frameBufferCache[m_currentFrame];
448448 if (buffer.status() == ImageFrame::FrameEmpty) {
449449 png_structp png = m_reader->pngPtr();
450  if (!buffer.setSize(scaledSize().width(), scaledSize().height())) {
 450 if (!buffer.setSize(scaledSize())) {
451451 longjmp(JMPBUF(png), 1);
452452 return;
453453 }

@@void PNGImageDecoder::rowAvailable(unsig
471471 initFrameBuffer(m_currentFrame);
472472 else
473473#endif
474  // For PNGs, the frame always fills the entire image.
475  buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
476474 }
477475
478476 /* libpng comments (here to explain what follows).

@@void PNGImageDecoder::rowAvailable(unsig
531529 }
532530
533531 // Write the decoded row pixels to the frame buffer.
534  ImageFrame::PixelData* address = buffer.getAddr(0, y);
 532 RGBA32* address = buffer.getAddr(0, y);
535533 int width = scaledSize().width();
536534 unsigned char nonTrivialAlphaMask = 0;
537535

@@void PNGImageDecoder::initFrameBuffer(si
820818 } else {
821819 // We want to clear the previous frame to transparent, without
822820 // affecting pixels in the image outside of the frame.
823  const IntRect& prevRect = prevBuffer->originalFrameRect();
 821 IntRect prevRect = prevBuffer->originalFrameRect();
824822 if (!frameIndex || prevRect.contains(IntRect(IntPoint(), scaledSize()))) {
825823 // Clearing the first frame, or a frame the size of the whole
826824 // image, results in a completely empty image.

@@void PNGImageDecoder::frameComplete()
844842 png_bytep interlaceBuffer = m_reader->interlaceBuffer();
845843
846844 if (m_currentFrame && interlaceBuffer) {
847  const IntRect& rect = buffer.originalFrameRect();
 845 IntRect rect = buffer.originalFrameRect();
848846 bool hasAlpha = m_reader->hasAlpha();
849847 unsigned colorChannels = hasAlpha ? 4 : 3;
850848 bool nonTrivialAlpha = false;

@@void PNGImageDecoder::frameComplete()
854852#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
855853 for (int y = 0; y < rect.maxY() - rect.y(); ++y) {
856854 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());
858856 for (int x = 0; x < rect.maxX() - rect.x(); ++x) {
859857 png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
860858 unsigned alpha = hasAlpha ? pixel[3] : 255;

@@void PNGImageDecoder::frameComplete()
870868 png_bytep row = interlaceBuffer;
871869 for (int y = rect.y(); y < rect.maxY(); ++y, row += colorChannels * size().width()) {
872870 png_bytep pixel = row;
873  ImageFrame::PixelData* address = buffer.getAddr(rect.x(), y);
 871 RGBA32* address = buffer.getAddr(rect.x(), y);
874872 for (int x = rect.x(); x < rect.maxX(); ++x, pixel += colorChannels) {
875873 unsigned alpha = hasAlpha ? pixel[3] : 255;
876874 nonTrivialAlpha |= alpha < 255;
205684

Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h

@@namespace WebCore {
4848 int repetitionCount() const override { return m_playCount-1; }
4949#endif
5050 bool isSizeAvailable() override;
51  bool setSize(unsigned width, unsigned height) override;
 51 bool setSize(const IntSize&) override;
5252 ImageFrame* frameBufferAtIndex(size_t index) override;
5353 // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid
5454 // accessing deleted memory, especially when calling this from inside
205684

Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp

@@bool WEBPImageDecoder::decode(bool onlyS
115115 return setFailed();
116116 m_hasAlpha = false;
117117#endif
118  if (!setSize(width, height))
 118 if (!setSize(IntSize(width, height)))
119119 return setFailed();
120120 }
121121

@@bool WEBPImageDecoder::decode(bool onlyS
128128 ASSERT(buffer.status() != ImageFrame::FrameComplete);
129129
130130 if (buffer.status() == ImageFrame::FrameEmpty) {
131  if (!buffer.setSize(size().width(), size().height()))
 131 if (!buffer.setSize(size()))
132132 return setFailed();
133133 buffer.setStatus(ImageFrame::FramePartial);
134134 buffer.setHasAlpha(m_hasAlpha);
135  buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
136135 }
137136
138137 if (!m_decoder) {
139138 WEBP_CSP_MODE mode = outputMode(m_hasAlpha);
140139 if (!m_premultiplyAlpha)
141140 mode = outputMode(false);
142  int rowStride = size().width() * sizeof(ImageFrame::PixelData);
 141 int rowStride = size().width() * sizeof(RGBA32);
143142 uint8_t* output = reinterpret_cast<uint8_t*>(buffer.getAddr(0, 0));
144143 int outputSize = size().height() * rowStride;
145144 m_decoder = WebPINewRGB(mode, output, outputSize, rowStride);
205684