Home | History | Annotate | Download | only in utils
      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