From bacd6ebbba6bba584d5ece44955419226f6d2b6b Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Thu, 5 Jan 2012 09:16:06 +0000
Subject: [PATCH] LMS-2735 feed imaging database with original image size

SVN: 24092
---
 .../dss/etl/AbsoluteImageReference.java       | 38 ++++-------
 .../dss/etl/Hdf5ThumbnailGenerator.java       | 10 +--
 .../etl/ImageSizeFeedingMaintenanceTask.java  |  8 +--
 .../dss/etl/PlateStorageProcessor.java        | 20 +++++-
 .../systemsx/cisd/openbis/dss/etl/Utils.java  | 64 +++++++++++++++++++
 .../dto/api/impl/ImageDataSetInformation.java | 28 ++++++++
 .../etl/jython/JythonPlateDataSetHandler.java | 23 +++++++
 7 files changed, 152 insertions(+), 39 deletions(-)
 create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Utils.java

diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java
index 95d90d19c98..0a2e1eb7e82 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.dss.etl;
 
-import java.awt.Dimension;
 import java.awt.image.BufferedImage;
 
 import ch.systemsx.cisd.common.io.hierarchical_content.api.IHierarchicalContentNode;
@@ -24,7 +23,7 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.ImageLibraryInfo;
 import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ChannelColorRGB;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.RequestedImageSize;
-import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ColorComponent;
 
 /**
@@ -101,37 +100,22 @@ public class AbsoluteImageReference extends AbstractImageReference
     {
         if (image == null)
         {
-            image = loadUnchangedImage(contentNode, tryGetImageID(), imageLibraryOrNull);
+            image = Utils.loadUnchangedImage(contentNode, tryGetImageID(), imageLibraryOrNull);
         }
         return image;
     }
-
-    static BufferedImage loadUnchangedImage(IHierarchicalContentNode contentNode,
-            String imageIdOrNull, ImageLibraryInfo imageLibraryOrNull)
-    {
-        String imageLibraryNameOrNull = null;
-        String imageLibraryReaderNameOrNull = null;
-        if (imageLibraryOrNull != null)
-        {
-            imageLibraryNameOrNull = imageLibraryOrNull.getName();
-            imageLibraryReaderNameOrNull = imageLibraryOrNull.getReaderName();
-        }
-        return ImageUtil.loadUnchangedImage(contentNode, imageIdOrNull, imageLibraryNameOrNull,
-                imageLibraryReaderNameOrNull, null);
-    }
-
-    static Dimension loadUnchangedImageDimension(IHierarchicalContentNode contentNode,
-            String imageIdOrNull, ImageLibraryInfo imageLibraryOrNull)
+    
+    /**
+     * Returns the image size. Preferred method if only image size is needed because only the
+     * header of an image file might be read to get the size.
+     */
+    public Size getUnchangedImageSize()
     {
-        String imageLibraryNameOrNull = null;
-        String imageLibraryReaderNameOrNull = null;
-        if (imageLibraryOrNull != null)
+        if (image != null)
         {
-            imageLibraryNameOrNull = imageLibraryOrNull.getName();
-            imageLibraryReaderNameOrNull = imageLibraryOrNull.getReaderName();
+            return new Size(image.getWidth(), image.getHeight());
         }
-        return ImageUtil.loadUnchangedImageDimension(contentNode, imageIdOrNull,
-                imageLibraryNameOrNull, imageLibraryReaderNameOrNull);
+        return Utils.loadUnchangedImageSize(contentNode, tryGetImageID(), imageLibraryOrNull);
     }
 
     public RequestedImageSize getRequestedSize()
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java
index 178a122e75f..432fe5f1c1c 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.dss.etl;
 
-import java.awt.Dimension;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -52,6 +51,7 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageFileInfo;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageIdentifier;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageStorageConfiguraton;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ThumbnailsStorageFormat;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil;
 
 /**
@@ -234,7 +234,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient
 
         if (thumbnailsStorageFormat.getZoomLevel() != null)
         {
-            Dimension originalSize = loadUnchangedImageDimension(imageFile, null);
+            Size originalSize = loadUnchangedImageDimension(imageFile, null);
             double zoomLevel = thumbnailsStorageFormat.getZoomLevel();
             width = (int) Math.round(zoomLevel * originalSize.getWidth());
             height = (int) Math.round(zoomLevel * originalSize.getHeight());
@@ -288,13 +288,13 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient
 
     private BufferedImage loadUnchangedImage(File imageFile, String imageIdOrNull)
     {
-        return AbsoluteImageReference.loadUnchangedImage(new FileBasedContentNode(imageFile),
+        return Utils.loadUnchangedImage(new FileBasedContentNode(imageFile),
                 imageIdOrNull, imageLibraryOrNull);
     }
 
-    private Dimension loadUnchangedImageDimension(File imageFile, String imageIdOrNull)
+    private Size loadUnchangedImageDimension(File imageFile, String imageIdOrNull)
     {
-        return AbsoluteImageReference.loadUnchangedImageDimension(new FileBasedContentNode(
+        return Utils.loadUnchangedImageSize(new FileBasedContentNode(
                 imageFile), imageIdOrNull, imageLibraryOrNull);
     }
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTask.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTask.java
index f46add68789..6d397da18b1 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTask.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTask.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.dss.etl;
 
-import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
@@ -38,6 +37,7 @@ import ch.systemsx.cisd.openbis.dss.etl.dataaccess.ImagingDatasetLoader;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgImageDatasetDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgImageZoomLevelDTO;
@@ -183,9 +183,9 @@ public class ImageSizeFeedingMaintenanceTask implements IDataStoreLockingMainten
         {
             return null;
         }
-        BufferedImage unchangedImage = image.getUnchangedImage();
-        int width = unchangedImage.getWidth();
-        int height = unchangedImage.getHeight();
+        Size size = image.getUnchangedImageSize();
+        int width = size.getWidth();
+        int height = size.getHeight();
         dao.addImageZoomLevel(new ImgImageZoomLevelDTO(dataSetCode, original, "", width, height,
                 null, null, dataSetId));
         return (original ? "Original" : "Thumbnail") + " size " + width + "x" + height
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java
index a9149c31a1d..ce7fa2ea346 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java
@@ -30,6 +30,7 @@ import ch.systemsx.cisd.openbis.dss.etl.dataaccess.IImagingQueryDAO;
 import ch.systemsx.cisd.openbis.dss.etl.dto.ImageDatasetInfo;
 import ch.systemsx.cisd.openbis.dss.etl.dto.ImageLibraryInfo;
 import ch.systemsx.cisd.openbis.dss.etl.dto.ImageZoomLevel;
+import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.ImageDataSetInformation;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.ThumbnailsInfo;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ThumbnailsStorageFormat.FileFormat;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
@@ -164,21 +165,34 @@ public final class PlateStorageProcessor extends AbstractImageStorageProcessor
             super(containerDatasetPermId, originalDataset);
             this.imageZoomLevels = createZoomLevels(originalDataset, thumbnailsInfosOrNull);
         }
+        
+        private static Integer nullifyIfZero(int value)
+        {
+            return value == 0 ? null : value;
+        }
 
         private static List<ImageZoomLevel> createZoomLevels(DataSetInformation originalDataset,
                 ThumbnailsInfo thumbnailsInfosOrNull)
         {
             List<ImageZoomLevel> zoomLevels = new ArrayList<ImageZoomLevel>();
-
+            Integer width = null;
+            Integer height = null;
+            if (originalDataset instanceof ImageDataSetInformation)
+            {
+                ImageDataSetInformation imageDataSet = (ImageDataSetInformation) originalDataset;
+                width = nullifyIfZero(imageDataSet.getMaximumImageWidth());
+                height = nullifyIfZero(imageDataSet.getMaximumImageHeight());
+            }
             ImageZoomLevel originalZoomLevel =
                     new ImageZoomLevel(originalDataset.getDataSetCode(), true,
-                            StringUtils.EMPTY_STRING, null, null, null, null);
+                            StringUtils.EMPTY_STRING, width, height, null, null);
             zoomLevels.add(originalZoomLevel);
             if (thumbnailsInfosOrNull != null)
             {
                 for (String permId : thumbnailsInfosOrNull.getThumbnailPhysicalDatasetsPermIds())
                 {
-                    Integer width = null, height = null;
+                    width = null;
+                    height = null;
                     Size dimension = thumbnailsInfosOrNull.tryGetDimension(permId);
                     if (dimension != null)
                     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Utils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Utils.java
new file mode 100644
index 00000000000..71c4afcefae
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Utils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.etl;
+
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+
+import ch.systemsx.cisd.common.io.hierarchical_content.api.IHierarchicalContentNode;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageLibraryInfo;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
+import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil;
+
+/**
+ * Collection of helper functions.
+ *
+ * @author Franz-Josef Elmer
+ */
+public class Utils
+{
+
+    public static BufferedImage loadUnchangedImage(IHierarchicalContentNode contentNode,
+            String imageIdOrNull, ImageLibraryInfo imageLibraryOrNull)
+    {
+        String imageLibraryNameOrNull = null;
+        String imageLibraryReaderNameOrNull = null;
+        if (imageLibraryOrNull != null)
+        {
+            imageLibraryNameOrNull = imageLibraryOrNull.getName();
+            imageLibraryReaderNameOrNull = imageLibraryOrNull.getReaderName();
+        }
+        return ImageUtil.loadUnchangedImage(contentNode, imageIdOrNull, imageLibraryNameOrNull,
+                imageLibraryReaderNameOrNull, null);
+    }
+
+    public static Size loadUnchangedImageSize(IHierarchicalContentNode contentNode,
+            String imageIdOrNull, ImageLibraryInfo imageLibraryOrNull)
+    {
+        String imageLibraryNameOrNull = null;
+        String imageLibraryReaderNameOrNull = null;
+        if (imageLibraryOrNull != null)
+        {
+            imageLibraryNameOrNull = imageLibraryOrNull.getName();
+            imageLibraryReaderNameOrNull = imageLibraryOrNull.getReaderName();
+        }
+        Dimension dimension = ImageUtil.loadUnchangedImageDimension(contentNode, imageIdOrNull,
+                imageLibraryNameOrNull, imageLibraryReaderNameOrNull);
+        return new Size(dimension.width, dimension.height);
+    }
+
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java
index 3505d444113..803eac5ebb0 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java
@@ -45,6 +45,10 @@ public class ImageDataSetInformation extends BasicDataSetInformation
     private ThumbnailsInfo thumbnailsInfos;
 
     private String containerDatasetPermId;
+    
+    private int maximumImageWidth;
+    
+    private int maximumImageHeight;
 
     public File getIncomingDirectory()
     {
@@ -100,6 +104,26 @@ public class ImageDataSetInformation extends BasicDataSetInformation
 
     // -------
 
+    public int getMaximumImageWidth()
+    {
+        return maximumImageWidth;
+    }
+
+    public void setMaximumImageWidth(int maximumImageWidth)
+    {
+        this.maximumImageWidth = maximumImageWidth;
+    }
+
+    public int getMaximumImageHeight()
+    {
+        return maximumImageHeight;
+    }
+
+    public void setMaximumImageHeight(int maximumImageHeight)
+    {
+        this.maximumImageHeight = maximumImageHeight;
+    }
+
     @Override
     public String toString()
     {
@@ -107,6 +131,10 @@ public class ImageDataSetInformation extends BasicDataSetInformation
         appendNameAndObject(buffer, "images structure", imageDataSetStructure);
         appendNameAndObject(buffer, "container dataset", containerDatasetPermId);
         appendNameAndObject(buffer, "original dataset", this.getDataSetCode());
+        if (maximumImageHeight > 0 && maximumImageWidth > 0)
+        {
+            appendNameAndObject(buffer, "bounding box", maximumImageWidth + "x" + maximumImageHeight);
+        }
         if (getThumbnailsInfos() != null)
         {
             appendNameAndObject(buffer, "thumbnail", getThumbnailsInfos());
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java
index 624149f0b2e..e83294278d9 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java
@@ -18,6 +18,7 @@ import ch.systemsx.cisd.bds.hcs.Location;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.io.FileBasedContentNode;
 import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult;
 import ch.systemsx.cisd.common.utilities.PropertyUtils;
 import ch.systemsx.cisd.etlserver.ITopLevelDataSetRegistratorDelegate;
@@ -33,6 +34,8 @@ import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSetRegistrationTra
 import ch.systemsx.cisd.openbis.dss.Constants;
 import ch.systemsx.cisd.openbis.dss.etl.Hdf5ThumbnailGenerator;
 import ch.systemsx.cisd.openbis.dss.etl.PlateGeometryOracle;
+import ch.systemsx.cisd.openbis.dss.etl.Utils;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageLibraryInfo;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.FeatureDefinition;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.FeatureVectorDataSetInformation;
 import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.FeaturesBuilder;
@@ -445,6 +448,7 @@ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<Data
                 }
                 imageDataSetInformation.setThumbnailsInfo(thumbnailsInfo);
             }
+            calculateBoundingBox(imageDataSetInformation, imageDataSetStructure, incomingDirectory);
             // create main dataset (with original images)
             @SuppressWarnings("unchecked")
             DataSet<ImageDataSetInformation> mainDataset =
@@ -469,6 +473,25 @@ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<Data
             return containerDataset;
         }
 
+        private void calculateBoundingBox(ImageDataSetInformation imageDataSetInformation,
+                ImageDataSetStructure imageDataSetStructure, File incomingDirectory)
+        {
+            ImageLibraryInfo imageLibrary =
+                    imageDataSetStructure.getImageStorageConfiguraton().tryGetImageLibrary();
+            List<ImageFileInfo> images = imageDataSetStructure.getImages();
+            for (ImageFileInfo imageFileInfo : images)
+            {
+                File file = new File(incomingDirectory, imageFileInfo.getImageRelativePath());
+                Size size =
+                        Utils.loadUnchangedImageSize(new FileBasedContentNode(file), null,
+                                imageLibrary);
+                imageDataSetInformation.setMaximumImageWidth(Math.max(
+                        imageDataSetInformation.getMaximumImageWidth(), size.getWidth()));
+                imageDataSetInformation.setMaximumImageHeight(Math.max(
+                        imageDataSetInformation.getMaximumImageHeight(), size.getHeight()));
+            }
+        }
+
         private File prependOriginalDirectory(String directoryPath)
         {
             return new File(originalDirName + File.separator + directoryPath);
-- 
GitLab