1 /*
2  * Copyright (c) 1996, 2013, 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 Scaling category of
28  * the macros used by the generic scaleloop function.
29  *
30  * This implementation uses a simple equation which simply chooses
31  * the closest input pixel to the location which is obtained from
32  * mapping inversely from the output rectangle to the input rectangle.
33  * The input pixels will be replicated when scaling larger than the
34  * original image size since the same input pixel will be chosen for
35  * more than one output pixel.  Conversely, when scaling smaller than
36  * the original image size, the input pixels will be omitted as needed
37  * to pare them down to the required number of samples for the output
38  * image.  If there is no scaling occurring in one or both directions
39  * the macros attempt to short-circuit most of the more complicated
40  * calculations in an attempt to impose little cost for using this
41  * implementation in the general case.  The calculations also do not
42  * impose any restrictions on the order of delivery of the pixels.
43  *
44  * This file can be used to provide the default implementation of the
45  * Scaling macros, handling both scaled and unscaled cases and any
46  * order of pixel delivery.
47  */
48 
49 #define DeclareScaleVars                                        \
50     int dstX1, dstY1, dstX, dstY, dstX2, dstY2;                 \
51     int srcX1, srcXinc, srcXrem, srcXincrem, srcX1increm;       \
52     int srcX, srcY, inputadjust;
53 
54 #define SRCX    srcX
55 #define SRCY    srcY
56 #define DSTX    dstX
57 #define DSTY    dstY
58 #define DSTX1   dstX1
59 #define DSTY1   dstY1
60 #define DSTX2   dstX2
61 #define DSTY2   dstY2
62 
63 #define InitScale(pixels, srcOff, srcScan,                              \
64                   srcOX, srcOY, srcW, srcH,                             \
65                   srcTW, srcTH, dstTW, dstTH)                           \
66     do {                                                                \
67         inputadjust = srcScan;                                          \
68         if (srcTW == dstTW) {                                           \
69             inputadjust -= srcW;                                        \
70             dstX1 = srcOX;                                              \
71             dstX2 = srcOX + srcW;                                       \
72         } else {                                                        \
73             dstX1 = DEST_XY_RANGE_START(srcOX, srcTW, dstTW);           \
74             dstX2 = DEST_XY_RANGE_START(srcOX+srcW, srcTW, dstTW);      \
75             if (dstX2 <= dstX1) {                                       \
76                 return SCALENOOP;                                       \
77             }                                                           \
78             srcX1 = SRC_XY(dstX1, srcTW, dstTW);                        \
79             srcXinc = srcTW / dstTW;                                    \
80             srcXrem = (2 * srcTW) % (2 * dstTW);                        \
81             srcX1increm = (((2 * (dstX1) * (srcTW)) + (srcTW))          \
82                           % (2 * (dstTW)));                             \
83         }                                                               \
84         if (srcTH == dstTH) {                                           \
85             dstY1 = srcOY;                                              \
86             dstY2 = srcOY + srcH;                                       \
87             SetInputRow(pixels, srcOff, srcScan, srcOY, srcOY);         \
88         } else {                                                        \
89             dstY1 = DEST_XY_RANGE_START(srcOY, srcTH, dstTH);           \
90             dstY2 = DEST_XY_RANGE_START(srcOY+srcH, srcTH, dstTH);      \
91             if (dstY2 <= dstY1) {                                       \
92                 return SCALENOOP;                                       \
93             }                                                           \
94         }                                                               \
95     } while (0)
96 
97 #define RowLoop(srcOY)                                                  \
98     for (dstY = dstY1; dstY < dstY2; dstY++)
99 
100 #define RowSetup(srcTH, dstTH, srcTW, dstTW,                            \
101                  srcOY, pixels, srcOff, srcScan)                        \
102         do {                                                            \
103             if (srcTH == dstTH) {                                       \
104                 srcY = dstY;                                            \
105             } else {                                                    \
106                 srcY = SRC_XY(dstY, srcTH, dstTH);                      \
107                 SetInputRow(pixels, srcOff, srcScan, srcY, srcOY);      \
108             }                                                           \
109             if (srcTW != dstTW) {                                       \
110                 srcXincrem = srcX1increm;                               \
111                 srcX = srcX1;                                           \
112             }                                                           \
113         } while (0)
114 
115 #define ColLoop(srcOX)                                                  \
116         for (dstX = dstX1; dstX < dstX2; dstX++)
117 
118 #define ColSetup(srcTW, dstTW, pixel)                                   \
119             do {                                                        \
120                 if (srcTW == dstTW) {                                   \
121                     srcX = dstX;                                        \
122                     pixel = GetPixelInc();                              \
123                 } else {                                                \
124                     pixel = GetPixel(srcX);                             \
125                     srcX += srcXinc;                                    \
126                     srcXincrem += srcXrem;                              \
127                     if (srcXincrem >= (2 * dstTW)) {                    \
128                         srcXincrem -= (2 * dstTW);                      \
129                         srcX++;                                         \
130                     }                                                   \
131                 }                                                       \
132             } while (0)
133 
134 #define RowEnd(srcTH, dstTH, srcW, srcScan)                             \
135         do {                                                            \
136             if (srcTH == dstTH) {                                       \
137                 InputPixelInc(inputadjust);                             \
138             }                                                           \
139         } while (0)
140