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 #include "SkKernel33MaskFilter.h"
      9 #include "SkColorPriv.h"
     10 #include "SkFlattenableBuffers.h"
     11 #include "SkString.h"
     12 
     13 SkMask::Format SkKernel33ProcMaskFilter::getFormat() const {
     14     return SkMask::kA8_Format;
     15 }
     16 
     17 bool SkKernel33ProcMaskFilter::filterMask(SkMask* dst, const SkMask& src,
     18                                       const SkMatrix&, SkIPoint* margin) const {
     19     // margin???
     20     dst->fImage = NULL;
     21     dst->fBounds = src.fBounds;
     22     dst->fBounds.inset(-1, -1);
     23     dst->fFormat = SkMask::kA8_Format;
     24 
     25     if (NULL == src.fImage) {
     26         return true;
     27     }
     28 
     29     dst->fRowBytes = dst->fBounds.width();
     30     size_t size = dst->computeImageSize();
     31     if (0 == size) {
     32         return false;   // too big to allocate, abort
     33     }
     34     dst->fImage = SkMask::AllocImage(size);
     35 
     36     const int h = src.fBounds.height();
     37     const int w = src.fBounds.width();
     38     const int srcRB = src.fRowBytes;
     39     const uint8_t* srcImage = src.fImage;
     40     uint8_t* dstImage = dst->fImage;
     41 
     42     uint8_t* srcRows[3];
     43     uint8_t storage[3][3];
     44 
     45     srcRows[0] = storage[0];
     46     srcRows[1] = storage[1];
     47     srcRows[2] = storage[2];
     48 
     49     unsigned scale = fPercent256;
     50 
     51     for (int y = -1; y <= h; y++) {
     52         uint8_t* dstRow = dstImage;
     53         for (int x = -1; x <= w; x++) {
     54             memset(storage, 0, sizeof(storage));
     55             uint8_t* storagePtr = &storage[0][0];
     56 
     57             for (int ky = y - 1; ky <= y + 1; ky++) {
     58                 const uint8_t* srcRow = srcImage + ky * srcRB;  // may be out-of-range
     59                 for (int kx = x - 1; kx <= x + 1; kx++) {
     60                     if ((unsigned)ky < (unsigned)h && (unsigned)kx < (unsigned)w) {
     61                         *storagePtr = srcRow[kx];
     62                     }
     63                     storagePtr++;
     64                 }
     65             }
     66             int value = this->computeValue(srcRows);
     67 
     68             if (scale < 256) {
     69                 value = SkAlphaBlend(value, srcRows[1][1], scale);
     70             }
     71             *dstRow++ = SkToU8(value);
     72         }
     73         dstImage += dst->fRowBytes;
     74     }
     75     return true;
     76 }
     77 
     78 void SkKernel33ProcMaskFilter::flatten(SkFlattenableWriteBuffer& wb) const {
     79     this->INHERITED::flatten(wb);
     80     wb.writeInt(fPercent256);
     81 }
     82 
     83 SkKernel33ProcMaskFilter::SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb)
     84         : SkMaskFilter(rb) {
     85     fPercent256 = rb.readInt();
     86 }
     87 
     88 #ifdef SK_DEVELOPER
     89 void SkKernel33ProcMaskFilter::toString(SkString* str) const {
     90     str->appendf("percent256: %d, ", fPercent256);
     91 }
     92 #endif
     93 
     94 ///////////////////////////////////////////////////////////////////////////////
     95 
     96 uint8_t SkKernel33MaskFilter::computeValue(uint8_t* const* srcRows) const {
     97     int value = 0;
     98 
     99     for (int i = 0; i < 3; i++) {
    100         for (int j = 0; j < 3; j++) {
    101             value += fKernel[i][j] * srcRows[i][j];
    102         }
    103     }
    104 
    105     value >>= fShift;
    106 
    107     if (value < 0) {
    108         value = 0;
    109     } else if (value > 255) {
    110         value = 255;
    111     }
    112     return (uint8_t)value;
    113 }
    114 
    115 void SkKernel33MaskFilter::flatten(SkFlattenableWriteBuffer& wb) const {
    116     this->INHERITED::flatten(wb);
    117     wb.writeIntArray(&fKernel[0][0], 9);
    118     wb.writeInt(fShift);
    119 }
    120 
    121 SkKernel33MaskFilter::SkKernel33MaskFilter(SkFlattenableReadBuffer& rb)
    122         : SkKernel33ProcMaskFilter(rb) {
    123     SkDEBUGCODE(const uint32_t count = )rb.readIntArray(&fKernel[0][0]);
    124     SkASSERT(9 == count);
    125     fShift = rb.readInt();
    126 }
    127 
    128 #ifdef SK_DEVELOPER
    129 void SkKernel33MaskFilter::toString(SkString* str) const {
    130     str->append("SkKernel33MaskFilter: (");
    131 
    132     str->appendf("kernel: (%d, %d, %d, %d, %d, %d, %d, %d, %d), ",
    133             fKernel[0][0], fKernel[0][1], fKernel[0][2],
    134             fKernel[1][0], fKernel[1][1], fKernel[1][2],
    135             fKernel[2][0], fKernel[2][1], fKernel[2][2]);
    136     str->appendf("shift: %d, ", fShift);
    137 
    138     this->INHERITED::toString(str);
    139 
    140     str->append(")");
    141 }
    142 #endif
    143