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 */