1 /* 2 * Copyright 2014 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 #ifndef SkTextureCompressorUtils_DEFINED 9 #define SkTextureCompressorUtils_DEFINED 10 11 namespace SkTextureCompressor { 12 13 // In some compression formats used for grayscale alpha, i.e. coverage masks, three 14 // bit indices are used to represent each pixel. A compression scheme must therefore 15 // quantize the full eight bits of grayscale to three bits. The simplest way to do 16 // this is to take the top three bits of the grayscale value. However, this does not 17 // provide an accurate quantization: 192 will be quantized to 219 instead of 185. In 18 // our compression schemes, we let these three-bit indices represent the full range 19 // of grayscale values, and so when we go from three bits to eight bits, we replicate 20 // the three bits into the lower bits of the eight bit value. Below are two different 21 // techniques that offer a quality versus speed tradeoff in terms of quantization. 22 #if 1 23 // Divides each byte in the 32-bit argument by three. 24 static inline uint32_t MultibyteDiv3(uint32_t x) { 25 const uint32_t a = (x >> 2) & 0x3F3F3F3F; 26 const uint32_t ar = (x & 0x03030303) << 4; 27 28 const uint32_t b = (x >> 4) & 0x0F0F0F0F; 29 const uint32_t br = (x & 0x0F0F0F0F) << 2; 30 31 const uint32_t c = (x >> 6) & 0x03030303; 32 const uint32_t cr = x & 0x3F3F3F3F; 33 34 return a + b + c + (((ar + br + cr) >> 6) & 0x03030303); 35 } 36 37 // Takes a loaded 32-bit integer of four 8-bit greyscale values and returns their 38 // quantization into 3-bit values, used by LATC and R11 EAC. Instead of taking the 39 // top three bits, the function computes the best three-bit value such that its 40 // reconstruction into an eight bit value via bit replication will yield the best 41 // results. In a 32-bit integer taking the range of values from 0-255 we would add 42 // 18 and divide by 36 (255 / 36 ~= 7). However, since we are working in constrained 43 // 8-bit space, our algorithm is the following: 44 // 1. Shift right by one to give room for overflow 45 // 2. Add 9 (18/2) 46 // 3. Divide by 18 (divide by two, then by three twice) 47 static inline uint32_t ConvertToThreeBitIndex(uint32_t x) { 48 x = (x >> 1) & 0x7F7F7F7F; // 1 49 x = x + 0x09090909; // 2 50 51 // Need to divide by 18... so first divide by two 52 x = (x >> 1) & 0x7F7F7F7F; 53 54 // Now divide by three twice 55 x = MultibyteDiv3(x); 56 x = MultibyteDiv3(x); 57 return x; 58 } 59 #else 60 // Moves the top three bits of each byte in the 32-bit argument to the least 61 // significant bits of their respective byte. 62 static inline uint32_t ConvertToThreeBitIndex(uint32_t x) { 63 return (x >> 5) & 0x07070707; 64 } 65 #endif 66 } 67 68 #endif // SkTextureCompressorUtils_DEFINED 69