OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #include "SkColorLookUpTable.h" |
| 9 #include "SkFloatingPoint.h" |
| 10 |
| 11 void SkColorLookUpTable::interp3D(float dst[3], float src[3]) const { |
| 12 // Call the src components x, y, and z. |
| 13 const uint8_t maxX = fGridPoints[0] - 1; |
| 14 const uint8_t maxY = fGridPoints[1] - 1; |
| 15 const uint8_t maxZ = fGridPoints[2] - 1; |
| 16 |
| 17 // An approximate index into each of the three dimensions of the table. |
| 18 const float x = src[0] * maxX; |
| 19 const float y = src[1] * maxY; |
| 20 const float z = src[2] * maxZ; |
| 21 |
| 22 // This gives us the low index for our interpolation. |
| 23 int ix = sk_float_floor2int(x); |
| 24 int iy = sk_float_floor2int(y); |
| 25 int iz = sk_float_floor2int(z); |
| 26 |
| 27 // Make sure the low index is not also the max index. |
| 28 ix = (maxX == ix) ? ix - 1 : ix; |
| 29 iy = (maxY == iy) ? iy - 1 : iy; |
| 30 iz = (maxZ == iz) ? iz - 1 : iz; |
| 31 |
| 32 // Weighting factors for the interpolation. |
| 33 const float diffX = x - ix; |
| 34 const float diffY = y - iy; |
| 35 const float diffZ = z - iz; |
| 36 |
| 37 // Constants to help us navigate the 3D table. |
| 38 // Ex: Assume x = a, y = b, z = c. |
| 39 // table[a * n001 + b * n010 + c * n100] logically equals table[a][b][c]
. |
| 40 const int n000 = 0; |
| 41 const int n001 = 3 * fGridPoints[1] * fGridPoints[2]; |
| 42 const int n010 = 3 * fGridPoints[2]; |
| 43 const int n011 = n001 + n010; |
| 44 const int n100 = 3; |
| 45 const int n101 = n100 + n001; |
| 46 const int n110 = n100 + n010; |
| 47 const int n111 = n110 + n001; |
| 48 |
| 49 // Base ptr into the table. |
| 50 const float* ptr = &(table()[ix*n001 + iy*n010 + iz*n100]); |
| 51 |
| 52 // The code below performs a tetrahedral interpolation for each of the three |
| 53 // dst components. Once the tetrahedron containing the interpolation point
is |
| 54 // identified, the interpolation is a weighted sum of grid values at the |
| 55 // vertices of the tetrahedron. The claim is that tetrahedral interpolation |
| 56 // provides a more accurate color conversion. |
| 57 // blogs.mathworks.com/steve/2006/11/24/tetrahedral-interpolation-for-colors
pace-conversion/ |
| 58 // |
| 59 // I have one test image, and visually I can't tell the difference between |
| 60 // tetrahedral and trilinear interpolation. In terms of computation, the |
| 61 // tetrahedral code requires more branches but less computation. The |
| 62 // SampleICC library provides an option for the client to choose either |
| 63 // tetrahedral or trilinear. |
| 64 for (int i = 0; i < 3; i++) { |
| 65 if (diffZ < diffY) { |
| 66 if (diffZ < diffX) { |
| 67 dst[i] = (ptr[n000] + diffZ * (ptr[n110] - ptr[n010]) + |
| 68 diffY * (ptr[n010] - ptr[n000]) + |
| 69 diffX * (ptr[n111] - ptr[n110])); |
| 70 } else if (diffY < diffX) { |
| 71 dst[i] = (ptr[n000] + diffZ * (ptr[n111] - ptr[n011]) + |
| 72 diffY * (ptr[n011] - ptr[n001]) + |
| 73 diffX * (ptr[n001] - ptr[n000])); |
| 74 } else { |
| 75 dst[i] = (ptr[n000] + diffZ * (ptr[n111] - ptr[n011]) + |
| 76 diffY * (ptr[n010] - ptr[n000]) + |
| 77 diffX * (ptr[n011] - ptr[n010])); |
| 78 } |
| 79 } else { |
| 80 if (diffZ < diffX) { |
| 81 dst[i] = (ptr[n000] + diffZ * (ptr[n101] - ptr[n001]) + |
| 82 diffY * (ptr[n111] - ptr[n101]) + |
| 83 diffX * (ptr[n001] - ptr[n000])); |
| 84 } else if (diffY < diffX) { |
| 85 dst[i] = (ptr[n000] + diffZ * (ptr[n100] - ptr[n000]) + |
| 86 diffY * (ptr[n111] - ptr[n101]) + |
| 87 diffX * (ptr[n101] - ptr[n100])); |
| 88 } else { |
| 89 dst[i] = (ptr[n000] + diffZ * (ptr[n100] - ptr[n000]) + |
| 90 diffY * (ptr[n110] - ptr[n100]) + |
| 91 diffX * (ptr[n111] - ptr[n110])); |
| 92 } |
| 93 } |
| 94 |
| 95 // Increment the table ptr in order to handle the next component. |
| 96 // Note that this is the how table is designed: all of nXXX |
| 97 // variables are multiples of 3 because there are 3 output |
| 98 // components. |
| 99 ptr++; |
| 100 } |
| 101 } |
OLD | NEW |