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)); |
} |