Home | History | Annotate | Download | only in effects
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkTableMaskFilter.h"
     11 #include "SkFlattenableBuffers.h"
     12 #include "SkString.h"
     13 
     14 SkTableMaskFilter::SkTableMaskFilter() {
     15     for (int i = 0; i < 256; i++) {
     16         fTable[i] = i;
     17     }
     18 }
     19 
     20 SkTableMaskFilter::SkTableMaskFilter(const uint8_t table[256]) {
     21     memcpy(fTable, table, sizeof(fTable));
     22 }
     23 
     24 SkTableMaskFilter::~SkTableMaskFilter() {}
     25 
     26 bool SkTableMaskFilter::filterMask(SkMask* dst, const SkMask& src,
     27                                  const SkMatrix&, SkIPoint* margin) const {
     28     if (src.fFormat != SkMask::kA8_Format) {
     29         return false;
     30     }
     31 
     32     dst->fBounds = src.fBounds;
     33     dst->fRowBytes = SkAlign4(dst->fBounds.width());
     34     dst->fFormat = SkMask::kA8_Format;
     35     dst->fImage = NULL;
     36 
     37     if (src.fImage) {
     38         dst->fImage = SkMask::AllocImage(dst->computeImageSize());
     39 
     40         const uint8_t* srcP = src.fImage;
     41         uint8_t* dstP = dst->fImage;
     42         const uint8_t* table = fTable;
     43         int dstWidth = dst->fBounds.width();
     44         int extraZeros = dst->fRowBytes - dstWidth;
     45 
     46         for (int y = dst->fBounds.height() - 1; y >= 0; --y) {
     47             for (int x = dstWidth - 1; x >= 0; --x) {
     48                 dstP[x] = table[srcP[x]];
     49             }
     50             srcP += src.fRowBytes;
     51             // we can't just inc dstP by rowbytes, because if it has any
     52             // padding between its width and its rowbytes, we need to zero those
     53             // so that the bitters can read those safely if that is faster for
     54             // them
     55             dstP += dstWidth;
     56             for (int i = extraZeros - 1; i >= 0; --i) {
     57                 *dstP++ = 0;
     58             }
     59         }
     60     }
     61 
     62     if (margin) {
     63         margin->set(0, 0);
     64     }
     65     return true;
     66 }
     67 
     68 SkMask::Format SkTableMaskFilter::getFormat() const {
     69     return SkMask::kA8_Format;
     70 }
     71 
     72 void SkTableMaskFilter::flatten(SkFlattenableWriteBuffer& wb) const {
     73     this->INHERITED::flatten(wb);
     74     wb.writeByteArray(fTable, 256);
     75 }
     76 
     77 SkTableMaskFilter::SkTableMaskFilter(SkFlattenableReadBuffer& rb)
     78         : INHERITED(rb) {
     79     SkASSERT(256 == rb.getArrayCount());
     80     rb.readByteArray(fTable, 256);
     81 }
     82 
     83 ///////////////////////////////////////////////////////////////////////////////
     84 
     85 void SkTableMaskFilter::MakeGammaTable(uint8_t table[256], SkScalar gamma) {
     86     const float dx = 1 / 255.0f;
     87     const float g = SkScalarToFloat(gamma);
     88 
     89     float x = 0;
     90     for (int i = 0; i < 256; i++) {
     91      // float ee = powf(x, g) * 255;
     92         table[i] = SkPin32(sk_float_round2int(powf(x, g) * 255), 0, 255);
     93         x += dx;
     94     }
     95 }
     96 
     97 void SkTableMaskFilter::MakeClipTable(uint8_t table[256], uint8_t min,
     98                                       uint8_t max) {
     99     if (0 == max) {
    100         max = 1;
    101     }
    102     if (min >= max) {
    103         min = max - 1;
    104     }
    105     SkASSERT(min < max);
    106 
    107     SkFixed scale = (1 << 16) * 255 / (max - min);
    108     memset(table, 0, min + 1);
    109     for (int i = min + 1; i < max; i++) {
    110         int value = SkFixedRound(scale * (i - min));
    111         SkASSERT(value <= 255);
    112         table[i] = value;
    113     }
    114     memset(table + max, 255, 256 - max);
    115 
    116 #if 0
    117     int j;
    118     for (j = 0; j < 256; j++) {
    119         if (table[j]) {
    120             break;
    121         }
    122     }
    123     SkDebugf("%d %d start [%d]", min, max, j);
    124     for (; j < 256; j++) {
    125         SkDebugf(" %d", table[j]);
    126     }
    127     SkDebugf("\n\n");
    128 #endif
    129 }
    130 
    131 #ifdef SK_DEVELOPER
    132 void SkTableMaskFilter::toString(SkString* str) const {
    133     str->append("SkTableMaskFilter: (");
    134 
    135     str->append("table: ");
    136     for (int i = 0; i < 255; ++i) {
    137         str->appendf("%d, ", fTable[i]);
    138     }
    139     str->appendf("%d", fTable[255]);
    140 
    141     str->append(")");
    142 }
    143 #endif
    144