Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/modama/jaiutil/operators/MosaicDescriptor.java


1   /*
2    * Copyright (C) Jerry Huxtable 1998-2001. All rights reserved.
3    */
4   package org.modama.jaiutil.operators;
5   
6   import java.util.*;
7   import java.awt.*;
8   import java.awt.image.*;
9   import java.awt.image.renderable.*;
10  import javax.media.jai.*;
11  
12  
13  /**
14   * A JAI operation descriptor for the Mosaic operation. This operation produces
15   * an image from a grid of tile sources, each tile being a separate JAI image.
16   * All source images must be the same size and have the same tile size, sample
17   * model and color model. The resulting image will have a tile size the same as
18   * the sources. The parameters are the number of rows and columns in
19   * the grid and a two dimensional array of the source tiles.
20   * @author Jerry Huxtable
21   */
22  public class MosaicDescriptor extends OperationDescriptorImpl implements RenderedImageFactory {
23  
24    private static final String[][] resources = {
25      {"GlobalName",  "Mosaic2"},
26      {"LocalName",   "Mosaic2"},
27      {"Vendor",      "com.jhlabs"},
28      {"Description", "An operation that tiles together images"},
29      {"DocURL",      "http://www.jhlabs.com/MosaicDescriptor.html"},
30      {"Version",     "1.0"},
31      {"arg0Desc",  "rows"},
32      {"arg1Desc",  "cols"},
33    };
34  
35    private static final String[] paramNames = {
36      "rows",
37      "cols",
38    };
39  
40    /** 
41     * The class types for the parameters of the "Mosaic" operation.  
42     */
43    private static final Class[] paramClasses = {
44      java.lang.Integer.class,
45      java.lang.Integer.class,
46    };
47   
48    /**
49     * The default parameter values for the "Mosaic" operation
50     * when using a ParameterBlockJAI.
51     */
52    private static final Object[] paramDefaults = {
53      new Integer(0),
54      new Integer(0),
55    };
56   
57    private static boolean registered = false;
58    
59    public static void register() {
60      if (!registered) {
61        OperationRegistry or = JAI.getDefaultInstance().getOperationRegistry();
62  
63        MosaicDescriptor d = new MosaicDescriptor();
64        String operationName = "mosaic2";
65        String productName = "com.jhlabs";
66        or.registerOperationDescriptor(d, operationName);
67        or.registerRIF(operationName, productName, d);
68        registered = true;
69      }
70    }
71  
72    /**
73     * Construct a MosaicDescriptor.
74     */
75    public MosaicDescriptor() {
76      super(resources, 0, paramClasses, paramNames, paramDefaults);
77    }
78  
79    /** 
80     *  Creates a MosaicOpImage with the given ParameterBlock if the 
81     *  MosaicOpImage can handle the particular ParameterBlock.
82     */
83    public RenderedImage create(ParameterBlock paramBlock, RenderingHints renderHints) {
84      if (!validateParameters(paramBlock))
85        return null;
86  
87      return new MosaicOpImage(
88        ((Integer)paramBlock.getObjectParameter(0)).intValue(),
89        ((Integer)paramBlock.getObjectParameter(1)).intValue(),
90        paramBlock.getSources()
91      );
92    }
93  
94    /**
95     *  Checks that all parameters in the ParameterBlock have the 
96     *  correct type before constructing the MosaicOpImage
97     */
98    public boolean validateParameters(ParameterBlock paramBlock) {
99      for (int i = 0; i < this.getNumParameters(); i++) {
100       Object arg = paramBlock.getObjectParameter(i);
101       if (arg == null) {
102         return false;
103       }
104       if ((i == 0 || i == 1) && !(arg instanceof Integer))
105         return false;
106     }
107     return true;
108   }
109 }
110 
111 /**
112  * The MosaicOpImage class.
113  * @see org.modama.jaiutil.operators.MosaicDescriptor
114  */
115 class MosaicOpImage extends OpImage {
116 
117   /**
118    * The number of rows in the mosaic.
119    */
120   private int rows;
121 
122   /**
123    * The number of columns in the mosaic.
124    */
125   private int cols;
126 
127   /**
128    * The image tile width.
129    */
130   private int tileWidth;
131 
132   /**
133    * The image tile height.
134    */
135   private int tileHeight;
136 
137   /**
138    * The image width.
139    */
140   private int width;
141 
142   /**
143    * The image height.
144    */
145   private int height;
146 
147   /**
148    * The number of tiles across the image.
149    */
150   private int tilesX;
151 
152   /**
153    * The number of tiles down the image.
154    */
155   private int tilesY;
156 
157   /**
158    * The width of the source tiles.
159    */
160   private int majorTileWidth;
161 
162   /**
163    * The height of the source tiles.
164    */
165   private int majorTileHeight;
166 
167   public MosaicOpImage(int rows, int cols, Vector sources) {
168     super(sources, null, null, true);
169     this.rows = rows;
170     this.cols = cols;
171 
172     //if (sources.size() < rows*cols)
173     //  throw new IllegalArgumentException("Not enough sources supplied to MosaicOperator");
174 
175     int count = sources.size();
176     for (int i = 0; i < count; i++)
177       addSource((PlanarImage)sources.elementAt(i));
178 
179     PlanarImage baseTile = (PlanarImage)sources.firstElement();
180     majorTileWidth = baseTile.getWidth();
181     majorTileHeight = baseTile.getHeight();
182     tileWidth = baseTile.getTileWidth();
183     tileHeight = baseTile.getTileHeight();
184     width = cols * majorTileWidth;
185     height = rows * majorTileHeight;
186 
187     tilesX = (width + tileWidth - 1) / tileWidth;
188     tilesY = (height + tileHeight - 1) / tileHeight;
189     
190     SampleModel sampleModel = baseTile.getSampleModel();
191     ColorModel colorModel = baseTile.getColorModel();
192 
193     ImageLayout imageLayout = new ImageLayout(0, 0, width, height, 0, 0, tileWidth, tileHeight, sampleModel, colorModel);
194     setImageLayout(imageLayout);
195   }
196 
197   public Raster computeTile(int x, int y) {
198     DataBuffer dataBuffer = sampleModel.createDataBuffer();
199 
200     if (x < 0 || x >= tilesX || y < 0 || y >= tilesY) {
201       System.out.println("Error: illegal tile requested from a MosaicOpImage.");
202       Raster raster = Raster.createRaster(sampleModel, dataBuffer, new Point(x * tileWidth, y * tileHeight));
203       return raster;
204     }
205     try {
206       int tx = x * tileWidth / majorTileWidth;
207       int ty = y * tileHeight / majorTileHeight;
208       Rectangle r = new Rectangle(tileWidth * (x % (majorTileWidth/tileWidth)), tileHeight * (y % (majorTileHeight/tileHeight)), tileWidth, tileHeight);
209       PlanarImage op = getSourceImage(ty*cols+tx);
210       Raster raster = null;
211       synchronized(op) {
212         raster = op.getData(r);
213         raster = raster.createTranslatedChild(x * tileWidth, y * tileHeight);
214       }
215       return raster;
216     }
217     catch (Exception e) {
218       e.printStackTrace();
219     }
220     return Raster.createRaster(sampleModel, dataBuffer, new Point(x * tileWidth, y * tileHeight));
221   }
222 
223     public Rectangle mapDestRect(Rectangle rectangle, int i) {
224       return rectangle;
225     }
226     
227     public Rectangle mapSourceRect(Rectangle rectangle, int i) {
228       return rectangle;
229     }
230 }