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 }
|