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 31 JNIEXPORT extern unsigned char mul8table[256][256]; 32 JNIEXPORT extern unsigned char div8table[256][256]; 33 extern 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 */