1 /*
2  * Copyright (c) 1996, 1997, 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 /*
27  * This file contains macro definitions for the Alpha category of the
28  * macros used by the generic scaleloop function.
29  *
30  * This implementation of the Alpha macros will perform an ordered
31  * dither of the 8-bit alpha values collected from the input pixel
32  * data to construct a 1-bit deep image mask used to control the
33  * pixel coverage of the color pixels in the output.  This is a
34  * minimal quality implementation of Alpha that has the advantage
35  * that it is easy to support on a wide variety of platforms and
36  * graphics systems.
37  *
38  * This file can be used to provide the default implementation of the
39  * Alpha macros, handling all transparency cases.
40  */
41 
42 /*
43  * The macro IfAlpha is used by the varous pixel conversion macros
44  * to conditionally compile code that is only needed if alpha values
45  * are going to be used.
46  */
47 #define IfAlpha(statements)     statements
48 
49 #ifdef DEBUG
50 #define DeclareAlphaDebugVars                           \
51     MaskBits *endMask;
52 #define SetupEndMask(mask, dstH, cvdata)                \
53     do {endMask = mask + dstH * MaskScan(cvdata);} while (0)
54 #else /* DEBUG */
55 #define DeclareAlphaDebugVars
56 #define SetupEndMask(mask, dstH, cvdata)                \
57     do {} while (0)
58 #endif /* DEBUG */
59 
60 #define DeclareAlphaVars                                \
61     DeclareAlphaDebugVars                               \
62     MaskBits *mask;                                     \
63     MaskBits maskbits, maskcurbit, maskadjust;          \
64     int laststore;                                      \
65     extern uns_ordered_dither_array img_oda_alpha;
66 
67 #define InitAlpha(cvdata, dstY, dstX1, dstX2)                   \
68     do {                                                        \
69         laststore = 1;                                          \
70         mask = (MaskBits *) cvdata->maskbuf;                    \
71         maskadjust = - (MaskOffset(dstX2) - MaskOffset(dstX1)); \
72         if (mask) {                                             \
73             SetupEndMask(mask, dstTotalHeight, cvdata);         \
74             mask += ((dstY * MaskScan(cvdata))                  \
75                      + MaskOffset(dstX1));                      \
76             maskadjust += MaskScan(cvdata);                     \
77             maskcurbit = 1;                                     \
78         } else {                                                \
79             maskcurbit = 0;                                     \
80         }                                                       \
81     } while (0)
82 
83 #define StartAlphaRow(cvdata, dstX, dstY)                       \
84     do {                                                        \
85         if (maskcurbit) {                                       \
86             maskbits = *mask;                                   \
87             maskcurbit = MaskInit(dstX);                        \
88         }                                                       \
89     } while (0)
90 
91 #define IncrementMaskBit(dstX)                                  \
92     do {                                                        \
93         if (((maskcurbit) >>= 1) == 0) {                        \
94             *mask++ = maskbits;                                 \
95             if (dstX < DSTX2 - 1) {                             \
96                 img_check(mask < endMask);                      \
97                 maskbits = *mask;                               \
98             } else {                                            \
99                 laststore = 0;                                  \
100             }                                                   \
101             maskcurbit = MaskInit(0);                           \
102         }                                                       \
103     } while (0)
104 
105 #define SetTransparentPixel(cvdata, dstX, dstY)                 \
106     do {                                                        \
107         if (!maskcurbit) {                                      \
108             mask = (MaskBits *) ImgInitMask(cvdata,             \
109                                             DSTX1, DSTY1,       \
110                                             DSTX2, DSTY2);      \
111             if (!mask) {                                        \
112                 SignalError(0, JAVAPKG "OutOfMemoryError", 0);  \
113                 return SCALEFAILURE;                            \
114             }                                                   \
115             SetupEndMask(mask, dstTotalHeight, cvdata);         \
116             mask += ((dstY * MaskScan(cvdata))                  \
117                      + MaskOffset(dstX));                       \
118             maskadjust += MaskScan(cvdata);                     \
119             maskbits = *mask;                                   \
120             maskcurbit = MaskInit(dstX);                        \
121         }                                                       \
122         SetTransparentBit(maskbits, maskcurbit);                \
123         IncrementMaskBit(dstX);                                 \
124     } while (0)
125 
126 #define SetOpaquePixel(cvdata, dstX, dstY)                      \
127     do {                                                        \
128         if (maskcurbit) {                                       \
129             SetOpaqueBit(maskbits, maskcurbit);                 \
130             IncrementMaskBit(dstX);                             \
131         }                                                       \
132     } while (0)
133 
134 #define ApplyAlpha(cvdata, dstX, dstY, alpha)                   \
135     do {                                                        \
136         if (alpha + img_oda_alpha[dstX & 7][dstY & 7] < 255) {  \
137             SetTransparentPixel(cvdata, dstX, dstY);            \
138         } else {                                                \
139             SetOpaquePixel(cvdata, dstX, dstY);                 \
140         }                                                       \
141     } while (0)
142 
143 #define EndMaskLine()                                           \
144     do {                                                        \
145         if (maskcurbit) {                                       \
146             if (laststore) {                                    \
147                 img_check(mask < endMask);                      \
148                 *mask = maskbits;                               \
149             }                                                   \
150             mask += maskadjust;                                 \
151         }                                                       \
152     } while (0)
153