| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SkColorCubeFilter_opts_DEFINED |
| #define SkColorCubeFilter_opts_DEFINED |
| |
| #include "SkColor.h" |
| #include "SkNx.h" |
| #include "SkUnPreMultiply.h" |
| |
| namespace SK_OPTS_NS { |
| |
| void color_cube_filter_span(const SkPMColor src[], |
| int count, |
| SkPMColor dst[], |
| const int* colorToIndex[2], |
| const SkScalar* colorToFactors[2], |
| int dim, |
| const SkColor* colorCube) { |
| uint8_t r, g, b, a; |
| |
| for (int i = 0; i < count; ++i) { |
| const SkPMColor input = src[i]; |
| a = input >> SK_A32_SHIFT; |
| |
| if (a != 255) { |
| const SkColor source = SkUnPreMultiply::PMColorToColor(input); |
| r = SkColorGetR(source); |
| g = SkColorGetG(source); |
| b = SkColorGetB(source); |
| } else { |
| r = SkGetPackedR32(input); |
| g = SkGetPackedG32(input); |
| b = SkGetPackedB32(input); |
| } |
| |
| const SkScalar g0 = colorToFactors[0][g], |
| g1 = colorToFactors[1][g], |
| b0 = colorToFactors[0][b], |
| b1 = colorToFactors[1][b]; |
| |
| const Sk4f g0b0(g0*b0), |
| g0b1(g0*b1), |
| g1b0(g1*b0), |
| g1b1(g1*b1); |
| |
| const int i00 = (colorToIndex[0][g] + colorToIndex[0][b] * dim) * dim; |
| const int i01 = (colorToIndex[0][g] + colorToIndex[1][b] * dim) * dim; |
| const int i10 = (colorToIndex[1][g] + colorToIndex[0][b] * dim) * dim; |
| const int i11 = (colorToIndex[1][g] + colorToIndex[1][b] * dim) * dim; |
| |
| Sk4f color(0.5f); // Starting from 0.5f gets us rounding for free. |
| for (int x = 0; x < 2; ++x) { |
| const int ix = colorToIndex[x][r]; |
| |
| const SkColor lutColor00 = colorCube[ix + i00]; |
| const SkColor lutColor01 = colorCube[ix + i01]; |
| const SkColor lutColor10 = colorCube[ix + i10]; |
| const SkColor lutColor11 = colorCube[ix + i11]; |
| |
| Sk4f sum = Sk4f::FromBytes((const uint8_t*)&lutColor00) * g0b0; |
| sum = sum + Sk4f::FromBytes((const uint8_t*)&lutColor01) * g0b1; |
| sum = sum + Sk4f::FromBytes((const uint8_t*)&lutColor10) * g1b0; |
| sum = sum + Sk4f::FromBytes((const uint8_t*)&lutColor11) * g1b1; |
| color = color + sum * Sk4f((float)colorToFactors[x][r]); |
| } |
| if (a != 255) { |
| color = color * Sk4f(a * (1.0f/255)); |
| } |
| |
| // color is BGRA (SkColor order), dst is SkPMColor order, so may need to swap R+B. |
| #if defined(SK_PMCOLOR_IS_RGBA) |
| color = SkNx_shuffle<2,1,0,3>(color); |
| #endif |
| uint8_t* dstBytes = (uint8_t*)(dst+i); |
| color.toBytes(dstBytes); |
| dstBytes[SK_A32_SHIFT/8] = a; |
| } |
| } |
| |
| } // namespace SK_OPTS NS |
| |
| #endif // SkColorCubeFilter_opts_DEFINED |