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