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