Path: blob/master/src/java.desktop/share/native/libawt/java2d/loops/AlphaMath.h
41159 views
/*1* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#ifndef AlphaMath_h_Included26#define AlphaMath_h_Included2728#include "jni.h"2930JNIEXPORT extern unsigned char mul8table[256][256];31JNIEXPORT extern unsigned char div8table[256][256];32extern void initAlphaTables();333435/*36* Multiply and Divide macros for single byte (8-bit) quantities representing37* the values 0.0 to 1.0 as 0x00 to 0xff.38* MUL8 multiplies its operands together39* DIV8 divides the first operand by the second, clipping to 0xff40* (Note that since the divisor for DIV8 is likely to be41* the alpha quantity which is likely to be the same for42* multiple adjacent invocations, the table is designed43* with the first index being the divisor to hopefully44* improve memory cache hits...)45*/46#define MUL8(a,b) mul8table[a][b]47#define DIV8(a,b) div8table[b][a]4849/*50* Multiply and Divide macros for operations involving a single short (16-bit)51* quantity and a single byte (8-bit) quantity. Typically, promoting the52* 8-bit value to 16 bits would lead to overflow when the operation occurs.53* These macros have been modified somewhat so that overflow will not occur.54* MUL8_16 multiplies an 8-bit value by a 16-bit value (the order of operands55* is unimportant since multiplication is a commutative operation)56* DIV16_8 divides the first (16-bit) operand by the second (8-bit) value57*/5859#define MUL8_16(a,b) (((a) * (b)) / 255)60#define DIV16_8(a,b) (((a) * 255) / (b))6162/*63* Multiply and Divide macros for single short (16-bit) quantities64* representing the values 0.0 to 1.0 as 0x0000 to 0xffff.65* MUL16 multiplies its operands using the standard multiplication operator66* and normalizes the result to the appropriate range67* DIV16 divides the first operand by the second and normalizes the result68* to a 16-bit value69*/70#define MUL16(a,b) (((a) * (b)) / 65535)71#define DIV16(a,b) (((a) * 65535) / (b))7273/*74* Macro for the sum of two normalized (16-bit) products. Refer to the75* following equation and note that the right side reduces the number of76* divide operations in the left side and increases the precision of the77* result:78* a*f1 + b*f2 a*f1 + b*f279* ---- ---- = ----------- (where n in this case will be 65535)80* n n n81*/82#define AddNormalizedProducts16(a, f1, b, f2) \83((((a) * (f1)) + ((b) * (f2))) / 65535)848586/*87* The following macros help to generalize the MaskBlit and MaskFill loops88* found in AlphaMacros.h. The appropriate macros will be used based on the89* strategy of the given loop. The strategy types take the form:90* <number of components per pixel><component data type><colorspace>91* For example, these are the current strategy types:92* 3ByteRgb (currently only used as a glyph list blending strategy where93* the alpha value itself is neither blended nor stored)94* 4ByteArgb (eg. IntArgb, ThreeByteBgr, Ushort555Rgb, ByteIndexed, etc.)95* 4ShortArgb (not used currently; could be used when surface types using96* 16 bits per component are implemented)97* 1ByteGray (eg. ByteGray)98* 1ShortGray (eg. UshortGray)99* Note that the macros which operate on alpha values have the word "Alpha"100* somewhere in their name. Those macros that only operate on the color/gray101* components of a given strategy will have the word "Components" or "Comps"102* in their name.103*/104105106/*107* MaxValFor ## STRATEGY108*/109#define MaxValFor4ByteArgb 0xff110#define MaxValFor1ByteGray 0xff111#define MaxValFor1ShortGray 0xffff112113114/*115* AlphaType ## STRATEGY116*/117#define AlphaType3ByteRgb jint118#define AlphaType4ByteArgb jint119#define AlphaType1ByteGray jint120#define AlphaType1ShortGray juint121122123/*124* ComponentType ## STRATEGY125*/126#define ComponentType3ByteRgb jint127#define ComponentType4ByteArgb jint128#define ComponentType1ByteGray jint129#define ComponentType1ShortGray juint130131132/*133* DeclareAlphaVarFor ## STRATEGY(VAR)134*135* jint a;136*/137#define DeclareAlphaVarFor3ByteRgb(VAR) \138AlphaType3ByteRgb VAR;139140#define DeclareAlphaVarFor4ByteArgb(VAR) \141AlphaType4ByteArgb VAR;142143#define DeclareAlphaVarFor1ByteGray(VAR) \144AlphaType1ByteGray VAR;145146#define DeclareAlphaVarFor1ShortGray(VAR) \147AlphaType1ShortGray VAR;148149150/*151* DeclareAndInitAlphaVarFor ## STRATEGY(VAR, initval)152*153* jint a = initval;154*/155#define DeclareAndInitAlphaVarFor4ByteArgb(VAR, initval) \156AlphaType4ByteArgb VAR = initval;157158#define DeclareAndInitAlphaVarFor1ByteGray(VAR, initval) \159AlphaType1ByteGray VAR = initval;160161#define DeclareAndInitAlphaVarFor1ShortGray(VAR, initval) \162AlphaType1ShortGray VAR = initval;163164165/*166* DeclareAndClearAlphaVarFor ## STRATEGY(VAR)167*168* jint a = 0;169*/170#define DeclareAndClearAlphaVarFor4ByteArgb(VAR) \171DeclareAndInitAlphaVarFor4ByteArgb(VAR, 0)172173#define DeclareAndClearAlphaVarFor1ByteGray(VAR) \174DeclareAndInitAlphaVarFor1ByteGray(VAR, 0)175176#define DeclareAndClearAlphaVarFor1ShortGray(VAR) \177DeclareAndInitAlphaVarFor1ShortGray(VAR, 0)178179180/*181* DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(VAR)182*183* jint a = 0xff;184*/185#define DeclareAndSetOpaqueAlphaVarFor4ByteArgb(VAR) \186DeclareAndInitAlphaVarFor4ByteArgb(VAR, MaxValFor4ByteArgb)187188#define DeclareAndSetOpaqueAlphaVarFor1ByteGray(VAR) \189DeclareAndInitAlphaVarFor1ByteGray(VAR, MaxValFor1ByteGray)190191#define DeclareAndSetOpaqueAlphaVarFor1ShortGray(VAR) \192DeclareAndInitAlphaVarFor1ShortGray(VAR, MaxValFor1ShortGray)193194195/*196* DeclareAndInvertAlphaVarFor ## STRATEGY(VAR, invalpha)197*198* jint a = 0xff - resA;199*/200#define DeclareAndInvertAlphaVarFor4ByteArgb(VAR, invalpha) \201DeclareAndInitAlphaVarFor4ByteArgb(VAR, MaxValFor4ByteArgb - invalpha)202203#define DeclareAndInvertAlphaVarFor1ByteGray(VAR, invalpha) \204DeclareAndInitAlphaVarFor1ByteGray(VAR, MaxValFor1ByteGray - invalpha)205206#define DeclareAndInvertAlphaVarFor1ShortGray(VAR, invalpha) \207DeclareAndInitAlphaVarFor1ShortGray(VAR, MaxValFor1ShortGray - invalpha)208209210/*211* DeclareCompVarsFor ## STRATEGY(PREFIX)212*213* jint c;214*/215#define DeclareCompVarsFor3ByteRgb(PREFIX) \216ComponentType3ByteRgb PREFIX ## R, PREFIX ## G, PREFIX ## B;217218#define DeclareCompVarsFor4ByteArgb(PREFIX) \219ComponentType4ByteArgb PREFIX ## R, PREFIX ## G, PREFIX ## B;220221#define DeclareCompVarsFor1ByteGray(PREFIX) \222ComponentType1ByteGray PREFIX ## G;223224#define DeclareCompVarsFor1ShortGray(PREFIX) \225ComponentType1ShortGray PREFIX ## G;226227228/*229* DeclareAndInitExtraAlphaFor ## STRATEGY(VAR)230*231* jint extraA = (int)(pCompInfo->details.extraAlpha * 255.0 + 0.5);232*/233#define DeclareAndInitExtraAlphaFor4ByteArgb(VAR) \234AlphaType4ByteArgb VAR = \235(AlphaType4ByteArgb)(pCompInfo->details.extraAlpha * 255.0 + 0.5);236237#define DeclareAndInitExtraAlphaFor1ByteGray(VAR) \238AlphaType1ByteGray VAR = \239(AlphaType1ByteGray)(pCompInfo->details.extraAlpha * 255.0 + 0.5);240241#define DeclareAndInitExtraAlphaFor1ShortGray(VAR) \242AlphaType1ShortGray VAR = \243(AlphaType1ShortGray)(pCompInfo->details.extraAlpha * 65535.0 + 0.5);244245246/*247* PromoteByteAlphaFor ## STRATEGY(a)248*/249#define PromoteByteAlphaFor4ByteArgb(a)250#define PromoteByteAlphaFor1ByteGray(a)251#define PromoteByteAlphaFor1ShortGray(a) \252(a) = (((a) << 8) + (a))253254255/*256* DeclareAndInitPathAlphaFor ## STRATEGY(VAR)257*258* jint pathA = *pMask++;259*/260#define DeclareAndInitPathAlphaFor4ByteArgb(VAR) \261AlphaType4ByteArgb VAR = *pMask++;262263#define DeclareAndInitPathAlphaFor1ByteGray(VAR) \264AlphaType1ByteGray VAR = *pMask++;265266#define DeclareAndInitPathAlphaFor1ShortGray(VAR) \267AlphaType1ShortGray VAR = *pMask++;268269270/*271* MultiplyAlphaFor ## STRATEGY(a, b)272*273* a * b274*/275#define MultiplyAlphaFor4ByteArgb(a, b) \276MUL8(a, b)277278#define MultiplyAlphaFor1ByteGray(a, b) \279MUL8(a, b)280281#define MultiplyAlphaFor1ShortGray(a, b) \282MUL16(a, b)283284285/*286* MultiplyAndStore ## STRATEGY ## Comps(PROD_PREFIX, M1, M2_PREFIX)287*288* c = m1 * m2;289*/290#define MultiplyAndStore3Components(PROD_PREFIX, M1, M2_PREFIX, PRECISION) \291do { \292PROD_PREFIX ## R = MUL ## PRECISION(M1, M2_PREFIX ## R); \293PROD_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G); \294PROD_PREFIX ## B = MUL ## PRECISION(M1, M2_PREFIX ## B); \295} while (0)296297#define MultiplyAndStore1Component(PROD_PREFIX, M1, M2_PREFIX, PRECISION) \298PROD_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G)299300#define MultiplyAndStore4ByteArgbComps(PROD_PREFIX, M1, M2_PREFIX) \301MultiplyAndStore3Components(PROD_PREFIX, M1, M2_PREFIX, 8)302303#define MultiplyAndStore1ByteGrayComps(PROD_PREFIX, M1, M2_PREFIX) \304MultiplyAndStore1Component(PROD_PREFIX, M1, M2_PREFIX, 8)305306#define MultiplyAndStore1ShortGrayComps(PROD_PREFIX, M1, M2_PREFIX) \307MultiplyAndStore1Component(PROD_PREFIX, M1, M2_PREFIX, 16)308309310/*311* DivideAndStore ## STRATEGY ## Comps(QUOT_PREFIX, D1_PREFIX, D2)312*313* c = d1 / d2;314*/315#define DivideAndStore3Components(QUOT_PREFIX, D1_PREFIX, D2, PRECISION) \316do { \317QUOT_PREFIX ## R = DIV ## PRECISION(D1_PREFIX ## R, D2); \318QUOT_PREFIX ## G = DIV ## PRECISION(D1_PREFIX ## G, D2); \319QUOT_PREFIX ## B = DIV ## PRECISION(D1_PREFIX ## B, D2); \320} while (0)321322#define DivideAndStore1Component(QUOT_PREFIX, D1_PREFIX, D2, PRECISION) \323QUOT_PREFIX ## G = DIV ## PRECISION(D1_PREFIX ## G, D2)324325#define DivideAndStore4ByteArgbComps(QUOT_PREFIX, D1_PREFIX, D2) \326DivideAndStore3Components(QUOT_PREFIX, D1_PREFIX, D2, 8)327328#define DivideAndStore1ByteGrayComps(QUOT_PREFIX, D1_PREFIX, D2) \329DivideAndStore1Component(QUOT_PREFIX, D1_PREFIX, D2, 8)330331#define DivideAndStore1ShortGrayComps(QUOT_PREFIX, D1_PREFIX, D2) \332DivideAndStore1Component(QUOT_PREFIX, D1_PREFIX, D2, 16)333334335/*336* MultiplyAddAndStore ## STRATEGY ## Comps(RES_PREFIX, M1, \337* M2_PREFIX, A_PREFIX)338*339* c = (m1 * m2) + a;340*/341#define MultiplyAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, \342PRECISION) \343do { \344RES_PREFIX ## R = MUL ## PRECISION(M1, M2_PREFIX ## R) + \345A_PREFIX ## R; \346RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + \347A_PREFIX ## G; \348RES_PREFIX ## B = MUL ## PRECISION(M1, M2_PREFIX ## B) + \349A_PREFIX ## B; \350} while (0)351352#define MultiplyAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, \353PRECISION) \354RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + A_PREFIX ## G355356#define MultiplyAddAndStore4ByteArgbComps(RES_PREFIX, M1, M2_PREFIX, \357A_PREFIX) \358MultiplyAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, 8)359360#define MultiplyAddAndStore1ByteGrayComps(RES_PREFIX, M1, M2_PREFIX, \361A_PREFIX) \362MultiplyAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, 8)363364#define MultiplyAddAndStore1ShortGrayComps(RES_PREFIX, M1, M2_PREFIX, \365A_PREFIX) \366MultiplyAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, A_PREFIX, 16)367368369/*370* MultMultAddAndStore ## STRATEGY ## Comps(RES_PREFIX, M1, M2_PREFIX, \371* M3, M4_PREFIX)372*373* c = (m1 * m2) + (m3 * m4);374*/375#define MultMultAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, \376M3, M4_PREFIX, PRECISION) \377do { \378RES_PREFIX ## R = MUL ## PRECISION(M1, M2_PREFIX ## R) + \379MUL ## PRECISION(M3, M4_PREFIX ## R); \380RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + \381MUL ## PRECISION(M3, M4_PREFIX ## G); \382RES_PREFIX ## B = MUL ## PRECISION(M1, M2_PREFIX ## B) + \383MUL ## PRECISION(M3, M4_PREFIX ## B); \384} while (0)385386387#define MultMultAddAndStoreLCD3Components(RES_PREFIX, M1, M2_PREFIX, \388M3, M4_PREFIX, PRECISION) \389do { \390RES_PREFIX ## R = MUL ## PRECISION(M1 ## R, M2_PREFIX ## R) + \391MUL ## PRECISION(M3 ## R, M4_PREFIX ## R); \392RES_PREFIX ## G = MUL ## PRECISION(M1 ## G, M2_PREFIX ## G) + \393MUL ## PRECISION(M3 ## G, M4_PREFIX ## G); \394RES_PREFIX ## B = MUL ## PRECISION(M1 ## B, M2_PREFIX ## B) + \395MUL ## PRECISION(M3 ## B, M4_PREFIX ## B); \396} while (0)397398#define MultMultAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, \399M3, M4_PREFIX, PRECISION) \400RES_PREFIX ## G = MUL ## PRECISION(M1, M2_PREFIX ## G) + \401MUL ## PRECISION(M3, M4_PREFIX ## G)402403#define MultMultAddAndStore3ByteRgbComps(RES_PREFIX, M1, M2_PREFIX, \404M3, M4_PREFIX) \405MultMultAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, \406M3, M4_PREFIX, 8)407408#define MultMultAddAndStoreLCD3ByteRgbComps(RES_PREFIX, M1, M2_PREFIX, \409M3, M4_PREFIX) \410MultMultAddAndStoreLCD3Components(RES_PREFIX, M1, M2_PREFIX, \411M3, M4_PREFIX, 8)412413#define MultMultAddAndStore4ByteArgbComps(RES_PREFIX, M1, M2_PREFIX, \414M3, M4_PREFIX) \415MultMultAddAndStore3Components(RES_PREFIX, M1, M2_PREFIX, \416M3, M4_PREFIX, 8)417418#define MultMultAddAndStoreLCD4ByteArgbComps(RES_PREFIX, M1, M2_PREFIX, \419M3, M4_PREFIX) \420MultMultAddAndStoreLCD3Components(RES_PREFIX, M1, M2_PREFIX, \421M3, M4_PREFIX, 8)422423#define MultMultAddAndStore1ByteGrayComps(RES_PREFIX, M1, M2_PREFIX, \424M3, M4_PREFIX) \425MultMultAddAndStore1Component(RES_PREFIX, M1, M2_PREFIX, \426M3, M4_PREFIX, 8)427428#define MultMultAddAndStore1ShortGrayComps(RES_PREFIX, M1, M2_PREFIX, \429M3, M4_PREFIX) \430RES_PREFIX ## G = AddNormalizedProducts16(M1, M2_PREFIX ## G, \431M3, M4_PREFIX ## G)432433434/*435* Store ## STRATEGY ## CompsUsingOp(L_PREFIX, OP, R_PREFIX)436*437* l op r; // where op can be something like = or +=438*/439#define Store3ComponentsUsingOp(L_PREFIX, OP, R_PREFIX) \440do { \441L_PREFIX ## R OP R_PREFIX ## R; \442L_PREFIX ## G OP R_PREFIX ## G; \443L_PREFIX ## B OP R_PREFIX ## B; \444} while (0)445446#define Store1ComponentUsingOp(L_PREFIX, OP, R_PREFIX) \447L_PREFIX ## G OP R_PREFIX ## G448449#define Store4ByteArgbCompsUsingOp(L_PREFIX, OP, R_PREFIX) \450Store3ComponentsUsingOp(L_PREFIX, OP, R_PREFIX)451452#define Store1ByteGrayCompsUsingOp(L_PREFIX, OP, R_PREFIX) \453Store1ComponentUsingOp(L_PREFIX, OP, R_PREFIX)454455#define Store1ShortGrayCompsUsingOp(L_PREFIX, OP, R_PREFIX) \456Store1ComponentUsingOp(L_PREFIX, OP, R_PREFIX)457458459/*460* Set ## STRATEGY ## CompsToZero(PREFIX)461*462* c = 0;463*/464#define Set4ByteArgbCompsToZero(PREFIX) \465PREFIX ## R = PREFIX ## G = PREFIX ## B = 0466467#define Set1ByteGrayCompsToZero(PREFIX) \468PREFIX ## G = 0469470#define Set1ShortGrayCompsToZero(PREFIX) \471PREFIX ## G = 0472473#endif /* AlphaMath_h_Included */474475476