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

          Line data    Source code
       1             : // Copyright (c) 2012 The Chromium Authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef SK_CONVOLVER_H
       6             : #define SK_CONVOLVER_H
       7             : 
       8             : #include "SkSize.h"
       9             : #include "SkTDArray.h"
      10             : 
      11             : // avoid confusion with Mac OS X's math library (Carbon)
      12             : #if defined(__APPLE__)
      13             : #undef FloatToConvolutionFixed
      14             : #undef ConvolutionFixedToFloat
      15             : #undef FloatToFixed
      16             : #undef FixedToFloat
      17             : #endif
      18             : 
      19             : // Represents a filter in one dimension. Each output pixel has one entry in this
      20             : // object for the filter values contributing to it. You build up the filter
      21             : // list by calling AddFilter for each output pixel (in order).
      22             : //
      23             : // We do 2-dimensional convolution by first convolving each row by one
      24             : // SkConvolutionFilter1D, then convolving each column by another one.
      25             : //
      26             : // Entries are stored in ConvolutionFixed point, shifted left by kShiftBits.
      27           0 : class SkConvolutionFilter1D {
      28             : public:
      29             :     typedef short ConvolutionFixed;
      30             : 
      31             :     // The number of bits that ConvolutionFixed point values are shifted by.
      32             :     enum { kShiftBits = 14 };
      33             : 
      34             :     SK_API SkConvolutionFilter1D();
      35             :     SK_API ~SkConvolutionFilter1D();
      36             : 
      37             :     // Convert between floating point and our ConvolutionFixed point representation.
      38           0 :     static ConvolutionFixed FloatToFixed(float f) {
      39           0 :         return static_cast<ConvolutionFixed>(f * (1 << kShiftBits));
      40             :     }
      41             :     static unsigned char FixedToChar(ConvolutionFixed x) {
      42             :         return static_cast<unsigned char>(x >> kShiftBits);
      43             :     }
      44             :     static float FixedToFloat(ConvolutionFixed x) {
      45             :         // The cast relies on ConvolutionFixed being a short, implying that on
      46             :         // the platforms we care about all (16) bits will fit into
      47             :         // the mantissa of a (32-bit) float.
      48             :         static_assert(sizeof(ConvolutionFixed) == 2, "ConvolutionFixed_type_should_fit_in_float_mantissa");
      49             :         float raw = static_cast<float>(x);
      50             :         return ldexpf(raw, -kShiftBits);
      51             :     }
      52             : 
      53             :     // Returns the maximum pixel span of a filter.
      54           0 :     int maxFilter() const { return fMaxFilter; }
      55             : 
      56             :     // Returns the number of filters in this filter. This is the dimension of the
      57             :     // output image.
      58           0 :     int numValues() const { return static_cast<int>(fFilters.count()); }
      59             : 
      60           0 :     void reserveAdditional(int filterCount, int filterValueCount) {
      61           0 :         fFilters.setReserve(fFilters.count() + filterCount);
      62           0 :         fFilterValues.setReserve(fFilterValues.count() + filterValueCount);
      63           0 :     }
      64             : 
      65             :     // Appends the given list of scaling values for generating a given output
      66             :     // pixel. |filterOffset| is the distance from the edge of the image to where
      67             :     // the scaling factors start. The scaling factors apply to the source pixels
      68             :     // starting from this position, and going for the next |filterLength| pixels.
      69             :     //
      70             :     // You will probably want to make sure your input is normalized (that is,
      71             :     // all entries in |filterValuesg| sub to one) to prevent affecting the overall
      72             :     // brighness of the image.
      73             :     //
      74             :     // The filterLength must be > 0.
      75             :     void AddFilter(int filterOffset,
      76             :                    const ConvolutionFixed* filterValues,
      77             :                    int filterLength);
      78             : 
      79             :     // Retrieves a filter for the given |valueOffset|, a position in the output
      80             :     // image in the direction we're convolving. The offset and length of the
      81             :     // filter values are put into the corresponding out arguments (see AddFilter
      82             :     // above for what these mean), and a pointer to the first scaling factor is
      83             :     // returned. There will be |filterLength| values in this array.
      84           0 :     inline const ConvolutionFixed* FilterForValue(int valueOffset,
      85             :                                        int* filterOffset,
      86             :                                        int* filterLength) const {
      87           0 :         const FilterInstance& filter = fFilters[valueOffset];
      88           0 :         *filterOffset = filter.fOffset;
      89           0 :         *filterLength = filter.fTrimmedLength;
      90           0 :         if (filter.fTrimmedLength == 0) {
      91           0 :             return nullptr;
      92             :         }
      93           0 :         return &fFilterValues[filter.fDataLocation];
      94             :     }
      95             : 
      96             :   // Retrieves the filter for the offset 0, presumed to be the one and only.
      97             :   // The offset and length of the filter values are put into the corresponding
      98             :   // out arguments (see AddFilter). Note that |filterLegth| and
      99             :   // |specifiedFilterLength| may be different if leading/trailing zeros of the
     100             :   // original floating point form were clipped.
     101             :   // There will be |filterLength| values in the return array.
     102             :   // Returns nullptr if the filter is 0-length (for instance when all floating
     103             :   // point values passed to AddFilter were clipped to 0).
     104             :     SK_API const ConvolutionFixed* GetSingleFilter(int* specifiedFilterLength,
     105             :         int* filterOffset,
     106             :         int* filterLength) const;
     107             : 
     108             :     // Add another value to the fFilterValues array -- useful for
     109             :     // SIMD padding which happens outside of this class.
     110             : 
     111             :     void addFilterValue( ConvolutionFixed val ) {
     112             :         fFilterValues.push( val );
     113             :     }
     114             : private:
     115             :     struct FilterInstance {
     116             :         // Offset within filterValues for this instance of the filter.
     117             :         int fDataLocation;
     118             : 
     119             :         // Distance from the left of the filter to the center. IN PIXELS
     120             :         int fOffset;
     121             : 
     122             :         // Number of values in this filter instance.
     123             :         int fTrimmedLength;
     124             : 
     125             :         // Filter length as specified. Note that this may be different from
     126             :         // 'trimmed_length' if leading/trailing zeros of the original floating
     127             :         // point form were clipped differently on each tail.
     128             :         int fLength;
     129             :     };
     130             : 
     131             :     // Stores the information for each filter added to this class.
     132             :     SkTDArray<FilterInstance> fFilters;
     133             : 
     134             :     // We store all the filter values in this flat list, indexed by
     135             :     // |FilterInstance.data_location| to avoid the mallocs required for storing
     136             :     // each one separately.
     137             :     SkTDArray<ConvolutionFixed> fFilterValues;
     138             : 
     139             :     // The maximum size of any filter we've added.
     140             :     int fMaxFilter;
     141             : };
     142             : 
     143             : // Does a two-dimensional convolution on the given source image.
     144             : //
     145             : // It is assumed the source pixel offsets referenced in the input filters
     146             : // reference only valid pixels, so the source image size is not required. Each
     147             : // row of the source image starts |sourceByteRowStride| after the previous
     148             : // one (this allows you to have rows with some padding at the end).
     149             : //
     150             : // The result will be put into the given output buffer. The destination image
     151             : // size will be xfilter.numValues() * yfilter.numValues() pixels. It will be
     152             : // in rows of exactly xfilter.numValues() * 4 bytes.
     153             : //
     154             : // |sourceHasAlpha| is a hint that allows us to avoid doing computations on
     155             : // the alpha channel if the image is opaque. If you don't know, set this to
     156             : // true and it will work properly, but setting this to false will be a few
     157             : // percent faster if you know the image is opaque.
     158             : //
     159             : // The layout in memory is assumed to be 4-bytes per pixel in B-G-R-A order
     160             : // (this is ARGB when loaded into 32-bit words on a little-endian machine).
     161             : /**
     162             :  *  Returns false if it was unable to perform the convolution/rescale. in which case the output
     163             :  *  buffer is assumed to be undefined.
     164             :  */
     165             : SK_API bool BGRAConvolve2D(const unsigned char* sourceData,
     166             :     int sourceByteRowStride,
     167             :     bool sourceHasAlpha,
     168             :     const SkConvolutionFilter1D& xfilter,
     169             :     const SkConvolutionFilter1D& yfilter,
     170             :     int outputByteRowStride,
     171             :     unsigned char* output);
     172             : 
     173             : #endif  // SK_CONVOLVER_H

Generated by: LCOV version 1.13