180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTableMaskFilter.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h" 12096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkString.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkTableMaskFilter::SkTableMaskFilter() { 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 256; i++) { 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTable[i] = i; 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkTableMaskFilter::SkTableMaskFilter(const uint8_t table[256]) { 21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger memcpy(fTable, table, sizeof(fTable)); 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkTableMaskFilter::~SkTableMaskFilter() {} 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkTableMaskFilter::filterMask(SkMask* dst, const SkMask& src, 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix&, SkIPoint* margin) const { 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (src.fFormat != SkMask::kA8_Format) { 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fBounds = src.fBounds; 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fRowBytes = SkAlign4(dst->fBounds.width()); 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fFormat = SkMask::kA8_Format; 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fImage = NULL; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (src.fImage) { 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fImage = SkMask::AllocImage(dst->computeImageSize()); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* srcP = src.fImage; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t* dstP = dst->fImage; 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* table = fTable; 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstWidth = dst->fBounds.width(); 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int extraZeros = dst->fRowBytes - dstWidth; 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int y = dst->fBounds.height() - 1; y >= 0; --y) { 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int x = dstWidth - 1; x >= 0; --x) { 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dstP[x] = table[srcP[x]]; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcP += src.fRowBytes; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we can't just inc dstP by rowbytes, because if it has any 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // padding between its width and its rowbytes, we need to zero those 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // so that the bitters can read those safely if that is faster for 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // them 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dstP += dstWidth; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = extraZeros - 1; i >= 0; --i) { 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *dstP++ = 0; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (margin) { 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru margin->set(0, 0); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerSkMask::Format SkTableMaskFilter::getFormat() const { 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkMask::kA8_Format; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkTableMaskFilter::flatten(SkFlattenableWriteBuffer& wb) const { 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::flatten(wb); 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wb.writeByteArray(fTable, 256); 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkTableMaskFilter::SkTableMaskFilter(SkFlattenableReadBuffer& rb) 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : INHERITED(rb) { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(256 == rb.getArrayCount()); 800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger rb.readByteArray(fTable, 256); 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkTableMaskFilter::MakeGammaTable(uint8_t table[256], SkScalar gamma) { 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const float dx = 1 / 255.0f; 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const float g = SkScalarToFloat(gamma); 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float x = 0; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 256; i++) { 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // float ee = powf(x, g) * 255; 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru table[i] = SkPin32(sk_float_round2int(powf(x, g) * 255), 0, 255); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x += dx; 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkTableMaskFilter::MakeClipTable(uint8_t table[256], uint8_t min, 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t max) { 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == max) { 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru max = 1; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (min >= max) { 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru min = max - 1; 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(min < max); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed scale = (1 << 16) * 255 / (max - min); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(table, 0, min + 1); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = min + 1; i < max; i++) { 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int value = SkFixedRound(scale * (i - min)); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(value <= 255); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru table[i] = value; 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(table + max, 255, 256 - max); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int j; 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (j = 0; j < 256; j++) { 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (table[j]) { 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("%d %d start [%d]", min, max, j); 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (; j < 256; j++) { 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %d", table[j]); 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\n\n"); 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 130096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 131096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#ifdef SK_DEVELOPER 132096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergervoid SkTableMaskFilter::toString(SkString* str) const { 133096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger str->append("SkTableMaskFilter: ("); 134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 135096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger str->append("table: "); 136096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int i = 0; i < 255; ++i) { 137096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger str->appendf("%d, ", fTable[i]); 138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 139096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger str->appendf("%d", fTable[255]); 140096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 141096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger str->append(")"); 142096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 143096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif 144