gfx/skia/trunk/src/core/SkConvolver.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial