<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[182685] releases/WebKitGTK/webkit-2.8</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/182685">182685</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2015-04-13 01:15:06 -0700 (Mon, 13 Apr 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/182067">r182067</a> - FEMorphology::platformApplyGeneric() should bail out if the radius is less than or equal to zero.
https://bugs.webkit.org/show_bug.cgi?id=142885.
Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2015-03-27
Reviewed by Dean Jackson.
Source/WebCore:
FEMorphology class implementation code clean up.
Tests: svg/filters/feMorphology-radius-cases.svg
* platform/graphics/filters/FEMorphology.cpp:
(WebCore::shouldSupersedeExtremum): Reuse code instead of repeating it and
use < and > instead of =< and >=.
(WebCore::pixelArrayIndex): Returns the array index of a pixel in an image
buffer, given: position(x, y), image width and the color channel.
(WebCore::columnExtremum): Returns the extremum of a column of pixels.
(WebCore::kernelExtremum): Returns the extremum of a filter kernel.
(WebCore::FEMorphology::platformApplyGeneric): Apply some code clean-up.
The kernel size should be equal to radius of the filter. The extra pixel
was causing the resulted image to be asymmetric in some cases.
(WebCore::FEMorphology::platformApplyDegenerate):
(WebCore::FEMorphology::platformApplySoftware): After applying scaling, we
still need to check the resulted radius is negative (overflow case) or less
than one (zero radius case) and treat these cases differently.
(WebCore::FEMorphology::morphologyOperator): Deleted.
(WebCore::FEMorphology::radiusX): Deleted.
(WebCore::FEMorphology::radiusY): Deleted.
* platform/graphics/filters/FEMorphology.h:
(WebCore::FEMorphology::morphologyOperator):
(WebCore::FEMorphology::radiusX):
(WebCore::FEMorphology::radiusY):
Move a single line functions from the source file to the header file.
LayoutTests:
* svg/filters/feMorphology-radius-cases-expected.svg: Added.
* svg/filters/feMorphology-radius-cases.svg: Added.
Test different cases for radius of the feMorphology filter. There are three
cases for the radius:
1. radius < 0: This is an error case, the source image should not be rendered.
2. radius = 0: This case is treated as if the filter never exists.
3. radius > 0: If the scaled radius is > 0, the filter is applied.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit28LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCoreplatformgraphicsfiltersFEMorphologycpp">releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCoreplatformgraphicsfiltersFEMorphologyh">releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit28LayoutTestssvgfiltersfeMorphologyradiuscasesexpectedsvg">releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases-expected.svg</a></li>
<li><a href="#releasesWebKitGTKwebkit28LayoutTestssvgfiltersfeMorphologyradiuscasessvg">releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases.svg</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit28LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog (182684 => 182685)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog        2015-04-13 08:12:50 UTC (rev 182684)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog        2015-04-13 08:15:06 UTC (rev 182685)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2015-03-27 Said Abou-Hallawa <sabouhallawa@apple.com>
+
+ FEMorphology::platformApplyGeneric() should bail out if the radius is less than or equal to zero.
+ https://bugs.webkit.org/show_bug.cgi?id=142885.
+
+ Reviewed by Dean Jackson.
+
+ * svg/filters/feMorphology-radius-cases-expected.svg: Added.
+ * svg/filters/feMorphology-radius-cases.svg: Added.
+ Test different cases for radius of the feMorphology filter. There are three
+ cases for the radius:
+ 1. radius < 0: This is an error case, the source image should not be rendered.
+ 2. radius = 0: This case is treated as if the filter never exists.
+ 3. radius > 0: If the scaled radius is > 0, the filter is applied.
+
</ins><span class="cx"> 2015-03-27 Michael Saboff <msaboff@apple.com>
</span><span class="cx">
</span><span class="cx"> Objects with numeric properties intermittently get a phantom 'length' property
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28LayoutTestssvgfiltersfeMorphologyradiuscasesexpectedsvg"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases-expected.svg (0 => 182685)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases-expected.svg         (rev 0)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases-expected.svg        2015-04-13 08:15:06 UTC (rev 182685)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="500">
+ <g stroke="black" stroke-width="10">
+ <rect x= "10" y="10" width="100" height="100" fill="lime"/>
+ <rect x="10" y="130" width="100" height="100" fill="lime"/>
+ <rect x="140" y="10" width="100" height="100" fill="lime"/>
+ <rect x="140" y="130" width="100" height="100" fill="lime"/>
+ <rect x= "270" y="10" width="100" height="100" fill="lime"/>
+ <rect x="270" y="130" width="100" height="100" fill="lime"/>
+ </g>
+
+ <svg x="400" y="10" width="100" height="100" viewBox="0 0 10000 10000">
+ <g stroke="black" stroke-width="1000">
+ <rect width="100%" height="100%" fill="lime"/>
+ </g>
+ </svg>
+ <svg x="400" y="130" width="100" height="100" viewBox="0 0 10000 10000">
+ <g stroke="black" stroke-width="1000">
+ <rect width="100%" height="100%" fill="lime"/>
+ </g>
+ </svg>
+
+ <svg x="535" y="15" width="90" height="90">
+ <g stroke="black" stroke-width="20">
+ <rect width="100%" height="100%" fill="lime"/>
+ </g>
+ </svg>
+ <svg x="530" y="130" width="100" height="100">
+ <rect width="100%" height="100%" fill="lime"/>
+ </svg>
+
+ <svg x="665" y="15" width="90" height="90">
+ <g stroke="black" stroke-width="20">
+ <rect width="100%" height="100%" fill="lime"/>
+ </g>
+ </svg>
+ <svg x="650" y="120" width="120" height="120">
+ <g stroke="black" stroke-width="10">
+ <rect width="100%" height="100%" fill="lime"/>
+ </g>
+ </svg>
+</svg>
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit28LayoutTestssvgfiltersfeMorphologyradiuscasessvg"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases.svg (0 => 182685)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases.svg         (rev 0)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/svg/filters/feMorphology-radius-cases.svg        2015-04-13 08:15:06 UTC (rev 182685)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="500">
+ <defs>
+ <filter id="Erode-1">
+ <feMorphology operator="erode" in="SourceGraphic" radius="-1" />
+ </filter>
+ <filter id="Erode0">
+ <feMorphology operator="erode" in="SourceGraphic" radius="0" />
+ </filter>
+ <filter id="Erode10">
+ <feMorphology operator="erode" in="SourceGraphic" radius="10" />
+ </filter>
+ <filter id="Dilate-1">
+ <feMorphology operator="dilate" in="SourceGraphic" radius="-1" />
+ </filter>
+ <filter id="Dilate0">
+ <feMorphology operator="dilate" in="SourceGraphic" radius="0" />
+ </filter>
+ <filter id="Dilate10">
+ <feMorphology operator="dilate" in="SourceGraphic" radius="10" />
+ </filter>
+ </defs>
+ <g stroke="black" stroke-width="10">
+ <rect x= "10" y="10" width="100" height="100" fill="lime"/>
+ <rect x="10" y="130" width="100" height="100" fill="lime"/>
+
+ <!-- negative radius case -->
+ <g>
+ <rect x="140" y="10" width="100" height="100" fill="lime"/>
+ <rect x="140" y="10" width="100" height="100" fill="red" filter="url(#Erode-1)"/>
+ </g>
+
+ <g>
+ <rect x="140" y="130" width="100" height="100" fill="lime"/>
+ <rect x="140" y="130" width="100" height="100" fill="red" filter="url(#Dilate-1)"/>
+ </g>
+
+ <!-- zero radius case -->
+ <rect x= "270" y="10" width="100" height="100" fill="lime" filter="url(#Erode0)"/>
+ <rect x="270" y="130" width="100" height="100" fill="lime" filter="url(#Dilate0)"/>
+ </g>
+
+ <!-- positive radius case but scaled down to less than 1 (treated as zero radius case) -->
+ <svg x="400" y="10" width="100" height="100" viewBox="0 0 10000 10000">
+ <g stroke="black" stroke-width="1000">
+ <rect width="100%" height="100%" fill="lime" filter="url(#Erode10)"/>
+ </g>
+ </svg>
+ <svg x="400" y="130" width="100" height="100" viewBox="0 0 10000 10000">
+ <g stroke="black" stroke-width="1000">
+ <rect width="100%" height="100%" fill="lime" filter="url(#Dilate10)"/>
+ </g>
+ </svg>
+
+ <!-- positive radius case but inside a nested svg -->
+ <svg x="530" y="10" width="100" height="100">
+ <g stroke="black" stroke-width="10">
+ <rect width="100%" height="100%" fill="lime" filter="url(#Erode10)"/>
+ </g>
+ </svg>
+ <svg x="530" y="130" width="100" height="100" viewBox="0 0 100 100">
+ <g stroke="black" stroke-width="10">
+ <rect width="100%" height="100%" fill="lime" filter="url(#Dilate10)"/>
+ </g>
+ </svg>
+
+ <!-- positive radius case -->
+ <g stroke="black" stroke-width="10">
+ <rect x="660" y="10" width="100" height="100" fill="lime" filter="url(#Erode10)"/>
+ <rect x="660" y="130" width="100" height="100" fill="lime" filter="url(#Dilate10)"/>
+ </g>
+</svg>
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog (182684 => 182685)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog        2015-04-13 08:12:50 UTC (rev 182684)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog        2015-04-13 08:15:06 UTC (rev 182685)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2015-03-27 Said Abou-Hallawa <sabouhallawa@apple.com>
+
+ FEMorphology::platformApplyGeneric() should bail out if the radius is less than or equal to zero.
+ https://bugs.webkit.org/show_bug.cgi?id=142885.
+
+ Reviewed by Dean Jackson.
+
+ FEMorphology class implementation code clean up.
+
+ Tests: svg/filters/feMorphology-radius-cases.svg
+
+ * platform/graphics/filters/FEMorphology.cpp:
+ (WebCore::shouldSupersedeExtremum): Reuse code instead of repeating it and
+ use < and > instead of =< and >=.
+
+ (WebCore::pixelArrayIndex): Returns the array index of a pixel in an image
+ buffer, given: position(x, y), image width and the color channel.
+
+ (WebCore::columnExtremum): Returns the extremum of a column of pixels.
+
+ (WebCore::kernelExtremum): Returns the extremum of a filter kernel.
+
+ (WebCore::FEMorphology::platformApplyGeneric): Apply some code clean-up.
+ The kernel size should be equal to radius of the filter. The extra pixel
+ was causing the resulted image to be asymmetric in some cases.
+
+ (WebCore::FEMorphology::platformApplyDegenerate):
+ (WebCore::FEMorphology::platformApplySoftware): After applying scaling, we
+ still need to check the resulted radius is negative (overflow case) or less
+ than one (zero radius case) and treat these cases differently.
+
+ (WebCore::FEMorphology::morphologyOperator): Deleted.
+ (WebCore::FEMorphology::radiusX): Deleted.
+ (WebCore::FEMorphology::radiusY): Deleted.
+ * platform/graphics/filters/FEMorphology.h:
+ (WebCore::FEMorphology::morphologyOperator):
+ (WebCore::FEMorphology::radiusX):
+ (WebCore::FEMorphology::radiusY):
+ Move a single line functions from the source file to the header file.
+
</ins><span class="cx"> 2015-03-26 Myles C. Maxfield <mmaxfield@apple.com>
</span><span class="cx">
</span><span class="cx"> Crash when laying out (char)0
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCoreplatformgraphicsfiltersFEMorphologycpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.cpp (182684 => 182685)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.cpp        2015-04-13 08:12:50 UTC (rev 182684)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.cpp        2015-04-13 08:15:06 UTC (rev 182685)
</span><span class="lines">@@ -46,11 +46,6 @@
</span><span class="cx"> return adoptRef(*new FEMorphology(filter, type, radiusX, radiusY));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-MorphologyOperatorType FEMorphology::morphologyOperator() const
-{
- return m_type;
-}
-
</del><span class="cx"> bool FEMorphology::setMorphologyOperator(MorphologyOperatorType type)
</span><span class="cx"> {
</span><span class="cx"> if (m_type == type)
</span><span class="lines">@@ -59,11 +54,6 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-float FEMorphology::radiusX() const
-{
- return m_radiusX;
-}
-
</del><span class="cx"> bool FEMorphology::setRadiusX(float radiusX)
</span><span class="cx"> {
</span><span class="cx"> if (m_radiusX == radiusX)
</span><span class="lines">@@ -72,9 +62,12 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-float FEMorphology::radiusY() const
</del><ins>+bool FEMorphology::setRadiusY(float radiusY)
</ins><span class="cx"> {
</span><del>- return m_radiusY;
</del><ins>+ if (m_radiusY == radiusY)
+ return false;
+ m_radiusY = radiusY;
+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void FEMorphology::determineAbsolutePaintRect()
</span><span class="lines">@@ -90,66 +83,77 @@
</span><span class="cx"> setAbsolutePaintRect(enclosingIntRect(paintRect));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool FEMorphology::setRadiusY(float radiusY)
</del><ins>+static inline bool shouldSupersedeExtremum(unsigned char newValue, unsigned char currentValue, MorphologyOperatorType type)
</ins><span class="cx"> {
</span><del>- if (m_radiusY == radiusY)
- return false;
- m_radiusY = radiusY;
- return true;
</del><ins>+ return (type == FEMORPHOLOGY_OPERATOR_ERODE && newValue < currentValue)
+ || (type == FEMORPHOLOGY_OPERATOR_DILATE && newValue > currentValue);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+static inline int pixelArrayIndex(int x, int y, int width, int colorChannel)
+{
+ return (y * width + x) * 4 + colorChannel;
+}
+
+static inline unsigned char columnExtremum(const Uint8ClampedArray* srcPixelArray, int x, int yStart, int yEnd, int width, unsigned colorChannel, MorphologyOperatorType type)
+{
+ unsigned char extremum = srcPixelArray->item(pixelArrayIndex(x, yStart, width, colorChannel));
+ for (int y = yStart + 1; y < yEnd; ++y) {
+ unsigned char pixel = srcPixelArray->item(pixelArrayIndex(x, y, width, colorChannel));
+ if (shouldSupersedeExtremum(pixel, extremum, type))
+ extremum = pixel;
+ }
+ return extremum;
+}
+
+static inline unsigned char kernelExtremum(const Vector<unsigned char>& kernel, MorphologyOperatorType type)
+{
+ Vector<unsigned char>::const_iterator iter = kernel.begin();
+ unsigned char extremum = *iter;
+ for (Vector<unsigned char>::const_iterator end = kernel.end(); ++iter != end; ) {
+ if (shouldSupersedeExtremum(*iter, extremum, type))
+ extremum = *iter;
+ }
+ return extremum;
+}
+
</ins><span class="cx"> void FEMorphology::platformApplyGeneric(PaintingData* paintingData, int yStart, int yEnd)
</span><span class="cx"> {
</span><span class="cx"> Uint8ClampedArray* srcPixelArray = paintingData->srcPixelArray;
</span><span class="cx"> Uint8ClampedArray* dstPixelArray = paintingData->dstPixelArray;
</span><ins>+ const int radiusX = paintingData->radiusX;
+ const int radiusY = paintingData->radiusY;
</ins><span class="cx"> const int width = paintingData->width;
</span><span class="cx"> const int height = paintingData->height;
</span><del>- const int effectWidth = width * 4;
- const int radiusX = paintingData->radiusX;
- const int radiusY = paintingData->radiusY;
</del><span class="cx">
</span><ins>+ ASSERT(radiusX <= width || radiusY <= height);
+ ASSERT(yStart >= 0 && yEnd <= height && yStart < yEnd);
+
</ins><span class="cx"> Vector<unsigned char> extrema;
</span><span class="cx"> for (int y = yStart; y < yEnd; ++y) {
</span><del>- int extremaStartY = std::max(0, y - radiusY);
- int extremaEndY = std::min(height - 1, y + radiusY);
- for (unsigned int clrChannel = 0; clrChannel < 4; ++clrChannel) {
</del><ins>+ int yStartExtrema = std::max(0, y - radiusY);
+ int yEndExtrema = std::min(height - 1, y + radiusY);
+
+ for (unsigned colorChannel = 0; colorChannel < 4; ++colorChannel) {
</ins><span class="cx"> extrema.clear();
</span><span class="cx"> // Compute extremas for each columns
</span><del>- for (int x = 0; x <= radiusX; ++x) {
- unsigned char columnExtrema = srcPixelArray->item(extremaStartY * effectWidth + 4 * x + clrChannel);
- for (int eY = extremaStartY + 1; eY < extremaEndY; ++eY) {
- unsigned char pixel = srcPixelArray->item(eY * effectWidth + 4 * x + clrChannel);
- if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema)
- || (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema)) {
- columnExtrema = pixel;
- }
- }
</del><ins>+ for (int x = 0; x < radiusX; ++x)
+ extrema.append(columnExtremum(srcPixelArray, x, yStartExtrema, yEndExtrema, width, colorChannel, m_type));
</ins><span class="cx">
</span><del>- extrema.append(columnExtrema);
- }
-
</del><span class="cx"> // Kernel is filled, get extrema of next column
</span><span class="cx"> for (int x = 0; x < width; ++x) {
</span><del>- const int endX = std::min(x + radiusX, width - 1);
- unsigned char columnExtrema = srcPixelArray->item(extremaStartY * effectWidth + endX * 4 + clrChannel);
- for (int i = extremaStartY + 1; i <= extremaEndY; ++i) {
- unsigned char pixel = srcPixelArray->item(i * effectWidth + endX * 4 + clrChannel);
- if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema)
- || (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
- columnExtrema = pixel;
</del><ins>+ if (x < width - radiusX) {
+ int xEnd = std::min(x + radiusX, width - 1);
+ extrema.append(columnExtremum(srcPixelArray, xEnd, yStartExtrema, yEndExtrema + 1, width, colorChannel, m_type));
</ins><span class="cx"> }
</span><del>- if (x - radiusX >= 0)
</del><ins>+
+ if (x > radiusX)
</ins><span class="cx"> extrema.remove(0);
</span><del>- if (x + radiusX <= width)
- extrema.append(columnExtrema);
</del><span class="cx">
</span><del>- unsigned char entireExtrema = extrema[0];
- for (unsigned kernelIndex = 1; kernelIndex < extrema.size(); ++kernelIndex) {
- if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && extrema[kernelIndex] <= entireExtrema)
- || (m_type == FEMORPHOLOGY_OPERATOR_DILATE && extrema[kernelIndex] >= entireExtrema))
- entireExtrema = extrema[kernelIndex];
- }
- dstPixelArray->set(y * effectWidth + 4 * x + clrChannel, entireExtrema);
</del><ins>+ // The extrema original size = radiusX.
+ // Number of new addition = width - radiusX.
+ // Number of removals = width - radiusX - 1.
+ ASSERT(extrema.size() >= static_cast<size_t>(radiusX + 1));
+ dstPixelArray->set(pixelArrayIndex(x, y, width, colorChannel), kernelExtremum(extrema, m_type));
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -189,7 +193,24 @@
</span><span class="cx"> platformApplyGeneric(paintingData, 0, paintingData->height);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool FEMorphology::platformApplyDegenerate(Uint8ClampedArray* dstPixelArray, const IntRect& imageRect, int radiusX, int radiusY)
+{
+ // Input radius is less than zero or an overflow happens when scaling it.
+ if (radiusX < 0 || radiusY < 0) {
+ dstPixelArray->zeroFill();
+ return true;
+ }
</ins><span class="cx">
</span><ins>+ // Input radius is equal to zero or the scaled radius is less than one.
+ if (!m_radiusX || !m_radiusY) {
+ FilterEffect* in = inputEffect(0);
+ in->copyPremultipliedImage(dstPixelArray, imageRect);
+ return true;
+ }
+
+ return false;
+}
+
</ins><span class="cx"> void FEMorphology::platformApplySoftware()
</span><span class="cx"> {
</span><span class="cx"> FilterEffect* in = inputEffect(0);
</span><span class="lines">@@ -199,25 +220,28 @@
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> setIsAlphaImage(in->isAlphaImage());
</span><del>- if (m_radiusX <= 0 || m_radiusY <= 0) {
- dstPixelArray->zeroFill();
</del><ins>+
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ if (platformApplyDegenerate(dstPixelArray, effectDrawingRect, m_radiusX, m_radiusY))
</ins><span class="cx"> return;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> Filter& filter = this->filter();
</span><ins>+ RefPtr<Uint8ClampedArray> srcPixelArray = in->asPremultipliedImage(effectDrawingRect);
</ins><span class="cx"> int radiusX = static_cast<int>(floorf(filter.applyHorizontalScale(m_radiusX)));
</span><span class="cx"> int radiusY = static_cast<int>(floorf(filter.applyVerticalScale(m_radiusY)));
</span><ins>+ radiusX = std::min(effectDrawingRect.width() - 1, radiusX);
+ radiusY = std::min(effectDrawingRect.height() - 1, radiusY);
</ins><span class="cx">
</span><del>- IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
- RefPtr<Uint8ClampedArray> srcPixelArray = in->asPremultipliedImage(effectDrawingRect);
</del><ins>+ if (platformApplyDegenerate(dstPixelArray, effectDrawingRect, radiusX, radiusY))
+ return;
</ins><span class="cx">
</span><span class="cx"> PaintingData paintingData;
</span><span class="cx"> paintingData.srcPixelArray = srcPixelArray.get();
</span><span class="cx"> paintingData.dstPixelArray = dstPixelArray;
</span><span class="cx"> paintingData.width = effectDrawingRect.width();
</span><span class="cx"> paintingData.height = effectDrawingRect.height();
</span><del>- paintingData.radiusX = std::min(effectDrawingRect.width() - 1, radiusX);
- paintingData.radiusY = std::min(effectDrawingRect.height() - 1, radiusY);
</del><ins>+ paintingData.radiusX = radiusX;
+ paintingData.radiusY = radiusY;
</ins><span class="cx">
</span><span class="cx"> platformApply(&paintingData);
</span><span class="cx"> }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCoreplatformgraphicsfiltersFEMorphologyh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.h (182684 => 182685)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.h        2015-04-13 08:12:50 UTC (rev 182684)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/platform/graphics/filters/FEMorphology.h        2015-04-13 08:15:06 UTC (rev 182685)
</span><span class="lines">@@ -36,13 +36,14 @@
</span><span class="cx"> class FEMorphology : public FilterEffect {
</span><span class="cx"> public:
</span><span class="cx"> static Ref<FEMorphology> create(Filter*, MorphologyOperatorType, float radiusX, float radiusY);
</span><del>- MorphologyOperatorType morphologyOperator() const;
</del><ins>+
+ MorphologyOperatorType morphologyOperator() const { return m_type; }
</ins><span class="cx"> bool setMorphologyOperator(MorphologyOperatorType);
</span><span class="cx">
</span><del>- float radiusX() const;
</del><ins>+ float radiusX() const { return m_radiusX; }
</ins><span class="cx"> bool setRadiusX(float);
</span><span class="cx">
</span><del>- float radiusY() const;
</del><ins>+ float radiusY() const { return m_radiusY; }
</ins><span class="cx"> bool setRadiusY(float);
</span><span class="cx">
</span><span class="cx"> virtual void platformApplySoftware();
</span><span class="lines">@@ -76,6 +77,7 @@
</span><span class="cx"> inline void platformApplyGeneric(PaintingData*, const int yStart, const int yEnd);
</span><span class="cx"> private:
</span><span class="cx"> FEMorphology(Filter*, MorphologyOperatorType, float radiusX, float radiusY);
</span><ins>+ bool platformApplyDegenerate(Uint8ClampedArray* dstPixelArray, const IntRect& imageRect, int radiusX, int radiusY);
</ins><span class="cx">
</span><span class="cx"> MorphologyOperatorType m_type;
</span><span class="cx"> float m_radiusX;
</span></span></pre>
</div>
</div>
</body>
</html>