[Sk4fGradient] Use infinity floats for clamp-mode extreme positions
In clamp mode, we use a couple of synthetic edges that are supposed to extend to +/- infinity (-inf .. P0 and Pn .. inf). Currently we use SK_ScalarMin/Max, but these can be overrun with large/malicious inputs. Use SK_ScalarInfinity/SK_ScalarNegativeInfinity instead, and tweak compute_interval_props() to handle inf values gracefully. BUG=skia:5835 R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2441733002 Review-Url: https://chromiumcodereview.appspot.com/2441733002
This commit is contained in:
parent
3ae677c8f8
commit
8f457591e6
@ -127,7 +127,14 @@ Interval::Interval(const Sk4f& c0, SkScalar p0,
|
|||||||
, fZeroRamp((c0 == c1).allTrue()) {
|
, fZeroRamp((c0 == c1).allTrue()) {
|
||||||
|
|
||||||
SkASSERT(p0 != p1);
|
SkASSERT(p0 != p1);
|
||||||
const Sk4f dc = (c1 - c0) / (p1 - p0);
|
// Either p0 or p1 can be (-)inf for synthetic clamp edge intervals.
|
||||||
|
SkASSERT(SkScalarIsFinite(p0) || SkScalarIsFinite(p1));
|
||||||
|
|
||||||
|
const auto dp = p1 - p0;
|
||||||
|
|
||||||
|
// Clamp edge intervals are always zero-ramp.
|
||||||
|
SkASSERT(SkScalarIsFinite(dp) || fZeroRamp);
|
||||||
|
const Sk4f dc = SkScalarIsFinite(dp) ? (c1 - c0) / dp : 0;
|
||||||
|
|
||||||
c0.store(&fC0.fVec);
|
c0.store(&fC0.fVec);
|
||||||
dc.store(&fDc.fVec);
|
dc.store(&fDc.fVec);
|
||||||
@ -223,7 +230,7 @@ GradientShaderBase4fContext::buildIntervals(const SkGradientShaderBase& shader,
|
|||||||
// synthetic edge interval: -/+inf .. P0
|
// synthetic edge interval: -/+inf .. P0
|
||||||
const Sk4f clamp_color = pack_color(shader.fOrigColors[first_index],
|
const Sk4f clamp_color = pack_color(shader.fOrigColors[first_index],
|
||||||
fColorsArePremul, componentScale);
|
fColorsArePremul, componentScale);
|
||||||
const SkScalar clamp_pos = reverse ? SK_ScalarMax : SK_ScalarMin;
|
const SkScalar clamp_pos = reverse ? SK_ScalarInfinity : SK_ScalarNegativeInfinity;
|
||||||
fIntervals.emplace_back(clamp_color, clamp_pos,
|
fIntervals.emplace_back(clamp_color, clamp_pos,
|
||||||
clamp_color, first_pos);
|
clamp_color, first_pos);
|
||||||
} else if (shader.fTileMode == SkShader::kMirror_TileMode && reverse) {
|
} else if (shader.fTileMode == SkShader::kMirror_TileMode && reverse) {
|
||||||
@ -248,7 +255,7 @@ GradientShaderBase4fContext::buildIntervals(const SkGradientShaderBase& shader,
|
|||||||
// synthetic edge interval: Pn .. +/-inf
|
// synthetic edge interval: Pn .. +/-inf
|
||||||
const Sk4f clamp_color = pack_color(shader.fOrigColors[last_index],
|
const Sk4f clamp_color = pack_color(shader.fOrigColors[last_index],
|
||||||
fColorsArePremul, componentScale);
|
fColorsArePremul, componentScale);
|
||||||
const SkScalar clamp_pos = reverse ? SK_ScalarMin : SK_ScalarMax;
|
const SkScalar clamp_pos = reverse ? SK_ScalarNegativeInfinity : SK_ScalarInfinity;
|
||||||
fIntervals.emplace_back(clamp_color, last_pos,
|
fIntervals.emplace_back(clamp_color, last_pos,
|
||||||
clamp_color, clamp_pos);
|
clamp_color, clamp_pos);
|
||||||
} else if (shader.fTileMode == SkShader::kMirror_TileMode && !reverse) {
|
} else if (shader.fTileMode == SkShader::kMirror_TileMode && !reverse) {
|
||||||
|
@ -322,11 +322,16 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void compute_interval_props(SkScalar t) {
|
void compute_interval_props(SkScalar t) {
|
||||||
const Sk4f dC = DstTraits<dstType, premul>::load(fInterval->fDc);
|
|
||||||
fCc = DstTraits<dstType, premul>::load(fInterval->fC0);
|
|
||||||
fCc = fCc + dC * Sk4f(t);
|
|
||||||
fDcDx = dC * fDx;
|
|
||||||
fZeroRamp = fIsVertical || fInterval->isZeroRamp();
|
fZeroRamp = fIsVertical || fInterval->isZeroRamp();
|
||||||
|
fCc = DstTraits<dstType, premul>::load(fInterval->fC0);
|
||||||
|
|
||||||
|
if (fInterval->isZeroRamp()) {
|
||||||
|
fDcDx = 0;
|
||||||
|
} else {
|
||||||
|
const Sk4f dC = DstTraits<dstType, premul>::load(fInterval->fDc);
|
||||||
|
fCc = fCc + dC * Sk4f(t);
|
||||||
|
fDcDx = dC * fDx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Interval* next_interval(const Interval* i) const {
|
const Interval* next_interval(const Interval* i) const {
|
||||||
|
Loading…
Reference in New Issue
Block a user