/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.env.rnd; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import omero.LockTimeout; import omero.api.RenderingEnginePrx; import omero.api.ResolutionDescription; import omero.model.Family; import omero.model.Length; import omero.model.LengthI; import omero.model.Pixels; import omero.model.QuantumDef; import omero.model.RenderingModel; import omero.model.enums.UnitsLength; import omero.romio.PlaneDef; import org.openmicroscopy.shoola.env.LookupNames; import omero.gateway.cache.CacheService; import org.openmicroscopy.shoola.env.config.Registry; import org.openmicroscopy.shoola.env.data.ConnectionExceptionHandler; import org.openmicroscopy.shoola.env.data.model.ProjectionParam; import omero.gateway.SecurityContext; import omero.gateway.exception.DSOutOfServiceException; import omero.gateway.exception.RenderingServiceException; import omero.log.LogMessage; import org.openmicroscopy.shoola.env.rnd.data.ResolutionLevel; import org.openmicroscopy.shoola.util.image.geom.Factory; import org.openmicroscopy.shoola.util.image.io.WriterImage; import omero.gateway.model.ChannelData; import omero.gateway.model.ExperimenterData; import omero.gateway.model.PixelsData; /** * UI-side implementation of the {@link RenderingControl} interface. * Runs in the Swing thread. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author <br>Andrea Falconi      * <a href="mailto:a.falconi@dundee.ac.uk">a.falconi@dundee.ac.uk</a> * @version 2.2 * @since OME2.2 */ class RenderingControlProxy implements RenderingControl { /** Default error message. */ private static final String ERROR = "An error occurred while trying to " + "set the "; /** Default error message. */ private static final String ERROR_RENDER = "An error occurred while " + "rendering "; /** The Red Color index. */ private static final Integer RED_INDEX = 0; /** The Green Color index. */ private static final Integer GREEN_INDEX = 1; /** The Blue Color index. */ private static final Integer BLUE_INDEX = 2; /** The Non-Primary Color index. */ private static final Integer NON_PRIMARY_INDEX = -1; /** The maximum number of retry.*/ private static final int MAX_RETRY = 2; /** List of supported families. */ private List families; /** List of supported models. */ private List models; /** The pixels set to render. */ private Pixels pixs; /** Reference to service to render pixels set. */ private RenderingEnginePrx servant; /** The id of the cache associated to this proxy. */ private int cacheID; /** The channel metadata. */ private ChannelData[] metadata; /** Local copy of the rendering settings used to speed-up the client. */ private RndProxyDef rndDef; /** Indicates if the compression level. */ private int compression; /** Helper reference to the registry. */ private Registry context; /** The size of the cache. */ private int cacheSize; /** The size of the image. */ private int imageSize; /** The rendering settings. */ private Map<String, List<RndProxyDef>> settings; /** The possible resolution levels if it is a big image.*/ private int resolutionLevels; /** The selected resolution level.*/ private int selectedResolutionLevel; /** The size of a tile. */ private Dimension tileSize; /** Flag indicating that the image is a big image or not.*/ private Boolean bigImage; /** The associated rendering controls.*/ private List<RenderingControl> slaves; /** Time of the last interaction.*/ private long lastAction; /** Flag indicating if the rendering engine is already shut down or not.*/ private boolean shutDown; /** The security context associated to the control.*/ private SecurityContext ctx; /** The number of retry.*/ private int retry; /** * Maps the color channel Red to {@link #RED_INDEX}, Blue to * {@link #BLUE_INDEX}, Green to {@link #GREEN_INDEX} and * non primary colors map to {@link #NON_PRIMARY_COLOUR}. * * @param channel * @return see above. */ private Integer colourIndex(int channel) { if (isChannelBlue(channel)) return BLUE_INDEX; if (isChannelRed(channel)) return RED_INDEX; if (isChannelGreen(channel)) return GREEN_INDEX; return NON_PRIMARY_INDEX; } /** * Handles only connection error. Returns <code>true</code> if it is not a * connection error, <code>false</code> otherwise. * * @param e The exception to handle. * @return See above. */ private boolean handleConnectionException(Throwable e) { ConnectionExceptionHandler handler = new ConnectionExceptionHandler(); int index = handler.handleConnectionException(e); if (index < 0) return true; log("Handle Exception:"+index); context.getTaskBar().sessionExpired(index); return index == ConnectionExceptionHandler.LOST_CONNECTION; } /** * Logs the specified message. * * @param error The message to log. */ private void log(String error) { context.getLogger().debug(this, error); } /** * Helper method to handle exceptions thrown by the connection library. * Methods in this class are required to fill in a meaningful context * message. * * @param e The exception. * @param message The context message. * @throws RenderingServiceException A rendering problem * @throws DSOutOfServiceException A connection problem. */ private void handleException(Throwable e, String message) throws RenderingServiceException, DSOutOfServiceException { if (shutDown) return; retry = 0; if (e instanceof Ice.OperationNotExistException) { RenderingServiceException ex = new RenderingServiceException(e); ex.setIndex(RenderingServiceException.OPERATION_NOT_SUPPORTED); throw ex; } if (!handleConnectionException(e)) throw new RenderingServiceException(message+"\n\n"+ printErrorText(e), e); } /** * Utility method to print the error message * * @param e The exception to handle. * @return See above. */ private String printErrorText(Throwable e) { if (e == null) return ""; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); return sw.toString(); } /** * Retrieves from the cache the buffered image representing the specified * plane definition. Note that only the images corresponding to an XY-plane * are cached. * * @param pd The specified {@link PlaneDef plane definition}. * @return The corresponding bufferedImage. */ private Object getFromCache(PlaneDef pd) { // We only cache XY images. if (pd.slice == omero.romio.XY.value && cacheID >= 0) { int index = pd.z+getPixelsDimensionsZ()*pd.t; return context.getCacheService().getElement(cacheID, index); } return null; } /** * Caches the specified image if it corresponds to an XYPlane. * * @param pd The plane definition. * @param object The buffered image to cache or the bytes array. */ private void cache(PlaneDef pd, Object object) { if (isBigImage()) return; if (pd.slice == omero.romio.XY.value) { //We only cache XY images. //if (xyCache != null) xyCache.add(pd, object); if (cacheID >= 0) { int index = pd.z+getPixelsDimensionsZ()*pd.t; //context.getCacheService().addElement(cacheID, // Integer.valueOf(index), object); } } } /** Clears the cache. */ private void invalidateCache() { if (isBigImage()) return; if (cacheID >= 0) context.getCacheService().clearCache(cacheID); } /** Clears the cache and releases memory. */ private void eraseCache() { if (isBigImage()) return; invalidateCache(); if (cacheID >=0) context.getCacheService().removeCache(cacheID); } /** * Initializes the cache for the specified plane. * * @param pDef The plane of reference. */ private void initializeCache(PlaneDef pDef) { if (isBigImage()) return; //if (xyCache != null) return; if (cacheID >= 0) return; /* if (pDef.getSlice() == PlaneDef.XY && xyCache == null) { // Okay, let's see if we can activate the xyCache. //In order to //do that, the dimensions of the pixels array and the //xyImgSize have to be available. //This happens if at least one XY plane has been rendered. //Note that doing remote calls upfront to eagerly //instantiate the xyCache is in most cases a total waste: //the client is likely to call getPixelsDims() before an //image is ever rendered and until an XY plane is //not requested it's pointless to have a cache. xyCache = CachingService.createXYCache(pixs.getId(), length, getPixelsDimensionsZ(), getPixelsDimensionsT()); } */ if (pDef.slice == omero.romio.XY.value) { try { cacheID = context.getCacheService().createCache( CacheService.IN_MEMORY, cacheSize/imageSize); } catch (Exception e) { //log the error for example if the cache manager could not //be initialized. LogMessage msg = new LogMessage(); msg.print("Initialize cache"); msg.print(e); context.getLogger().error(this, msg); } } } /** * Checks if the passed bit resolution is supported. * * @param v The value to check. */ private void checkBitResolution(int v) { switch (v) { case DEPTH_1BIT: case DEPTH_2BIT: case DEPTH_3BIT: case DEPTH_4BIT: case DEPTH_5BIT: case DEPTH_6BIT: case DEPTH_7BIT: case DEPTH_8BIT: return; default: throw new IllegalArgumentException("Bit resolution " + "not supported."); } } /** * Returns if <code>true</code> if one of the channels is of the specified * color, <code>false</code> otherwise. * * @param red The red component in the range [0, 255] in the default sRGB * space. * @param green The green component in the range [0, 255] in the default * sRGB space. * @param blue The blue component in the range [0, 255] in the default sRGB * space. * @return See above. */ private boolean isRightColor(int red, int green, int blue) { for (int i = 0; i < getPixelsDimensionsC(); i++) { if (isActive(i)) { if (isRightChannelColor(i, red, green, blue)) return true; } } return false; } /** * Returns if <code>true</code> if the channel is of the specified * color, <code>false</code> otherwise. * * @param index The index of the channel. * @param red The red component in the range [0, 255] in the default sRGB * space. * @param green The green component in the range [0, 255] in the default * sRGB space. * @param blue The blue component in the range [0, 255] in the default sRGB * space. * @return See above. */ private boolean isRightChannelColor(int index, int red, int green, int blue) { int[] rgba = rndDef.getChannel(index).getRGBA(); return (rgba[0] == red && rgba[1] == green && rgba[2] == blue); } /** * Returns the size. * * @param pDef The plane object to handle. * @return See above. */ private Point getSize(PlaneDef pDef) { int sizeX1, sizeX2; switch (pDef.slice) { case omero.romio.XZ.value: sizeX1 = pixs.getSizeX().getValue(); sizeX2 = pixs.getSizeZ().getValue(); break; case omero.romio.ZY.value: sizeX1 = pixs.getSizeZ().getValue(); sizeX2 = pixs.getSizeY().getValue(); break; case omero.romio.XY.value: default: sizeX1 = pixs.getSizeX().getValue(); sizeX2 = pixs.getSizeY().getValue(); if (pDef.region != null) { sizeX1 = pDef.region.width; sizeX2 = pDef.region.height; } break; } return new Point(sizeX1, sizeX2); } /** Initializes the cached rendering settings to speed up process. */ private void initialize() { try { rndDef.setTypeSigned(servant.isPixelsTypeSigned()); rndDef.setDefaultZ(servant.getDefaultZ()); rndDef.setDefaultT(servant.getDefaultT()); QuantumDef qDef = servant.getQuantumDef(); rndDef.setBitResolution(qDef.getBitResolution().getValue()); rndDef.setColorModel(servant.getModel().getValue().getValue()); rndDef.setCodomain(qDef.getCdStart().getValue(), qDef.getCdEnd().getValue()); ChannelBindingsProxy cb; ChannelData channel; for (int i = 0; i < metadata.length; i++) { channel = metadata[i]; cb = rndDef.getChannel(channel.getIndex()); if (cb == null) { cb = new ChannelBindingsProxy(); rndDef.setChannel(channel.getIndex(), cb); } cb.setActive(servant.isActive(i)); cb.setInterval(servant.getChannelWindowStart(i), servant.getChannelWindowEnd(i)); cb.setQuantization( servant.getChannelFamily(i).getValue().getValue(), servant.getChannelCurveCoefficient(i), servant.getChannelNoiseReduction(i)); cb.setRGBA(servant.getRGBA(i)); cb.setLowerBound(servant.getPixelsTypeLowerBound(i)); cb.setUpperBound(servant.getPixelsTypeUpperBound(i)); } tmpSolutionForNoiseReduction(); } catch (Exception e) { LogMessage msg = new LogMessage(); msg.print("Initialize proxy"); msg.print(e); context.getLogger().error(this, msg); } } private void tmpSolutionForNoiseReduction() { //DOES NOTHING TMP SOLUTION. try { for (int i = 0; i < pixs.getSizeC().getValue(); i++) { setQuantizationMap(i, getChannelFamily(i), getChannelCurveCoefficient(i), false); } } catch (Exception e) { } } /** * Sets the color. * * @param w The index of the channel. * @param rgba The color to set. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. * @see RenderingControl#setRGBA(int, Color) */ private void setRGBA(int w, int[] rgba) throws RenderingServiceException, DSOutOfServiceException { try { servant.setRGBA(w, rgba[0], rgba[1], rgba[2], rgba[3]); rndDef.getChannel(w).setRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); invalidateCache(); } catch (Exception e) { handleException(e, ERROR+"color for: "+w+"."); } } /** * Renders the compressed image. * * @param pDef A plane orthogonal to one of the <i>X</i>, <i>Y</i>, * or <i>Z</i> axes. * @return See above. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ private BufferedImage renderCompressedBI(PlaneDef pDef) throws RenderingServiceException, DSOutOfServiceException { //Need to adjust the cache. //Object array = getFromCache(pDef); try { byte[] values = servant.renderCompressed(pDef); imageSize = values.length; return WriterImage.bytesToImage(values); } catch (Throwable e) { if (e instanceof LockTimeout && retry < MAX_RETRY) { //retry retry++; return renderCompressedBI(pDef); } handleException(e, ERROR_RENDER+"the compressed image."); } return null; } /** * Renders the image without compression. * * @param pDef A plane orthogonal to one of the <i>X</i>, <i>Y</i>, * or <i>Z</i> axes. * @return See above. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ private BufferedImage renderUncompressed(PlaneDef pDef) throws RenderingServiceException, DSOutOfServiceException { //See if the requested image is in cache. BufferedImage img = (BufferedImage) getFromCache(pDef); //if (img != null) return img; try { int[] buf = servant.renderAsPackedInt(pDef); Point p = getSize(pDef); imageSize = 3*buf.length; initializeCache(pDef); img = Factory.createImage(buf, 32, p.x, p.y); cache(pDef, img); } catch (Throwable e) { if (e instanceof LockTimeout && retry < MAX_RETRY) { //retry retry++; return renderUncompressed(pDef); } handleException(e, ERROR_RENDER+"the uncompressed plane."); } return img; } /** * Projects the selected section of the optical sections * and renders a compressed image. * * @param startZ The first optical section. * @param endZ The last optical section. * @param stepping The stepping of the projection. * @param type The projection type. * @return See above. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ private BufferedImage renderProjectedCompressed(int startZ, int endZ, int stepping, int type) throws RenderingServiceException, DSOutOfServiceException { try { byte[] values = servant.renderProjectedCompressed( ProjectionParam.convertType(type), getDefaultT(), stepping, startZ, endZ); return WriterImage.bytesToImage(values); } catch (Throwable e) { if (e instanceof LockTimeout && retry < MAX_RETRY) { //retry retry++; return renderProjectedCompressed(startZ, endZ, stepping, type); } handleException(e, ERROR_RENDER+"the projected selection."); } return null; } /** * Projects the selected section of the optical sections * and renders a compressed image. * * @param startZ The first optical section. * @param endZ The last optical section. * @param stepping The stepping of the projection. * @param type The projection type. * @return See above. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ private BufferedImage renderProjectedUncompressed(int startZ, int endZ, int stepping, int type) throws RenderingServiceException, DSOutOfServiceException { BufferedImage img = null; try { int[] buf = servant.renderProjectedAsPackedInt( ProjectionParam.convertType(type), getDefaultT(), stepping, startZ, endZ); int sizeX1 = pixs.getSizeX().getValue(); int sizeX2 = pixs.getSizeY().getValue(); img = Factory.createImage(buf, 32, sizeX1, sizeX2); } catch (Throwable e) { if (e instanceof LockTimeout && retry < MAX_RETRY) { //retry retry++; return renderProjectedUncompressed(startZ, endZ, stepping, type); } handleException(e, ERROR_RENDER+"the projected selection."); } return img; } /** Checks if the proxy is still alive.*/ private void isSessionAlive() throws RenderingServiceException { lastAction = System.currentTimeMillis(); boolean b = false; try { b = context.getImageService().isAlive(ctx); if (!b) { context.getTaskBar().sessionExpired( ConnectionExceptionHandler.NETWORK); } } catch (DSOutOfServiceException e) { RenderingServiceException ex = new RenderingServiceException(e); ex.setIndex(RenderingServiceException.CONNECTION); throw ex; } } /** * Returns the identifier of the user currently logged in. * * @return See above. */ private long getUserID() { ExperimenterData exp = (ExperimenterData) context.lookup( LookupNames.CURRENT_USER_DETAILS); return exp.getId(); } /** * Creates a new instance. * * @param ctx The security context. * @param context Helper reference to the registry. * @param re The service to render a pixels set. * Mustn't be <code>null</code>. * @param pixels The pixels set. Mustn't be <code>null</code>. * @param m The channel metadata. * @param compression Pass <code>0</code> if no compression otherwise * pass the compression used. * @param rndDefs Local copy of the rendering settings used to * speed-up the client. * @param cacheSize The desired size of the cache. */ RenderingControlProxy(Registry context, SecurityContext ctx, RenderingEnginePrx re, Pixels pixels, List<ChannelData> m, int compression, List<RndProxyDef> rndDefs, int cacheSize) { if (re == null) throw new NullPointerException("No rendering engine."); if (pixels == null) throw new NullPointerException("No pixels set."); if (context == null) throw new NullPointerException("No registry."); if (ctx == null) throw new NullPointerException("No security context."); this.ctx = ctx; slaves = new ArrayList<RenderingControl>(); resolutionLevels = -1; selectedResolutionLevel = -1; lastAction = System.currentTimeMillis(); shutDown = false; this.cacheSize = cacheSize; this.context = context; servant = re; pixs = pixels; families = null; models = null; try { families = servant.getAvailableFamilies(); models = servant.getAvailableModels(); cacheID = -1; imageSize = 1; this.compression = compression; metadata = new ChannelData[m.size()]; Iterator<ChannelData> j = m.iterator(); ChannelData cm; while (j.hasNext()) { cm = j.next(); metadata[cm.getIndex()] = cm; } if (rndDefs.size() < 1) { this.rndDef = context.getImageService().getSettings(ctx, servant.getRenderingDefId()); initialize(); } else { this.rndDef = rndDefs.get(0); ChannelBindingsProxy cb; for (int i = 0; i < pixs.getSizeC().getValue(); i++) { cb = rndDef.getChannel(i); cb.setLowerBound(servant.getPixelsTypeLowerBound(i)); cb.setUpperBound(servant.getPixelsTypeUpperBound(i)); } } tmpSolutionForNoiseReduction(); } catch (Exception e) { } } /** * Reloads the settings after a saveAs w/o creating a thumbnail * This method should only be invoked after a save as to update the * other rendering engine. * * @param rndId The identifier of the rendering settigns. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ void loadRenderingSettings(long rndId) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.loadRenderingDef(rndId); servant.load(); } catch (Throwable e) { handleException(e, "An error occurred while loading the settings."); } } /** * Returns <code>true</code> if the rendering engine is still active, * <code>false</code> otherwise. * * @param timeout The time after which the engine is considered to be * inactive. * @return See above. */ boolean isProxyActive(long timeout) { long time = System.currentTimeMillis(); return time-lastAction < timeout; } /** Sets the rendering control associated to the main control.*/ void setSlaves(List<RenderingControl> slaves) { if (slaves == null) return; this.slaves = slaves; } /** * Resets the rendering engine. * * @param servant The value to set. * @param rndDef Local copy of the rendering settings used to speed-up the * client. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ void resetRenderingEngine(RenderingEnginePrx servant, RndProxyDef rndDef) throws RenderingServiceException, DSOutOfServiceException { if (servant == null) return; try { this.servant.close(); } catch (Exception e) { log("Error while closing the rendering engine "+e); } invalidateCache(); this.servant = servant; shutDown = false; lastAction = System.currentTimeMillis(); try { if (rndDef == null) { initialize(); } else { this.rndDef = rndDef; ChannelBindingsProxy cb; for (int i = 0; i < pixs.getSizeC().getValue(); i++) { cb = rndDef.getChannel(i); cb.setLowerBound(servant.getPixelsTypeLowerBound(i)); cb.setUpperBound(servant.getPixelsTypeUpperBound(i)); } } } catch (Exception e) { handleException(e, "Cannot reset the rendering engine."); } } /** * Reloads the rendering engine. * * @param servant The value to set. * @throws RenderingServiceException If an error occurred while setting * the value. * @throws DSOutOfServiceException If the connection is broken. */ void setRenderingEngine(RenderingEnginePrx servant) throws RenderingServiceException, DSOutOfServiceException { if (servant == null) return; this.servant = servant; shutDown = false; lastAction = System.currentTimeMillis(); // reset default of the rendering engine. if (rndDef == null) return; try { servant.setDefaultZ(rndDef.getDefaultZ()); servant.setDefaultT(rndDef.getDefaultT()); servant.setQuantumStrategy(rndDef.getBitResolution()); Iterator k = models.iterator(); RenderingModel model; String value = rndDef.getColorModel(); while (k.hasNext()) { model= (RenderingModel) k.next(); if (model.getValue().getValue().equals(value)) servant.setModel(model); } servant.setCodomainInterval(rndDef.getCdStart(), rndDef.getCdEnd()); ChannelBindingsProxy cb; Family family; int[] rgba; for (int i = 0; i < pixs.getSizeC().getValue(); i++) { cb = rndDef.getChannel(i); servant.setActive(i, cb.isActive()); servant.setChannelWindow(i, cb.getInputStart(), cb.getInputEnd()); k = families.iterator(); value = cb.getFamily(); while (k.hasNext()) { family= (Family) k.next(); if (family.getValue().getValue().equals(value)) { servant.setQuantizationMap(i, family, cb.getCurveCoefficient(), cb.isNoiseReduction()); } } rgba = cb.getRGBA(); servant.setRGBA(i, rgba[0], rgba[1], rgba[2], rgba[3]); } } catch (Exception e) { handleException(e, "Cannot reset the rendering engine."); } } /** * Shuts down the service. Returns <code>true</code> if the proxy * was already shut down, <code>false</code> otherwise. * * @param keepCache Pass <code>true</code> to keep the cache, * <code>false</code> otherwise. * @return See above. */ boolean shutDown(boolean keepCache) { if (shutDown) return shutDown; try { if (!keepCache && cacheID >= 0) context.getCacheService().removeCache(cacheID); Iterator<RenderingControl> j = slaves.iterator(); while (j.hasNext()) ((RenderingControlProxy) j.next()).shutDown(); } catch (Exception e) { log(e.toString()); } shutDown = true; return false; } /** Shuts down the service. */ void shutDown() { shutDown(false); } /** * Resets the size of the cache. * * @param size The size, in bytes, of the cache. */ void setCacheSize(int size) { if (imageSize == 0) imageSize = 1; if (cacheID >= 0) context.getCacheService().setCacheEntries(cacheID, size/imageSize); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setModel(String) */ public void setModel(String value) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { Iterator i = models.iterator(); RenderingModel model; while (i.hasNext()) { model= (RenderingModel) i.next(); if (model.getValue().getValue().equals(value)) { servant.setModel(model); rndDef.setColorModel(value); invalidateCache(); } } Iterator<RenderingControl> j = slaves.iterator(); while (j.hasNext()) j.next().setModel(value); } catch (Exception e) { handleException(e, ERROR+"model."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getModel() */ public String getModel() { return rndDef.getColorModel(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getDefaultZ() */ public int getDefaultZ() { return rndDef.getDefaultZ(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getDefaultT() */ public int getDefaultT() { return rndDef.getDefaultT(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setDefaultZ(int) */ public void setDefaultZ(int z) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { int maxZ = getPixelsDimensionsZ(); if (z < 0) z = 0; if (z >= maxZ) z = maxZ-1; servant.setDefaultZ(z); rndDef.setDefaultZ(z); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setDefaultZ(z); } catch (Exception e) { handleException(e, ERROR+"default Z."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setDefaultT(int) */ public void setDefaultT(int t) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { int maxT = getPixelsDimensionsT(); if (t < 0) t = 0; if (t >= maxT) t = maxT-1; servant.setDefaultT(t); rndDef.setDefaultT(t); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setDefaultT(t); } catch (Exception e) { handleException(e, ERROR+"default T."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setQuantumStrategy(int) */ public void setQuantumStrategy(int bitResolution) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { checkBitResolution(bitResolution); servant.setQuantumStrategy(bitResolution); rndDef.setBitResolution(bitResolution); invalidateCache(); Iterator<RenderingControl> j = slaves.iterator(); while (j.hasNext()) j.next().setQuantumStrategy(bitResolution); } catch (Exception e) { handleException(e, ERROR+"bit resolution."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setCodomainInterval(int, int) */ public void setCodomainInterval(int start, int end) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.setCodomainInterval(start, end); rndDef.setCodomain(start, end); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setCodomainInterval(start, end); invalidateCache(); } catch (Exception e) { handleException(e, ERROR+"codomain interval."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setQuantizationMap(int, String, double, boolean) */ public void setQuantizationMap(int w, String value, double coefficient, boolean noiseReduction) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { List list = servant.getAvailableFamilies(); Iterator i = list.iterator(); Family family; while (i.hasNext()) { family = (Family) i.next(); if (family.getValue().getValue().equals(value)) { servant.setQuantizationMap(w, family, coefficient, noiseReduction); rndDef.getChannel(w).setQuantization(value, coefficient, noiseReduction); invalidateCache(); } } Iterator<RenderingControl> j = slaves.iterator(); while (j.hasNext()) j.next().setQuantizationMap(w, value, coefficient, noiseReduction); } catch (Exception e) { handleException(e, ERROR+"quantization map."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelFamily(int) */ public String getChannelFamily(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return ""; return rndDef.getChannel(w).getFamily(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelNoiseReduction(int) */ public boolean getChannelNoiseReduction(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return false; return channel.isNoiseReduction(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelCurveCoefficient(int) */ public double getChannelCurveCoefficient(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return 1; return channel.getCurveCoefficient(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setChannelWindow(int, double, double) */ public void setChannelWindow(int w, double start, double end) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.setChannelWindow(w, start, end); rndDef.getChannel(w).setInterval(start, end); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setChannelWindow(w, start, end); invalidateCache(); } catch (Exception e) { handleException(e, ERROR+"input channel for: "+w+"."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelWindowStart(int) */ public double getChannelWindowStart(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return 0; return channel.getInputStart(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelWindowEnd(int) */ public double getChannelWindowEnd(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return 0; return channel.getInputEnd(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setRGBA(int, Color) */ public void setRGBA(int w, Color c) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.setRGBA(w, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); rndDef.getChannel(w).setRGBA(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); invalidateCache(); Iterator<RenderingControl> j = slaves.iterator(); while (j.hasNext()) j.next().setRGBA(w, c); } catch (Exception e) { handleException(e, ERROR+"color for: "+w+"."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getRGBA(int) */ public Color getRGBA(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return Color.black; int[] rgba = channel.getRGBA(); return new Color(rgba[0], rgba[1], rgba[2], rgba[3]); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setActive(int, boolean) */ public void setActive(int w, boolean active) throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.setActive(w, active); rndDef.getChannel(w).setActive(active); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setActive(w, active); invalidateCache(); } catch (Exception e) { handleException(e, ERROR+"active channel for: "+w+"."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isActive(int) */ public boolean isActive(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return false; return channel.isActive(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#addCodomainMap(CodomainMapContext) */ /* public void addCodomainMap(CodomainMapContext mapCtx) throws RenderingServiceException, DSOutOfServiceException { //servant.addCodomainMap(mapCtx); invalidateCache(); } */ /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#updateCodomainMap(CodomainMapContext) */ /* public void updateCodomainMap(CodomainMapContext mapCtx) throws RenderingServiceException, DSOutOfServiceException { //servant.updateCodomainMap(mapCtx); invalidateCache(); } */ /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#removeCodomainMap(CodomainMapContext) */ /* public void removeCodomainMap(CodomainMapContext mapCtx) throws RenderingServiceException, DSOutOfServiceException { //servant.removeCodomainMap(mapCtx); invalidateCache(); } */ /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getCodomainMaps() */ public List getCodomainMaps() { // TODO Auto-generated method stub return new ArrayList(0); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#saveCurrentSettings() */ public RndProxyDef saveCurrentSettings() throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); Iterator<RenderingControl> i = slaves.iterator(); try { long userID = getUserID(); long ownerID = rndDef.getOwnerID(); if (userID == ownerID) { servant.saveCurrentSettings(); while (i.hasNext()) i.next().saveCurrentSettings(); return rndDef.copy(); } else { long id = servant.saveAsNewSettings(); rndDef = context.getImageService().getSettings(ctx, id); while (i.hasNext()) { ((RenderingControlProxy) i.next()).loadRenderingSettings(id); } return rndDef.copy(); } } catch (Throwable e) { handleException(e, "An error occurred while saving the current " + "settings."); } return null; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#resetDefaults() */ public void resetDefaults() throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.resetDefaultSettings(false); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().resetDefaults(); invalidateCache(); initialize(); } catch (Throwable e) { handleException(e, ERROR+"default settings."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsPhysicalSizeX() */ public Length getPixelsPhysicalSizeX() { if (pixs.getPhysicalSizeX() == null) return new LengthI(1, UnitsLength.PIXEL); return pixs.getPhysicalSizeX(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsPhysicalSizeY() */ public Length getPixelsPhysicalSizeY() { if (pixs.getPhysicalSizeY() == null) return new LengthI(1, UnitsLength.PIXEL); return pixs.getPhysicalSizeY(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsPhysicalSizeZ() */ public Length getPixelsPhysicalSizeZ() { if (pixs.getPhysicalSizeZ() == null) return new LengthI(1, UnitsLength.PIXEL); return pixs.getPhysicalSizeZ(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsDimensionsX() */ public int getPixelsDimensionsX() { return pixs.getSizeX().getValue(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsDimensionsY() */ public int getPixelsDimensionsY() { return pixs.getSizeY().getValue(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsDimensionsZ() */ public int getPixelsDimensionsZ() { return pixs.getSizeZ().getValue(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsDimensionsT() */ public int getPixelsDimensionsT() { return pixs.getSizeT().getValue(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsDimensionsC() */ public int getPixelsDimensionsC() { return pixs.getSizeC().getValue(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getFamilies() */ public List getFamilies() { List<String> l = new ArrayList<String>(families.size()); Iterator i= families.iterator(); while (i.hasNext()) l.add(((Family) i.next()).getValue().getValue()); return l; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelData(int) */ public ChannelData getChannelData(int w) { return metadata[w]; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getChannelData() */ public ChannelData[] getChannelData() { return metadata; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getCodomainStart() */ public int getCodomainStart() { return rndDef.getCdStart(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getCodomainEnd() */ public int getCodomainEnd() { return rndDef.getCdEnd(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getBitResolution() */ public int getBitResolution() { return rndDef.getBitResolution(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#hasActiveChannelBlue() */ public boolean hasActiveChannelBlue() { return isRightColor(0, 0, 255); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#hasActiveChannelGreen() */ public boolean hasActiveChannelGreen() { return isRightColor(0, 255, 0); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#hasActiveChannelRed() */ public boolean hasActiveChannelRed() { return isRightColor(255, 0, 0); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isChannelRed(int) */ public boolean isChannelRed(int index) { if (index < 0 || index > getPixelsDimensionsC()) return false; return isRightChannelColor(index, 255, 0, 0); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isChannelBlue(int) */ public boolean isChannelBlue(int index) { if (index < 0 || index > getPixelsDimensionsC()) return false; return isRightChannelColor(index, 0, 0, 255); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isChannelGreen(int) */ public boolean isChannelGreen(int index) { if (index < 0 || index > getPixelsDimensionsC()) return false; return isRightChannelColor(index, 0, 255, 0); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getRndSettingsCopy() */ public RndProxyDef getRndSettingsCopy() { return rndDef.copy(); } public void resetSettings(RndProxyDef rndDef) throws RenderingServiceException, DSOutOfServiceException { resetSettings(rndDef, false); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#resetSettings(RndProxyDef, boolean) */ public void resetSettings(RndProxyDef rndDef, boolean includeZT) throws RenderingServiceException, DSOutOfServiceException { if (rndDef == null) throw new IllegalArgumentException("No rendering settings to " + "set"); if (rndDef.getNumberOfChannels() != getPixelsDimensionsC()) throw new IllegalArgumentException("Rendering settings not " + "compatible."); if (includeZT) { setDefaultT(rndDef.getDefaultT()); setDefaultZ(rndDef.getDefaultZ()); } setModel(rndDef.getColorModel()); setCodomainInterval(rndDef.getCdStart(), rndDef.getCdEnd()); setQuantumStrategy(rndDef.getBitResolution()); ChannelBindingsProxy c; for (int i = 0; i < getPixelsDimensionsC(); i++) { c = rndDef.getChannel(i); if (c != null) { setRGBA(i, c.getRGBA()); setChannelWindow(i, c.getInputStart(), c.getInputEnd()); setQuantizationMap(i, c.getFamily(), c.getCurveCoefficient(), c.isNoiseReduction()); setActive(i, c.isActive()); } } Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().resetSettings(rndDef); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsTypeLowerBound(int) */ public double getPixelsTypeLowerBound(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return 0; return channel.getLowerBound(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsTypeUpperBound(int) */ public double getPixelsTypeUpperBound(int w) { ChannelBindingsProxy channel = rndDef.getChannel(w); if (channel == null) return 0; return channel.getUpperBound(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isPixelsTypeSigned() */ public boolean isPixelsTypeSigned() { return rndDef.isTypeSigned(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#validatePixels(PixelsData) */ public boolean validatePixels(PixelsData pixels) { if (pixels == null) return false; long id = pixs.getDetails().getGroup().getId().getValue(); if (id != pixels.getGroupId()) return false; if (getPixelsDimensionsC() != pixels.getSizeC()) return false; if (getPixelsDimensionsY() != pixels.getSizeY()) return false; if (getPixelsDimensionsX() != pixels.getSizeX()) return false; String s = pixels.getPixelType(); String value = pixs.getPixelsType().getValue().getValue(); if (!value.equals(s)) return false; return true; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#render(PlaneDef) */ public BufferedImage render(PlaneDef pDef) throws RenderingServiceException, DSOutOfServiceException { return render(pDef, compression); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#render(PlaneDef, int) */ public BufferedImage render(PlaneDef pDef, int value) throws RenderingServiceException, DSOutOfServiceException { if (pDef == null) throw new IllegalArgumentException("Plane def cannot be null."); try { context.getImageService().isAlive(ctx); servant.ice_ping(); } catch (Exception e) { return null; } retry = 0; //since this method is always invoked after another change in //the settings and due to the fact that the proxy is usually invoked //in the swing thread. if (value != compression) setCompression(value); BufferedImage img; if (isCompressed()) img = renderCompressedBI(pDef); else img = renderUncompressed(pDef); if (value != compression) setCompression(compression); return img; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setCompression(int) */ public void setCompression(int compression) { try { isSessionAlive(); float f = PixelsServicesFactory.getCompressionQuality(compression); rndDef.setCompression(f); servant.setCompressionLevel(f); this.compression = compression; Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setCompression(compression); eraseCache(); } catch (Exception e) {} } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isCompressed() */ public boolean isCompressed() { return (compression != RenderingControl.UNCOMPRESSED); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getCompressionLevel() */ public int getCompressionLevel() { return compression; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setOriginalRndSettings() */ public void setOriginalRndSettings() throws RenderingServiceException, DSOutOfServiceException { isSessionAlive(); try { servant.resetDefaultSettings(false); if (getPixelsDimensionsC() > 1) setModel(RGB); List list = servant.getAvailableFamilies(); ChannelData m; Iterator j; Family family; String value; for (int i = 0; i < pixs.getSizeC().getValue(); i++) { j = list.iterator(); while (j.hasNext()) { family= (Family) j.next(); value = family.getValue().getValue(); if (value.equals(getChannelFamily(i))) { servant.setQuantizationMap(i, family, getChannelCurveCoefficient(i), false); } } m = getChannelData(i); servant.setChannelWindow(i, m.getGlobalMin(), m.getGlobalMax()); } invalidateCache(); initialize(); Iterator<RenderingControl> i = slaves.iterator(); while (i.hasNext()) i.next().setOriginalRndSettings(); } catch (Throwable e) { handleException(e, ERROR+"default settings."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#renderProjected(int, int, int, int, List) */ public BufferedImage renderProjected(int startZ, int endZ, int stepping, int type, List<Integer> channels) throws RenderingServiceException, DSOutOfServiceException { List<Integer> active = getActiveChannels(); for (int i = 0; i < getPixelsDimensionsC(); i++) setActive(i, false); Iterator<Integer> j = channels.iterator(); while (j.hasNext()) setActive(j.next(), true); BufferedImage img; retry = 0; if (isCompressed()) img = renderProjectedCompressed(startZ, endZ, stepping, type); else img = renderProjectedUncompressed(startZ, endZ, stepping, type); //reset j = active.iterator(); while (j.hasNext()) setActive(j.next(), true); return img; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#copyRenderingSettings(RndProxyDef, List) */ public void copyRenderingSettings(RndProxyDef rndToCopy, List<Integer> indexes) throws RenderingServiceException, DSOutOfServiceException { if (rndDef == null) throw new IllegalArgumentException("No rendering settings to set"); setModel(rndToCopy.getColorModel()); setCodomainInterval(rndToCopy.getCdStart(), rndToCopy.getCdEnd()); setQuantumStrategy(rndToCopy.getBitResolution()); int defaultT = rndToCopy.getDefaultT(); int maxT = getPixelsDimensionsT(); if (defaultT >= 0 && defaultT < maxT) setDefaultT(rndToCopy.getDefaultT()); ChannelBindingsProxy c; Iterator<Integer> j = indexes.iterator(); Integer index; int k = 0; while (j.hasNext()) { index = j.next(); c = rndToCopy.getChannel(index); if (c != null) { setRGBA(k, c.getRGBA()); setChannelWindow(k, c.getInputStart(), c.getInputEnd()); setQuantizationMap(k, c.getFamily(), c.getCurveCoefficient(), c.isNoiseReduction()); setActive(k, c.isActive()); } k++; } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getActiveChannels() */ public List<Integer> getActiveChannels() { List<Integer> active = new ArrayList<Integer>(); for (int i = 0; i < getPixelsDimensionsC(); i++) if (isActive(i)) active.add(Integer.valueOf(i)); return active; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isSameSettings(RndProxyDef, boolean) */ public boolean isSameSettings(RndProxyDef def, boolean checkPlane) { return isSameSettings(def, checkPlane, false); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isSameSettings(RndProxyDef, boolean, boolean) */ public boolean isSameSettings(RndProxyDef def, boolean checkPlane, boolean checkInactiveChannels) { if (def == null) return false; if (checkPlane) { if (def.getDefaultZ() != getDefaultZ()) return false; if (def.getDefaultT() != getDefaultT()) return false; } if (def.getBitResolution() != getBitResolution()) return false; if (def.getCdEnd() != getCodomainEnd()) return false; if (def.getCdStart() != getCodomainStart()) return false; if (!def.getColorModel().equals(getModel())) return false; if (def.getNumberOfChannels() != getPixelsDimensionsC()) return false; ChannelBindingsProxy channel; int[] rgba; Color color; Map<Integer, ChannelBindingsProxy> oldChannels = new HashMap<Integer, ChannelBindingsProxy>(); for (int i = 0; i < getPixelsDimensionsC(); i++) { channel = def.getChannel(i); if (channel.isActive()) { oldChannels.put(i, channel); } } List<Integer> indexes = new ArrayList<Integer>(); for (int i = 0; i < getPixelsDimensionsC(); i++) { if (isActive(i)) { indexes.add(i); } } if (indexes.size() != oldChannels.size()) return false; if(checkInactiveChannels) { for (int i = 0; i < getPixelsDimensionsC(); i++) { channel = def.getChannel(i); oldChannels.put(i, channel); } for (int i = 0; i < getPixelsDimensionsC(); i++) { indexes.add(i); } } Iterator<Integer> j = oldChannels.keySet().iterator(); int i; while (j.hasNext()) { i = j.next(); if (!(indexes.contains(i))) return false; channel = oldChannels.get(i); if (channel.getInputStart() != getChannelWindowStart(i)) return false; if (channel.getInputEnd() != getChannelWindowEnd(i)) return false; if (channel.getCurveCoefficient() != getChannelCurveCoefficient(i)) return false; if (!channel.getFamily().equals(getChannelFamily(i))) return false; if (channel.isNoiseReduction() != getChannelNoiseReduction(i)) return false; rgba = channel.getRGBA(); color = getRGBA(i); if (rgba[0] != color.getRed()) return false; if (rgba[1] != color.getGreen()) return false; if (rgba[2] != color.getBlue()) return false; if (rgba[3] != color.getAlpha()) return false; } return true; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getPixelsID() */ public long getPixelsID() { return pixs.getId().getValue(); } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isActiveImageRGB(List) */ public boolean isMappedImageRGB(List channels) { if (channels == null) channels = getActiveChannels(); if (channels.size() == 0) return false; Set<Integer> rgb = new HashSet<Integer>(); int cIndex; int index; Iterator i = channels.iterator(); while (i.hasNext()) { index = (Integer) i.next(); cIndex = colourIndex(index); if (cIndex != NON_PRIMARY_INDEX) { if (rgb.contains(cIndex)) return false; else rgb.add(cIndex); } else return false; } return true; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setOverlays(long, Map) */ public void setOverlays(long tableID, Map<Long, Integer> overlays) throws RenderingServiceException, DSOutOfServiceException { if (tableID < 0) return; try { invalidateCache(); //servant.setOverlays(omero.rtypes.rlong(tableID), // pixs.getImage().getId(), overlays); } catch (Exception e) { handleException(e, ERROR+"overlays."); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getResolutionLevels() */ public int getResolutionLevels() { try { if (resolutionLevels < 0) resolutionLevels = servant.getResolutionLevels(); } catch (Exception e) { resolutionLevels = 1; } return resolutionLevels; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getSelectedResolutionLevel() */ public int getSelectedResolutionLevel() { try { if (selectedResolutionLevel < 0) selectedResolutionLevel = servant.getResolutionLevel(); } catch (Exception e) { selectedResolutionLevel = 0; } return selectedResolutionLevel; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#setSelectedResolutionLevel(int) */ public void setSelectedResolutionLevel(int level) throws RenderingServiceException, DSOutOfServiceException { tileSize = null; if (level > getResolutionLevels()) level = getResolutionLevels(); isSessionAlive(); try { servant.setResolutionLevel(level); selectedResolutionLevel = level; Iterator<RenderingControl> j = slaves.iterator(); while (j.hasNext()) j.next().setSelectedResolutionLevel(level); } catch (Exception e) { handleException(e, ERROR+" resolution level: "+level); } } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getTileSize() */ public Dimension getTileSize() throws RenderingServiceException, DSOutOfServiceException { try { if (tileSize == null) { int[] values = servant.getTileSize(); tileSize = new Dimension(values[0], values[1]); } } catch (Exception e) { handleException(e, "An error occurred while retrieving " + "the tile size."); } return tileSize; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isBigImage() */ public boolean isBigImage() { if (bigImage != null) return bigImage.booleanValue(); try { bigImage = servant.requiresPixelsPyramid(); return bigImage.booleanValue(); } catch (Exception e) {} return false; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isBigImage() */ public List<RenderingControl> getSlaves() { return slaves; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#isShutDown() */ public boolean isShutDown() { return shutDown; } /** * Implemented as specified by {@link RenderingControl}. * @see RenderingControl#getResolutionDescriptions() */ public List<ResolutionLevel> getResolutionDescriptions() throws RenderingServiceException, DSOutOfServiceException { List<ResolutionLevel> levels = new ArrayList<ResolutionLevel>(); Dimension d; int sizeX = getPixelsDimensionsX(); int sizeY = getPixelsDimensionsY(); if (!isBigImage()) { d = new Dimension(sizeX, sizeY); levels.add(new ResolutionLevel(0, d, d)); return levels; } try { ResolutionDescription[] v = servant.getResolutionDescriptions(); ResolutionLevel level; ResolutionDescription r; int n = v.length-1; for (int i = n; i >= 0; i--) { r = v[i]; setSelectedResolutionLevel(n-i); d = new Dimension(r.sizeX, r.sizeY); level = new ResolutionLevel(n-i, getTileSize(), d); level.setRatio((double) r.sizeX/sizeX, (double) r.sizeY/sizeY); levels.add(level); } } catch (Exception e) { handleException(e, "An error occurred while retrieving " + "the resolutions."); } return levels; } }