| Index: src/effects/SkColorFilterImageFilter.cpp
|
| diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
|
| index acd6fac25e4a793405a87dc0f4d5559d0538b18f..0a4a693ab0ce71e0272bbf251e548a734b1c774f 100755
|
| --- a/src/effects/SkColorFilterImageFilter.cpp
|
| +++ b/src/effects/SkColorFilterImageFilter.cpp
|
| @@ -12,6 +12,7 @@
|
| #include "SkDevice.h"
|
| #include "SkColorFilter.h"
|
| #include "SkReadBuffer.h"
|
| +#include "SkTableColorFilter.h"
|
| #include "SkWriteBuffer.h"
|
|
|
| namespace {
|
| @@ -21,7 +22,19 @@ void mult_color_matrix(SkScalar a[20], SkScalar b[20], SkScalar out[20]) {
|
| for (int i = 0; i < 5; ++i) {
|
| out[i+j*5] = 4 == i ? a[4+j*5] : 0;
|
| for (int k = 0; k < 4; ++k)
|
| - out[i+j*5] += SkScalarMul(a[k+j*5], b[i+k*5]);
|
| + out[i+j*5] += a[k+j*5] * b[i+k*5];
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Combines the two lookup tables so that making a lookup using OUT has
|
| +// the same effect as making a lookup through B then A.
|
| +void combine_color_tables(const uint8_t a[4 * 256],
|
| + const uint8_t b[4 * 256],
|
| + uint8_t out[4 * 256]) {
|
| + for (int i = 0; i < 4; i++) {
|
| + for (int j = 0; j < 256; j++) {
|
| + out[i * 256 + j] = a[i * 256 + b[i * 256 + j]];
|
| }
|
| }
|
| }
|
| @@ -59,23 +72,44 @@ bool matrix_needs_clamping(SkScalar matrix[20]) {
|
|
|
| SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
|
| SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID) {
|
| - SkASSERT(cf);
|
| if (NULL == cf) {
|
| return NULL;
|
| }
|
| - SkScalar colorMatrix[20], inputMatrix[20];
|
| +
|
| SkColorFilter* inputColorFilter;
|
| - if (input && cf->asColorMatrix(colorMatrix)
|
| - && input->asColorFilter(&inputColorFilter)
|
| - && (inputColorFilter)) {
|
| + if (input && input->asColorFilter(&inputColorFilter) && inputColorFilter) {
|
| SkAutoUnref autoUnref(inputColorFilter);
|
| - if (inputColorFilter->asColorMatrix(inputMatrix) && !matrix_needs_clamping(inputMatrix)) {
|
| +
|
| + // Try to collapse two consecutive matrix filters
|
| + SkScalar colorMatrix[20], inputMatrix[20];
|
| + if (cf->asColorMatrix(colorMatrix) && inputColorFilter->asColorMatrix(inputMatrix)
|
| + && !matrix_needs_clamping(inputMatrix)) {
|
| SkScalar combinedMatrix[20];
|
| mult_color_matrix(colorMatrix, inputMatrix, combinedMatrix);
|
| SkAutoTUnref<SkColorFilter> newCF(SkColorMatrixFilter::Create(combinedMatrix));
|
| return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
|
| }
|
| +
|
| + // Try to collapse two consecutive table filters
|
| + SkBitmap colorTable, inputTable;
|
| + if (cf->asComponentTable(&colorTable) && inputColorFilter->asComponentTable(&inputTable)) {
|
| + uint8_t combinedTable[4 * 256];
|
| + SkAutoLockPixels colorLock(colorTable);
|
| + SkAutoLockPixels inputLock(inputTable);
|
| +
|
| + combine_color_tables(colorTable.getAddr8(0, 0), inputTable.getAddr8(0, 0),
|
| + combinedTable);
|
| + SkAutoTUnref<SkColorFilter> newCF(SkTableColorFilter::CreateARGB(
|
| + &combinedTable[256 * 0],
|
| + &combinedTable[256 * 1],
|
| + &combinedTable[256 * 2],
|
| + &combinedTable[256 * 3])
|
| + );
|
| +
|
| + return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect, 0));
|
| + }
|
| }
|
| +
|
| return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect, uniqueID));
|
| }
|
|
|
|
|