1 /*
2 * Copyright (c) 2001, 2016, 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
157 int ity = (int) Math.floor(ty + 0.5);
158 if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
159 (closeToInteger(itx, tx) && closeToInteger(ity, ty)))
160 {
161 renderImageCopy(sg, img, null, x+itx, y+ity, 0, 0, imgw, imgh);
162 return;
163 }
164 checkfinalxform = false;
165 } else if (sg.transformState <= SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
166 ((txtype & (AffineTransform.TYPE_FLIP |
167 AffineTransform.TYPE_MASK_ROTATION |
168 AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0))
169 {
170 // Second optimization - both are some kind of translate or scale
171
172 // Combine the scales and check if interpolation is necessary.
173
174 // Transform source bounds by extraAT,
175 // then translate the bounds again by x, y
176 // then transform the bounds again by sg.transform
177 double coords[] = new double[] {
178 0, 0, imgw, imgh,
179 };
180 extraAT.transform(coords, 0, coords, 0, 2);
181 coords[0] += x;
182 coords[1] += y;
183 coords[2] += x;
184 coords[3] += y;
185 sg.transform.transform(coords, 0, coords, 0, 2);
186
187 if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh,
188 null, interpType, coords))
189 {
190 return;
191 }
192 checkfinalxform = false;
193 } else {
194 checkfinalxform = true;
195 }
196
197 // Begin Transform
224 *
225 * Note: The transform supplied here has an origin that is
226 * already adjusted to point to the device location where
227 * the (sx1, sy1) location of the source image should be placed.
228 */
229 protected void transformImage(SunGraphics2D sg, Image img,
230 AffineTransform tx, int interpType,
231 int sx1, int sy1, int sx2, int sy2,
232 Color bgColor)
233 {
234 // Transform 3 source corners by tx and analyze them
235 // for simplified operations (Copy or Scale). Using
236 // 3 points lets us analyze any kind of transform,
237 // even transforms that involve very tiny amounts of
238 // rotation or skew to see if they degenerate to a
239 // simple scale or copy operation within the allowable
240 // error bounds.
241 // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
242 // because the transform is already translated such that
243 // the origin is where sx1, sy1 should go.
244 double coords[] = new double[6];
245 /* index: 0 1 2 3 4 5 */
246 /* coord: (0, 0), (w, h), (0, h) */
247 coords[2] = sx2 - sx1;
248 coords[3] = coords[5] = sy2 - sy1;
249 tx.transform(coords, 0, coords, 0, 3);
250 // First test if the X coords of the transformed UL
251 // and LL points match and that the Y coords of the
252 // transformed LR and LL points also match.
253 // If they do then it is a "rectilinear" transform and
254 // tryCopyOrScale will make sure it is upright and
255 // integer-based.
256 if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR &&
257 Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR &&
258 tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2,
259 bgColor, interpType, coords))
260 {
261 return;
262 }
263
264 renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor);
265 }
266
267 /*
268 * Check the bounding coordinates of the transformed source
269 * image to see if they fall on integer coordinates such
270 * that they will cause no interpolation anomalies if we
271 * use our simplified Blit or ScaledBlit operations instead
272 * of a full transform operation.
273 */
274 protected boolean tryCopyOrScale(SunGraphics2D sg,
275 Image img,
276 int sx1, int sy1,
277 int sx2, int sy2,
278 Color bgColor, int interpType,
279 double coords[])
280 {
281 double dx1 = coords[0];
282 double dy1 = coords[1];
283 double dx2 = coords[2];
284 double dy2 = coords[3];
285 double dw = dx2 - dx1;
286 double dh = dy2 - dy1;
287
288 /* If any of the destination coordinates exceed the integer range,
289 * then the calculations performed in calls made here cannot be
290 * guaranteed to be correct, or to converge (terminate).
291 * So return out of here, deferring to code that can handle this.
292 */
293 if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
294 dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
295 dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
296 dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
297 {
298 return false;
299 }
|
1 /*
2 * Copyright (c) 2001, 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
157 int ity = (int) Math.floor(ty + 0.5);
158 if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
159 (closeToInteger(itx, tx) && closeToInteger(ity, ty)))
160 {
161 renderImageCopy(sg, img, null, x+itx, y+ity, 0, 0, imgw, imgh);
162 return;
163 }
164 checkfinalxform = false;
165 } else if (sg.transformState <= SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
166 ((txtype & (AffineTransform.TYPE_FLIP |
167 AffineTransform.TYPE_MASK_ROTATION |
168 AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0))
169 {
170 // Second optimization - both are some kind of translate or scale
171
172 // Combine the scales and check if interpolation is necessary.
173
174 // Transform source bounds by extraAT,
175 // then translate the bounds again by x, y
176 // then transform the bounds again by sg.transform
177 double[] coords = new double[] {
178 0, 0, imgw, imgh,
179 };
180 extraAT.transform(coords, 0, coords, 0, 2);
181 coords[0] += x;
182 coords[1] += y;
183 coords[2] += x;
184 coords[3] += y;
185 sg.transform.transform(coords, 0, coords, 0, 2);
186
187 if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh,
188 null, interpType, coords))
189 {
190 return;
191 }
192 checkfinalxform = false;
193 } else {
194 checkfinalxform = true;
195 }
196
197 // Begin Transform
224 *
225 * Note: The transform supplied here has an origin that is
226 * already adjusted to point to the device location where
227 * the (sx1, sy1) location of the source image should be placed.
228 */
229 protected void transformImage(SunGraphics2D sg, Image img,
230 AffineTransform tx, int interpType,
231 int sx1, int sy1, int sx2, int sy2,
232 Color bgColor)
233 {
234 // Transform 3 source corners by tx and analyze them
235 // for simplified operations (Copy or Scale). Using
236 // 3 points lets us analyze any kind of transform,
237 // even transforms that involve very tiny amounts of
238 // rotation or skew to see if they degenerate to a
239 // simple scale or copy operation within the allowable
240 // error bounds.
241 // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
242 // because the transform is already translated such that
243 // the origin is where sx1, sy1 should go.
244 double[] coords = new double[6];
245 /* index: 0 1 2 3 4 5 */
246 /* coord: (0, 0), (w, h), (0, h) */
247 coords[2] = sx2 - sx1;
248 coords[3] = coords[5] = sy2 - sy1;
249 tx.transform(coords, 0, coords, 0, 3);
250 // First test if the X coords of the transformed UL
251 // and LL points match and that the Y coords of the
252 // transformed LR and LL points also match.
253 // If they do then it is a "rectilinear" transform and
254 // tryCopyOrScale will make sure it is upright and
255 // integer-based.
256 if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR &&
257 Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR &&
258 tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2,
259 bgColor, interpType, coords))
260 {
261 return;
262 }
263
264 renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor);
265 }
266
267 /*
268 * Check the bounding coordinates of the transformed source
269 * image to see if they fall on integer coordinates such
270 * that they will cause no interpolation anomalies if we
271 * use our simplified Blit or ScaledBlit operations instead
272 * of a full transform operation.
273 */
274 protected boolean tryCopyOrScale(SunGraphics2D sg,
275 Image img,
276 int sx1, int sy1,
277 int sx2, int sy2,
278 Color bgColor, int interpType,
279 double[] coords)
280 {
281 double dx1 = coords[0];
282 double dy1 = coords[1];
283 double dx2 = coords[2];
284 double dy2 = coords[3];
285 double dw = dx2 - dx1;
286 double dh = dy2 - dy1;
287
288 /* If any of the destination coordinates exceed the integer range,
289 * then the calculations performed in calls made here cannot be
290 * guaranteed to be correct, or to converge (terminate).
291 * So return out of here, deferring to code that can handle this.
292 */
293 if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
294 dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
295 dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
296 dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
297 {
298 return false;
299 }
|