gfx/2d/convolver.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 // Copyright (c) 2006-2012 The Chromium Authors. All rights reserved.
     2 //
     3 // Redistribution and use in source and binary forms, with or without
     4 // modification, are permitted provided that the following conditions
     5 // are met:
     6 //  * Redistributions of source code must retain the above copyright
     7 //    notice, this list of conditions and the following disclaimer.
     8 //  * Redistributions in binary form must reproduce the above copyright
     9 //    notice, this list of conditions and the following disclaimer in
    10 //    the documentation and/or other materials provided with the
    11 //    distribution.
    12 //  * Neither the name of Google, Inc. nor the names of its contributors
    13 //    may be used to endorse or promote products derived from this
    14 //    software without specific prior written permission.
    15 //
    16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    19 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    20 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    21 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    22 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
    23 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    24 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    26 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    27 // SUCH DAMAGE.
    29 #ifndef SKIA_EXT_CONVOLVER_H_
    30 #define SKIA_EXT_CONVOLVER_H_
    32 #include <cmath>
    33 #include <vector>
    35 #include "base/basictypes.h"
    36 #include "base/cpu.h"
    37 #include "mozilla/Assertions.h"
    38 #include "skia/SkTypes.h"
    40 // avoid confusion with Mac OS X's math library (Carbon)
    41 #if defined(__APPLE__)
    42 #undef FloatToFixed
    43 #undef FixedToFloat
    44 #endif
    46 namespace skia {
    48 // Represents a filter in one dimension. Each output pixel has one entry in this
    49 // object for the filter values contributing to it. You build up the filter
    50 // list by calling AddFilter for each output pixel (in order).
    51 //
    52 // We do 2-dimensional convolution by first convolving each row by one
    53 // ConvolutionFilter1D, then convolving each column by another one.
    54 //
    55 // Entries are stored in fixed point, shifted left by kShiftBits.
    56 class ConvolutionFilter1D {
    57  public:
    58   typedef short Fixed;
    60   // The number of bits that fixed point values are shifted by.
    61   enum { kShiftBits = 14 };
    63   ConvolutionFilter1D();
    64   ~ConvolutionFilter1D();
    66   // Convert between floating point and our fixed point representation.
    67   static Fixed FloatToFixed(float f) {
    68     return static_cast<Fixed>(f * (1 << kShiftBits));
    69   }
    70   static unsigned char FixedToChar(Fixed x) {
    71     return static_cast<unsigned char>(x >> kShiftBits);
    72   }
    73   static float FixedToFloat(Fixed x) {
    74     // The cast relies on Fixed being a short, implying that on
    75     // the platforms we care about all (16) bits will fit into
    76     // the mantissa of a (32-bit) float.
    77     static_assert(sizeof(Fixed) == 2,
    78                   "fixed type should fit in float mantissa");
    79     float raw = static_cast<float>(x);
    80     return ldexpf(raw, -kShiftBits);
    81   }
    83   // Returns the maximum pixel span of a filter.
    84   int max_filter() const { return max_filter_; }
    86   // Returns the number of filters in this filter. This is the dimension of the
    87   // output image.
    88   int num_values() const { return static_cast<int>(filters_.size()); }
    90   // Appends the given list of scaling values for generating a given output
    91   // pixel. |filter_offset| is the distance from the edge of the image to where
    92   // the scaling factors start. The scaling factors apply to the source pixels
    93   // starting from this position, and going for the next |filter_length| pixels.
    94   //
    95   // You will probably want to make sure your input is normalized (that is,
    96   // all entries in |filter_values| sub to one) to prevent affecting the overall
    97   // brighness of the image.
    98   //
    99   // The filter_length must be > 0.
   100   //
   101   // This version will automatically convert your input to fixed point.
   102   void AddFilter(int filter_offset,
   103                         const float* filter_values,
   104                         int filter_length);
   106   // Same as the above version, but the input is already fixed point.
   107   void AddFilter(int filter_offset,
   108                  const Fixed* filter_values,
   109                  int filter_length);
   111   // Retrieves a filter for the given |value_offset|, a position in the output
   112   // image in the direction we're convolving. The offset and length of the
   113   // filter values are put into the corresponding out arguments (see AddFilter
   114   // above for what these mean), and a pointer to the first scaling factor is
   115   // returned. There will be |filter_length| values in this array.
   116   inline const Fixed* FilterForValue(int value_offset,
   117                                      int* filter_offset,
   118                                      int* filter_length) const {
   119     const FilterInstance& filter = filters_[value_offset];
   120     *filter_offset = filter.offset;
   121     *filter_length = filter.length;
   122     if (filter.length == 0) {
   123       return NULL;
   124     }
   125     return &filter_values_[filter.data_location];
   126   }
   129   inline void PaddingForSIMD(int padding_count) {
   130     // Padding |padding_count| of more dummy coefficients after the coefficients
   131     // of last filter to prevent SIMD instructions which load 8 or 16 bytes
   132     // together to access invalid memory areas. We are not trying to align the
   133     // coefficients right now due to the opaqueness of <vector> implementation.
   134     // This has to be done after all |AddFilter| calls.
   135     for (int i = 0; i < padding_count; ++i)
   136       filter_values_.push_back(static_cast<Fixed>(0));
   137   }
   139  private:
   140   struct FilterInstance {
   141     // Offset within filter_values for this instance of the filter.
   142     int data_location;
   144     // Distance from the left of the filter to the center. IN PIXELS
   145     int offset;
   147     // Number of values in this filter instance.
   148     int length;
   149   };
   151   // Stores the information for each filter added to this class.
   152   std::vector<FilterInstance> filters_;
   154   // We store all the filter values in this flat list, indexed by
   155   // |FilterInstance.data_location| to avoid the mallocs required for storing
   156   // each one separately.
   157   std::vector<Fixed> filter_values_;
   159   // The maximum size of any filter we've added.
   160   int max_filter_;
   161 };
   163 // Does a two-dimensional convolution on the given source image.
   164 //
   165 // It is assumed the source pixel offsets referenced in the input filters
   166 // reference only valid pixels, so the source image size is not required. Each
   167 // row of the source image starts |source_byte_row_stride| after the previous
   168 // one (this allows you to have rows with some padding at the end).
   169 //
   170 // The result will be put into the given output buffer. The destination image
   171 // size will be xfilter.num_values() * yfilter.num_values() pixels. It will be
   172 // in rows of exactly xfilter.num_values() * 4 bytes.
   173 //
   174 // |source_has_alpha| is a hint that allows us to avoid doing computations on
   175 // the alpha channel if the image is opaque. If you don't know, set this to
   176 // true and it will work properly, but setting this to false will be a few
   177 // percent faster if you know the image is opaque.
   178 //
   179 // The layout in memory is assumed to be 4-bytes per pixel in B-G-R-A order
   180 // (this is ARGB when loaded into 32-bit words on a little-endian machine).
   181 void BGRAConvolve2D(const unsigned char* source_data,
   182                     int source_byte_row_stride,
   183                     bool source_has_alpha,
   184                     const ConvolutionFilter1D& xfilter,
   185                     const ConvolutionFilter1D& yfilter,
   186                     int output_byte_row_stride,
   187                     unsigned char* output,
   188                     bool use_sse2);
   189 }  // namespace skia
   191 #endif  // SKIA_EXT_CONVOLVER_H_

mercurial