| Index: src/effects/SkColorFilterImageFilter.cpp
|
| diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
|
| index 10976d77f0db790c50de8ca3daa0c731ee6e33b6..0acb539360ff8abd4b927ffc1cdaa29fed0e7793 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 {
|
| @@ -26,6 +27,14 @@ void mult_color_matrix(SkScalar a[20], SkScalar b[20], SkScalar out[20]) {
|
| }
|
| }
|
|
|
| +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]];
|
| + }
|
| + }
|
| +}
|
| +
|
| // To detect if we need to apply clamping after applying a matrix, we check if
|
| // any output component might go outside of [0, 255] for any combination of
|
| // input components in [0..255].
|
| @@ -59,23 +68,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));
|
| }
|
|
|
|
|