1 /* 2 * $RCSfile: ImageServer.java,v $ 3 * 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Use is subject to license terms. 7 * 8 * $Revision: 1.1 $ 9 * $Date: 2005/02/11 04:56:51 $ 10 * $State: Exp $ 11 */ 12 package com.lightcrafts.media.jai.rmi; 13 14 import java.awt.Rectangle; 15 import java.awt.image.RenderedImage; 16 import java.awt.image.renderable.ParameterBlock; 17 import java.rmi.Remote; 18 import java.rmi.RemoteException; 19 import java.util.List; 20 import com.lightcrafts.mediax.jai.RenderableOp; 21 import com.lightcrafts.mediax.jai.RenderedOp; 22 import com.lightcrafts.mediax.jai.remote.NegotiableCapabilitySet; 23 import com.lightcrafts.mediax.jai.remote.SerializableState; 24 25 /** 26 * An interface for server-side imaging. This interface attempts to 27 * mimic the RenderedImage interface as much as possible. However, there 28 * are several unavoidable differences: 29 * 30 * <ul> 31 * <li> Additional setRenderedSource() and setRenderableSource methods 32 * are provided to inform the server as to the source of image data for 33 * this image. Sources may be set 34 * either from a RenderedImage that is copied over to the server, or 35 * from a graph of RenderedOp objects indicating an abstract 36 * imaging chain to be instantiated using the server's 37 * OperationRegistry. 38 * 39 * <li> All methods throw RemoteException. This is a requirement of 40 * any Remote interface. 41 * 42 * <li> The getTile() method does not return a reference to a `live' 43 * tile; instead it returns a client-side copy of the server image's 44 * tile. The difference is moot since the server image is immutable. 45 * </ul> 46 * 47 * To instantiate a ImageServer, do the following: 48 * 49 * <pre> 50 * ImageServer im; 51 * im = java.rmi.Naming.lookup("//host:1099/com.lightcrafts.mediax.jai.RemoteImageServer"); 52 * </pre> 53 * 54 * <p> The hostname and port will of course depend on the local setup. 55 * The host must be running an <code>rmiregistry</code> process and have a 56 * RemoteImageServer listening at the desired port. 57 * 58 * <p> This call will result in the creation of a server-side 59 * JAIRMIImageServer object and a client-side stub object. 60 * The client stub serializes its method arguments and transfers 61 * them to the server over a socket; the server serializes it return 62 * values and returns them in the same manner. 63 * 64 * <p> This process implies that all arguments and return values must 65 * be serializable. In the case of a RenderedImage source, 66 * serializability is not guaranteed and must be considered on a 67 * class-by-class basis. For RenderedOps, which are basically 68 * simple nodes connected by ParameterBlocks, serializability will be 69 * determined by the serializabiility of the ultimate 70 * (non-RenderedOp) sources of the DAG and the serializability 71 * of any ad-hoc Object parameters held in the ParameterBlocks. 72 * 73 * <p> The return values of the getData(), copyData(), and getTile() 74 * methods are various kinds of Rasters; at present, Java2D does not 75 * define serialization on Rasters. We will either need to add this 76 * feature to Java2D or else coerce the server-side Rasters into a 77 * serializable subclass form. In any case, we will want to 78 * implement lossless (and possibly lossy) compression as part of 79 * the serialization process wherever possible. 80 * 81 * @see java.rmi.Remote 82 * @see java.rmi.RemoteException 83 * @see java.awt.image.RenderedImage 84 * 85 * 86 */ 87 public interface ImageServer extends Remote { 88 89 /** 90 * Returns the identifier of the remote image. This method should be 91 * called to return an identifier before any other methods are invoked. 92 * The same ID must be used in all subsequent references to the remote 93 * image. 94 */ getRemoteID()95 Long getRemoteID() throws RemoteException; 96 97 /** 98 * Disposes of any resouces allocated to the client object with 99 * the specified ID. 100 */ dispose(Long id)101 void dispose(Long id) throws RemoteException; 102 103 /** 104 * Increments the reference count for this id, i.e. increments the 105 * number of RMIServerProxy objects that currently reference this id. 106 */ incrementRefCount(Long id)107 void incrementRefCount(Long id) throws RemoteException; 108 109 110 /// Methods Common To Rendered as well as Renderable modes. 111 112 113 /** 114 * Gets a property from the property set of this image. 115 * If the property name is not recognized, java.awt.Image.UndefinedProperty 116 * will be returned. 117 * 118 * @param id An ID for the source which must be unique across all clients. 119 * @param name the name of the property to get, as a String. 120 * @return a reference to the property Object, or the value 121 * java.awt.Image.UndefinedProperty. 122 */ getProperty(Long id, String name)123 Object getProperty(Long id, String name) throws RemoteException; 124 125 /** 126 * Returns a list of names recognized by getProperty(String). 127 * 128 * @return an array of Strings representing proeprty names. 129 */ getPropertyNames(Long id)130 String [] getPropertyNames(Long id) throws RemoteException; 131 132 /** 133 * Returns a list of names recognized by getProperty(). 134 * 135 * @return an array of Strings representing property names. 136 */ getPropertyNames(String opName)137 String[] getPropertyNames(String opName) throws RemoteException; 138 139 140 /// Rendered Mode Methods 141 142 143 /** Returns the ColorModel associated with this image. */ getColorModel(Long id)144 SerializableState getColorModel(Long id) throws RemoteException; 145 146 /** Returns the SampleModel associated with this image. */ getSampleModel(Long id)147 SerializableState getSampleModel(Long id) throws RemoteException; 148 149 /** Returns the width of the image on the ImageServer. */ getWidth(Long id)150 int getWidth(Long id) throws RemoteException; 151 152 /** Returns the height of the image on the ImageServer. */ getHeight(Long id)153 int getHeight(Long id) throws RemoteException; 154 155 /** 156 * Returns the minimum X coordinate of the image on the ImageServer. 157 */ getMinX(Long id)158 int getMinX(Long id) throws RemoteException; 159 160 /** 161 * Returns the minimum Y coordinate of the image on the ImageServer. 162 */ getMinY(Long id)163 int getMinY(Long id) throws RemoteException; 164 165 /** Returns the number of tiles across the image. */ getNumXTiles(Long id)166 int getNumXTiles(Long id) throws RemoteException; 167 168 /** Returns the number of tiles down the image. */ getNumYTiles(Long id)169 int getNumYTiles(Long id) throws RemoteException; 170 171 /** 172 * Returns the index of the minimum tile in the X direction of the image. 173 */ getMinTileX(Long id)174 int getMinTileX(Long id) throws RemoteException; 175 176 /** 177 * Returns the index of the minimum tile in the Y direction of the image. 178 */ getMinTileY(Long id)179 int getMinTileY(Long id) throws RemoteException; 180 181 /** Returns the width of a tile in pixels. */ getTileWidth(Long id)182 int getTileWidth(Long id) throws RemoteException; 183 184 /** Returns the height of a tile in pixels. */ getTileHeight(Long id)185 int getTileHeight(Long id) throws RemoteException; 186 187 /** Returns the X offset of the tile grid relative to the origin. */ getTileGridXOffset(Long id)188 int getTileGridXOffset(Long id) throws RemoteException; 189 190 /** Returns the Y offset of the tile grid relative to the origin. */ getTileGridYOffset(Long id)191 int getTileGridYOffset(Long id) throws RemoteException; 192 193 /** 194 * Returns tile (x, y). Note that x and y are indices into the 195 * tile array, not pixel locations. Unlike in the true RenderedImage 196 * interface, the Raster that is returned should be considered a copy. 197 * 198 * @param id An ID for the source which must be unique across all clients. 199 * @param x the x index of the requested tile in the tile array 200 * @param y the y index of the requested tile in the tile array 201 * @return a copy of the tile as a Raster. 202 */ getTile(Long id, int x, int y)203 SerializableState getTile(Long id, int x, int y) throws RemoteException; 204 205 /** 206 * Compresses tile (x, y) and returns the compressed tile's contents 207 * as a byte array. Note that x and y are indices into the 208 * tile array, not pixel locations. 209 * 210 * @param id An ID for the source which must be unique across all clients. 211 * @param x the x index of the requested tile in the tile array 212 * @param y the y index of the requested tile in the tile array 213 * @return a byte array containing the compressed tile contents. 214 */ getCompressedTile(Long id, int x, int y)215 byte[] getCompressedTile(Long id, int x, int y) throws RemoteException; 216 217 /** 218 * Returns the entire image as a single Raster. 219 * 220 * @return a SerializableState containing a copy of this image's data. 221 */ getData(Long id)222 SerializableState getData(Long id) throws RemoteException; 223 224 /** 225 * Returns an arbitrary rectangular region of the RenderedImage 226 * in a Raster. The rectangle of interest will be clipped against 227 * the image bounds. 228 * 229 * @param id An ID for the source which must be unique across all clients. 230 * @param bounds the region of the RenderedImage to be returned. 231 * @return a SerializableState containing a copy of the desired data. 232 */ getData(Long id, Rectangle bounds)233 SerializableState getData(Long id, Rectangle bounds) 234 throws RemoteException; 235 236 /** 237 * Returns the same result as getData(Rectangle) would for the 238 * same rectangular region. 239 */ copyData(Long id, Rectangle bounds)240 SerializableState copyData(Long id, Rectangle bounds) 241 throws RemoteException; 242 243 /** 244 * Creates a RenderedOp on the server side with a parameter block 245 * empty of sources. The sources are set by separate calls depending 246 * upon the type and serializabilty of the source. 247 */ 248 createRenderedOp(Long id, String opName, ParameterBlock pb, SerializableState hints)249 void createRenderedOp(Long id, String opName, 250 ParameterBlock pb, 251 SerializableState hints) throws RemoteException; 252 253 /** 254 * Calls for Rendering of the Op and returns true if the RenderedOp 255 * could be rendered else false 256 */ getRendering(Long id)257 boolean getRendering(Long id) throws RemoteException; 258 259 /** 260 * Retrieve a node from the hashtable. 261 */ getNode(Long id)262 RenderedOp getNode(Long id) throws RemoteException; 263 264 /** 265 * Sets the source of the image as a RenderedImage on the server side 266 */ setRenderedSource(Long id, RenderedImage source, int index)267 void setRenderedSource(Long id, RenderedImage source, int index) 268 throws RemoteException; 269 270 /** 271 * Sets the source of the image as a RenderedOp on the server side 272 */ setRenderedSource(Long id, RenderedOp source, int index)273 void setRenderedSource(Long id, RenderedOp source, int index) 274 throws RemoteException; 275 276 /** 277 * Sets the source of the image which is on the same 278 * server 279 */ setRenderedSource(Long id, Long sourceId, int index)280 void setRenderedSource(Long id, Long sourceId, int index) 281 throws RemoteException; 282 283 /** 284 * Sets the source of the image which is on a different 285 * server 286 */ setRenderedSource(Long id, Long sourceId, String serverName, String opName, int index)287 void setRenderedSource(Long id, Long sourceId, String serverName, 288 String opName, int index) throws RemoteException; 289 290 291 /// Renderable mode methods 292 293 294 /** 295 * Gets the minimum X coordinate of the rendering-independent image 296 * stored against the given ID. 297 * 298 * @return the minimum X coordinate of the rendering-independent image 299 * data. 300 */ getRenderableMinX(Long id)301 float getRenderableMinX(Long id) throws RemoteException; 302 303 /** 304 * Gets the minimum Y coordinate of the rendering-independent image 305 * stored against the given ID. 306 * 307 * @return the minimum X coordinate of the rendering-independent image 308 * data. 309 */ getRenderableMinY(Long id)310 float getRenderableMinY(Long id) throws RemoteException; 311 312 /** 313 * Gets the width (in user coordinate space) of the 314 * <code>RenderableImage</code> stored against the given ID. 315 * 316 * @return the width of the renderable image in user coordinates. 317 */ getRenderableWidth(Long id)318 float getRenderableWidth(Long id) throws RemoteException; 319 320 /** 321 * Gets the height (in user coordinate space) of the 322 * <code>RenderableImage</code> stored against the given ID. 323 * 324 * @return the height of the renderable image in user coordinates. 325 */ getRenderableHeight(Long id)326 float getRenderableHeight(Long id) throws RemoteException; 327 328 /** 329 * Creates a RenderedImage instance of this image with width w, and 330 * height h in pixels. The RenderContext is built automatically 331 * with an appropriate usr2dev transform and an area of interest 332 * of the full image. All the rendering hints come from hints 333 * passed in. 334 * 335 * <p> If w == 0, it will be taken to equal 336 * Math.round(h*(getWidth()/getHeight())). 337 * Similarly, if h == 0, it will be taken to equal 338 * Math.round(w*(getHeight()/getWidth())). One of 339 * w or h must be non-zero or else an IllegalArgumentException 340 * will be thrown. 341 * 342 * <p> The created RenderedImage may have a property identified 343 * by the String HINTS_OBSERVED to indicate which RenderingHints 344 * were used to create the image. In addition any RenderedImages 345 * that are obtained via the getSources() method on the created 346 * RenderedImage may have such a property. 347 * 348 * @param w the width of rendered image in pixels, or 0. 349 * @param h the height of rendered image in pixels, or 0. 350 * @param hints a RenderingHints object containg hints. 351 * @return a RenderedImage containing the rendered data. 352 */ createScaledRendering(Long id, int w, int h, SerializableState hintsState)353 RenderedImage createScaledRendering(Long id, 354 int w, 355 int h, 356 SerializableState hintsState) 357 throws RemoteException; 358 359 /** 360 * Returnd a RenderedImage instance of this image with a default 361 * width and height in pixels. The RenderContext is built 362 * automatically with an appropriate usr2dev transform and an area 363 * of interest of the full image. The rendering hints are 364 * empty. createDefaultRendering may make use of a stored 365 * rendering for speed. 366 * 367 * @return a RenderedImage containing the rendered data. 368 */ createDefaultRendering(Long id)369 RenderedImage createDefaultRendering(Long id) throws RemoteException; 370 371 /** 372 * Creates a RenderedImage that represented a rendering of this image 373 * using a given RenderContext. This is the most general way to obtain a 374 * rendering of a RenderableImage. 375 * 376 * <p> The created RenderedImage may have a property identified 377 * by the String HINTS_OBSERVED to indicate which RenderingHints 378 * (from the RenderContext) were used to create the image. 379 * In addition any RenderedImages 380 * that are obtained via the getSources() method on the created 381 * RenderedImage may have such a property. 382 * 383 * @param renderContext the RenderContext to use to produce the rendering. 384 * @return a RenderedImage containing the rendered data. 385 */ createRendering(Long id, SerializableState renderContextState)386 RenderedImage createRendering(Long id, 387 SerializableState renderContextState) 388 throws RemoteException; 389 390 /** 391 * Creates a RenderableOp on the server side with a parameter block 392 * empty of sources. The sources are set by separate calls depending 393 * upon the type and serializabilty of the source. 394 */ createRenderableOp(Long id, String opName, ParameterBlock pb)395 void createRenderableOp(Long id, String opName, ParameterBlock pb) 396 throws RemoteException; 397 398 /** 399 * Calls for rendering of a RenderableOp with the given SerializableState 400 * which should be a RenderContextState. 401 */ getRendering(Long id, SerializableState rcs)402 Long getRendering(Long id, SerializableState rcs) throws RemoteException; 403 404 /** 405 * Sets the source of the image which is on the same 406 * server 407 */ setRenderableSource(Long id, Long sourceId, int index)408 void setRenderableSource(Long id, Long sourceId, int index) 409 throws RemoteException; 410 411 /** 412 * Sets the source of the image which is on a different 413 * server 414 */ setRenderableSource(Long id, Long sourceId, String serverName, String opName, int index)415 void setRenderableSource(Long id, Long sourceId, String serverName, 416 String opName, int index) throws RemoteException; 417 418 /** 419 * Sets the source of the operation refered to by the supplied 420 * <code>id</code> to the <code>RenderableRMIServerProxy</code> 421 * that exists on the supplied <code>serverName</code> under the 422 * supplied <code>sourceId</code>. 423 */ setRenderableRMIServerProxyAsSource(Long id, Long sourceId, String serverName, String opName, int index)424 void setRenderableRMIServerProxyAsSource(Long id, 425 Long sourceId, 426 String serverName, 427 String opName, 428 int index) throws RemoteException; 429 430 /** 431 * Sets the source of the image as a RenderableOp on the server side. 432 */ setRenderableSource(Long id, RenderableOp source, int index)433 void setRenderableSource(Long id, RenderableOp source, 434 int index) throws RemoteException; 435 436 /** 437 * Sets the source of the image as a RenderableImage on the server side. 438 */ setRenderableSource(Long id, SerializableRenderableImage source, int index)439 void setRenderableSource(Long id, SerializableRenderableImage source, 440 int index) throws RemoteException; 441 442 /** 443 * Sets the source of the image as a RenderedImage on the server side 444 */ setRenderableSource(Long id, RenderedImage source, int index)445 void setRenderableSource(Long id, RenderedImage source, int index) 446 throws RemoteException; 447 448 /** 449 * Maps the RenderContext for the remote Image 450 */ mapRenderContext(int id, Long nodeId, String operationName, SerializableState rcs)451 SerializableState mapRenderContext(int id, Long nodeId, 452 String operationName, 453 SerializableState rcs) 454 throws RemoteException; 455 456 /** 457 * Gets the Bounds2D of the specified Remote Image 458 */ getBounds2D(Long nodeId, String operationName)459 SerializableState getBounds2D(Long nodeId, String operationName) 460 throws RemoteException; 461 462 /** 463 * Returns <code>true</code> if successive renderings with the same 464 * arguments may produce different results for this opName 465 * 466 * @return <code>false</code> indicating that the rendering is static. 467 */ isDynamic(String opName)468 public boolean isDynamic(String opName) throws RemoteException; 469 470 /** 471 * Returns <code>true</code> if successive renderings with the same 472 * arguments may produce different results for this opName 473 * 474 * @return <code>false</code> indicating that the rendering is static. 475 */ isDynamic(Long id)476 public boolean isDynamic(Long id) throws RemoteException; 477 478 /** 479 * Gets the operation names supported on the Server 480 */ getServerSupportedOperationNames()481 String[] getServerSupportedOperationNames() throws RemoteException; 482 483 /** 484 * Gets the <code>OperationDescriptor</code>s of the operations 485 * supported on this server. 486 */ getOperationDescriptors()487 List getOperationDescriptors() throws RemoteException; 488 489 /** 490 * Calculates the region over which two distinct renderings 491 * of an operation may be expected to differ. 492 * 493 * <p> The class of the returned object will vary as a function of 494 * the nature of the operation. For rendered and renderable two- 495 * dimensional images this should be an instance of a class which 496 * implements <code>java.awt.Shape</code>. 497 * 498 * @return The region over which the data of two renderings of this 499 * operation may be expected to be invalid or <code>null</code> 500 * if there is no common region of validity. 501 */ getInvalidRegion(Long id, ParameterBlock oldParamBlock, SerializableState oldHints, ParameterBlock newParamBlock, SerializableState newHints)502 SerializableState getInvalidRegion(Long id, 503 ParameterBlock oldParamBlock, 504 SerializableState oldHints, 505 ParameterBlock newParamBlock, 506 SerializableState newHints) 507 throws RemoteException; 508 509 /** 510 * Returns a conservative estimate of the destination region that 511 * can potentially be affected by the pixels of a rectangle of a 512 * given source. 513 * 514 * @param id A <code>Long</code> identifying the node for whom 515 * the destination region needs to be calculated . 516 * @param sourceRect The <code>Rectangle</code> in source coordinates. 517 * @param sourceIndex The index of the source image. 518 * 519 * @return A <code>Rectangle</code> indicating the potentially 520 * affected destination region, or <code>null</code> if 521 * the region is unknown. 522 */ mapSourceRect(Long id, Rectangle sourceRect, int sourceIndex)523 Rectangle mapSourceRect(Long id, Rectangle sourceRect, int sourceIndex) 524 throws RemoteException; 525 526 /** 527 * Returns a conservative estimate of the region of a specified 528 * source that is required in order to compute the pixels of a 529 * given destination rectangle. 530 * 531 * @param id A <code>Long</code> identifying the node for whom 532 * the source region needs to be calculated . 533 * @param destRect The <code>Rectangle</code> in destination coordinates. 534 * @param sourceIndex The index of the source image. 535 * 536 * @return A <code>Rectangle</code> indicating the required source region. 537 */ mapDestRect(Long id, Rectangle destRect, int sourceIndex)538 Rectangle mapDestRect(Long id, Rectangle destRect, int sourceIndex) 539 throws RemoteException; 540 541 /** 542 * A method that handles a change in some critical parameter. 543 */ handleEvent(Long renderedOpID, String propName, Object oldValue, Object newValue)544 Long handleEvent(Long renderedOpID, 545 String propName, 546 Object oldValue, 547 Object newValue) throws RemoteException; 548 549 /** 550 * A method that handles a change in one of it's source's rendering, 551 * i.e. a change that would be signalled by RenderingChangeEvent. 552 */ handleEvent(Long renderedOpID, int srcIndex, SerializableState srcInvalidRegion, Object oldRendering)553 Long handleEvent(Long renderedOpID, 554 int srcIndex, 555 SerializableState srcInvalidRegion, 556 Object oldRendering) throws RemoteException; 557 558 /** 559 * Returns the server's capabilities as a 560 * <code>NegotiableCapabilitySet</code>. Currently the only capabilities 561 * that are returned are those of TileCodecs. 562 */ getServerCapabilities()563 NegotiableCapabilitySet getServerCapabilities() throws RemoteException; 564 565 /** 566 * Informs the server of the negotiated values that are the result of 567 * a successful negotiation. 568 * 569 * @param id An ID for the node which must be unique across all clients. 570 * @param negotiatedValues The result of the negotiation. 571 */ setServerNegotiatedValues(Long id, NegotiableCapabilitySet negotiatedValues)572 void setServerNegotiatedValues(Long id, 573 NegotiableCapabilitySet negotiatedValues) 574 throws RemoteException; 575 } 576