| Index: skia/effects/SkColorMatrixFilter.cpp
|
| ===================================================================
|
| --- skia/effects/SkColorMatrixFilter.cpp (revision 16859)
|
| +++ skia/effects/SkColorMatrixFilter.cpp (working copy)
|
| @@ -1,330 +0,0 @@
|
| -#include "SkColorMatrixFilter.h"
|
| -#include "SkColorMatrix.h"
|
| -#include "SkColorPriv.h"
|
| -#include "SkUnPreMultiply.h"
|
| -
|
| -static int32_t rowmul4(const int32_t array[], unsigned r, unsigned g,
|
| - unsigned b, unsigned a) {
|
| - return array[0] * r + array[1] * g + array[2] * b + array[3] * a + array[4];
|
| -}
|
| -
|
| -static int32_t rowmul3(const int32_t array[], unsigned r, unsigned g,
|
| - unsigned b) {
|
| - return array[0] * r + array[1] * g + array[2] * b + array[4];
|
| -}
|
| -
|
| -static void General(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - const int shift = state->fShift;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - result[0] = rowmul4(&array[0], r, g, b, a) >> shift;
|
| - result[1] = rowmul4(&array[5], r, g, b, a) >> shift;
|
| - result[2] = rowmul4(&array[10], r, g, b, a) >> shift;
|
| - result[3] = rowmul4(&array[15], r, g, b, a) >> shift;
|
| -}
|
| -
|
| -static void General16(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - result[0] = rowmul4(&array[0], r, g, b, a) >> 16;
|
| - result[1] = rowmul4(&array[5], r, g, b, a) >> 16;
|
| - result[2] = rowmul4(&array[10], r, g, b, a) >> 16;
|
| - result[3] = rowmul4(&array[15], r, g, b, a) >> 16;
|
| -}
|
| -
|
| -static void AffineAdd(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - const int shift = state->fShift;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - result[0] = rowmul3(&array[0], r, g, b) >> shift;
|
| - result[1] = rowmul3(&array[5], r, g, b) >> shift;
|
| - result[2] = rowmul3(&array[10], r, g, b) >> shift;
|
| - result[3] = a;
|
| -}
|
| -
|
| -static void AffineAdd16(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - result[0] = rowmul3(&array[0], r, g, b) >> 16;
|
| - result[1] = rowmul3(&array[5], r, g, b) >> 16;
|
| - result[2] = rowmul3(&array[10], r, g, b) >> 16;
|
| - result[3] = a;
|
| -}
|
| -
|
| -static void ScaleAdd(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - const int shift = state->fShift;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - // cast to (int) to keep the expression signed for the shift
|
| - result[0] = (array[0] * (int)r + array[4]) >> shift;
|
| - result[1] = (array[6] * (int)g + array[9]) >> shift;
|
| - result[2] = (array[12] * (int)b + array[14]) >> shift;
|
| - result[3] = a;
|
| -}
|
| -
|
| -static void ScaleAdd16(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - // cast to (int) to keep the expression signed for the shift
|
| - result[0] = (array[0] * (int)r + array[4]) >> 16;
|
| - result[1] = (array[6] * (int)g + array[9]) >> 16;
|
| - result[2] = (array[12] * (int)b + array[14]) >> 16;
|
| - result[3] = a;
|
| -}
|
| -
|
| -static void Add(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - const int shift = state->fShift;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - result[0] = r + (array[4] >> shift);
|
| - result[1] = g + (array[9] >> shift);
|
| - result[2] = b + (array[14] >> shift);
|
| - result[3] = a;
|
| -}
|
| -
|
| -static void Add16(SkColorMatrixFilter::State* state,
|
| - unsigned r, unsigned g, unsigned b, unsigned a) {
|
| - const int32_t* SK_RESTRICT array = state->fArray;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - result[0] = r + (array[4] >> 16);
|
| - result[1] = g + (array[9] >> 16);
|
| - result[2] = b + (array[14] >> 16);
|
| - result[3] = a;
|
| -}
|
| -
|
| -#define kNO_ALPHA_FLAGS (SkColorFilter::kAlphaUnchanged_Flag | \
|
| - SkColorFilter::kHasFilter16_Flag)
|
| -
|
| -void SkColorMatrixFilter::setup(const SkScalar SK_RESTRICT src[20]) {
|
| - if (NULL == src) {
|
| - fProc = NULL; // signals identity
|
| - fFlags = kNO_ALPHA_FLAGS;
|
| - // fState is undefined, but that is OK, since we shouldn't look at it
|
| - return;
|
| - }
|
| -
|
| - int32_t* SK_RESTRICT array = fState.fArray;
|
| -
|
| - int i;
|
| - SkFixed max = 0;
|
| -
|
| - for (int i = 0; i < 20; i++) {
|
| - SkFixed value = SkScalarToFixed(src[i]);
|
| - array[i] = value;
|
| - value = SkAbs32(value);
|
| - max = SkMax32(max, value);
|
| - }
|
| -
|
| - /* All of fArray[] values must fit in 23 bits, to safely allow me to
|
| - multiply them by 8bit unsigned values, and get a signed answer without
|
| - overflow. This means clz needs to be 9 or bigger
|
| - */
|
| - int bits = SkCLZ(max);
|
| - int32_t one = SK_Fixed1;
|
| -
|
| - fState.fShift = 16; // we are starting out as fixed 16.16
|
| - if (bits < 9) {
|
| - bits = 9 - bits;
|
| - fState.fShift -= bits;
|
| - for (i = 0; i < 20; i++) {
|
| - array[i] >>= bits;
|
| - }
|
| - one >>= bits;
|
| - }
|
| -
|
| - // check if we have to munge Alpha
|
| - int32_t changesAlpha = (array[15] | array[16] | array[17] |
|
| - (array[18] - one) | array[19]);
|
| - int32_t usesAlpha = (array[3] | array[8] | array[13]);
|
| - bool shiftIs16 = (16 == fState.fShift);
|
| -
|
| - if (changesAlpha | usesAlpha) {
|
| - fProc = shiftIs16 ? General16 : General;
|
| - fFlags = changesAlpha ? 0 : SkColorFilter::kAlphaUnchanged_Flag;
|
| - } else {
|
| - fFlags = kNO_ALPHA_FLAGS;
|
| -
|
| - int32_t needsScale = (array[0] - one) | // red axis
|
| - (array[6] - one) | // green axis
|
| - (array[12] - one); // blue axis
|
| -
|
| - int32_t needs3x3 = array[1] | array[2] | // red off-axis
|
| - array[5] | array[7] | // green off-axis
|
| - array[10] | array[11]; // blue off-axis
|
| -
|
| - if (needs3x3) {
|
| - fProc = shiftIs16 ? AffineAdd16 : AffineAdd;
|
| - } else if (needsScale) {
|
| - fProc = shiftIs16 ? ScaleAdd16 : ScaleAdd;
|
| - } else if (array[4] | array[9] | array[14]) { // needs add
|
| - fProc = shiftIs16 ? Add16 : Add;
|
| - } else {
|
| - fProc = NULL; // identity
|
| - }
|
| - }
|
| -
|
| - /* preround our add values so we get a rounded shift. We do this after we
|
| - analyze the array, so we don't miss the case where the caller has zeros
|
| - which could make us accidentally take the General or Add case.
|
| - */
|
| - if (NULL != fProc) {
|
| - int32_t add = 1 << (fState.fShift - 1);
|
| - array[4] += add;
|
| - array[9] += add;
|
| - array[14] += add;
|
| - array[19] += add;
|
| - }
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -static int32_t pin(int32_t value, int32_t max) {
|
| - if (value < 0) {
|
| - value = 0;
|
| - }
|
| - if (value > max) {
|
| - value = max;
|
| - }
|
| - return value;
|
| -}
|
| -
|
| -SkColorMatrixFilter::SkColorMatrixFilter() {
|
| - this->setup(NULL);
|
| -}
|
| -
|
| -SkColorMatrixFilter::SkColorMatrixFilter(const SkColorMatrix& cm) {
|
| - this->setup(cm.fMat);
|
| -}
|
| -
|
| -SkColorMatrixFilter::SkColorMatrixFilter(const SkScalar array[20]) {
|
| - this->setup(array);
|
| -}
|
| -
|
| -uint32_t SkColorMatrixFilter::getFlags() {
|
| - return this->INHERITED::getFlags() | fFlags;
|
| -}
|
| -
|
| -void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count,
|
| - SkPMColor dst[]) {
|
| - Proc proc = fProc;
|
| - State* state = &fState;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - if (NULL == proc) {
|
| - if (src != dst) {
|
| - memcpy(dst, src, count * sizeof(SkPMColor));
|
| - }
|
| - return;
|
| - }
|
| -
|
| - const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
|
| -
|
| - for (int i = 0; i < count; i++) {
|
| - SkPMColor c = src[i];
|
| -
|
| - unsigned r = SkGetPackedR32(c);
|
| - unsigned g = SkGetPackedG32(c);
|
| - unsigned b = SkGetPackedB32(c);
|
| - unsigned a = SkGetPackedA32(c);
|
| -
|
| - // need our components to be un-premultiplied
|
| - if (255 != a) {
|
| - SkUnPreMultiply::Scale scale = table[a];
|
| - r = SkUnPreMultiply::ApplyScale(scale, r);
|
| - g = SkUnPreMultiply::ApplyScale(scale, g);
|
| - b = SkUnPreMultiply::ApplyScale(scale, b);
|
| -
|
| - SkASSERT(r <= 255);
|
| - SkASSERT(g <= 255);
|
| - SkASSERT(b <= 255);
|
| - }
|
| -
|
| - proc(state, r, g, b, a);
|
| -
|
| - r = pin(result[0], SK_R32_MASK);
|
| - g = pin(result[1], SK_G32_MASK);
|
| - b = pin(result[2], SK_B32_MASK);
|
| - a = pin(result[3], SK_A32_MASK);
|
| - // re-prepremultiply if needed
|
| - if (255 != a) {
|
| - int scale = SkAlpha255To256(a);
|
| - r = SkAlphaMul(r, scale);
|
| - g = SkAlphaMul(g, scale);
|
| - b = SkAlphaMul(b, scale);
|
| - }
|
| - dst[i] = SkPackARGB32(a, r, g, b);
|
| - }
|
| -}
|
| -
|
| -void SkColorMatrixFilter::filterSpan16(const uint16_t src[], int count,
|
| - uint16_t dst[]) {
|
| - SkASSERT(fFlags & SkColorFilter::kHasFilter16_Flag);
|
| -
|
| - Proc proc = fProc;
|
| - State* state = &fState;
|
| - int32_t* SK_RESTRICT result = state->fResult;
|
| -
|
| - if (NULL == proc) {
|
| - if (src != dst) {
|
| - memcpy(dst, src, count * sizeof(uint16_t));
|
| - }
|
| - return;
|
| - }
|
| -
|
| - for (int i = 0; i < count; i++) {
|
| - uint16_t c = src[i];
|
| -
|
| - // expand to 8bit components (since our matrix translate is 8bit biased
|
| - unsigned r = SkPacked16ToR32(c);
|
| - unsigned g = SkPacked16ToG32(c);
|
| - unsigned b = SkPacked16ToB32(c);
|
| -
|
| - proc(state, r, g, b, 0);
|
| -
|
| - r = pin(result[0], SK_R32_MASK);
|
| - g = pin(result[1], SK_G32_MASK);
|
| - b = pin(result[2], SK_B32_MASK);
|
| -
|
| - // now packed it back down to 16bits (hmmm, could dither...)
|
| - dst[i] = SkPack888ToRGB16(r, g, b);
|
| - }
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -void SkColorMatrixFilter::flatten(SkFlattenableWriteBuffer& buffer) {
|
| - this->INHERITED::flatten(buffer);
|
| -
|
| - buffer.writeFunctionPtr((void*)fProc);
|
| - buffer.writeMul4(&fState, sizeof(fState));
|
| - buffer.write32(fFlags);
|
| -}
|
| -
|
| -SkFlattenable::Factory SkColorMatrixFilter::getFactory() { return CreateProc; }
|
| -
|
| -SkColorMatrixFilter::SkColorMatrixFilter(SkFlattenableReadBuffer& buffer)
|
| - : INHERITED(buffer) {
|
| - fProc = (Proc)buffer.readFunctionPtr();
|
| - buffer.read(&fState, sizeof(fState));
|
| - fFlags = buffer.readU32();
|
| -}
|
| -
|
| -SkFlattenable* SkColorMatrixFilter::CreateProc(SkFlattenableReadBuffer& buf) {
|
| - return SkNEW_ARGS(SkColorMatrixFilter, (buf));
|
| -}
|
| -
|
|
|