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