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(bool success = )rb.readIntArray(&fKernel[0][0], 9); 124 SkASSERT(success); 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