Skip to content

Use length of Base64 binary array instead of bin data length#2039

Merged
petebankhead merged 1 commit intoqupath:mainfrom
Rylern:exception-when-importing-bioformats-objects
Nov 19, 2025
Merged

Use length of Base64 binary array instead of bin data length#2039
petebankhead merged 1 commit intoqupath:mainfrom
Rylern:exception-when-importing-bioformats-objects

Conversation

@Rylern
Copy link
Contributor

@Rylern Rylern commented Nov 12, 2025

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.

@petebankhead petebankhead merged commit c9f0ef5 into qupath:main Nov 19, 2025
3 checks passed
@Rylern Rylern deleted the exception-when-importing-bioformats-objects branch November 19, 2025 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants