/[classpath]/classpath/java/awt/image/AffineTransformOp.java
ViewVC logotype

Diff of /classpath/java/awt/image/AffineTransformOp.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.2.2 by gnu_andrew, Sat Jan 15 17:01:49 2005 UTC revision 1.1.2.3 by gnu_andrew, Sun Jan 16 02:14:47 2005 UTC
# Line 42  import java.awt.Graphics2D; Line 42  import java.awt.Graphics2D;
42  import java.awt.Rectangle;  import java.awt.Rectangle;
43  import java.awt.RenderingHints;  import java.awt.RenderingHints;
44  import java.awt.geom.AffineTransform;  import java.awt.geom.AffineTransform;
45    import java.awt.geom.NoninvertibleTransformException;
46  import java.awt.geom.Point2D;  import java.awt.geom.Point2D;
47  import java.awt.geom.Rectangle2D;  import java.awt.geom.Rectangle2D;
48    import java.util.Arrays;
49    
50  /**  /**
51   * This class performs affine transformation between two images or   * This class performs affine transformation between two images or
52   * rasters in 2 dimensions.   * rasters in 2 dimensions.
53   *   *
54   * @author Olga Rodimina <rodimina@redhat.com>   * @author Olga Rodimina (rodimina@redhat.com)
55   */   */
   
56  public class AffineTransformOp implements BufferedImageOp, RasterOp  public class AffineTransformOp implements BufferedImageOp, RasterOp
57  {  {
58      public static final int TYPE_NEAREST_NEIGHBOR = 1;      public static final int TYPE_NEAREST_NEIGHBOR = 1;
59        
60      public static final int TYPE_BILINEAR = 2;      public static final int TYPE_BILINEAR = 2;
61        
62        /**
63         * @since 1.5.0
64         */
65        public static final int TYPE_BICUBIC = 3;
66    
67      private AffineTransform transform;      private AffineTransform transform;
68      private RenderingHints hints;      private RenderingHints hints;
69            
70      /**      /**
71       * Construct AffineTransformOp with the given xform and interpolationType.       * Construct AffineTransformOp with the given xform and interpolationType.
72       * Interpolation type can be either TYPE_BILINEAR or TYPE_NEAREST_NEIGHBOR.       * Interpolation type can be TYPE_BILINEAR, TYPE_BICUBIC or
73         * TYPE_NEAREST_NEIGHBOR.
74       *       *
75       * @param xform AffineTransform that will applied to the source image       * @param xform AffineTransform that will applied to the source image
76       * @param interpolationType type of interpolation used       * @param interpolationType type of interpolation used
# Line 70  public class AffineTransformOp implement Line 78  public class AffineTransformOp implement
78      public AffineTransformOp (AffineTransform xform, int interpolationType)      public AffineTransformOp (AffineTransform xform, int interpolationType)
79      {      {
80        this.transform = xform;        this.transform = xform;
81          if (xform.getDeterminant() == 0)
82            throw new ImagingOpException(null);
83    
84        if (interpolationType == 0)        switch (interpolationType)
85          {
86          case TYPE_BILINEAR:
87          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
88                                      RenderingHints.VALUE_INTERPOLATION_BILINEAR);                                      RenderingHints.VALUE_INTERPOLATION_BILINEAR);
89                                              break;
90        else        case TYPE_BICUBIC:
91            hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
92                                        RenderingHints.VALUE_INTERPOLATION_BICUBIC);
93            break;
94          default:
95          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
96                                      RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);                                      RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
97          }
98      }      }
99    
100      /**      /**
# Line 91  public class AffineTransformOp implement Line 107  public class AffineTransformOp implement
107      {      {
108        this.transform = xform;        this.transform = xform;
109        this.hints = hints;        this.hints = hints;
110          if (xform.getDeterminant() == 0)
111            throw new ImagingOpException(null);
112      }      }
113    
114      /**      /**
# Line 150  public class AffineTransformOp implement Line 168  public class AffineTransformOp implement
168       * @param dst destination image       * @param dst destination image
169       * @return transformed source image       * @return transformed source image
170       */       */
171      public BufferedImage filter (BufferedImage src, BufferedImage dst)      public final BufferedImage filter (BufferedImage src, BufferedImage dst)
172      {      {
173    
174        if (dst == src)        if (dst == src)
# Line 181  public class AffineTransformOp implement Line 199  public class AffineTransformOp implement
199       * @param dst destination raster       * @param dst destination raster
200       * @return transformed raster       * @return transformed raster
201       */       */
202      public WritableRaster filter (Raster src, WritableRaster dst)      public final WritableRaster filter (Raster src, WritableRaster dst)
203      {      {
204        throw new UnsupportedOperationException ("not implemented yet");          if (dst == src)
205            throw new IllegalArgumentException("src image cannot be the same as"
206                                               + " the dst image");
207    
208          if (dst == null)
209            dst = createCompatibleDestRaster(src);
210    
211          if (src.getNumBands() != dst.getNumBands())
212            throw new IllegalArgumentException("src and dst must have same number"
213                                               + " of bands");
214          
215          double[] dpts = new double[dst.getWidth() * 2];
216          double[] pts = new double[dst.getWidth() * 2];
217          for (int x = 0; x < dst.getWidth(); x++)
218          {
219            dpts[2 * x] = x + dst.getMinX();
220            dpts[2 * x + 1] = x;
221          }
222          Rectangle srcbounds = src.getBounds();
223          if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
224          {
225            for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
226              {
227                try {
228                  transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
229                } catch (NoninvertibleTransformException e) {
230                  // Can't happen since the constructor traps this
231                  e.printStackTrace();
232                }
233            
234                for (int x = 0; x < dst.getWidth(); x++)
235                  {
236                    if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
237                      continue;
238                    dst.setDataElements(x + dst.getMinX(), y,
239                                        src.getDataElements((int)pts[2 * x],
240                                                            (int)pts[2 * x + 1],
241                                                            null));
242                  }
243              }
244          }
245          else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
246          {
247            double[] tmp = new double[4 * src.getNumBands()];
248            for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
249            {
250              try {
251                transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
252              } catch (NoninvertibleTransformException e) {
253                // Can't happen since the constructor traps this
254                e.printStackTrace();
255              }
256                
257              for (int x = 0; x < dst.getWidth(); x++)
258              {
259                if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
260                  continue;
261                int xx = (int)pts[2 * x];
262                int yy = (int)pts[2 * x + 1];
263                double dx = (pts[2 * x] - xx);
264                double dy = (pts[2 * x + 1] - yy);
265                    
266                // TODO write this more intelligently
267                if (xx == src.getMinX() + src.getWidth() - 1 ||
268                    yy == src.getMinY() + src.getHeight() - 1)
269                {
270                  // bottom or right edge
271                  Arrays.fill(tmp, 0);
272                  src.getPixel(xx, yy, tmp);
273                }
274                else
275                {
276                  // Normal case
277                  src.getPixels(xx, yy, 2, 2, tmp);
278                  for (int b = 0; b < src.getNumBands(); b++)
279                    tmp[b] = dx * dy * tmp[b]
280                      + (1 - dx) * dy * tmp[b + src.getNumBands()]
281                      + dx * (1 - dy) * tmp[b + 2 * src.getNumBands()]
282                      + (1 - dx) * (1 - dy) * tmp[b + 3 * src.getNumBands()];
283                }
284                dst.setPixel(x, y, tmp);
285              }
286            }
287          }
288          else
289          {
290            // Bicubic
291            throw new UnsupportedOperationException("not implemented yet");
292          }
293          
294          return dst;  
295      }      }
296    
297      /**      /**
# Line 193  public class AffineTransformOp implement Line 301  public class AffineTransformOp implement
301       * @param src image to be transformed       * @param src image to be transformed
302       * @return bounds of the transformed image.       * @return bounds of the transformed image.
303       */       */
304      public Rectangle2D getBounds2D (BufferedImage src)      public final Rectangle2D getBounds2D (BufferedImage src)
305      {      {
306        return getBounds2D (src.getRaster());        return getBounds2D (src.getRaster());
307      }      }
# Line 204  public class AffineTransformOp implement Line 312  public class AffineTransformOp implement
312       * @param src raster to be transformed       * @param src raster to be transformed
313       * @return bounds of the transformed raster.       * @return bounds of the transformed raster.
314       */       */
315      public Rectangle2D getBounds2D (Raster src)      public final Rectangle2D getBounds2D (Raster src)
316      {      {
317        // determine new size for the transformed raster.        // determine new size for the transformed raster.
318        // Need to calculate transformed coordinates of the lower right        // Need to calculate transformed coordinates of the lower right
# Line 223  public class AffineTransformOp implement Line 331  public class AffineTransformOp implement
331       *       *
332       * @return interpolation type       * @return interpolation type
333       */       */
334      public int getInterpolationType ()      public final int getInterpolationType ()
335      {      {
336        if(hints.containsValue (RenderingHints.VALUE_INTERPOLATION_BILINEAR))        if(hints.containsValue (RenderingHints.VALUE_INTERPOLATION_BILINEAR))
337          return TYPE_BILINEAR;          return TYPE_BILINEAR;
# Line 244  public class AffineTransformOp implement Line 352  public class AffineTransformOp implement
352        return transform.transform (srcPt, dstPt);        return transform.transform (srcPt, dstPt);
353      }      }
354    
355      /** Returns rendering hints that are used during transformation.      /**
356         * Returns rendering hints that are used during transformation.
357       *       *
358       * @return rendering hints       * @return rendering hints
359       */       */
360      public RenderingHints getRenderingHints ()      public final RenderingHints getRenderingHints ()
361      {      {
362        return hints;        return hints;
363      }      }
364    
365      /** Returns transform used in transformation between source and destination      /**
366         * Returns transform used in transformation between source and destination
367       * image.       * image.
368       *       *
369       * @return transform       * @return transform
370       */       */
371      public AffineTransform getTransform ()      public final AffineTransform getTransform ()
372      {      {
373        return transform;        return transform;
374      }      }

Legend:
Removed from v.1.1.2.2  
changed lines
  Added in v.1.1.2.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26