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