blob: 7bbc6ea53d3423fa27a71d6b8385f684e536c942 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#ifndef AlphaMath_h_Included
27#define AlphaMath_h_Included
28
29extern unsigned char mul8table[256][256];
30extern unsigned char div8table[256][256];
31extern void initAlphaTables();
32
33
34/*
35 * Multiply and Divide macros for single byte (8-bit) quantities representing
36 * the values 0.0 to 1.0 as 0x00 to 0xff.
37 * MUL8 multiplies its operands together
38 * DIV8 divides the first operand by the second, clipping to 0xff
39 * (Note that since the divisor for DIV8 is likely to be
40 * the alpha quantity which is likely to be the same for
41 * multiple adjacent invocations, the table is designed
42 * with the first index being the divisor to hopefully
43 * improve memory cache hits...)
44 */
45#define MUL8(a,b) mul8table[a][b]
46#define DIV8(a,b) div8table[b][a]
47
48/*
49 * Multiply and Divide macros for operations involving a single short (16-bit)
50 * quantity and a single byte (8-bit) quantity. Typically, promoting the
51 * 8-bit value to 16 bits would lead to overflow when the operation occurs.
52 * These macros have been modified somewhat so that overflow will not occur.
53 * MUL8_16 multiplies an 8-bit value by a 16-bit value (the order of operands
54 * is unimportant since multiplication is a commutative operation)
55 * DIV16_8 divides the first (16-bit) operand by the second (8-bit) value
56 */
57
58#define MUL8_16(a,b) (((a) * (b)) / 255)
59#define DIV16_8(a,b) (((a) * 255) / (b))
60
61/*
62 * Multiply and Divide macros for single short (16-bit) quantities
63 * representing the values 0.0 to 1.0 as 0x0000 to 0xffff.
64 * MUL16 multiplies its operands using the standard multiplication operator
65 * and normalizes the result to the appropriate range
66 * DIV16 divides the first operand by the second and normalizes the result
67 * to a 16-bit value
68 */
69#define MUL16(a,b) (((a) * (b)) / 65535)
70#define DIV16(a,b) (((a) * 65535) / (b))
71
72/*
73 * Macro for the sum of two normalized (16-bit) products. Refer to the
74 * following equation and note that the right side reduces the number of
75 * divide operations in the left side and increases the precision of the
76 * result:
77 * a*f1 + b*f2 a*f1 + b*f2
78 * ---- ---- = ----------- (where n in this case will be 65535)
79 * n n n
80 */
81#define AddNormalizedProducts16(a, f1, b, f2) \
82 ((((a) * (f1)) + ((b) * (f2))) / 65535)
83
84
85/*
86 * The following macros help to generalize the MaskBlit and MaskFill loops
87 * found in AlphaMacros.h. The appropriate macros will be used based on the
88 * strategy of the given loop. The strategy types take the form:
89 * <number of components per pixel><component data type><colorspace>
90 * For example, these are the current strategy types:
91 * 3ByteRgb (currently only used as a glyph list blending strategy where
92 * the alpha value itself is neither blended nor stored)
93 * 4ByteArgb (eg. IntArgb, ThreeByteBgr, Ushort555Rgb, ByteIndexed, etc.)
94 * 4ShortArgb (not used currently; could be used when surface types using
95 * 16 bits per component are implemented)
96 * 1ByteGray (eg. ByteGray)
97 * 1ShortGray (eg. UshortGray)
98 * Note that the macros which operate on alpha values have the word "Alpha"
99 * somewhere in their name. Those macros that only operate on the color/gray
100 * components of a given strategy will have the word "Components" or "Comps"
101 * in their name.
102 */
103
104
105/*
106 * MaxValFor ## STRATEGY
107 */
108#define MaxValFor4ByteArgb 0xff
109#define MaxValFor1ByteGray 0xff
110#define MaxValFor1ShortGray 0xffff
111
112
113/*
114 * AlphaType ## STRATEGY
115 */
116#define AlphaType3ByteRgb jint
117#define AlphaType4ByteArgb jint
118#define AlphaType1ByteGray jint
119#define AlphaType1ShortGray juint
120
121
122/*
123 * ComponentType ## STRATEGY
124 */
125#define ComponentType3ByteRgb jint
126#define ComponentType4ByteArgb jint
127#define ComponentType1ByteGray jint
128#define ComponentType1ShortGray juint
129
130
131/*
132 * DeclareAlphaVarFor ## STRATEGY(VAR)
133 *
134 * jint a;
135 */
136#define DeclareAlphaVarFor3ByteRgb(VAR) \
137 AlphaType3ByteRgb VAR;
138
139#define DeclareAlphaVarFor4ByteArgb(VAR) \
140 AlphaType4ByteArgb VAR;
141
142#define DeclareAlphaVarFor1ByteGray(VAR) \
143 AlphaType1ByteGray VAR;
144
145#define DeclareAlphaVarFor1ShortGray(VAR) \
146 AlphaType1ShortGray VAR;
147
148
149/*
150 * DeclareAndInitAlphaVarFor ## STRATEGY(VAR, initval)
151 *
152 * jint a = initval;
153 */
154#define DeclareAndInitAlphaVarFor4ByteArgb(VAR, initval) \
155 AlphaType4ByteArgb VAR = initval;
156
157#define DeclareAndInitAlphaVarFor1ByteGray(VAR, initval) \
158 AlphaType1ByteGray VAR = initval;
159
160#define DeclareAndInitAlphaVarFor1ShortGray(VAR, initval) \
161 AlphaType1ShortGray VAR = initval;
162
163
164/*
165 * DeclareAndClearAlphaVarFor ## STRATEGY(VAR)
166 *
167 * jint a = 0;
168 */
169#define DeclareAndClearAlphaVarFor4ByteArgb(VAR) \
170 DeclareAndInitAlphaVarFor4ByteArgb(VAR, 0)
171
172#define DeclareAndClearAlphaVarFor1ByteGray(VAR) \
173 DeclareAndInitAlphaVarFor1ByteGray(VAR, 0)
174
175#define DeclareAndClearAlphaVarFor1ShortGray(VAR) \
176 DeclareAndInitAlphaVarFor1ShortGray(VAR, 0)
177
178
179/*
180 * DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(VAR)
181 *
182 * jint a = 0xff;
183 */
184#define DeclareAndSetOpaqueAlphaVarFor4ByteArgb(VAR) \
185 DeclareAndInitAlphaVarFor4ByteArgb(VAR, MaxValFor4ByteArgb)
186
187#define DeclareAndSetOpaqueAlphaVarFor1ByteGray(VAR) \
188 DeclareAndInitAlphaVarFor1ByteGray(VAR, MaxValFor1ByteGray)
189
190#define DeclareAndSetOpaqueAlphaVarFor1ShortGray(VAR) \
191 DeclareAndInitAlphaVarFor1ShortGray(VAR, MaxValFor1ShortGray)
192
193
194/*
195 * DeclareAndInvertAlphaVarFor ## STRATEGY(VAR, invalpha)
196 *
197 * jint a = 0xff - resA;
198 */
199#define DeclareAndInvertAlphaVarFor4ByteArgb(VAR, invalpha) \
200 DeclareAndInitAlphaVarFor4ByteArgb(VAR, MaxValFor4ByteArgb - invalpha)
201
202#define DeclareAndInvertAlphaVarFor1ByteGray(VAR, invalpha) \
203 DeclareAndInitAlphaVarFor1ByteGray(VAR, MaxValFor1ByteGray - invalpha)
204
205#define DeclareAndInvertAlphaVarFor1ShortGray(VAR, invalpha) \
206 DeclareAndInitAlphaVarFor1ShortGray(VAR, MaxValFor1ShortGray - invalpha)
207
208
209/*
210 * DeclareCompVarsFor ## STRATEGY(PREFIX)
211 *
212 * jint c;
213 */
214#define DeclareCompVarsFor3ByteRgb(PREFIX) \
215 ComponentType3ByteRgb PREFIX ## R, PREFIX ## G, PREFIX ## B;
216
217#define DeclareCompVarsFor4ByteArgb(PREFIX) \
218 ComponentType4ByteArgb PREFIX ## R, PREFIX ## G, PREFIX ## B;
219
220#define DeclareCompVarsFor1ByteGray(PREFIX) \
221 ComponentType1ByteGray PREFIX ## G;
222
223#define DeclareCompVarsFor1ShortGray(PREFIX) \
224 ComponentType1ShortGray PREFIX ## G;
225
226
227/*
228 * DeclareAndInitExtraAlphaFor ## STRATEGY(VAR)
229 *
230 * jint extraA = (int)(pCompInfo->details.extraAlpha * 255.0 + 0.5);
231 */
232#define DeclareAndInitExtraAlphaFor4ByteArgb(VAR) \
233 AlphaType4ByteArgb VAR = \
234 (AlphaType4ByteArgb)(pCompInfo->details.extraAlpha * 255.0 + 0.5);
235
236#define DeclareAndInitExtraAlphaFor1ByteGray(VAR) \
237 AlphaType1ByteGray VAR = \
238 (AlphaType1ByteGray)(pCompInfo->details.extraAlpha * 255.0 + 0.5);
239
240#define DeclareAndInitExtraAlphaFor1ShortGray(VAR) \
241 AlphaType1ShortGray VAR = \
242 (AlphaType1ShortGray)(pCompInfo->details.extraAlpha * 65535.0 + 0.5);
243
244
245/*
246 * PromoteByteAlphaFor ## STRATEGY(a)
247 */
248#define PromoteByteAlphaFor4ByteArgb(a)
249#define PromoteByteAlphaFor1ByteGray(a)
250#define PromoteByteAlphaFor1ShortGray(a) \
251 (a) = (((a) << 8) + (a))
252
253
254/*
255 * DeclareAndInitPathAlphaFor ## STRATEGY(VAR)
256 *
257 * jint pathA = *pMask++;
258 */
259#define DeclareAndInitPathAlphaFor4ByteArgb(VAR) \
260 AlphaType4ByteArgb VAR = *pMask++;
261
262#define DeclareAndInitPathAlphaFor1ByteGray(VAR) \
263 AlphaType1ByteGray VAR = *pMask++;
264
265#define DeclareAndInitPathAlphaFor1ShortGray(VAR) \
266 AlphaType1ShortGray VAR = *pMask++;
267
268
269/*
270 * MultiplyAlphaFor ## STRATEGY(a, b)
271 *
272 * a * b
273 */
274#define MultiplyAlphaFor4ByteArgb(a, b) \
275 MUL8(a, b)
276
277#define MultiplyAlphaFor1ByteGray(a, b) \
278 MUL8(a, b)
279
280#define MultiplyAlphaFor1ShortGray(a, b) \
281 MUL16(a, b)
282
283
284/*
285 * MultiplyAndStore ## STRATEGY ## Comps(PROD_PREFIX, M1, M2_PREFIX)
286 *
287 * c = m1 * m2;
288 */
289#define MultiplyAndStore3Components(PROD_PREFIX, M1, M2_PREFIX, PRECISION) \
290 do { \
291 PROD_PREFIX ## R = MUL ## PRECISION(M1, M2_PREFIX ## R); \
292 PROD_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G); \
293 PROD_PREFIX ## B = MUL ## PRECISION(M1, M2_PREFIX ## B); \
294 } while (0)
295
296#define MultiplyAndStore1Component(PROD_PREFIX, M1, M2_PREFIX, PRECISION) \
297 PROD_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G)
298
299#define MultiplyAndStore4ByteArgbComps(PROD_PREFIX, M1, M2_PREFIX) \
300 MultiplyAndStore3Components(PROD_PREFIX, M1, M2_PREFIX, 8)
301
302#define MultiplyAndStore1ByteGrayComps(PROD_PREFIX, M1, M2_PREFIX) \
303 MultiplyAndStore1Component(PROD_PREFIX, M1, M2_PREFIX, 8)
304
305#define MultiplyAndStore1ShortGrayComps(PROD_PREFIX, M1, M2_PREFIX) \
306 MultiplyAndStore1Component(PROD_PREFIX, M1, M2_PREFIX, 16)
307
308
309/*
310 * DivideAndStore ## STRATEGY ## Comps(QUOT_PREFIX, D1_PREFIX, D2)
311 *
312 * c = d1 / d2;
313 */
314#define DivideAndStore3Components(QUOT_PREFIX, D1_PREFIX, D2, PRECISION) \
315 do { \
316 QUOT_PREFIX ## R = DIV ## PRECISION(D1_PREFIX ## R, D2); \
317 QUOT_PREFIX ## G = DIV ## PRECISION(D1_PREFIX ## G, D2); \
318 QUOT_PREFIX ## B = DIV ## PRECISION(D1_PREFIX ## B, D2); \
319 } while (0)
320
321#define DivideAndStore1Component(QUOT_PREFIX, D1_PREFIX, D2, PRECISION) \
322 QUOT_PREFIX ## G = DIV ## PRECISION(D1_PREFIX ## G, D2)
323
324#define DivideAndStore4ByteArgbComps(QUOT_PREFIX, D1_PREFIX, D2) \
325 DivideAndStore3Components(QUOT_PREFIX, D1_PREFIX, D2, 8)
326
327#define DivideAndStore1ByteGrayComps(QUOT_PREFIX, D1_PREFIX, D2) \
328 DivideAndStore1Component(QUOT_PREFIX, D1_PREFIX, D2, 8)
329
330#define DivideAndStore1ShortGrayComps(QUOT_PREFIX, D1_PREFIX, D2) \
331 DivideAndStore1Component(QUOT_PREFIX, D1_PREFIX, D2, 16)
332
333
334/*
335 * MultiplyAddAndStore ## STRATEGY ## Comps(RES_PREFIX, M1, \
336 * M2_PREFIX, A_PREFIX)
337 *
338 * c = (m1 * m2) + a;
339 */
340#define MultiplyAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, \
341 PRECISION) \
342 do { \
343 RES_PREFIX ## R = MUL ## PRECISION(M1, M2_PREFIX ## R) + \
344 A_PREFIX ## R; \
345 RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + \
346 A_PREFIX ## G; \
347 RES_PREFIX ## B = MUL ## PRECISION(M1, M2_PREFIX ## B) + \
348 A_PREFIX ## B; \
349 } while (0)
350
351#define MultiplyAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, \
352 PRECISION) \
353 RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + A_PREFIX ## G
354
355#define MultiplyAddAndStore4ByteArgbComps(RES_PREFIX, M1, M2_PREFIX, \
356 A_PREFIX) \
357 MultiplyAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, 8)
358
359#define MultiplyAddAndStore1ByteGrayComps(RES_PREFIX, M1, M2_PREFIX, \
360 A_PREFIX) \
361 MultiplyAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, 8)
362
363#define MultiplyAddAndStore1ShortGrayComps(RES_PREFIX, M1, M2_PREFIX, \
364 A_PREFIX) \
365 MultiplyAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, 16)
366
367
368/*
369 * MultMultAddAndStore ## STRATEGY ## Comps(RES_PREFIX, M1, M2_PREFIX, \
370 * M3, M4_PREFIX)
371 *
372 * c = (m1 * m2) + (m3 * m4);
373 */
374#define MultMultAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, \
375 M3, M4_PREFIX, PRECISION) \
376 do { \
377 RES_PREFIX ## R = MUL ## PRECISION(M1, M2_PREFIX ## R) + \
378 MUL ## PRECISION(M3, M4_PREFIX ## R); \
379 RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + \
380 MUL ## PRECISION(M3, M4_PREFIX ## G); \
381 RES_PREFIX ## B = MUL ## PRECISION(M1, M2_PREFIX ## B) + \
382 MUL ## PRECISION(M3, M4_PREFIX ## B); \
383 } while (0)
384
385
386#define MultMultAddAndStoreLCD3Components(RES_PREFIX, M1, M2_PREFIX, \
387 M3, M4_PREFIX, PRECISION) \
388 do { \
389 RES_PREFIX ## R = MUL ## PRECISION(M1 ## R, M2_PREFIX ## R) + \
390 MUL ## PRECISION(M3 ## R, M4_PREFIX ## R); \
391 RES_PREFIX ## G = MUL ## PRECISION(M1 ## G, M2_PREFIX ## G) + \
392 MUL ## PRECISION(M3 ## G, M4_PREFIX ## G); \
393 RES_PREFIX ## B = MUL ## PRECISION(M1 ## B, M2_PREFIX ## B) + \
394 MUL ## PRECISION(M3 ## B, M4_PREFIX ## B); \
395 } while (0)
396
397#define MultMultAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, \
398 M3, M4_PREFIX, PRECISION) \
399 RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + \
400 MUL ## PRECISION(M3, M4_PREFIX ## G)
401
402#define MultMultAddAndStore3ByteRgbComps(RES_PREFIX, M1, M2_PREFIX, \
403 M3, M4_PREFIX) \
404 MultMultAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, \
405 M3, M4_PREFIX, 8)
406
407#define MultMultAddAndStoreLCD3ByteRgbComps(RES_PREFIX, M1, M2_PREFIX, \
408 M3, M4_PREFIX) \
409 MultMultAddAndStoreLCD3Components(RES_PREFIX, M1, M2_PREFIX, \
410 M3, M4_PREFIX, 8)
411
412#define MultMultAddAndStore4ByteArgbComps(RES_PREFIX, M1, M2_PREFIX, \
413 M3, M4_PREFIX) \
414 MultMultAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, \
415 M3, M4_PREFIX, 8)
416
417#define MultMultAddAndStoreLCD4ByteArgbComps(RES_PREFIX, M1, M2_PREFIX, \
418 M3, M4_PREFIX) \
419 MultMultAddAndStoreLCD3Components(RES_PREFIX, M1, M2_PREFIX, \
420 M3, M4_PREFIX, 8)
421
422#define MultMultAddAndStore1ByteGrayComps(RES_PREFIX, M1, M2_PREFIX, \
423 M3, M4_PREFIX) \
424 MultMultAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, \
425 M3, M4_PREFIX, 8)
426
427#define MultMultAddAndStore1ShortGrayComps(RES_PREFIX, M1, M2_PREFIX, \
428 M3, M4_PREFIX) \
429 RES_PREFIX ## G = AddNormalizedProducts16(M1, M2_PREFIX ## G, \
430 M3, M4_PREFIX ## G)
431
432
433/*
434 * Store ## STRATEGY ## CompsUsingOp(L_PREFIX, OP, R_PREFIX)
435 *
436 * l op r; // where op can be something like = or +=
437 */
438#define Store3ComponentsUsingOp(L_PREFIX, OP, R_PREFIX) \
439 do { \
440 L_PREFIX ## R OP R_PREFIX ## R; \
441 L_PREFIX ## G OP R_PREFIX ## G; \
442 L_PREFIX ## B OP R_PREFIX ## B; \
443 } while (0)
444
445#define Store1ComponentUsingOp(L_PREFIX, OP, R_PREFIX) \
446 L_PREFIX ## G OP R_PREFIX ## G
447
448#define Store4ByteArgbCompsUsingOp(L_PREFIX, OP, R_PREFIX) \
449 Store3ComponentsUsingOp(L_PREFIX, OP, R_PREFIX)
450
451#define Store1ByteGrayCompsUsingOp(L_PREFIX, OP, R_PREFIX) \
452 Store1ComponentUsingOp(L_PREFIX, OP, R_PREFIX)
453
454#define Store1ShortGrayCompsUsingOp(L_PREFIX, OP, R_PREFIX) \
455 Store1ComponentUsingOp(L_PREFIX, OP, R_PREFIX)
456
457
458/*
459 * Set ## STRATEGY ## CompsToZero(PREFIX)
460 *
461 * c = 0;
462 */
463#define Set4ByteArgbCompsToZero(PREFIX) \
464 PREFIX ## R = PREFIX ## G = PREFIX ## B = 0
465
466#define Set1ByteGrayCompsToZero(PREFIX) \
467 PREFIX ## G = 0
468
469#define Set1ShortGrayCompsToZero(PREFIX) \
470 PREFIX ## G = 0
471
472#endif /* AlphaMath_h_Included */