| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkColorMatrixFilter.h" | 8 #include "SkColorMatrixFilter.h" |
| 9 #include "SkColorMatrix.h" | 9 #include "SkColorMatrix.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 unsigned r, unsigned g, unsigned b, unsigned a, | 130 unsigned r, unsigned g, unsigned b, unsigned a, |
| 131 int32_t* SK_RESTRICT result) { | 131 int32_t* SK_RESTRICT result) { |
| 132 const int32_t* SK_RESTRICT array = state.fArray; | 132 const int32_t* SK_RESTRICT array = state.fArray; |
| 133 | 133 |
| 134 result[0] = r + (array[SkColorMatrix::kR_Trans] >> 16); | 134 result[0] = r + (array[SkColorMatrix::kR_Trans] >> 16); |
| 135 result[1] = g + (array[SkColorMatrix::kG_Trans] >> 16); | 135 result[1] = g + (array[SkColorMatrix::kG_Trans] >> 16); |
| 136 result[2] = b + (array[SkColorMatrix::kB_Trans] >> 16); | 136 result[2] = b + (array[SkColorMatrix::kB_Trans] >> 16); |
| 137 result[3] = a; | 137 result[3] = a; |
| 138 } | 138 } |
| 139 | 139 |
| 140 #define kNO_ALPHA_FLAGS (SkColorFilter::kAlphaUnchanged_Flag | \ | |
| 141 SkColorFilter::kHasFilter16_Flag) | |
| 142 | |
| 143 // src is [20] but some compilers won't accept __restrict__ on anything | 140 // src is [20] but some compilers won't accept __restrict__ on anything |
| 144 // but an raw pointer or reference | 141 // but an raw pointer or reference |
| 145 void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) { | 142 void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) { |
| 146 transpose_to_pmorder(fTranspose, src); | 143 transpose_to_pmorder(fTranspose, src); |
| 147 | 144 |
| 148 int32_t* array = fState.fArray; | 145 int32_t* array = fState.fArray; |
| 149 SkFixed max = 0; | 146 SkFixed max = 0; |
| 150 for (int i = 0; i < 20; i++) { | 147 for (int i = 0; i < 20; i++) { |
| 151 SkFixed value = SkScalarToFixed(src[i]); | 148 SkFixed value = SkScalarToFixed(src[i]); |
| 152 array[i] = value; | 149 array[i] = value; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 174 // check if we have to munge Alpha | 171 // check if we have to munge Alpha |
| 175 int32_t changesAlpha = (array[15] | array[16] | array[17] | | 172 int32_t changesAlpha = (array[15] | array[16] | array[17] | |
| 176 (array[18] - one) | array[19]); | 173 (array[18] - one) | array[19]); |
| 177 int32_t usesAlpha = (array[3] | array[8] | array[13]); | 174 int32_t usesAlpha = (array[3] | array[8] | array[13]); |
| 178 bool shiftIs16 = (16 == fState.fShift); | 175 bool shiftIs16 = (16 == fState.fShift); |
| 179 | 176 |
| 180 if (changesAlpha | usesAlpha) { | 177 if (changesAlpha | usesAlpha) { |
| 181 fProc = shiftIs16 ? General16 : General; | 178 fProc = shiftIs16 ? General16 : General; |
| 182 fFlags = changesAlpha ? 0 : SkColorFilter::kAlphaUnchanged_Flag; | 179 fFlags = changesAlpha ? 0 : SkColorFilter::kAlphaUnchanged_Flag; |
| 183 } else { | 180 } else { |
| 184 fFlags = kNO_ALPHA_FLAGS; | 181 fFlags = SkColorFilter::kAlphaUnchanged_Flag; |
| 185 | 182 |
| 186 int32_t needsScale = (array[SkColorMatrix::kR_Scale] - one) | | 183 int32_t needsScale = (array[SkColorMatrix::kR_Scale] - one) | |
| 187 (array[SkColorMatrix::kG_Scale] - one) | | 184 (array[SkColorMatrix::kG_Scale] - one) | |
| 188 (array[SkColorMatrix::kB_Scale] - one); | 185 (array[SkColorMatrix::kB_Scale] - one); |
| 189 | 186 |
| 190 int32_t needs3x3 = array[1] | array[2] | // red off-axis | 187 int32_t needs3x3 = array[1] | array[2] | // red off-axis |
| 191 array[5] | array[7] | // green off-axis | 188 array[5] | array[7] | // green off-axis |
| 192 array[10] | array[11]; // blue off-axis | 189 array[10] | array[11]; // blue off-axis |
| 193 | 190 |
| 194 if (needs3x3) { | 191 if (needs3x3) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 r = pin(result[0], SK_R32_MASK); | 353 r = pin(result[0], SK_R32_MASK); |
| 357 g = pin(result[1], SK_G32_MASK); | 354 g = pin(result[1], SK_G32_MASK); |
| 358 b = pin(result[2], SK_B32_MASK); | 355 b = pin(result[2], SK_B32_MASK); |
| 359 a = pin(result[3], SK_A32_MASK); | 356 a = pin(result[3], SK_A32_MASK); |
| 360 // re-prepremultiply if needed | 357 // re-prepremultiply if needed |
| 361 dst[i] = SkPremultiplyARGBInline(a, r, g, b); | 358 dst[i] = SkPremultiplyARGBInline(a, r, g, b); |
| 362 } | 359 } |
| 363 } | 360 } |
| 364 } | 361 } |
| 365 | 362 |
| 366 void SkColorMatrixFilter::filterSpan16(const uint16_t src[], int count, | |
| 367 uint16_t dst[]) const { | |
| 368 SkASSERT(fFlags & SkColorFilter::kHasFilter16_Flag); | |
| 369 | |
| 370 Proc proc = fProc; | |
| 371 const State& state = fState; | |
| 372 int32_t result[4]; | |
| 373 | |
| 374 if (NULL == proc) { | |
| 375 if (src != dst) { | |
| 376 memcpy(dst, src, count * sizeof(uint16_t)); | |
| 377 } | |
| 378 return; | |
| 379 } | |
| 380 | |
| 381 for (int i = 0; i < count; i++) { | |
| 382 uint16_t c = src[i]; | |
| 383 | |
| 384 // expand to 8bit components (since our matrix translate is 8bit biased | |
| 385 unsigned r = SkPacked16ToR32(c); | |
| 386 unsigned g = SkPacked16ToG32(c); | |
| 387 unsigned b = SkPacked16ToB32(c); | |
| 388 | |
| 389 proc(state, r, g, b, 0, result); | |
| 390 | |
| 391 r = pin(result[0], SK_R32_MASK); | |
| 392 g = pin(result[1], SK_G32_MASK); | |
| 393 b = pin(result[2], SK_B32_MASK); | |
| 394 | |
| 395 // now packed it back down to 16bits (hmmm, could dither...) | |
| 396 dst[i] = SkPack888ToRGB16(r, g, b); | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 /////////////////////////////////////////////////////////////////////////////// | 363 /////////////////////////////////////////////////////////////////////////////// |
| 401 | 364 |
| 402 void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const { | 365 void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const { |
| 403 SkASSERT(sizeof(fMatrix.fMat)/sizeof(SkScalar) == 20); | 366 SkASSERT(sizeof(fMatrix.fMat)/sizeof(SkScalar) == 20); |
| 404 buffer.writeScalarArray(fMatrix.fMat, 20); | 367 buffer.writeScalarArray(fMatrix.fMat, 20); |
| 405 } | 368 } |
| 406 | 369 |
| 407 SkFlattenable* SkColorMatrixFilter::CreateProc(SkReadBuffer& buffer) { | 370 SkFlattenable* SkColorMatrixFilter::CreateProc(SkReadBuffer& buffer) { |
| 408 SkColorMatrix matrix; | 371 SkColorMatrix matrix; |
| 409 if (buffer.readScalarArray(matrix.fMat, 20)) { | 372 if (buffer.readScalarArray(matrix.fMat, 20)) { |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 str->append("matrix: ("); | 575 str->append("matrix: ("); |
| 613 for (int i = 0; i < 20; ++i) { | 576 for (int i = 0; i < 20; ++i) { |
| 614 str->appendScalar(fMatrix.fMat[i]); | 577 str->appendScalar(fMatrix.fMat[i]); |
| 615 if (i < 19) { | 578 if (i < 19) { |
| 616 str->append(", "); | 579 str->append(", "); |
| 617 } | 580 } |
| 618 } | 581 } |
| 619 str->append(")"); | 582 str->append(")"); |
| 620 } | 583 } |
| 621 #endif | 584 #endif |
| OLD | NEW |