From 0118aeb807382efcf1294b5d685f0e9afcc2ca8a Mon Sep 17 00:00:00 2001 From: Dominik Lindner Date: Fri, 20 Sep 2024 11:59:14 +0100 Subject: [PATCH 1/5] Call lookupPixels when RenderingEngine is created --- src/main/java/omero/gateway/Gateway.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/omero/gateway/Gateway.java b/src/main/java/omero/gateway/Gateway.java index 10dad087..513e0573 100644 --- a/src/main/java/omero/gateway/Gateway.java +++ b/src/main/java/omero/gateway/Gateway.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2015-2022 University of Dundee. All rights reserved. + * Copyright (C) 2015-2024 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify @@ -973,8 +973,11 @@ public RenderingEnginePrx getRenderingService(SecurityContext ctx, long pixelsID) throws DSOutOfServiceException, ServerError { Connector c = getConnector(ctx, true, false); - if (c != null) - return c.getRenderingService(pixelsID, ctx.getCompression()); + if (c != null) { + RenderingEnginePrx re = c.getRenderingService(pixelsID, ctx.getCompression()); + re.lookupPixels(pixelsID); + return re; + } return null; } From a4d367bd279b355a064f14798a05f4db382e0a7a Mon Sep 17 00:00:00 2001 From: Dominik Lindner Date: Fri, 20 Sep 2024 12:00:38 +0100 Subject: [PATCH 2/5] Just rethrow is already DS...Exception --- src/main/java/omero/gateway/facility/Facility.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/omero/gateway/facility/Facility.java b/src/main/java/omero/gateway/facility/Facility.java index 5eb1ac55..481566ca 100644 --- a/src/main/java/omero/gateway/facility/Facility.java +++ b/src/main/java/omero/gateway/facility/Facility.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2015-2017 University of Dundee. All rights reserved. + * Copyright (C) 2015-2024 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify @@ -289,11 +289,17 @@ void handleException(Object originator, Throwable t, String message) throws DSOutOfServiceException, DSAccessException { logError(originator, message, t); + if (t instanceof DSOutOfServiceException) + throw (DSOutOfServiceException)t; + if (t instanceof DSAccessException) + throw (DSAccessException)t; + ConnectionStatus b = getConnectionStatus(t); if (b != ConnectionStatus.OK) throw new DSOutOfServiceException("Connection lost.", t); if (!gateway.isConnected()) throw new DSOutOfServiceException("Gateway is disconnected.", t); + Throwable cause = t.getCause(); if (cause instanceof SecurityViolation) { String s = "For security reasons, cannot access data. \n"; From fe4388cee93da16ce49c595618f655a858f13659 Mon Sep 17 00:00:00 2001 From: Dominik Lindner Date: Fri, 20 Sep 2024 12:02:37 +0100 Subject: [PATCH 3/5] Add RenderFacility --- .../gateway/facility/RenderFacility.java | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/main/java/omero/gateway/facility/RenderFacility.java diff --git a/src/main/java/omero/gateway/facility/RenderFacility.java b/src/main/java/omero/gateway/facility/RenderFacility.java new file mode 100644 index 00000000..1a022c7f --- /dev/null +++ b/src/main/java/omero/gateway/facility/RenderFacility.java @@ -0,0 +1,161 @@ +/* + *------------------------------------------------------------------------------ + * Copyright (C) 2024 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 omero.gateway.facility; + +import omero.api.RenderingEnginePrx; +import omero.gateway.Gateway; +import omero.gateway.SecurityContext; +import omero.gateway.exception.DSAccessException; +import omero.gateway.exception.DSOutOfServiceException; +import omero.gateway.model.ImageData; +import omero.romio.PlaneDef; + +import java.awt.image.BufferedImage; + +public class RenderFacility extends Facility { + /** + * Creates a new instance + * + * @param gateway Reference to the {@link Gateway} + */ + RenderFacility(Gateway gateway) { + super(gateway); + } + + /** + * Get a RenderingEngine for an image. + * + * @param ctx The security context. + * @param imageId The image ID + * @param initDefaultSettings Flag to create default rendering settings if the + * image doesn't have any for the current user. + * @return A RenderingEngine for the image + * @throws DSOutOfServiceException If the connection is broken, or not logged in + * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO + * service. + */ + public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, boolean initDefaultSettings) + throws DSOutOfServiceException, DSAccessException { + try { + long pixelsId = gateway.getFacility(LoadFacility.class).getImage(ctx, imageId).getDefaultPixels().getId(); + RenderingEnginePrx re = gateway.getRenderingService(ctx, pixelsId); + if (!re.lookupRenderingDef(pixelsId)) { + if (initDefaultSettings) { + re.resetDefaultSettings(true); + re.lookupRenderingDef(pixelsId); + } else { + throw new DSOutOfServiceException("Image doesn't have rendering settings."); + } + } + re.load(); + return re; + } catch (Throwable t) { + handleException(this, t, "Could not load RenderingEngine."); + } + return null; + } + + /** + * Checks if an image is an RGB(A) image. + * + * @param ctx The security context. + * @param imageId The image ID + * @return True if the image is RGB(A) + * @throws DSOutOfServiceException If the connection is broken, or not logged in + * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO + * service. + */ + public boolean isRGB(SecurityContext ctx, long imageId) throws DSOutOfServiceException, DSAccessException { + try { + ImageData img = gateway.getFacility(LoadFacility.class).getImage(ctx, imageId); + int nChannles = img.getDefaultPixels().getSizeC(); + if (nChannles < 3 || nChannles > 4) + return false; + boolean r = false, g = false, b = false; + RenderingEnginePrx re = getRenderingEngine(ctx, imageId, true); + for (int i=0; i Date: Tue, 26 Nov 2024 15:16:20 +0000 Subject: [PATCH 4/5] Fix typo and clarify method comment --- src/main/java/omero/gateway/facility/RenderFacility.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/omero/gateway/facility/RenderFacility.java b/src/main/java/omero/gateway/facility/RenderFacility.java index 1a022c7f..d28c2dcf 100644 --- a/src/main/java/omero/gateway/facility/RenderFacility.java +++ b/src/main/java/omero/gateway/facility/RenderFacility.java @@ -74,7 +74,8 @@ public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, } /** - * Checks if an image is an RGB(A) image. + * Tries to determine if an image is an RGB(A) image. + * (Note: This does not necessarily give the same results as Bioformats isRGB()!) * * @param ctx The security context. * @param imageId The image ID @@ -86,12 +87,12 @@ public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, public boolean isRGB(SecurityContext ctx, long imageId) throws DSOutOfServiceException, DSAccessException { try { ImageData img = gateway.getFacility(LoadFacility.class).getImage(ctx, imageId); - int nChannles = img.getDefaultPixels().getSizeC(); - if (nChannles < 3 || nChannles > 4) + int nChannels = img.getDefaultPixels().getSizeC(); + if (nChannels < 3 || nChannels > 4) return false; boolean r = false, g = false, b = false; RenderingEnginePrx re = getRenderingEngine(ctx, imageId, true); - for (int i=0; i Date: Tue, 26 Nov 2024 15:31:05 +0000 Subject: [PATCH 5/5] Make sure RenderingEngine is closed again as default --- .../gateway/facility/RenderFacility.java | 90 +++++++++++++++++-- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/src/main/java/omero/gateway/facility/RenderFacility.java b/src/main/java/omero/gateway/facility/RenderFacility.java index d28c2dcf..1b80629c 100644 --- a/src/main/java/omero/gateway/facility/RenderFacility.java +++ b/src/main/java/omero/gateway/facility/RenderFacility.java @@ -20,6 +20,7 @@ */ package omero.gateway.facility; +import omero.ServerError; import omero.api.RenderingEnginePrx; import omero.gateway.Gateway; import omero.gateway.SecurityContext; @@ -52,11 +53,32 @@ public class RenderFacility extends Facility { * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO * service. */ - public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, boolean initDefaultSettings) + public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, + boolean initDefaultSettings) + throws DSOutOfServiceException, DSAccessException, ServerError { + return getRenderingEngine(ctx, imageId, initDefaultSettings, true); + } + + /** + * Get a RenderingEngine for an image. + * + * @param ctx The security context. + * @param imageId The image ID + * @param initDefaultSettings Flag to create default rendering settings if the + * image doesn't have any for the current user. + * @param closeRE Close the rendering engine again + * @return A RenderingEngine for the image + * @throws DSOutOfServiceException If the connection is broken, or not logged in + * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO + * service. + */ + public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, + boolean initDefaultSettings, boolean closeRE) throws DSOutOfServiceException, DSAccessException { + RenderingEnginePrx re = null; try { long pixelsId = gateway.getFacility(LoadFacility.class).getImage(ctx, imageId).getDefaultPixels().getId(); - RenderingEnginePrx re = gateway.getRenderingService(ctx, pixelsId); + re = gateway.getRenderingService(ctx, pixelsId); if (!re.lookupRenderingDef(pixelsId)) { if (initDefaultSettings) { re.resetDefaultSettings(true); @@ -69,6 +91,14 @@ public RenderingEnginePrx getRenderingEngine(SecurityContext ctx, long imageId, return re; } catch (Throwable t) { handleException(this, t, "Could not load RenderingEngine."); + } finally { + if (closeRE && re != null) { + try { + re.close(); + } catch (ServerError e) { + // just ignore + } + } } return null; } @@ -112,8 +142,8 @@ public boolean isRGB(SecurityContext ctx, long imageId) throws DSOutOfServiceExc * Renders the selected z, t plane of the given image as RGB image. * @param ctx The security context. * @param imageId The image ID - * @param z The z plane - * @param t The time point + * @param z The z plane + * @param t The time point * @return An RGB image ready to be displayed on screen. * @throws DSOutOfServiceException If the connection is broken, or not logged in * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO @@ -121,13 +151,39 @@ public boolean isRGB(SecurityContext ctx, long imageId) throws DSOutOfServiceExc */ public int[] renderPlane(SecurityContext ctx, long imageId, int z, int t) throws DSOutOfServiceException, DSAccessException { + return renderPlane(ctx, imageId, z, t, true); + } + + /** + * Renders the selected z, t plane of the given image as RGB image. + * @param ctx The security context. + * @param imageId The image ID + * @param z The z plane + * @param t The time point + * @param closeRE Close the rendering engine again + * @return An RGB image ready to be displayed on screen. + * @throws DSOutOfServiceException If the connection is broken, or not logged in + * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO + * service. + */ + public int[] renderPlane(SecurityContext ctx, long imageId, int z, int t, boolean closeRE) + throws DSOutOfServiceException, DSAccessException { + RenderingEnginePrx re = null; try { - RenderingEnginePrx re = getRenderingEngine(ctx, imageId, true); + re = getRenderingEngine(ctx, imageId, true, closeRE); PlaneDef plane = new PlaneDef(omeis.providers.re.data.PlaneDef.XY, 0, 0, z, t, null, -1); return re.renderAsPackedInt(plane); } catch (Throwable e) { handleException(this, e, "Could not render plane."); + } finally { + if (closeRE && re != null) { + try { + re.close(); + } catch (ServerError e) { + // just ignore + } + } } return null; } @@ -136,8 +192,8 @@ public int[] renderPlane(SecurityContext ctx, long imageId, int z, int t) * Renders the selected z, t plane of the given image as BufferedImage. * @param ctx The security context. * @param imageId The image ID - * @param z The z plane - * @param t The time point + * @param z The z plane + * @param t The time point * @return A BufferedImage ready to be displayed on screen. * @throws DSOutOfServiceException If the connection is broken, or not logged in * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO @@ -145,9 +201,27 @@ public int[] renderPlane(SecurityContext ctx, long imageId, int z, int t) */ public BufferedImage renderPlaneAsBufferedImage(SecurityContext ctx, long imageId, int z, int t) throws DSOutOfServiceException, DSAccessException { + return renderPlaneAsBufferedImage(ctx, imageId, z, t, true); + } + + /** + * Renders the selected z, t plane of the given image as BufferedImage. + * @param ctx The security context. + * @param imageId The image ID + * @param z The z plane + * @param t The time point + * @param closeRE Close the rendering engine again + * @return A BufferedImage ready to be displayed on screen. + * @throws DSOutOfServiceException If the connection is broken, or not logged in + * @throws DSAccessException If an error occurred while trying to retrieve data from OMERO + * service. + */ + public BufferedImage renderPlaneAsBufferedImage(SecurityContext ctx, long imageId, int z, int t, + boolean closeRE) + throws DSOutOfServiceException, DSAccessException { try { ImageData img = gateway.getFacility(LoadFacility.class).getImage(ctx, imageId); - int[] pixels = renderPlane(ctx, imageId, 0, 0); + int[] pixels = renderPlane(ctx, imageId, 0, 0, closeRE); int w = img.getDefaultPixels().getSizeX(); int h = img.getDefaultPixels().getSizeY(); BufferedImage image = new BufferedImage(w, h,