• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getFormat() const13 SkMask::Format SkKernel33ProcMaskFilter::getFormat() const {
14     return SkMask::kA8_Format;
15 }
16 
filterMask(SkMask * dst,const SkMask & src,const SkMatrix &,SkIPoint * margin) const17 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 
flatten(SkFlattenableWriteBuffer & wb) const78 void SkKernel33ProcMaskFilter::flatten(SkFlattenableWriteBuffer& wb) const {
79     this->INHERITED::flatten(wb);
80     wb.writeInt(fPercent256);
81 }
82 
SkKernel33ProcMaskFilter(SkFlattenableReadBuffer & rb)83 SkKernel33ProcMaskFilter::SkKernel33ProcMaskFilter(SkFlattenableReadBuffer& rb)
84         : SkMaskFilter(rb) {
85     fPercent256 = rb.readInt();
86 }
87 
88 #ifdef SK_DEVELOPER
toString(SkString * str) const89 void SkKernel33ProcMaskFilter::toString(SkString* str) const {
90     str->appendf("percent256: %d, ", fPercent256);
91 }
92 #endif
93 
94 ///////////////////////////////////////////////////////////////////////////////
95 
computeValue(uint8_t * const * srcRows) const96 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 
flatten(SkFlattenableWriteBuffer & wb) const115 void SkKernel33MaskFilter::flatten(SkFlattenableWriteBuffer& wb) const {
116     this->INHERITED::flatten(wb);
117     wb.writeIntArray(&fKernel[0][0], 9);
118     wb.writeInt(fShift);
119 }
120 
SkKernel33MaskFilter(SkFlattenableReadBuffer & rb)121 SkKernel33MaskFilter::SkKernel33MaskFilter(SkFlattenableReadBuffer& rb)
122         : SkKernel33ProcMaskFilter(rb) {
123     SkDEBUGCODE(bool success = )rb.readIntArray(&fKernel[0][0], 9);
124     SkASSERT(success);
125     fShift = rb.readInt();
126 }
127 
128 #ifdef SK_DEVELOPER
toString(SkString * str) const129 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