LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBitmapFilter.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 83 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef SkBitmapFilter_DEFINED
       9             : #define SkBitmapFilter_DEFINED
      10             : 
      11             : #include "SkFixed.h"
      12             : #include "SkMath.h"
      13             : #include "SkScalar.h"
      14             : 
      15             : #include "SkNx.h"
      16             : 
      17             : // size of the precomputed bitmap filter tables for high quality filtering.
      18             : // Used to precompute the shape of the filter kernel.
      19             : // Table size chosen from experiments to see where I could start to see a difference.
      20             : 
      21             : #define SKBITMAP_FILTER_TABLE_SIZE 128
      22             : 
      23             : class SkBitmapFilter {
      24             : public:
      25           0 :     SkBitmapFilter(float width) : fWidth(width), fInvWidth(1.f/width) {
      26           0 :         fPrecomputed = false;
      27           0 :         fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1);
      28           0 :     }
      29           0 :     virtual ~SkBitmapFilter() {}
      30             : 
      31             :     SkScalar lookupScalar(float x) const {
      32             :         if (!fPrecomputed) {
      33             :             precomputeTable();
      34             :         }
      35             :         int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
      36             :         SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
      37             :         return fFilterTableScalar[filter_idx];
      38             :     }
      39             : 
      40           0 :     float width() const { return fWidth; }
      41           0 :     float invWidth() const { return fInvWidth; }
      42             :     virtual float evaluate(float x) const = 0;
      43             : 
      44           0 :     virtual float evaluate_n(float val, float diff, int count, float* output) const {
      45           0 :         float sum = 0;
      46           0 :         for (int index = 0; index < count; index++) {
      47           0 :             float filterValue = evaluate(val);
      48           0 :             *output++ = filterValue;
      49           0 :             sum += filterValue;
      50           0 :             val += diff;
      51             :         }
      52           0 :         return sum;
      53             :     }
      54             : 
      55             : protected:
      56             :     float fWidth;
      57             :     float fInvWidth;
      58             :     float fLookupMultiplier;
      59             : 
      60             :     mutable bool fPrecomputed;
      61             :     mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE];
      62             : 
      63             : private:
      64             :     void precomputeTable() const {
      65             :         fPrecomputed = true;
      66             :         SkScalar *ftpScalar = fFilterTableScalar;
      67             :         for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) {
      68             :             float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABLE_SIZE;
      69             :             float filter_value = evaluate(fx);
      70             :             *ftpScalar++ = filter_value;
      71             :         }
      72             :     }
      73             : };
      74             : 
      75           0 : class SkMitchellFilter final : public SkBitmapFilter {
      76             : public:
      77           0 :     SkMitchellFilter()
      78           0 :         : INHERITED(2)
      79             :         , fB(1.f / 3.f)
      80             :         , fC(1.f / 3.f)
      81           0 :         , fA1(-fB - 6*fC)
      82           0 :         , fB1(6*fB + 30*fC)
      83           0 :         , fC1(-12*fB - 48*fC)
      84           0 :         , fD1(8*fB + 24*fC)
      85           0 :         , fA2(12 - 9*fB - 6*fC)
      86           0 :         , fB2(-18 + 12*fB + 6*fC)
      87           0 :         , fD2(6 - 2*fB)
      88           0 :     {}
      89             : 
      90           0 :     float evaluate(float x) const override {
      91           0 :         x = fabsf(x);
      92           0 :         if (x > 2.f) {
      93           0 :             return 0;
      94           0 :         } else if (x > 1.f) {
      95           0 :             return (((fA1 * x + fB1) * x + fC1) * x + fD1) * (1.f/6.f);
      96             :         } else {
      97           0 :             return ((fA2 * x + fB2) * x*x + fD2) * (1.f/6.f);
      98             :         }
      99             :     }
     100             : 
     101           0 :     Sk4f evalcore_n(const Sk4f& val) const {
     102           0 :         Sk4f x = val.abs();
     103           0 :         Sk4f over2 = x > Sk4f(2);
     104           0 :         Sk4f over1 = x > Sk4f(1);
     105           0 :         Sk4f poly1 = (((Sk4f(fA1) * x + Sk4f(fB1)) * x + Sk4f(fC1)) * x + Sk4f(fD1))
     106           0 :                      * Sk4f(1.f/6.f);
     107           0 :         Sk4f poly0 = ((Sk4f(fA2) * x + Sk4f(fB2)) * x*x + Sk4f(fD2)) * Sk4f(1.f/6.f);
     108           0 :         return over2.thenElse(Sk4f(0), over1.thenElse(poly1, poly0));
     109             :     }
     110             : 
     111           0 :     float evaluate_n(float val, float diff, int count, float* output) const override {
     112             :         Sk4f sum(0);
     113           0 :         while (count >= 4) {
     114           0 :             float v0 = val;
     115           0 :             float v1 = val += diff;
     116           0 :             float v2 = val += diff;
     117           0 :             float v3 = val += diff;
     118           0 :             val += diff;
     119           0 :             Sk4f filterValue = evalcore_n(Sk4f(v0, v1, v2, v3));
     120             :             filterValue.store(output);
     121           0 :             output += 4;
     122           0 :             sum = sum + filterValue;
     123           0 :             count -= 4;
     124             :         }
     125             :         float sums[4];
     126             :         sum.store(sums);
     127           0 :         float result = sums[0] + sums[1] + sums[2] + sums[3];
     128           0 :         result += INHERITED::evaluate_n(val, diff, count, output);
     129           0 :         return result;
     130             :     }
     131             : 
     132             :   protected:
     133             :       float fB, fC;
     134             :       float fA1, fB1, fC1, fD1;
     135             :       float fA2, fB2, fD2;
     136             : private:
     137             :     typedef SkBitmapFilter INHERITED;
     138             : };
     139             : 
     140             : class SkGaussianFilter final : public SkBitmapFilter {
     141             :     float fAlpha, fExpWidth;
     142             : 
     143             : public:
     144             :     SkGaussianFilter(float a, float width = 2)
     145             :         : SkBitmapFilter(width)
     146             :         , fAlpha(a)
     147             :         , fExpWidth(expf(-a * width * width))
     148             :     {}
     149             : 
     150             :     float evaluate(float x) const override {
     151             :         return SkTMax(0.f, float(expf(-fAlpha*x*x) - fExpWidth));
     152             :     }
     153             : };
     154             : 
     155           0 : class SkTriangleFilter final : public SkBitmapFilter {
     156             : public:
     157           0 :     SkTriangleFilter(float width = 1) : SkBitmapFilter(width) {}
     158             : 
     159           0 :     float evaluate(float x) const override {
     160           0 :         return SkTMax(0.f, fWidth - fabsf(x));
     161             :     }
     162             : };
     163             : 
     164           0 : class SkBoxFilter final : public SkBitmapFilter {
     165             : public:
     166           0 :     SkBoxFilter(float width = 0.5f) : SkBitmapFilter(width) {}
     167             : 
     168           0 :     float evaluate(float x) const override {
     169           0 :         return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f;
     170             :     }
     171             : };
     172             : 
     173           0 : class SkHammingFilter final : public SkBitmapFilter {
     174             : public:
     175           0 :     SkHammingFilter(float width = 1) : SkBitmapFilter(width) {}
     176             : 
     177           0 :     float evaluate(float x) const override {
     178           0 :         if (x <= -fWidth || x >= fWidth) {
     179           0 :             return 0.0f;  // Outside of the window.
     180             :         }
     181           0 :         if (x > -FLT_EPSILON && x < FLT_EPSILON) {
     182           0 :             return 1.0f;  // Special case the sinc discontinuity at the origin.
     183             :         }
     184           0 :         const float xpi = x * static_cast<float>(SK_ScalarPI);
     185             : 
     186           0 :         return ((sk_float_sin(xpi) / xpi) *  // sinc(x)
     187           0 :                 (0.54f + 0.46f * sk_float_cos(xpi / fWidth)));  // hamming(x)
     188             :     }
     189             : };
     190             : 
     191           0 : class SkLanczosFilter final : public SkBitmapFilter {
     192             : public:
     193           0 :     SkLanczosFilter(float width = 3.f) : SkBitmapFilter(width) {}
     194             : 
     195           0 :     float evaluate(float x) const override {
     196           0 :         if (x <= -fWidth || x >= fWidth) {
     197           0 :             return 0.0f;  // Outside of the window.
     198             :         }
     199           0 :         if (x > -FLT_EPSILON && x < FLT_EPSILON) {
     200           0 :             return 1.0f;  // Special case the discontinuity at the origin.
     201             :         }
     202           0 :         float xpi = x * static_cast<float>(SK_ScalarPI);
     203           0 :         return (sk_float_sin(xpi) / xpi) *  // sinc(x)
     204           0 :                sk_float_sin(xpi / fWidth) / (xpi / fWidth);  // sinc(x/fWidth)
     205             :     }
     206             : };
     207             : 
     208             : 
     209             : #endif

Generated by: LCOV version 1.13