1 /*
2  * Copyright (c) 2000, 2005, Oracle and/or its affiliates. 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #ifndef AlphaMath_h_Included
27 #define AlphaMath_h_Included
28 
29 extern unsigned char mul8table[256][256];
30 extern unsigned char div8table[256][256];
31 extern 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 */
473