Rev 1891 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1891 | Rev 3931 | ||
---|---|---|---|
Line 29... | Line 29... | ||
29 | #include |
29 | #include |
Line 30... | Line 30... | ||
30 | 30 | ||
Line 31... | Line 31... | ||
31 | #include "pixman-private.h" |
31 | #include "pixman-private.h" |
32 | 32 | ||
- | 33 | pixman_bool_t |
|
- | 34 | _pixman_multiply_overflows_size (size_t a, size_t b) |
|
- | 35 | { |
|
- | 36 | return a >= SIZE_MAX / b; |
|
- | 37 | } |
|
33 | pixman_bool_t |
38 | |
34 | pixman_multiply_overflows_int (unsigned int a, |
39 | pixman_bool_t |
35 | unsigned int b) |
40 | _pixman_multiply_overflows_int (unsigned int a, unsigned int b) |
36 | { |
41 | { |
Line 37... | Line 42... | ||
37 | return a >= INT32_MAX / b; |
42 | return a >= INT32_MAX / b; |
38 | } |
43 | } |
39 | - | ||
40 | pixman_bool_t |
44 | |
41 | pixman_addition_overflows_int (unsigned int a, |
45 | pixman_bool_t |
42 | unsigned int b) |
46 | _pixman_addition_overflows_int (unsigned int a, unsigned int b) |
Line 43... | Line 47... | ||
43 | { |
47 | { |
Line 65... | Line 69... | ||
65 | return NULL; |
69 | return NULL; |
66 | else |
70 | else |
67 | return malloc (a * b * c); |
71 | return malloc (a * b * c); |
68 | } |
72 | } |
Line 69... | Line -... | ||
69 | - | ||
70 | /* |
- | |
71 | * Helper routine to expand a color component from 0 < n <= 8 bits to 16 |
- | |
72 | * bits by replication. |
- | |
73 | */ |
73 | |
74 | static inline uint64_t |
74 | static force_inline uint16_t |
75 | expand16 (const uint8_t val, int nbits) |
75 | float_to_unorm (float f, int n_bits) |
76 | { |
- | |
77 | /* Start out with the high bit of val in the high bit of result. */ |
76 | { |
Line 78... | Line 77... | ||
78 | uint16_t result = (uint16_t)val << (16 - nbits); |
77 | uint32_t u; |
79 | 78 | ||
- | 79 | if (f > 1.0) |
|
- | 80 | f = 1.0; |
|
Line 80... | Line -... | ||
80 | if (nbits == 0) |
- | |
81 | return 0; |
81 | if (f < 0.0) |
82 | - | ||
83 | /* Copy the bits in result, doubling the number of bits each time, until |
82 | f = 0.0; |
84 | * we fill all 16 bits. |
83 | |
85 | */ |
- | |
86 | while (nbits < 16) |
84 | u = f * (1 << n_bits); |
87 | { |
85 | u -= (u >> n_bits); |
Line -... | Line 86... | ||
- | 86 | ||
- | 87 | return u; |
|
- | 88 | } |
|
- | 89 | ||
- | 90 | static force_inline float |
|
88 | result |= result >> nbits; |
91 | unorm_to_float (uint16_t u, int n_bits) |
89 | nbits *= 2; |
92 | { |
Line 90... | Line 93... | ||
90 | } |
93 | uint32_t m = ((1 << n_bits) - 1); |
91 | 94 | ||
92 | return result; |
95 | return (u & m) * (1.f / (float)m); |
- | 96 | } |
|
- | 97 | ||
93 | } |
98 | /* |
94 | 99 | * This function expands images from a8r8g8b8 to argb_t. To preserve |
|
95 | /* |
100 | * precision, it needs to know from which source format the a8r8g8b8 pixels |
- | 101 | * originally came. |
|
96 | * This function expands images from ARGB8 format to ARGB16. To preserve |
102 | * |
97 | * precision, it needs to know the original source format. For example, if the |
103 | * For example, if the source was PIXMAN_x1r5g5b5 and the red component |
98 | * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then |
104 | * contained bits 12345, then the 8-bit value is 12345123. To correctly |
99 | * the expanded value is 12345123. To correctly expand this to 16 bits, it |
105 | * expand this to floating point, it should be 12345 / 31.0 and not |
100 | * should be 1234512345123451 and not 1234512312345123. |
106 | * 12345123 / 255.0. |
101 | */ |
107 | */ |
102 | void |
108 | void |
- | 109 | pixman_expand_to_float (argb_t *dst, |
|
- | 110 | const uint32_t *src, |
|
- | 111 | pixman_format_code_t format, |
|
- | 112 | int width) |
|
- | 113 | { |
|
- | 114 | static const float multipliers[16] = { |
|
- | 115 | 0.0f, |
|
- | 116 | 1.0f / ((1 << 1) - 1), |
|
- | 117 | 1.0f / ((1 << 2) - 1), |
|
- | 118 | 1.0f / ((1 << 3) - 1), |
|
- | 119 | 1.0f / ((1 << 4) - 1), |
|
- | 120 | 1.0f / ((1 << 5) - 1), |
|
- | 121 | 1.0f / ((1 << 6) - 1), |
|
- | 122 | 1.0f / ((1 << 7) - 1), |
|
- | 123 | 1.0f / ((1 << 8) - 1), |
|
- | 124 | 1.0f / ((1 << 9) - 1), |
|
- | 125 | 1.0f / ((1 << 10) - 1), |
|
- | 126 | 1.0f / ((1 << 11) - 1), |
|
- | 127 | 1.0f / ((1 << 12) - 1), |
|
- | 128 | 1.0f / ((1 << 13) - 1), |
|
- | 129 | 1.0f / ((1 << 14) - 1), |
|
- | 130 | 1.0f / ((1 << 15) - 1), |
|
- | 131 | }; |
|
- | 132 | int a_size, r_size, g_size, b_size; |
|
- | 133 | int a_shift, r_shift, g_shift, b_shift; |
|
- | 134 | float a_mul, r_mul, g_mul, b_mul; |
|
- | 135 | uint32_t a_mask, r_mask, g_mask, b_mask; |
|
103 | pixman_expand (uint64_t * dst, |
136 | int i; |
104 | const uint32_t * src, |
137 | |
105 | pixman_format_code_t format, |
138 | if (!PIXMAN_FORMAT_VIS (format)) |
106 | int width) |
139 | format = PIXMAN_a8r8g8b8; |
107 | { |
140 | |
108 | /* |
141 | /* |
109 | * Determine the sizes of each component and the masks and shifts |
142 | * Determine the sizes of each component and the masks and shifts |
110 | * required to extract them from the source pixel. |
143 | * required to extract them from the source pixel. |
- | 144 | */ |
|
111 | */ |
145 | a_size = PIXMAN_FORMAT_A (format); |
112 | const int a_size = PIXMAN_FORMAT_A (format), |
146 | r_size = PIXMAN_FORMAT_R (format); |
113 | r_size = PIXMAN_FORMAT_R (format), |
147 | g_size = PIXMAN_FORMAT_G (format); |
114 | g_size = PIXMAN_FORMAT_G (format), |
148 | b_size = PIXMAN_FORMAT_B (format); |
- | 149 | ||
115 | b_size = PIXMAN_FORMAT_B (format); |
150 | a_shift = 32 - a_size; |
116 | const int a_shift = 32 - a_size, |
151 | r_shift = 24 - r_size; |
117 | r_shift = 24 - r_size, |
152 | g_shift = 16 - g_size; |
118 | g_shift = 16 - g_size, |
153 | b_shift = 8 - b_size; |
- | 154 | ||
- | 155 | a_mask = ((1 << a_size) - 1); |
|
- | 156 | r_mask = ((1 << r_size) - 1); |
|
- | 157 | g_mask = ((1 << g_size) - 1); |
|
119 | b_shift = 8 - b_size; |
158 | b_mask = ((1 << b_size) - 1); |
Line 120... | Line 159... | ||
120 | const uint8_t a_mask = ~(~0 << a_size), |
159 | |
121 | r_mask = ~(~0 << r_size), |
160 | a_mul = multipliers[a_size]; |
122 | g_mask = ~(~0 << g_size), |
161 | r_mul = multipliers[r_size]; |
123 | b_mask = ~(~0 << b_size); |
162 | g_mul = multipliers[g_size]; |
124 | int i; |
163 | b_mul = multipliers[b_size]; |
125 | 164 | ||
126 | /* Start at the end so that we can do the expansion in place |
- | |
127 | * when src == dst |
- | |
128 | */ |
- | |
129 | for (i = width - 1; i >= 0; i--) |
- | |
130 | { |
- | |
131 | const uint32_t pixel = src[i]; |
- | |
132 | const uint8_t a = (pixel >> a_shift) & a_mask, |
- | |
133 | r = (pixel >> r_shift) & r_mask, |
- | |
Line -... | Line 165... | ||
- | 165 | /* Start at the end so that we can do the expansion in place |
|
- | 166 | * when src == dst |
|
- | 167 | */ |
|
134 | g = (pixel >> g_shift) & g_mask, |
168 | for (i = width - 1; i >= 0; i--) |
135 | b = (pixel >> b_shift) & b_mask; |
169 | { |
136 | const uint64_t a16 = a_size ? expand16 (a, a_size) : 0xffff, |
170 | const uint32_t pixel = src[i]; |
Line -... | Line 171... | ||
- | 171 | ||
- | 172 | dst[i].a = a_mask? ((pixel >> a_shift) & a_mask) * a_mul : 1.0f; |
|
137 | r16 = expand16 (r, r_size), |
173 | dst[i].r = ((pixel >> r_shift) & r_mask) * r_mul; |
- | 174 | dst[i].g = ((pixel >> g_shift) & g_mask) * g_mul; |
|
- | 175 | dst[i].b = ((pixel >> b_shift) & b_mask) * b_mul; |
|
- | 176 | } |
|
- | 177 | } |
|
138 | g16 = expand16 (g, g_size), |
178 | |
- | 179 | uint16_t |
|
139 | b16 = expand16 (b, b_size); |
180 | pixman_float_to_unorm (float f, int n_bits) |
140 | 181 | { |
|
- | 182 | return float_to_unorm (f, n_bits); |
|
141 | dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16; |
183 | } |
142 | } |
184 | |
143 | } |
185 | float |
144 | 186 | pixman_unorm_to_float (uint16_t u, int n_bits) |
|
145 | /* |
187 | { |
146 | * Contracting is easier than expanding. We just need to truncate the |
188 | return unorm_to_float (u, n_bits); |
Line 147... | Line -... | ||
147 | * components. |
- | |
148 | */ |
- | |
149 | void |
- | |
150 | pixman_contract (uint32_t * dst, |
189 | } |
151 | const uint64_t *src, |
190 | |
152 | int width) |
191 | void |
- | 192 | pixman_contract_from_float (uint32_t *dst, |
|
153 | { |
193 | const argb_t *src, |
154 | int i; |
194 | int width) |
- | 195 | { |
|
155 | 196 | int i; |
|
Line 156... | Line 197... | ||
156 | /* Start at the beginning so that we can do the contraction in |
197 | |
- | 198 | for (i = 0; i < width; ++i) |
|
157 | * place when src == dst |
199 | { |
- | 200 | uint8_t a, r, g, b; |
|
- | 201 | ||
- | 202 | a = float_to_unorm (src[i].a, 8); |
|
- | 203 | r = float_to_unorm (src[i].r, 8); |
|
- | 204 | g = float_to_unorm (src[i].g, 8); |
|
158 | */ |
205 | b = float_to_unorm (src[i].b, 8); |
Line 159... | Line 206... | ||
159 | for (i = 0; i < width; i++) |
206 | |
Line 160... | Line 207... | ||
160 | { |
207 | dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0); |
Line 234... | Line 281... | ||
234 | free (boxes32); |
281 | free (boxes32); |
Line 235... | Line 282... | ||
235 | 282 | ||
236 | return retval; |
283 | return retval; |
Line -... | Line 284... | ||
- | 284 | } |
|
237 | } |
285 | |
- | 286 | /* This function is exported for the sake of the test suite and not part |
|
- | 287 | * of the ABI. |
|
- | 288 | */ |
|
- | 289 | PIXMAN_EXPORT pixman_implementation_t * |
|
- | 290 | _pixman_internal_only_get_implementation (void) |
|
- | 291 | { |
|
Line 238... | Line 292... | ||
238 | 292 | return get_implementation (); |
|
239 | #ifdef DEBUG |
293 | } |
240 | 294 | ||
241 | void |
295 | void |
Line 252... | Line 306... | ||
252 | function, message); |
306 | function, message); |
Line 253... | Line 307... | ||
253 | 307 | ||
254 | n_messages++; |
308 | n_messages++; |
255 | } |
309 | } |
256 | } |
- | |
257 | - |