diff options
-rw-r--r-- | core/fpdfapi/render/cpdf_renderstatus.cpp | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 9f4bda1409..9170ae9daf 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -673,6 +673,17 @@ struct Coon_Bezier { float Distance() { return x.Distance() + y.Distance(); } }; +int Interpolate(int p1, int p2, int delta1, int delta2, bool* overflow) { + pdfium::base::CheckedNumeric<int> p = p2; + p -= p1; + p *= delta1; + p /= delta2; + p += p1; + if (!p.IsValid()) + *overflow = true; + return p.ValueOrDefault(0); +} + int BiInterpolImpl(int c0, int c1, int c2, @@ -680,26 +691,30 @@ int BiInterpolImpl(int c0, int x, int y, int x_scale, - int y_scale) { - int x1 = c0 + (c3 - c0) * x / x_scale; - int x2 = c1 + (c2 - c1) * x / x_scale; - return x1 + (x2 - x1) * y / y_scale; + int y_scale, + bool* overflow) { + int x1 = Interpolate(c0, c3, x, x_scale, overflow); + int x2 = Interpolate(c1, c2, x, x_scale, overflow); + return Interpolate(x1, x2, y, y_scale, overflow); } struct Coon_Color { Coon_Color() { memset(comp, 0, sizeof(int) * 3); } int comp[3]; - void BiInterpol(Coon_Color colors[4], + // Returns true if successful, false if overflow detected. + bool BiInterpol(Coon_Color colors[4], int x, int y, int x_scale, int y_scale) { + bool overflow = false; for (int i = 0; i < 3; i++) { comp[i] = BiInterpolImpl(colors[0].comp[i], colors[1].comp[i], colors[2].comp[i], colors[3].comp[i], x, y, - x_scale, y_scale); + x_scale, y_scale, &overflow); } + return !overflow; } int Distance(Coon_Color& o) { @@ -731,14 +746,23 @@ struct CPDF_PatchDrawer { int d_left = 0; int d_top = 0; int d_right = 0; - div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale); + if (!div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, + y_scale)) { + return; + } if (!bSmall) { - div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale, - y_scale); - div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale, - y_scale); - div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale, - y_scale); + if (!div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale, + y_scale)) { + return; + } + if (!div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale, + y_scale)) { + return; + } + if (!div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale, + y_scale)) { + return; + } d_bottom = div_colors[3].Distance(div_colors[0]); d_left = div_colors[1].Distance(div_colors[0]); d_top = div_colors[1].Distance(div_colors[2]); |