2362N/A * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A // Only accelerate scale if: 0N/A // - w/h positive values 0N/A // - no bgColor in operation 0N/A * This method is only called in those circumstances where the 0N/A * operation has a non-null secondary transform specfied. Its 0N/A * role is to check for various optimizations based on the types 0N/A * of both the secondary and SG2D transforms and to do some 0N/A * quick calculations to avoid having to combine the transforms 0N/A * and/or to call a more generalized method. 0N/A // First optimization - both are some kind of translate 0N/A // Combine the translations and check if interpolation is necessary. 0N/A // Second optimization - both are some kind of translate or scale 0N/A // Combine the scales and check if interpolation is necessary. 0N/A // Transform source bounds by extraAT, 0N/A // then translate the bounds again by x, y 0N/A // then transform the bounds again by sg.transform 0N/A // Do not try any more optimizations if either of the cases 0N/A // above was tried as we have already verified that the 0N/A // resulting transform will not simplify. 0N/A // In this case neither of the above simple transform 0N/A // pairs was found so we will do some final tests on 0N/A // the final rendering transform which may be the 0N/A // simple product of two complex transforms. 0N/A * This method is called with a final rendering transform that 0N/A * has combined all of the information about the Graphics2D 0N/A * transform attribute with the transformations specified by 0N/A * the arguments to the drawImage call. 0N/A * Its role is to see if the combined transform ends up being 0N/A * acceleratable by either a renderImageCopy or renderImageScale 0N/A * once all of the math is done. 0N/A * Note: The transform supplied here has an origin that is 0N/A * already adjusted to point to the device location where 0N/A * the (sx1, sy1) location of the source image should be placed. 0N/A // Transform 3 source corners by tx and analyze them 0N/A // for simplified operations (Copy or Scale). Using 0N/A // 3 points lets us analyze any kind of transform, 0N/A // even transforms that involve very tiny amounts of 0N/A // rotation or skew to see if they degenerate to a 0N/A // simple scale or copy operation within the allowable 0N/A // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2) 0N/A // because the transform is already translated such that 0N/A // the origin is where sx1, sy1 should go. 0N/A /* index: 0 1 2 3 4 5 */ 0N/A /* coord: (0, 0), (w, h), (0, h) */ 0N/A // First test if the X coords of the transformed UL 0N/A // and LL points match and that the Y coords of the 0N/A // transformed LR and LL points also match. 0N/A // If they do then it is a "rectilinear" transform and 0N/A // tryCopyOrScale will make sure it is upright and 0N/A * Check the bounding coordinates of the transformed source 0N/A * image to see if they fall on integer coordinates such 0N/A * that they will cause no interpolation anomalies if we 0N/A * use our simplified Blit or ScaledBlit operations instead 0N/A * of a full transform operation. 0N/A // First check if width and height are very close to img w&h. 0N/A // Round location to nearest pixel and then test 0N/A // if it will cause interpolation anomalies. 0N/A // (For now) We can only use our ScaledBlits if the image 0N/A // is upright (i.e. dw & dh both > 0) 0N/A * Return a BufferedImage of the requested type with the indicated 0N/A * subimage of the original image located at 0,0 in the new image. 0N/A * If a bgColor is supplied, composite the original image over that 0N/A * color with a SrcOver operation, otherwise make a SrcNoEa copy. 0N/A // REMIND: Is this correct? Can this happen? 0N/A // We cannot perform bg operations during transform so make 0N/A // an opaque temp image with the appropriate background 0N/A // and work from there. 0N/A // Temp image has appropriate subimage at 0,0 now. 0N/A /* We have no helper for this source image type. 0N/A * But we know that we do have helpers for both RGB and ARGB, 0N/A * so convert to one of those types depending on transparency. 0N/A * ARGB_PRE might be a better choice if the source image has 0N/A * alpha, but it may cause some recursion here since we only 0N/A * tend to have converters that convert to ARGB. 0N/A // Temp image has appropriate subimage at 0,0 now. 0N/A // assert(helper != null); 0N/A // Non-invertible transform means no output 0N/A * Find the maximum bounds on the destination that will be 0N/A * affected by the transformed source. First, transform all 0N/A * four corners of the source and then min and max the resulting 0N/A * destination coordinates of the transformed corners. 0N/A * Note that tx already has the offset to sx1,sy1 accounted 0N/A * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the 0N/A * source coordinates. 0N/A /* corner: UL UR LL LR */ 0N/A /* index: 0 1 2 3 4 5 6 7 */ 0N/A /* coord: (0, 0), (w, 0), (0, h), (w, h) */ 0N/A /* NOTE: We either have, or we can make, 0N/A * a MaskBlit for any alpha composite type 0N/A /* NOTE: We can only use the native TransformHelper 0N/A * func to go directly to the dest if both the helper 0N/A * and the MaskBlit are native. 0N/A * All helpers are native at this point, but some MaskBlit 0N/A * objects are implemented in Java, so we need to check. 0N/A // We can render directly. 0N/A /* NOTE: We either have, or we can make, 0N/A * a Blit for any composite type, even Custom 0N/A // We need to transform to a temp image and then copy 0N/A // just the pieces that are valid data to the dest. 0N/A * The helper function fills a temporary edges buffer 0N/A * for us with the bounding coordinates of each scanline 0N/A * in the following format: 0N/A * edges[0, 1] = [top y, bottom y) 0N/A * edges[2, 3] = [left x, right x) of top row 0N/A * edges[h*2, h*2+1] = [left x, right x) of bottom row 0N/A * all coordinates in the edges array will be relative to dx1, dy1 0N/A * edges thus has to be h*2+2 in length 4301N/A // It is important that edges[0]=edges[1]=0 when we call 4301N/A // Transform in case it must return early and we would 4301N/A // not want to render anything on an error condition. 0N/A * Now copy the results, scanline by scanline, into the dest. 0N/A * The edges array helps us minimize the work. 0N/A // Render an image using only integer translation 0N/A // (no scale or transform or sub-pixel interpolated translations). 0N/A // Loop up to twice through; this gives us a chance to 0N/A // revalidate the surfaceData objects in case of an exception 0N/A // and try it once more 0N/A // Something else caused the exception, throw it... 0N/A // NOP if we have been disposed 0N/A // Always catch the exception; try this a couple of times 0N/A // and fail silently if the system is not yet ready to 0N/A // revalidate the source or dest surfaceData objects. 0N/A // Render an image using only integer scaling (no transform). 0N/A // Currently only NEAREST_NEIGHBOR interpolation is implemented 0N/A // for ScaledBlit operations. 0N/A // Loop up to twice through; this gives us a chance to 0N/A // revalidate the surfaceData objects in case of an exception 0N/A // and try it once more 0N/A // Something else caused the exception, throw it... 0N/A // NOP if we have been disposed 0N/A // Always catch the exception; try this a couple of times 0N/A // and fail silently if the system is not yet ready to 0N/A // revalidate the source or dest surfaceData objects. 0N/A // Only accelerate scale if it does not involve a flip or transform 0N/A // Make sure we are not out of bounds 0N/A // Note: src[WH] are currently the right and bottom coordinates. 0N/A // The following two lines would adjust src[WH] back to being 0N/A // Since transformImage needs right and bottom coords we will 0N/A // omit this adjustment. 0N/A ** The following methods are used by the public methods above 0N/A ** for performing various operations 0N/A * This constant represents a tradeoff between the 0N/A * need to make sure that image transformations are 0N/A * "very close" to integer device coordinates before 0N/A * we decide to use an integer scale or copy operation 0N/A * as a substitute and the fact that roundoff errors 0N/A * in AffineTransforms are frequently introduced by 0N/A * performing multiple sequential operations on them. 0N/A * The evaluation of bug 4990624 details the potential 0N/A * for this error cutoff to result in display anomalies 0N/A * in different types of image operations and how this 0N/A * value represents a good compromise here. 0N/A // Integer translates are always "simple" 0N/A // Scales and beyond are always "not simple" 0N/A // non-integer translates are only simple when not interpolating 0N/A // If we cannot get the srcData, then cannot assume anything about 0N/A // Must be VolatileImage; get BufferedImage representation 0N/A * Return the color model to be used with this BufferedImage and 0N/A // Check out the matrix. A non-integral scale will force ARGB 0N/A // since the edge conditions cannot be guaranteed. 0N/A // Just need to make sure that we have a transparent pixel 0N/A // Only scaling so do not need to create 0N/A }
/* if (matrix[0] < 1.f ...) */ 0N/A }
/* raster instanceof sun.awt.image.BytePackedRaster */ 0N/A }
/* if (cm.getTransparency() == cm.OPAQUE) */ 0N/A }
/* if (cm instanceof IndexColorModel) */ 0N/A // Need a bitmask transparency 0N/A // REMIND: for now, use full transparency since no loops 0N/A }
/* if (sg.renderHint == RENDER_QUALITY) */ 0N/A // Need a bitmask transparency 0N/A // REMIND: for now, use full transparency since no loops 0N/A if (w <=
0 || h <=
0) {
0N/A * Fix for bugid 4783274 - BlitBg throws an exception for 0N/A * a particular set of anomalous parameters. 0N/A * REMIND: The native loops do proper clipping and would 0N/A * detect this situation themselves, but the Java loops 0N/A * all seem to trust their parameters a little too well 0N/A * to the point where they will try to process a negative 0N/A * area of pixels and throw exceptions. The real fix is 0N/A * to modify the Java loops to do proper clipping so that 0N/A * they can deal with negative dimensions as well as 0N/A * improperly large dimensions, but that fix is too risky 0N/A * to integrate for Mantis at this point. In the meantime 0N/A * eliminating the negative or zero dimensions here is 0N/A * "correct" and saves them from some nasty exceptional 0N/A * conditions, one of which is the test case of 4783274.