Use length of Base64 binary array instead of bin data length by Rylern · Pull Request #2039 · qupath/qupath

When importing a particular OME TIFF image with its OME XML shapes, the following exception occured:

09:50:31.855 [project-import39] [WARN ] q.l.g.c.ProjectImportImagesCommand - Exception adding Tumour-5-MorphologyMarkers.ome.tiff - 5
java.lang.ArrayIndexOutOfBoundsException: Index 53429 out of bounds for length 53429
        at qupath.lib.images.servers.bioformats.BioFormatsShapeConverter.convertMask(BioFormatsShapeConverter.java:118)
        at qupath.lib.images.servers.bioformats.BioFormatsShapeConverter.convertShapeToRoi(BioFormatsShapeConverter.java:56)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
        at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toList(Unknown Source)
        at qupath.lib.images.servers.bioformats.BioFormatsImageServer.lambda$readPathObjects$3(BioFormatsImageServer.java:1062)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
        at java.base/java.util.stream.IntPipeline$1$1.accept(Unknown Source)
        at java.base/java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.Spliterator$OfInt.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.toList(Unknown Source)
        at qupath.lib.images.servers.bioformats.BioFormatsImageServer.readPathObjects(BioFormatsImageServer.java:1106)
        at qupath.lib.gui.commands.ProjectImportImagesCommand.initializeEntry(ProjectImportImagesCommand.java:747)
        at qupath.lib.gui.commands.ProjectImportImagesCommand$1.lambda$call$2(ProjectImportImagesCommand.java:468)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)

This PR fixes that.

Note that support for OME XML masks is quite brittle, mainly because I don't think the OME XML Schema matches with real examples. For example:

  • The mask width is supposed to represent the width of the mask in pixels. Yet, masks in this image have their mask width attributes defined to around 1, while in reality the masks have widths of around 30. So, the current code in QuPath is not using these mask width values. Same for the mask height.
  • The length of a bin data is supposed to represent the length of the base-64 encoded block. Yet, this is not the case in masks of the image that caused the exception mentioned above (this mismatch actually caused the exception). With this PR, QuPath uses the length of the base-64 byte array.

Because of these issues, the current QuPath code skips problematic shapes and doesn't import them. This means that in the future, it is not unlikely to have a user reporting missing shapes when importing OME XML shapes to QuPath.