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