Index: src/utils/SkTextureCompressor_Utils.h |
diff --git a/src/utils/SkTextureCompressor_Utils.h b/src/utils/SkTextureCompressor_Utils.h |
new file mode 100755 |
index 0000000000000000000000000000000000000000..9b115a29647b95525cf445db686a65d92f4849fa |
--- /dev/null |
+++ b/src/utils/SkTextureCompressor_Utils.h |
@@ -0,0 +1,68 @@ |
+/* |
+* Copyright 2014 Google Inc. |
+* |
+* Use of this source code is governed by a BSD-style license that can be |
+* found in the LICENSE file. |
+*/ |
+ |
+#ifndef SkTextureCompressorUtils_DEFINED |
+#define SkTextureCompressorUtils_DEFINED |
+ |
+namespace SkTextureCompressor { |
+ |
+ // In some compression formats used for grayscale alpha, i.e. coverage masks, three |
+ // bit indices are used to represent each pixel. A compression scheme must therefore |
+ // quantize the full eight bits of grayscale to three bits. The simplest way to do |
+ // this is to take the top three bits of the grayscale value. However, this does not |
+ // provide an accurate quantization: 192 will be quantized to 219 instead of 185. In |
+ // our compression schemes, we let these three-bit indices represent the full range |
+ // of grayscale values, and so when we go from three bits to eight bits, we replicate |
+ // the three bits into the lower bits of the eight bit value. Below are two different |
+ // techniques that offer a quality versus speed tradeoff in terms of quantization. |
+#if 1 |
+ // Divides each byte in the 32-bit argument by three. |
+ static inline uint32_t MultibyteDiv3(uint32_t x) { |
+ const uint32_t a = (x >> 2) & 0x3F3F3F3F; |
+ const uint32_t ar = (x & 0x03030303) << 4; |
+ |
+ const uint32_t b = (x >> 4) & 0x0F0F0F0F; |
+ const uint32_t br = (x & 0x0F0F0F0F) << 2; |
+ |
+ const uint32_t c = (x >> 6) & 0x03030303; |
+ const uint32_t cr = x & 0x3F3F3F3F; |
+ |
+ return a + b + c + (((ar + br + cr) >> 6) & 0x03030303); |
+ } |
+ |
+ // Takes a loaded 32-bit integer of four 8-bit greyscale values and returns their |
+ // quantization into 3-bit values, used by LATC and R11 EAC. Instead of taking the |
+ // top three bits, the function computes the best three-bit value such that its |
+ // reconstruction into an eight bit value via bit replication will yield the best |
+ // results. In a 32-bit integer taking the range of values from 0-255 we would add |
+ // 18 and divide by 36 (255 / 36 ~= 7). However, since we are working in constrained |
+ // 8-bit space, our algorithm is the following: |
+ // 1. Shift right by one to give room for overflow |
+ // 2. Add 9 (18/2) |
+ // 3. Divide by 18 (divide by two, then by three twice) |
+ static inline uint32_t ConvertToThreeBitIndex(uint32_t x) { |
+ x = (x >> 1) & 0x7F7F7F7F; // 1 |
+ x = x + 0x09090909; // 2 |
+ |
+ // Need to divide by 18... so first divide by two |
+ x = (x >> 1) & 0x7F7F7F7F; |
+ |
+ // Now divide by three twice |
+ x = MultibyteDiv3(x); |
+ x = MultibyteDiv3(x); |
+ return x; |
+ } |
+#else |
+ // Moves the top three bits of each byte in the 32-bit argument to the least |
+ // significant bits of their respective byte. |
+ static inline uint32_t ConvertToThreeBitIndex(uint32_t x) { |
+ return (x >> 5) & 0x07070707; |
+ } |
+#endif |
+} |
+ |
+#endif // SkTextureCompressorUtils_DEFINED |