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