if (evt instanceof RenderingChangeEvent) {
// RenderingChangeEvent presumably from a source
// RenderedOp.
RenderingChangeEvent rcEvent = (RenderingChangeEvent)evt;
// Get the invalidated region of the source.
srcInvalidRegion = rcEvent.getInvalidRegion();
// If entire source is invalid replace with source bounds.
if (srcInvalidRegion == null) {
srcInvalidRegion =
((PlanarImage)rcEvent.getOldValue()).getBounds();
}
} else {
// Get the invalidated region of the source.
srcInvalidRegion = (Shape)evt.getNewValue();
// If entire source is invalid replace with source bounds.
if (srcInvalidRegion == null) {
RenderedImage rSrc = (RenderedImage)evtSrc;
srcInvalidRegion =
new Rectangle(rSrc.getMinX(), rSrc.getMinY(),
rSrc.getWidth(), rSrc.getHeight());
}
}
// Only process further if the rendering is a
// PlanarImageServerProxy.
if (!(theImage instanceof PlanarImageServerProxy)) {
// Clear the current rendering.
theImage = null;
} else {
// Save the previous rendering as a PlanarImageServerProxy.
PlanarImageServerProxy oldPISP =
(PlanarImageServerProxy)theImage;
// Cache source invalid bounds.
Rectangle srcInvalidBounds = srcInvalidRegion.getBounds();
// If bounds are empty, replace srcInvalidRegion with
// the complement of the image bounds within the
// bounds of all tiles.
if (srcInvalidBounds.isEmpty()) {
int x = oldPISP.tileXToX(oldPISP.getMinTileX());
int y = oldPISP.tileYToY(oldPISP.getMinTileY());
int w =
oldPISP.getNumXTiles() * oldPISP.getTileWidth();
int h =
oldPISP.getNumYTiles() * oldPISP.getTileHeight();
Rectangle tileBounds = new Rectangle(x, y, w, h);
Rectangle imageBounds = oldPISP.getBounds();
if (!tileBounds.equals(imageBounds)) {
Area tmpArea = new Area(tileBounds);
tmpArea.subtract(new Area(imageBounds));
srcInvalidRegion = tmpArea;
srcInvalidBounds = srcInvalidRegion.getBounds();
}
}
// ----- Determine invalid destination region. -----
boolean saveAllTiles = false;
ArrayList validTiles = null;
if (srcInvalidBounds.isEmpty()) {
invalidRegion = srcInvalidRegion;
saveAllTiles = true;
} else {
// Get index of source which changed.
int idx = nodeSources.indexOf(evtSrc);
// Determine bounds of invalid destination region.
Rectangle dstRegionBounds =
oldPISP.mapSourceRect(srcInvalidBounds, idx);
if (dstRegionBounds == null) {
dstRegionBounds = oldPISP.getBounds();
}
// Determine invalid destination region.
Point[] indices = getTileIndices(dstRegionBounds);
int numIndices = indices != null ? indices.length : 0;
GeneralPath gp = null;
for(int i = 0; i < numIndices; i++) {
if (i % 1000 == 0 && gp != null)
gp = new GeneralPath(new Area(gp));
Rectangle dstRect =
getTileRect(indices[i].x, indices[i].y);
Rectangle srcRect =
oldPISP.mapDestRect(dstRect, idx);
if(srcRect == null) {
gp = null;
break;
}
if(srcInvalidRegion.intersects(srcRect)) {
if(gp == null) {
gp = new GeneralPath(dstRect);
} else {
gp.append(dstRect, false);
}
} else {
if(validTiles == null) {
validTiles = new ArrayList();
}
validTiles.add(indices[i]);
}
}
invalidRegion = (gp == null) ? null : new Area(gp);
}
// Retrieve the old TileCache.
TileCache oldCache = oldPISP.getTileCache();
theImage = null;
// Only perform further processing if there is a cache
// and there are tiles to save.
if (oldCache != null &&
(saveAllTiles || validTiles != null)) {
// Create new rendering
newEventRendering(protocolName,
oldPISP,
(PropertyChangeEventJAI)evt);
// Only perform further processing if the new
// rendering is an OpImage with a non-null TileCache.
if (theImage instanceof PlanarImageServerProxy &&
((PlanarImageServerProxy)theImage).getTileCache() !=
null) {
PlanarImageServerProxy newPISP =
(PlanarImageServerProxy)theImage;
TileCache newCache = newPISP.getTileCache();
Object tileCacheMetric =
newPISP.getTileCacheMetric();
if (saveAllTiles) {
Raster[] tiles = oldCache.getTiles(oldPISP);
int numTiles = tiles == null ?
0 : tiles.length;
for(int i = 0; i < numTiles; i++) {
Raster tile = tiles[i];
int tx = newPISP.XToTileX(tile.getMinX());
int ty = newPISP.YToTileY(tile.getMinY());
newCache.add(newPISP,
tx, ty, tile,
tileCacheMetric);
}
} else { // save some, but not all, tiles
int numValidTiles = validTiles.size();
for(int i = 0; i < numValidTiles; i++) {
Point tileIndex = (Point)validTiles.get(i);
Raster tile =
oldCache.getTile(oldPISP,
tileIndex.x,
tileIndex.y);
if (tile != null) {
newCache.add(newPISP,
tileIndex.x,
tileIndex.y,
tile,
tileCacheMetric);
}
}
}
}
}
}
} else { // not op name or registry change nor RenderingChangeEvent
ParameterBlock oldPB = null;
ParameterBlock newPB = null;
String oldServerName = serverName;
String newServerName = serverName;
boolean checkInvalidRegion = false;
if (propName.equals("operationname")) {
if (theImage instanceof PlanarImageServerProxy) {
newEventRendering(protocolName,
(PlanarImageServerProxy)theImage,
(PropertyChangeEventJAI)evt);
} else {
theImage = null;
createRendering();
}
// Do not set checkInvalidRegion to true, since there
// are no tiles to save for this case.
shouldFireEvent = true;
// XXX Do we need to do any evaluation of any
// DeferredData parameters.
} else if (propName.equals("parameterblock")) {
oldPB = (ParameterBlock)evt.getOldValue();
newPB = (ParameterBlock)evt.getNewValue();
checkInvalidRegion = true;
} else if (propName.equals("sources")) {
// Replace source(s)
Vector params =
nodeSupport.getParameterBlock().getParameters();
oldPB = new ParameterBlock((Vector)evt.getOldValue(),
params);
newPB = new ParameterBlock((Vector)evt.getNewValue(),
params);
checkInvalidRegion = true;
} else if (propName.equals("parameters")) {
// Replace parameter(s)
oldPB = new ParameterBlock(nodeSources,
(Vector)evt.getOldValue());
newPB = new ParameterBlock(nodeSources,
(Vector)evt.getNewValue());
checkInvalidRegion = true;
} else if (propName.equals("renderinghints")) {
oldPB = newPB = nodeSupport.getParameterBlock();
checkInvalidRegion = true;
} else if (propName.equals("servername")) {
oldPB = newPB = nodeSupport.getParameterBlock();
oldServerName = (String)evt.getOldValue();
newServerName = (String)evt.getNewValue();
checkInvalidRegion = true;
} else if (evt instanceof CollectionChangeEvent) {
// Event from a CollectionOp source.
// Replace appropriate source.
int collectionIndex = nodeSources.indexOf(evtSrc);
Vector oldSources = (Vector)nodeSources.clone();
Vector newSources = (Vector)nodeSources.clone();
oldSources.set(collectionIndex, evt.getOldValue());
newSources.set(collectionIndex, evt.getNewValue());
Vector params =
nodeSupport.getParameterBlock().getParameters();
oldPB = new ParameterBlock(oldSources, params);
newPB = new ParameterBlock(newSources, params);
checkInvalidRegion = true;
}
if (checkInvalidRegion) {
// Set event flag.
shouldFireEvent = true;
// Get the associated RemoteDescriptor.
OperationRegistry registry = nodeSupport.getRegistry();
RemoteDescriptor odesc = (RemoteDescriptor)
registry.getDescriptor(RemoteDescriptor.class,
protocolName);
// XXX
// Evaluate any DeferredData parameters.
oldPB = ImageUtil.evaluateParameters(oldPB);
newPB = ImageUtil.evaluateParameters(newPB);
// Determine the invalid region.
invalidRegion = (Shape)
odesc.getInvalidRegion("rendered",
oldServerName,
oldPB,
oldHints,
newServerName,
newPB,
nodeSupport.getRenderingHints(),
this);
if (invalidRegion == null ||
!(theImage instanceof PlanarImageServerProxy)) {
// Can't save any tiles; clear the rendering.
theImage = null;
} else {
// Create a new rendering.
PlanarImageServerProxy oldRendering =
(PlanarImageServerProxy)theImage;
newEventRendering(protocolName, oldRendering,
(PropertyChangeEventJAI)evt);
// If the new rendering is also a
// PlanarImageServerProxy, save some tiles.
if (theImage instanceof PlanarImageServerProxy &&
oldRendering.getTileCache() != null &&
((PlanarImageServerProxy)theImage).getTileCache()
!= null) {
PlanarImageServerProxy newRendering =
(PlanarImageServerProxy)theImage;
TileCache oldCache = oldRendering.getTileCache();
TileCache newCache = newRendering.getTileCache();
Object tileCacheMetric =
newRendering.getTileCacheMetric();
// If bounds are empty, replace invalidRegion with
// the complement of the image bounds within the
// bounds of all tiles.
if (invalidRegion.getBounds().isEmpty()) {
int x = oldRendering.tileXToX(
oldRendering.getMinTileX());
int y = oldRendering.tileYToY(
oldRendering.getMinTileY());
int w = oldRendering.getNumXTiles() *
oldRendering.getTileWidth();
int h = oldRendering.getNumYTiles() *
oldRendering.getTileHeight();
Rectangle tileBounds =
new Rectangle(x, y, w, h);
Rectangle imageBounds =
oldRendering.getBounds();
if (!tileBounds.equals(imageBounds)) {
Area tmpArea = new Area(tileBounds);
tmpArea.subtract(new Area(imageBounds));
invalidRegion = tmpArea;
}
}
if (invalidRegion.getBounds().isEmpty()) {
// Save all tiles.
Raster[] tiles =
oldCache.getTiles(oldRendering);
int numTiles = tiles == null ?
0 : tiles.length;
for(int i = 0; i < numTiles; i++) {
Raster tile = tiles[i];
int tx =
newRendering.XToTileX(tile.getMinX());
int ty =
newRendering.YToTileY(tile.getMinY());
newCache.add(newRendering,
tx, ty, tile,
tileCacheMetric);
}
} else {
// Copy tiles not in invalid region from old
// TileCache to new TileCache.
Raster[] tiles =
oldCache.getTiles(oldRendering);
int numTiles = tiles == null ?
0 : tiles.length;
for(int i = 0; i < numTiles; i++) {
Raster tile = tiles[i];
Rectangle bounds = tile.getBounds();
if (!invalidRegion.intersects(bounds)) {
newCache.add(
newRendering,
newRendering.XToTileX(bounds.x),
newRendering.YToTileY(bounds.y),
tile,
tileCacheMetric);
}
}
}
}
}
}
}
// Re-render the node. This will only occur if theImage
// has been set to null above.
if (theOldImage instanceof PlanarImageServerProxy &&
theImage == null) {
newEventRendering(protocolName,
(PlanarImageServerProxy)theOldImage,
(PropertyChangeEventJAI)evt);
} else {
createRendering();
}
// Fire an event if the flag was set.
if (shouldFireEvent) {
// Clear the synthetic and cached properties and reset the
// property source.
resetProperties(true);
// Create the event object.
RenderingChangeEvent rcEvent =
new RenderingChangeEvent(this, theOldImage, theImage,
invalidRegion);
// Fire to all registered listeners.
eventManager.firePropertyChange(rcEvent);