OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2015 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 "SkMasks.h" | |
9 #include "SkTypes.h" | |
10 | |
11 /* | |
12 * | |
13 * Used to convert 1-7 bit color components into 8-bit color components | |
14 * | |
15 */ | |
16 const static uint8_t n_bit_to_8_bit_lookup_table[] = { | |
17 // 1 bit | |
18 0, 255, | |
19 // 2 bits | |
20 0, 85, 170, 255, | |
21 // 3 bits | |
22 0, 36, 73, 109, 146, 182, 219, 255, | |
23 // 4 bits | |
24 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, | |
25 // 5 bits | |
26 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, | |
27 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255, | |
28 // 6 bits | |
29 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, | |
30 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, | |
31 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, | |
32 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, | |
33 // 7 bits | |
34 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, | |
35 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, | |
36 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, | |
37 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141, | |
38 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, | |
39 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, | |
40 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, | |
41 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 | |
42 }; | |
43 | |
44 /* | |
45 * | |
46 * Convert an n bit component to an 8-bit component | |
47 * | |
48 */ | |
49 static uint8_t convert_to_8(uint32_t component, uint32_t n) { | |
50 if (0 == n) { | |
51 return 0; | |
52 } else if (8 > n) { | |
53 return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component]; | |
54 } else { | |
55 SkASSERT(8 == n); | |
56 return component; | |
57 } | |
58 } | |
59 | |
60 static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift, | |
61 uint32_t size) { | |
62 return convert_to_8((pixel & mask) >> shift, size); | |
63 } | |
64 | |
65 /* | |
66 * | |
67 * Get a color component | |
68 * | |
69 */ | |
70 uint8_t SkMasks::getRed(uint32_t pixel) { | |
71 return get_comp(pixel, fRed.mask, fRed.shift, fRed.size); | |
72 } | |
73 uint8_t SkMasks::getGreen(uint32_t pixel) { | |
74 return get_comp(pixel, fGreen.mask, fGreen.shift, fGreen.size); | |
75 } | |
76 uint8_t SkMasks::getBlue(uint32_t pixel) { | |
77 return get_comp(pixel, fBlue.mask, fBlue.shift, fBlue.size); | |
78 } | |
79 uint8_t SkMasks::getAlpha(uint32_t pixel) { | |
80 return get_comp(pixel, fAlpha.mask, fAlpha.shift, fAlpha.size); | |
81 } | |
82 | |
83 /* | |
84 * | |
85 * Process an input mask to obtain the necessary information | |
86 * | |
87 */ | |
88 const SkMasks::MaskInfo SkMasks::ProcessMask(uint32_t mask, uint32_t bpp) { | |
scroggo
2015/03/11 19:22:45
This can be a static function local to this file.
msarett
2015/03/11 20:03:11
Done. Might be worth noting that this change requ
scroggo
2015/03/11 21:14:25
Ah, that might be a good enough reason to make it
| |
89 // Trim the masks to the allowed number of bits | |
90 if (bpp < 32) { | |
91 mask &= (1 << bpp) - 1; | |
92 } | |
93 | |
94 // Determine properties of the mask | |
95 uint32_t tempMask = mask; | |
96 uint32_t shift = 0; | |
97 uint32_t size = 0; | |
98 if (tempMask != 0) { | |
99 // Count trailing zeros on masks | |
100 for (; (tempMask & 1) == 0; tempMask >>= 1) { | |
101 shift++; | |
102 } | |
103 // Count the size of the mask | |
104 for (; tempMask & 1; tempMask >>= 1) { | |
105 size++; | |
106 } | |
107 // Check that the mask is continuous | |
108 if (tempMask != 0) { | |
109 SkDebugf("Warning: Bit masks is not continuous.\n"); | |
110 } | |
111 // Truncate masks greater than 8 bits | |
112 if (size > 8) { | |
113 shift += size - 8; | |
114 size = 8; | |
115 } | |
116 } | |
117 | |
118 // Save the calculated values | |
119 const MaskInfo info = { mask, shift, size }; | |
120 return info; | |
121 } | |
122 | |
123 /* | |
124 * | |
125 * Create the masks object | |
126 * | |
127 */ | |
128 SkMasks* SkMasks::CreateMasks(InputMasks masks, uint32_t bitsPerPixel) { | |
129 // Trim the input masks according to bitsPerPixel | |
130 if (bitsPerPixel < 32) { | |
131 masks.red &= (1 << bitsPerPixel) - 1; | |
132 masks.green &= (1 << bitsPerPixel) - 1; | |
133 masks.blue &= (1 << bitsPerPixel) - 1; | |
134 masks.alpha &= (1 << bitsPerPixel) - 1; | |
135 } | |
136 | |
137 // Check that masks do not overlap | |
138 if (((masks.red & masks.green) | (masks.red & masks.blue) | | |
139 (masks.red & masks.alpha) | (masks.green & masks.blue) | | |
140 (masks.green & masks.alpha) | (masks.blue & masks.alpha)) != 0) { | |
141 return NULL; | |
142 } | |
143 | |
144 // Collect information about the masks | |
145 const MaskInfo red = ProcessMask(masks.red, bitsPerPixel); | |
146 const MaskInfo green = ProcessMask(masks.green, bitsPerPixel); | |
147 const MaskInfo blue = ProcessMask(masks.blue, bitsPerPixel); | |
148 const MaskInfo alpha = ProcessMask(masks.alpha, bitsPerPixel); | |
149 | |
150 return SkNEW_ARGS(SkMasks, (red, green, blue, alpha)); | |
151 } | |
152 | |
153 | |
154 SkMasks::SkMasks(const MaskInfo red, const MaskInfo green, | |
155 const MaskInfo blue, const MaskInfo alpha) | |
156 : fRed(red) | |
157 , fGreen(green) | |
158 , fBlue(blue) | |
159 , fAlpha(alpha) | |
160 {} | |
OLD | NEW |