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