/[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.3 by mkoch, Fri Oct 1 19:35:26 2004 UTC revision 1.4 by smarothy, Sat Nov 6 16:24:37 2004 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
# Line 56  public class AffineTransformOp implement Line 58  public class AffineTransformOp implement
58  {  {
59      public static final int TYPE_NEAREST_NEIGHBOR = 1;      public static final int TYPE_NEAREST_NEIGHBOR = 1;
60      public static final int TYPE_BILINEAR = 2;      public static final int TYPE_BILINEAR = 2;
61        public static final int TYPE_BICUBIC = 3;
62    
63      private AffineTransform transform;      private AffineTransform transform;
64      private RenderingHints hints;      private RenderingHints hints;
65            
66      /**      /**
67       * Construct AffineTransformOp with the given xform and interpolationType.       * Construct AffineTransformOp with the given xform and interpolationType.
68       * Interpolation type can be either TYPE_BILINEAR or TYPE_NEAREST_NEIGHBOR.       * Interpolation type can be TYPE_BILINEAR, TYPE_BICUBIC or
69         * TYPE_NEAREST_NEIGHBOR.
70       *       *
71       * @param xform AffineTransform that will applied to the source image       * @param xform AffineTransform that will applied to the source image
72       * @param interpolationType type of interpolation used       * @param interpolationType type of interpolation used
# Line 70  public class AffineTransformOp implement Line 74  public class AffineTransformOp implement
74      public AffineTransformOp (AffineTransform xform, int interpolationType)      public AffineTransformOp (AffineTransform xform, int interpolationType)
75      {      {
76        this.transform = xform;        this.transform = xform;
77          if (xform.getDeterminant() == 0)
78            throw new ImagingOpException(null);
79    
80        if (interpolationType == 0)        switch (interpolationType)
81          {
82          case TYPE_BILINEAR:
83          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
84                                      RenderingHints.VALUE_INTERPOLATION_BILINEAR);                                      RenderingHints.VALUE_INTERPOLATION_BILINEAR);
85                                              break;
86        else        case TYPE_BICUBIC:
87            hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
88                                        RenderingHints.VALUE_INTERPOLATION_BICUBIC);
89            break;
90          default:
91          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,          hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
92                                      RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);                                      RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
93          }
94      }      }
95    
96      /**      /**
# Line 91  public class AffineTransformOp implement Line 103  public class AffineTransformOp implement
103      {      {
104        this.transform = xform;        this.transform = xform;
105        this.hints = hints;        this.hints = hints;
106          if (xform.getDeterminant() == 0)
107            throw new ImagingOpException(null);
108      }      }
109    
110      /**      /**
# Line 183  public class AffineTransformOp implement Line 197  public class AffineTransformOp implement
197       */       */
198      public WritableRaster filter (Raster src, WritableRaster dst)      public WritableRaster filter (Raster src, WritableRaster dst)
199      {      {
200        throw new UnsupportedOperationException ("not implemented yet");          if (dst == src)
201            throw new IllegalArgumentException("src image cannot be the same as"
202                                               + " the dst image");
203    
204          if (dst == null)
205            dst = createCompatibleDestRaster(src);
206    
207          if (src.getNumBands() != dst.getNumBands())
208            throw new IllegalArgumentException("src and dst must have same number"
209                                               + " of bands");
210          
211          double[] dpts = new double[dst.getWidth() * 2];
212          double[] pts = new double[dst.getWidth() * 2];
213          for (int x = 0; x < dst.getWidth(); x++)
214          {
215            dpts[2 * x] = x + dst.getMinX();
216            dpts[2 * x + 1] = x;
217          }
218          Rectangle srcbounds = src.getBounds();
219          if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
220          {
221            for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
222              {
223                try {
224                  transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
225                } catch (NoninvertibleTransformException e) {
226                  // Can't happen since the constructor traps this
227                  e.printStackTrace();
228                }
229            
230                for (int x = 0; x < dst.getWidth(); x++)
231                  {
232                    if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
233                      continue;
234                    dst.setDataElements(x + dst.getMinX(), y,
235                                        src.getDataElements((int)pts[2 * x],
236                                                            (int)pts[2 * x + 1],
237                                                            null));
238                  }
239              }
240          }
241          else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
242          {
243            double[] tmp = new double[4 * src.getNumBands()];
244            for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
245            {
246              try {
247                transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
248              } catch (NoninvertibleTransformException e) {
249                // Can't happen since the constructor traps this
250                e.printStackTrace();
251              }
252                
253              for (int x = 0; x < dst.getWidth(); x++)
254              {
255                if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
256                  continue;
257                int xx = (int)pts[2 * x];
258                int yy = (int)pts[2 * x + 1];
259                double dx = (pts[2 * x] - xx);
260                double dy = (pts[2 * x + 1] - yy);
261                    
262                // TODO write this more intelligently
263                if (xx == src.getMinX() + src.getWidth() - 1 ||
264                    yy == src.getMinY() + src.getHeight() - 1)
265                {
266                  // bottom or right edge
267                  Arrays.fill(tmp, 0);
268                  src.getPixel(xx, yy, tmp);
269                }
270                else
271                {
272                  // Normal case
273                  src.getPixels(xx, yy, 2, 2, tmp);
274                  for (int b = 0; b < src.getNumBands(); b++)
275                    tmp[b] = dx * dy * tmp[b]
276                      + (1 - dx) * dy * tmp[b + src.getNumBands()]
277                      + dx * (1 - dy) * tmp[b + 2 * src.getNumBands()]
278                      + (1 - dx) * (1 - dy) * tmp[b + 3 * src.getNumBands()];
279                }
280                dst.setPixel(x, y, tmp);
281              }
282            }
283          }
284          else
285          {
286            // Bicubic
287            throw new UnsupportedOperationException("not implemented yet");
288          }
289          
290          return dst;  
291      }      }
292    
293      /**      /**

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

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