Line data Source code
1 : #define R16_BITS 5
2 : #define G16_BITS 6
3 : #define B16_BITS 5
4 :
5 : #define R16_SHIFT (B16_BITS + G16_BITS)
6 : #define G16_SHIFT (B16_BITS)
7 : #define B16_SHIFT 0
8 :
9 : #define MASK 0xff
10 : #define ONE_HALF 0x80
11 :
12 : #define A_SHIFT 8 * 3
13 : #define R_SHIFT 8 * 2
14 : #define G_SHIFT 8
15 : #define A_MASK 0xff000000
16 : #define R_MASK 0xff0000
17 : #define G_MASK 0xff00
18 :
19 : #define RB_MASK 0xff00ff
20 : #define AG_MASK 0xff00ff00
21 : #define RB_ONE_HALF 0x800080
22 : #define RB_MASK_PLUS_ONE 0x10000100
23 :
24 : #define ALPHA_8(x) ((x) >> A_SHIFT)
25 : #define RED_8(x) (((x) >> R_SHIFT) & MASK)
26 : #define GREEN_8(x) (((x) >> G_SHIFT) & MASK)
27 : #define BLUE_8(x) ((x) & MASK)
28 :
29 : // This uses the same dithering technique that Skia does.
30 : // It is essentially preturbing the lower bit based on the
31 : // high bit
32 0 : static inline uint16_t dither_32_to_16(uint32_t c)
33 : {
34 0 : uint8_t b = BLUE_8(c);
35 0 : uint8_t g = GREEN_8(c);
36 0 : uint8_t r = RED_8(c);
37 0 : r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS);
38 0 : g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS);
39 0 : b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS);
40 0 : return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT));
41 : }
42 :
43 0 : static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle)
44 : {
45 : // alternate between a preturbed truncation and a regular truncation
46 0 : if (toggle) {
47 0 : return dither_32_to_16(color);
48 : } else {
49 0 : return convert_8888_to_0565(color);
50 : }
51 : }
|