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