src/share/classes/java/awt/image/AffineTransformOp.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 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


  93      * hints are specified (<CODE>hints</CODE> is null),
  94      * the interpolation type is {@link #TYPE_NEAREST_NEIGHBOR
  95      * TYPE_NEAREST_NEIGHBOR}.
  96      *
  97      * @param xform The <CODE>AffineTransform</CODE> to use for the
  98      * operation.
  99      *
 100      * @param hints The <CODE>RenderingHints</CODE> object used to specify
 101      * the interpolation type for the operation.
 102      *
 103      * @throws ImagingOpException if the transform is non-invertible.
 104      * @see java.awt.RenderingHints#KEY_INTERPOLATION
 105      * @see java.awt.RenderingHints#KEY_RENDERING
 106      */
 107     public AffineTransformOp(AffineTransform xform, RenderingHints hints){
 108         validateTransform(xform);
 109         this.xform = (AffineTransform) xform.clone();
 110         this.hints = hints;
 111 
 112         if (hints != null) {
 113             Object value = hints.get(hints.KEY_INTERPOLATION);
 114             if (value == null) {
 115                 value = hints.get(hints.KEY_RENDERING);
 116                 if (value == hints.VALUE_RENDER_SPEED) {
 117                     interpolationType = TYPE_NEAREST_NEIGHBOR;
 118                 }
 119                 else if (value == hints.VALUE_RENDER_QUALITY) {
 120                     interpolationType = TYPE_BILINEAR;
 121                 }
 122             }
 123             else if (value == hints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR) {
 124                 interpolationType = TYPE_NEAREST_NEIGHBOR;
 125             }
 126             else if (value == hints.VALUE_INTERPOLATION_BILINEAR) {
 127                 interpolationType = TYPE_BILINEAR;
 128             }
 129             else if (value == hints.VALUE_INTERPOLATION_BICUBIC) {
 130                 interpolationType = TYPE_BICUBIC;
 131             }
 132         }
 133         else {
 134             interpolationType = TYPE_NEAREST_NEIGHBOR;
 135         }
 136     }
 137 
 138     /**
 139      * Constructs an <CODE>AffineTransformOp</CODE> given an affine transform
 140      * and the interpolation type.
 141      *
 142      * @param xform The <CODE>AffineTransform</CODE> to use for the operation.
 143      * @param interpolationType One of the integer
 144      * interpolation type constants defined by this class:
 145      * {@link #TYPE_NEAREST_NEIGHBOR TYPE_NEAREST_NEIGHBOR},
 146      * {@link #TYPE_BILINEAR TYPE_BILINEAR},
 147      * {@link #TYPE_BICUBIC TYPE_BICUBIC}.
 148      * @throws ImagingOpException if the transform is non-invertible.
 149      */


 218                                                "same as the dst image");
 219         }
 220 
 221         boolean needToConvert = false;
 222         ColorModel srcCM = src.getColorModel();
 223         ColorModel dstCM;
 224         BufferedImage origDst = dst;
 225 
 226         if (dst == null) {
 227             dst = createCompatibleDestImage(src, null);
 228             dstCM = srcCM;
 229             origDst = dst;
 230         }
 231         else {
 232             dstCM = dst.getColorModel();
 233             if (srcCM.getColorSpace().getType() !=
 234                 dstCM.getColorSpace().getType())
 235             {
 236                 int type = xform.getType();
 237                 boolean needTrans = ((type&
 238                                       (xform.TYPE_MASK_ROTATION|
 239                                        xform.TYPE_GENERAL_TRANSFORM))
 240                                      != 0);
 241                 if (! needTrans && type != xform.TYPE_TRANSLATION && type != xform.TYPE_IDENTITY)


 242                 {
 243                     double[] mtx = new double[4];
 244                     xform.getMatrix(mtx);
 245                     // Check out the matrix.  A non-integral scale will force ARGB
 246                     // since the edge conditions can't be guaranteed.
 247                     needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]);
 248                 }
 249 
 250                 if (needTrans &&
 251                     srcCM.getTransparency() == Transparency.OPAQUE)
 252                 {
 253                     // Need to convert first
 254                     ColorConvertOp ccop = new ColorConvertOp(hints);
 255                     BufferedImage tmpSrc = null;
 256                     int sw = src.getWidth();
 257                     int sh = src.getHeight();
 258                     if (dstCM.getTransparency() == Transparency.OPAQUE) {
 259                         tmpSrc = new BufferedImage(sw, sh,
 260                                                   BufferedImage.TYPE_INT_ARGB);
 261                     }


   1 /*
   2  * Copyright (c) 1997, 2014, 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


  93      * hints are specified (<CODE>hints</CODE> is null),
  94      * the interpolation type is {@link #TYPE_NEAREST_NEIGHBOR
  95      * TYPE_NEAREST_NEIGHBOR}.
  96      *
  97      * @param xform The <CODE>AffineTransform</CODE> to use for the
  98      * operation.
  99      *
 100      * @param hints The <CODE>RenderingHints</CODE> object used to specify
 101      * the interpolation type for the operation.
 102      *
 103      * @throws ImagingOpException if the transform is non-invertible.
 104      * @see java.awt.RenderingHints#KEY_INTERPOLATION
 105      * @see java.awt.RenderingHints#KEY_RENDERING
 106      */
 107     public AffineTransformOp(AffineTransform xform, RenderingHints hints){
 108         validateTransform(xform);
 109         this.xform = (AffineTransform) xform.clone();
 110         this.hints = hints;
 111 
 112         if (hints != null) {
 113             Object value = hints.get(RenderingHints.KEY_INTERPOLATION);
 114             if (value == null) {
 115                 value = hints.get(RenderingHints.KEY_RENDERING);
 116                 if (value == RenderingHints.VALUE_RENDER_SPEED) {
 117                     interpolationType = TYPE_NEAREST_NEIGHBOR;
 118                 }
 119                 else if (value == RenderingHints.VALUE_RENDER_QUALITY) {
 120                     interpolationType = TYPE_BILINEAR;
 121                 }
 122             }
 123             else if (value == RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR) {
 124                 interpolationType = TYPE_NEAREST_NEIGHBOR;
 125             }
 126             else if (value == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
 127                 interpolationType = TYPE_BILINEAR;
 128             }
 129             else if (value == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
 130                 interpolationType = TYPE_BICUBIC;
 131             }
 132         }
 133         else {
 134             interpolationType = TYPE_NEAREST_NEIGHBOR;
 135         }
 136     }
 137 
 138     /**
 139      * Constructs an <CODE>AffineTransformOp</CODE> given an affine transform
 140      * and the interpolation type.
 141      *
 142      * @param xform The <CODE>AffineTransform</CODE> to use for the operation.
 143      * @param interpolationType One of the integer
 144      * interpolation type constants defined by this class:
 145      * {@link #TYPE_NEAREST_NEIGHBOR TYPE_NEAREST_NEIGHBOR},
 146      * {@link #TYPE_BILINEAR TYPE_BILINEAR},
 147      * {@link #TYPE_BICUBIC TYPE_BICUBIC}.
 148      * @throws ImagingOpException if the transform is non-invertible.
 149      */


 218                                                "same as the dst image");
 219         }
 220 
 221         boolean needToConvert = false;
 222         ColorModel srcCM = src.getColorModel();
 223         ColorModel dstCM;
 224         BufferedImage origDst = dst;
 225 
 226         if (dst == null) {
 227             dst = createCompatibleDestImage(src, null);
 228             dstCM = srcCM;
 229             origDst = dst;
 230         }
 231         else {
 232             dstCM = dst.getColorModel();
 233             if (srcCM.getColorSpace().getType() !=
 234                 dstCM.getColorSpace().getType())
 235             {
 236                 int type = xform.getType();
 237                 boolean needTrans = ((type&
 238                                       (AffineTransform.TYPE_MASK_ROTATION|
 239                                        AffineTransform.TYPE_GENERAL_TRANSFORM))
 240                                      != 0);
 241                 if (! needTrans &&
 242                     type != AffineTransform.TYPE_TRANSLATION &&
 243                     type != AffineTransform.TYPE_IDENTITY)
 244                 {
 245                     double[] mtx = new double[4];
 246                     xform.getMatrix(mtx);
 247                     // Check out the matrix.  A non-integral scale will force ARGB
 248                     // since the edge conditions can't be guaranteed.
 249                     needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]);
 250                 }
 251 
 252                 if (needTrans &&
 253                     srcCM.getTransparency() == Transparency.OPAQUE)
 254                 {
 255                     // Need to convert first
 256                     ColorConvertOp ccop = new ColorConvertOp(hints);
 257                     BufferedImage tmpSrc = null;
 258                     int sw = src.getWidth();
 259                     int sh = src.getHeight();
 260                     if (dstCM.getTransparency() == Transparency.OPAQUE) {
 261                         tmpSrc = new BufferedImage(sw, sh,
 262                                                   BufferedImage.TYPE_INT_ARGB);
 263                     }