From cb55d7fe749d962fd7504b04b6ef39b2b71cd4d7 Mon Sep 17 00:00:00 2001 From: Ed Scanlon Date: Tue, 21 Nov 2023 12:10:26 -0500 Subject: [PATCH 001/100] Work-around for breaking change in CellSens 4.1: missing metadata in .vsi file was causing exception when parsing .ets file. Added logic to dynamically associate .efs files with .vsi file metadata. --- .../src/loci/formats/in/CellSensReader.java | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/CellSensReader.java b/components/formats-gpl/src/loci/formats/in/CellSensReader.java index 04cf9190152..2cbb4504193 100644 --- a/components/formats-gpl/src/loci/formats/in/CellSensReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellSensReader.java @@ -771,8 +771,15 @@ else if (zCount > 0) { if (s < files.size() - 1) { setCoreIndex(index); String ff = files.get(s); + /** + * If there are fewer metadata 'pyramids' defined in the vsi than there + * are frame_*.ets files, we are missing the metadata associated with + * one or more frame_*.ets files. In this case we need to dynamically + * match the metadata we do have with the appropriate frame_*.ets file. + */ + boolean missingMetadata = pyramids.size() < (files.size() - 1); try (RandomAccessInputStream stream = new RandomAccessInputStream(ff)) { - parseETSFile(stream, ff, s); + parseETSFile(stream, ff, s, missingMetadata); } ms.littleEndian = compressionType.get(index) == RAW; @@ -797,10 +804,6 @@ else if (zCount > 0) { } index += ms.resolutionCount; - if (s < pyramids.size()) { - ms.seriesMetadata = pyramids.get(s).originalMetadata; - } - setCoreIndex(0); ms.dimensionOrder = "XYCZT"; } @@ -1188,7 +1191,8 @@ else if (dim.equals("T")) { return buf; } - private void parseETSFile(RandomAccessInputStream etsFile, String file, int s) + private void parseETSFile(RandomAccessInputStream etsFile, String file, int s, + boolean missingMetadata) throws FormatException, IOException { fileMap.put(core.size() - 1, file); @@ -1286,7 +1290,40 @@ private void parseETSFile(RandomAccessInputStream etsFile, String file, int s) int[] maxC = new int[maxResolution]; int[] maxT = new int[maxResolution]; - HashMap dimOrder = pyramids.get(s).dimensionOrdering; + HashMap dimOrder = new HashMap(); + Pyramid pyramid = null; + /** + * If there is metadata missing from the vsi file, we need to see if we can match up + * this frame_*.ets file with its correct metadata block if it exists. To do that we + * search the metadata blocks (ie 'pyramids') for the one whose width and height are + * within the correct range for this frame_*.ets file. + */ + if (missingMetadata) { + int maxXAtRes0 = 0; + int maxYAtRes0 = 0; + for (TileCoordinate t : tmpTiles) { + if (!usePyramid || t.coordinate[t.coordinate.length - 1] == 0) { + maxXAtRes0 = Math.max(maxXAtRes0, t.coordinate[0]); + maxYAtRes0 = Math.max(maxYAtRes0, t.coordinate[1]); + } + } + int maxPixelWidth = (maxXAtRes0 + 1) * tileX.get(tileX.size()-1); + int maxPixelHeight = (maxYAtRes0 + 1) * tileY.get(tileY.size()-1); + for (Pyramid p : pyramids) { + if ( (p.width <= maxPixelWidth ) && (p.width >= maxPixelWidth - tileX.get(tileX.size()-1)) + && (p.height <= maxPixelHeight) && (p.height >= maxPixelHeight - tileY.get(tileY.size()-1)) ) { + pyramid = p; + break; + } + } + } + else { + pyramid = pyramids.get(s); + } + + if (pyramid != null) { + dimOrder = pyramid.dimensionOrdering; + } for (TileCoordinate t : tmpTiles) { int resolution = usePyramid ? t.coordinate[t.coordinate.length - 1] : 0; @@ -1381,12 +1418,23 @@ private void parseETSFile(RandomAccessInputStream etsFile, String file, int s) maxC[resolution] = t.coordinate[cIndex]; } } - - if (pyramids.get(s).width != null) { - ms.sizeX = pyramids.get(s).width; + /** + * If this ets file has an associated metadata block, grab the correct width and height, + * and link it to the full metadata block. + */ + if (pyramid != null) { + ms.sizeX = pyramid.width; + ms.sizeY = pyramid.height; + ms.seriesMetadata = pyramid.originalMetadata; } - if (pyramids.get(s).height != null) { - ms.sizeY = pyramids.get(s).height; + else { + /** + * Otherwise, compute the closest approximation, since the real info couldn't be found. + */ + ms.sizeX = (maxX[0] + 1) * tileX.get(tileX.size()-1); + ms.sizeY = (maxY[0] + 1) * tileY.get(tileY.size()-1); + ms.seriesMetadata = new Hashtable(); + ms.seriesMetadata.put("Metadata", "Not Found"); // leave a trail that the metadata was missing for this ets. } ms.sizeZ = maxZ[0] + 1; if (maxC[0] > 0) { From 4557c98af3d19e872f35977573007988c7b9e683 Mon Sep 17 00:00:00 2001 From: Ed Scanlon Date: Thu, 7 Dec 2023 17:18:05 -0500 Subject: [PATCH 002/100] Altered the original work-around logic so that when a .ets file has no associated metadata block in the .vsi file, its contents are omitted from the series list, and the file is treated the same way as the blob_*.meta files, which is to say, their names are included in the 'extraFiles' list, and they are otherwise ignored. --- .../src/loci/formats/in/CellSensReader.java | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/CellSensReader.java b/components/formats-gpl/src/loci/formats/in/CellSensReader.java index 2cbb4504193..8827ab8de69 100644 --- a/components/formats-gpl/src/loci/formats/in/CellSensReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellSensReader.java @@ -772,14 +772,28 @@ else if (zCount > 0) { setCoreIndex(index); String ff = files.get(s); /** - * If there are fewer metadata 'pyramids' defined in the vsi than there - * are frame_*.ets files, we are missing the metadata associated with - * one or more frame_*.ets files. In this case we need to dynamically - * match the metadata we do have with the appropriate frame_*.ets file. + * If there are more frame_*.ets files than there are metadata 'pyramids' + * defined in the .vsi, then we have orphaned frame files. In this case + * we need to determine which are the valid frame files and which are + * the orphans. The valid ones need to be matched with the appropriate + * metadata blocks in the vsi, and the orphaned ones need to be ignored. */ - boolean missingMetadata = pyramids.size() < (files.size() - 1); + boolean hasOrphanEtsFiles = pyramids.size() < (files.size() - 1); try (RandomAccessInputStream stream = new RandomAccessInputStream(ff)) { - parseETSFile(stream, ff, s, missingMetadata); + boolean validFrameFile = parseETSFile(stream, ff, s, hasOrphanEtsFiles); + /* + * If this frame file is an orphan, "undo" the work that was done for + * it and change its status to being an "extra" file. + */ + if (!validFrameFile) { + core.remove(core.size()-1); + extraFiles.add(files.get(s)); + files.remove(s); + usedFiles = files.toArray(new String[files.size()]); + s--; + seriesCount--; + continue; + } } ms.littleEndian = compressionType.get(index) == RAW; @@ -1191,8 +1205,8 @@ else if (dim.equals("T")) { return buf; } - private void parseETSFile(RandomAccessInputStream etsFile, String file, int s, - boolean missingMetadata) + private boolean parseETSFile(RandomAccessInputStream etsFile, String file, int s, + boolean hasOrphanEtsFiles) throws FormatException, IOException { fileMap.put(core.size() - 1, file); @@ -1293,12 +1307,13 @@ private void parseETSFile(RandomAccessInputStream etsFile, String file, int s, HashMap dimOrder = new HashMap(); Pyramid pyramid = null; /** - * If there is metadata missing from the vsi file, we need to see if we can match up - * this frame_*.ets file with its correct metadata block if it exists. To do that we - * search the metadata blocks (ie 'pyramids') for the one whose width and height are - * within the correct range for this frame_*.ets file. - */ - if (missingMetadata) { + * If there are orphaned .ets files with this vsi file, we need to determine whether + * the current one is an orphan or a legit file. The logic to determine this is to + * see of there is a metadata block (ie 'pyramid') whose width and height are + * within the correct range for this .ets file. If there is no matching metadata + * block, then we have to assume this is an orphan + **/ + if (hasOrphanEtsFiles) { int maxXAtRes0 = 0; int maxYAtRes0 = 0; for (TileCoordinate t : tmpTiles) { @@ -1316,14 +1331,24 @@ private void parseETSFile(RandomAccessInputStream etsFile, String file, int s, break; } } + /** + * No matching metadata block. This is an orphan ets file. Undo and erase + * all the data elements that have been gathered up for this .ets file. + **/ + if (pyramid == null) { + nDimensions.remove(nDimensions.size() - 1); + compressionType.remove(compressionType.size() - 1); + tileX.remove(tileX.size() - 1); + tileY.remove(tileY.size() - 1); + backgroundColor.remove(getCoreIndex()); + tileOffsets.remove(tileOffsets.size()-1); + return(false); + } } else { pyramid = pyramids.get(s); } - - if (pyramid != null) { - dimOrder = pyramid.dimensionOrdering; - } + dimOrder = pyramid.dimensionOrdering; for (TileCoordinate t : tmpTiles) { int resolution = usePyramid ? t.coordinate[t.coordinate.length - 1] : 0; @@ -1418,24 +1443,9 @@ private void parseETSFile(RandomAccessInputStream etsFile, String file, int s, maxC[resolution] = t.coordinate[cIndex]; } } - /** - * If this ets file has an associated metadata block, grab the correct width and height, - * and link it to the full metadata block. - */ - if (pyramid != null) { - ms.sizeX = pyramid.width; - ms.sizeY = pyramid.height; - ms.seriesMetadata = pyramid.originalMetadata; - } - else { - /** - * Otherwise, compute the closest approximation, since the real info couldn't be found. - */ - ms.sizeX = (maxX[0] + 1) * tileX.get(tileX.size()-1); - ms.sizeY = (maxY[0] + 1) * tileY.get(tileY.size()-1); - ms.seriesMetadata = new Hashtable(); - ms.seriesMetadata.put("Metadata", "Not Found"); // leave a trail that the metadata was missing for this ets. - } + ms.sizeX = pyramid.width; + ms.sizeY = pyramid.height; + ms.seriesMetadata = pyramid.originalMetadata; ms.sizeZ = maxZ[0] + 1; if (maxC[0] > 0) { ms.sizeC *= (maxC[0] + 1); @@ -1529,6 +1539,7 @@ else if (newResolution.sizeY > maxSizeY) { ms.resolutionCount = finalResolution; } + return(true); } private int convertPixelType(int pixelType) throws FormatException { From f7da097666d60fd9479c7c08eb3d90304c3d3075 Mon Sep 17 00:00:00 2001 From: Tim Blackmore Date: Wed, 31 Jan 2024 23:05:46 +0000 Subject: [PATCH 003/100] Added support for ColumbusReader to import data that contains multiple z planes. --- .../src/loci/formats/in/ColumbusReader.java | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/ColumbusReader.java b/components/formats-gpl/src/loci/formats/in/ColumbusReader.java index a502fbd1194..fcf52845653 100644 --- a/components/formats-gpl/src/loci/formats/in/ColumbusReader.java +++ b/components/formats-gpl/src/loci/formats/in/ColumbusReader.java @@ -186,7 +186,7 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) Plane p = null; for (Plane plane : planes) { if (plane.series == getSeries() && plane.timepoint == zct[2] && - plane.channel == zct[1]) + plane.channel == zct[1] && plane.z == zct[0]) { p = plane; break; @@ -287,6 +287,9 @@ public int compare(Plane p1, Plane p2) { if (p1.channel != p2.channel) { return p1.channel - p2.channel; } + if (p1.z != p2.z) { + return p1.z - p2.z; + } return 0; } @@ -303,6 +306,7 @@ public int compare(Plane p1, Plane p2) { m.sizeC = 0; m.sizeT = 0; + m.sizeZ = 0; ArrayList uniqueSamples = new ArrayList(); ArrayList uniqueRows = new ArrayList(); @@ -332,10 +336,12 @@ public int compare(Plane p1, Plane p2) { if (p.timepoint >= getSizeT()) { m.sizeT = p.timepoint + 1; } - + if (p.z >= getSizeZ()) { + m.sizeZ = p.z + 1; + } } - m.sizeZ = 1; + m.imageCount = getSizeZ() * getSizeC() * getSizeT(); m.dimensionOrder = "XYCTZ"; m.rgb = false; @@ -376,7 +382,7 @@ public int compare(Plane p1, Plane p2) { store.setWellColumn(new NonNegativeInteger(col), 0, nextWell); for (int field=0; field Date: Mon, 12 Feb 2024 16:28:47 -0600 Subject: [PATCH 004/100] Add stopwatches to DICOM reader and writer --- .../src/loci/formats/in/DicomReader.java | 69 +++++++++++++++++++ .../src/loci/formats/out/DicomWriter.java | 53 +++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/in/DicomReader.java b/components/formats-bsd/src/loci/formats/in/DicomReader.java index aba35119fd4..c5916a6c3f4 100644 --- a/components/formats-bsd/src/loci/formats/in/DicomReader.java +++ b/components/formats-bsd/src/loci/formats/in/DicomReader.java @@ -65,6 +65,8 @@ import ome.xml.model.primitives.Timestamp; import ome.units.quantity.Length; import ome.units.UNITS; +import org.perf4j.StopWatch; +import org.perf4j.slf4j.Slf4JStopWatch; import loci.formats.dicom.DicomAttribute; import loci.formats.dicom.DicomFileInfo; @@ -275,6 +277,8 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) { FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); + StopWatch watch = stopWatch(); + int bpp = FormatTools.getBytesPerPixel(getPixelType()); int pixel = bpp * getRGBChannelCount(); Region currentRegion = new Region(x, y, w, h); @@ -289,12 +293,16 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) // look for any tiles that match the requested tile and plane List zs = zOffsets.get(getCoreIndex()); List tiles = tilePositions.get(getCoreIndex()); + watch.stop("openBytes setup, w=" + w + ", h=" + h); + watch.start(); + // TODO: stop tile scan as soon as whole requested area is read? for (int t=0; t 0; invert the values so that // white -> 255 (or 65535) if (bpp == 1) { @@ -327,6 +338,7 @@ else if (bpp == 2) { DataTools.unpackBytes(maxPixelValue - s, buf, i, 2, little); } } + watch.stop("inverted pixel values"); } // NB: do *not* apply the rescale function @@ -377,6 +389,9 @@ public void close(boolean fileOnly) throws IOException { @Override protected void initFile(String id) throws FormatException, IOException { super.initFile(id); + + StopWatch watch = stopWatch(); + if (in != null) { in.close(); } @@ -384,8 +399,14 @@ protected void initFile(String id) throws FormatException, IOException { in.order(true); CoreMetadata m = core.get(0, 0); + watch.stop("open selected file"); + // look for companion files + watch.start(); attachCompanionFiles(); + watch.stop("companion file scan"); + + watch.start(); m.littleEndian = true; long location = 0; @@ -432,7 +453,9 @@ protected void initFile(String id) throws FormatException, IOException { int opticalChannels = 0; List opticalPathIDs = new ArrayList(); + watch.stop("header check and variable init"); + watch.start(); while (decodingTags) { if (in.getFilePointer() + 4 >= in.length()) { break; @@ -682,9 +705,11 @@ else if (child.attribute == OPTICAL_PATH_DESCRIPTION) { decodingTags = false; } } + watch.stop("tag decoding"); if (imagesPerFile == 0) imagesPerFile = 1; if (new Location(currentId).getName().equals("DICOMDIR")) { + watch.start(); String parent = new Location(currentId).getAbsoluteFile().getParent(); Integer[] fileKeys = fileList.keySet().toArray(new Integer[0]); Arrays.sort(fileKeys); @@ -705,8 +730,10 @@ else if (child.attribute == OPTICAL_PATH_DESCRIPTION) { tilePositions = new HashMap>(); zOffsets = new HashMap>(); core.clear(); + watch.stop("DICOMDIR parsing"); } else { + watch.start(); if (m.sizeZ == 0) { m.sizeZ = 1; } @@ -787,7 +814,10 @@ else if (y + originalY < getSizeY()) { LOGGER.info("Calculating image offsets"); calculatePixelsOffsets(baseOffset); + + watch.stop("tile and dimension calculation"); } + watch.start(); makeFileList(); LOGGER.info("Populating metadata"); @@ -796,6 +826,7 @@ else if (y + originalY < getSizeY()) { Integer[] keys = fileList.keySet().toArray(new Integer[0]); Arrays.sort(keys); + watch.stop("assembled file list"); // at this point, we have a list of all files to be grouped together // and have parsed tags from the current file @@ -804,6 +835,7 @@ else if (y + originalY < getSizeY()) { if (seriesCount > 1) { for (int i=0; i currentFileList = fileList.get(keys[i]); DicomFileInfo fileInfo = createFileInfo(currentFileList.get(0)); zOffsets.put(i, fileInfo.zOffsets); @@ -827,17 +859,22 @@ else if (y + originalY < getSizeY()) { fileInfo.positionZ = z; metadataInfo.add(fileInfo); tilePositions.put(i, positions); + seriesWatch.stop("populated series #" + i); } } else { List allFiles = fileList.get(keys[0]); List infos = new ArrayList(); + StopWatch singleSeriesWatch = stopWatch(); + // parse tags for each file for (String file : allFiles) { DicomFileInfo info = createFileInfo(file); infos.add(info); } + singleSeriesWatch.stop("created " + infos.size() + " file infos"); + singleSeriesWatch.start(); if (infos.size() > 1) { infos.sort(null); @@ -931,8 +968,11 @@ else if (info.concatenationIndex == 0) { metadataInfo.add(infos.get(0)); zOffsets.put(0, infos.get(0).zOffsets); } + singleSeriesWatch.stop("updated metadata from file infos"); } + watch.start(); + // The metadata store we're working with. MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this, true); @@ -1001,6 +1041,7 @@ else if (info.concatenationIndex == 0) { } } setSeries(0); + watch.stop("populated MetadataStore"); } // -- Helper methods -- @@ -1008,6 +1049,7 @@ else if (info.concatenationIndex == 0) { // TODO: target for refactoring, this can possibly be combined with the // tag parsing loop that calls this private void addInfo(DicomTag info) throws IOException { + StopWatch infoWatch = stopWatch(); CoreMetadata m = core.get(0, 0); m.littleEndian = in.isLittleEndian(); @@ -1152,6 +1194,7 @@ else if (infoString.startsWith("MONOCHROME")) { addOriginalMetadata(key, info); } } + infoWatch.stop("addInfo attribute = " + info.attribute); } /** @@ -1195,6 +1238,7 @@ private void addOriginalMetadata(String key, DicomTag info) { * Build a list of files that belong with the current file. */ private void makeFileList() throws FormatException, IOException { + StopWatch fileScanWatch = stopWatch(); LOGGER.info("Building file list"); if (fileList == null && originalInstance != null && originalDate != null && @@ -1227,11 +1271,13 @@ private void makeFileList() throws FormatException, IOException { } } } + fileScanWatch.stop("finished file scanning"); } else if (fileList == null || !isGroupFiles()) { fileList = new HashMap>(); fileList.put(0, new ArrayList()); fileList.get(0).add(new Location(currentId).getAbsolutePath()); + fileScanWatch.stop("single file, no scanning needed"); } } @@ -1245,6 +1291,7 @@ private void scanDirectory(Location dir, boolean checkSeries) { String[] files = dir.list(true); if (files == null) return; + StopWatch directoryWatch = stopWatch(); Arrays.sort(files); for (String f : files) { String file = new Location(dir, f).getAbsolutePath(); @@ -1253,6 +1300,7 @@ private void scanDirectory(Location dir, boolean checkSeries) addFileToList(file, checkSeries); } } + directoryWatch.stop("scanned directory " + dir); } /** @@ -1261,6 +1309,8 @@ private void scanDirectory(Location dir, boolean checkSeries) private void addFileToList(String file, boolean checkSeries) throws FormatException, IOException { + StopWatch addFileWatch = stopWatch(); + int currentX = 0, currentY = 0; int fileSeries = -1; String thisSpecimen = null; @@ -1341,6 +1391,9 @@ private void addFileToList(String file, boolean checkSeries) } } } + finally { + addFileWatch.stop("checked tags from " + file); + } LOGGER.debug("file = {}", file); LOGGER.debug(" date = {}, originalDate = {}", date, originalDate); @@ -1508,6 +1561,7 @@ private void getTile(DicomTile tile, byte[] buf, int x, int y, int w, int h) CodecOptions options = new CodecOptions(); options.maxBytes = tile.region.width * tile.region.height; for (int c=0; c getTags() { return tags; } + protected Slf4JStopWatch stopWatch() { + return new Slf4JStopWatch(LOGGER, Slf4JStopWatch.DEBUG_LEVEL); + } + } diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index b3f25f64dd4..bdc4f9c1eb5 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -78,6 +78,9 @@ import ome.units.UNITS; import ome.units.quantity.Length; +import org.perf4j.StopWatch; +import org.perf4j.slf4j.Slf4JStopWatch; + import static loci.formats.dicom.DicomAttribute.*; import static loci.formats.dicom.DicomVR.*; @@ -143,6 +146,8 @@ public DicomWriter() { public void setExtraMetadata(String tagSource) { FormatTools.assertId(currentId, false, 1); + StopWatch metadataWatch = stopWatch(); + // get the provider (parser) from the source name // uses the file extension, this might need improvement @@ -163,6 +168,7 @@ public void setExtraMetadata(String tagSource) { LOGGER.error("Could not parse extra metadata: " + tagSource, e); } } + metadataWatch.stop("parsed extra metadata from " + tagSource); } /** @@ -193,23 +199,31 @@ public boolean writeDualPersonality() { @Override public void setSeries(int s) throws FormatException { super.setSeries(s); + StopWatch seriesWatch = stopWatch(); try { openFile(series, resolution); } catch (IOException e) { LOGGER.error("Could not open file for series #" + s, e); } + finally { + seriesWatch.stop("setSeries(" + s + ")"); + } } @Override public void setResolution(int r) { super.setResolution(r); + StopWatch resolutionWatch = stopWatch(); try { openFile(series, resolution); } catch (IOException e) { LOGGER.error("Could not open file for series #" + series + ", resolution #" + r, e); } + finally { + resolutionWatch.stop("setResolution(" + r + ")"); + } } @Override @@ -241,6 +255,8 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) throw new FormatException("DicomWriter does not allow tiles for non-pyramid images"); } + StopWatch precompressedWatch = stopWatch(); + int bytesPerPixel = FormatTools.getBytesPerPixel( FormatTools.pixelTypeFromString( r.getPixelsType(series).toString())); @@ -297,6 +313,9 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) ifds[resolutionIndex][no].put(IFD.PHOTOMETRIC_INTERPRETATION, PhotoInterp.Y_CB_CR.getCode()); } } + precompressedWatch.stop("precompressed tile setup"); + + precompressedWatch.start(); out.seek(out.length()); long start = out.getFilePointer(); @@ -322,6 +341,10 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) out.writeByte(0); } + precompressedWatch.stop("wrote precompressed tile"); + + precompressedWatch.start(); + // update the IFD to include this tile int xTiles = (int) Math.ceil((double) getSizeX() / tileWidth[resolutionIndex]); int xTile = x / tileWidth[resolutionIndex]; @@ -351,6 +374,7 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) end.elementLength = 0; writeTag(end); } + precompressedWatch.stop("updated IFD"); } /** @@ -380,6 +404,7 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || throw new FormatException("Tile too small, expected " + thisTileWidth + "x" + thisTileHeight + ". Setting the tile size to " + getSizeX() + "x" + getSizeY() + " or smaller may work."); } + StopWatch tileWatch = stopWatch(); checkPixelCount(false); boolean first = x == 0 && y == 0; @@ -437,6 +462,9 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || } } } + tileWatch.stop("setup tile writing"); + + tileWatch.start(); int bytesPerPixel = FormatTools.getBytesPerPixel( FormatTools.pixelTypeFromString( @@ -491,9 +519,12 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || paddedBuf = interleavedBuf; } + tileWatch.stop("repacked tile for compression"); // now we actually compress and write the pixel data + tileWatch.start(); + // we need to know the tile index to write save the tile offset // in the IFD // this tries to calculate the index without assuming sequential tile @@ -577,7 +608,7 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || writeTag(end); } } - + tileWatch.stop("compressed and wrote tile"); } /* @see loci.formats.IFormatWriter#canDoStacks() */ @@ -609,6 +640,8 @@ public void setId(String id) throws FormatException, IOException { out.close(); } + StopWatch initWatch = stopWatch(); + checkPixelCount(true); uids = new UIDCreator(); @@ -647,6 +680,9 @@ public void setId(String id) throws FormatException, IOException { String seriesInstanceUID = uids.getUID(); String studyInstanceUID = uids.getUID(); + initWatch.stop("setup data structures"); + initWatch.start(); + for (int pyramid=0; pyramid> 16)); @@ -1627,6 +1669,7 @@ else if (tag.value != null) { throw new IllegalArgumentException(String.valueOf(tag.vr.getCode())); } } + tagWatch.stop("wrote single tag: " + tag); } /** @@ -1710,6 +1753,7 @@ private void openFile(int pyramid, int res) throws IOException { // filename for this series/resolution return; } + StopWatch openWatch = stopWatch(); if (out != null) { out.close(); } @@ -1731,6 +1775,7 @@ else if (r.getPixelsBinDataCount(pyramid) == 0) { if (out.length() == 0) { writeHeader(); } + openWatch.stop("opened " + filename); } /** @@ -1738,6 +1783,7 @@ else if (r.getPixelsBinDataCount(pyramid) == 0) { * See http://dicom.nema.org/medical/dicom/current/output/html/part10.html#sect_7.1 */ private void writeHeader() throws IOException { + StopWatch headerWatch = stopWatch(); boolean littleEndian = out.isLittleEndian(); if (writeDualPersonality()) { // write a TIFF header in the preamble @@ -1811,6 +1857,7 @@ private void writeHeader() throws IOException { out.skipBytes(fileMetaBytes); out.order(littleEndian); + headerWatch.stop("wrote header for series = " + series + ", resolution = " + resolution); } private String getFilename(int pyramid, int res) { @@ -2043,6 +2090,10 @@ private void checkPixelCount(boolean warn) throws FormatException { } } + protected Slf4JStopWatch stopWatch() { + return new Slf4JStopWatch(LOGGER, Slf4JStopWatch.DEBUG_LEVEL); + } + class PlaneOffset { public long xOffset; public long yOffset; From 5493c1ea8df70308a6e4309b1493426e0748e6fa Mon Sep 17 00:00:00 2001 From: Ed Scanlon Date: Tue, 27 Feb 2024 17:51:28 -0500 Subject: [PATCH 005/100] Improved the method of detecting orphan ETS file by ensuring that any given 'pyramid' metadata struct is not associated with more than one ETS file. This change is to handle the case where the image sizes of multiple ETS files are the same or nearly the same as a single 'pyramid' metadata struct, resulting in an erroneous associations that cause the program to crash. --- .../formats-gpl/src/loci/formats/in/CellSensReader.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/formats-gpl/src/loci/formats/in/CellSensReader.java b/components/formats-gpl/src/loci/formats/in/CellSensReader.java index 8827ab8de69..86c699bdecf 100644 --- a/components/formats-gpl/src/loci/formats/in/CellSensReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellSensReader.java @@ -1325,9 +1325,12 @@ private boolean parseETSFile(RandomAccessInputStream etsFile, String file, int s int maxPixelWidth = (maxXAtRes0 + 1) * tileX.get(tileX.size()-1); int maxPixelHeight = (maxYAtRes0 + 1) * tileY.get(tileY.size()-1); for (Pyramid p : pyramids) { + if (p.HasAssociatedEtsFile) // If this pyramid has already been linked to an ETS + continue; // then don't allow it to be linked to another. if ( (p.width <= maxPixelWidth ) && (p.width >= maxPixelWidth - tileX.get(tileX.size()-1)) && (p.height <= maxPixelHeight) && (p.height >= maxPixelHeight - tileY.get(tileY.size()-1)) ) { pyramid = p; + p.HasAssociatedEtsFile = true; // Rememeber that this pyramid is now taken by an Ets. break; } } @@ -2664,6 +2667,7 @@ class Pyramid { public transient Double zStart; public transient Double zIncrement; public transient ArrayList zValues = new ArrayList(); + public boolean HasAssociatedEtsFile = false; } } From ec129c92fd40a3d58700f7381b340ea86edcdde7 Mon Sep 17 00:00:00 2001 From: Ed Scanlon Date: Wed, 6 Mar 2024 13:49:44 -0500 Subject: [PATCH 006/100] When an ETS file is determined to be an orphan, also remove it from the filemap. --- components/formats-gpl/src/loci/formats/in/CellSensReader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/formats-gpl/src/loci/formats/in/CellSensReader.java b/components/formats-gpl/src/loci/formats/in/CellSensReader.java index 86c699bdecf..0884c9b4767 100644 --- a/components/formats-gpl/src/loci/formats/in/CellSensReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellSensReader.java @@ -1339,6 +1339,7 @@ private boolean parseETSFile(RandomAccessInputStream etsFile, String file, int s * all the data elements that have been gathered up for this .ets file. **/ if (pyramid == null) { + fileMap.remove(core.size() - 1); nDimensions.remove(nDimensions.size() - 1); compressionType.remove(compressionType.size() - 1); tileX.remove(tileX.size() - 1); From 63eba7e63ad63369974e659f29a1cfddfcf6c05e Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 11 Mar 2024 18:33:20 -0500 Subject: [PATCH 007/100] Remove duplicate enum check and add clarifying comment Fixes #4143. --- components/formats-bsd/src/loci/formats/out/DicomWriter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index b3f25f64dd4..d92dc50e032 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -1862,11 +1862,12 @@ private boolean isReallySequential() { return sizeC * sizeZ * sizeT == 1; } + // check that there is a single channel or Z section (so order doesn't matter) + // or the dimension order indicates that Z is before C DimensionOrder order = retrieve.getPixelsDimensionOrder(series); return sequential && (sizeC == 1 || sizeZ == 1 || order == DimensionOrder.XYZCT || order == DimensionOrder.XYZTC || - order == DimensionOrder.XYZTC || order == DimensionOrder.XYTZC); } From 2f778ba0f60677f382d38a409b6be27d0744982c Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 11 Mar 2024 20:03:21 -0500 Subject: [PATCH 008/100] SimplePCI: restrict "Position_Z" check so that "*Position_Z_Fine" is excluded Fixes #4133. As noted there, .cxd files produced by newer versions of HCImage include both a "Position_Z" and "Position_Z_Fine" value. This can result in the "uniqueZ" list being larger than the number of detected planes. That causes line 381 to set sizeT to 0, which means that the following "while" loop runs until sizeZ and sizeT overflow to negative values. This intentionally does not check that the name equals "Position_Z", as some older files add a prefix to this name. --- components/formats-gpl/src/loci/formats/in/PCIReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/PCIReader.java b/components/formats-gpl/src/loci/formats/in/PCIReader.java index 6dae3ff5589..2e0acdd889d 100644 --- a/components/formats-gpl/src/loci/formats/in/PCIReader.java +++ b/components/formats-gpl/src/loci/formats/in/PCIReader.java @@ -296,7 +296,7 @@ else if (relativePath.indexOf("Image_Width") != -1 && getSizeX() == 0) { else if (relativePath.indexOf("Time_From_Start") != -1) { timestamps.put(getTimestampIndex(parent), stream.readDouble()); } - else if (relativePath.indexOf("Position_Z") != -1) { + else if (relativePath.endsWith("Position_Z")) { double zPos = stream.readDouble(); if (!uniqueZ.contains(zPos) && getSizeZ() <= 1) { From d79d678c873389b7126527c2f18c0781d192eb20 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 12 Mar 2024 16:38:59 -0500 Subject: [PATCH 009/100] Trim stream name before checking against known metadata keys Sometimes the stream name will have a bunch of whitespace appended. This doesn't affect the stream path that is used to actually retrieve metadata values. --- components/formats-gpl/src/loci/formats/in/PCIReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/PCIReader.java b/components/formats-gpl/src/loci/formats/in/PCIReader.java index 2e0acdd889d..7ff38888ada 100644 --- a/components/formats-gpl/src/loci/formats/in/PCIReader.java +++ b/components/formats-gpl/src/loci/formats/in/PCIReader.java @@ -228,7 +228,7 @@ protected void initFile(String id) throws FormatException, IOException { for (String name : allFiles) { int separator = name.lastIndexOf(File.separator); String parent = name.substring(0, separator); - String relativePath = name.substring(separator + 1); + String relativePath = name.substring(separator + 1).trim(); RandomAccessInputStream stream = null; if (!(relativePath.startsWith("Bitmap") || From 4e81795abba41f6fdf5e9ca12370d55ef2422f44 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 13 Mar 2024 18:05:51 -0500 Subject: [PATCH 010/100] Write header to an in-memory buffer before saving to disk This reduces the number of writes during initialization, which reduces overall conversion time. --- .../src/loci/formats/out/DicomWriter.java | 125 ++++++++++-------- 1 file changed, 69 insertions(+), 56 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index bdc4f9c1eb5..4bab31a2d7b 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -45,6 +45,7 @@ import java.util.Comparator; import java.util.List; +import loci.common.ByteArrayHandle; import loci.common.Constants; import loci.common.DataTools; import loci.common.DateTools; @@ -1485,45 +1486,49 @@ private int getStoredLength(DicomTag tag) { } private void writeTag(DicomTag tag) throws IOException { + writeTag(tag, out); + } + + private void writeTag(DicomTag tag, RandomAccessOutputStream output) throws IOException { StopWatch tagWatch = stopWatch(); int tagCode = tag.attribute == null ? tag.tag : tag.attribute.getTag(); - out.writeShort((short) ((tagCode & 0xffff0000) >> 16)); - out.writeShort((short) (tagCode & 0xffff)); + output.writeShort((short) ((tagCode & 0xffff0000) >> 16)); + output.writeShort((short) (tagCode & 0xffff)); if (tag.vr == IMPLICIT) { - out.writeInt(getStoredLength(tag)); + output.writeInt(getStoredLength(tag)); } else { - boolean order = out.isLittleEndian(); - out.order(false); - out.writeShort(tag.vr.getCode()); - out.order(order); + boolean order = output.isLittleEndian(); + output.order(false); + output.writeShort(tag.vr.getCode()); + output.order(order); if (tag.vr == OB || tag.vr == OW || tag.vr == SQ || tag.vr == UN || tag.vr == UT || tag.vr == UC) { - out.writeShort((short) 0); - out.writeInt(getStoredLength(tag)); + output.writeShort((short) 0); + output.writeInt(getStoredLength(tag)); } else { - out.writeShort((short) getStoredLength(tag)); + output.writeShort((short) getStoredLength(tag)); } if (tag.attribute == TRANSFER_SYNTAX_UID) { - transferSyntaxPointer[getIndex(series, resolution)] = out.getFilePointer(); + transferSyntaxPointer[getIndex(series, resolution)] = output.getFilePointer(); } else if (tag.attribute == LOSSY_IMAGE_COMPRESSION_METHOD) { - compressionMethodPointer[getIndex(series, resolution)] = out.getFilePointer(); + compressionMethodPointer[getIndex(series, resolution)] = output.getFilePointer(); } else if (tag.attribute == FILE_META_INFO_GROUP_LENGTH) { - fileMetaLengthPointer = out.getFilePointer(); + fileMetaLengthPointer = output.getFilePointer(); } // sequences with no items still need to write a SequenceDelimitationItem below if (tag.children.size() == 0 && tag.value == null && tag.vr != SQ) { if (tag.attribute != PIXEL_DATA) { - out.skipBytes(tag.elementLength); + output.skipBytes(tag.elementLength); } return; } @@ -1574,27 +1579,27 @@ else if (tag.value != null) { } switch (tag.attribute) { case OPTICAL_PATH_ID: - planeOffsets[resolutionIndex][currentPlane].cOffset = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].cOffset = output.getFilePointer(); break; case ROW_POSITION_IN_MATRIX: - planeOffsets[resolutionIndex][currentPlane].yOffset = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].yOffset = output.getFilePointer(); break; case COLUMN_POSITION_IN_MATRIX: - planeOffsets[resolutionIndex][currentPlane].xOffset = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].xOffset = output.getFilePointer(); break; case DIMENSION_INDEX_VALUES: - planeOffsets[resolutionIndex][currentPlane].dimensionIndex = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].dimensionIndex = output.getFilePointer(); break; case X_OFFSET_IN_SLIDE: - planeOffsets[resolutionIndex][currentPlane].xOffsetReal = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].xOffsetReal = output.getFilePointer(); planeOffsets[resolutionIndex][currentPlane].xOffsetSize = tag.elementLength; break; case Y_OFFSET_IN_SLIDE: - planeOffsets[resolutionIndex][currentPlane].yOffsetReal = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].yOffsetReal = output.getFilePointer(); planeOffsets[resolutionIndex][currentPlane].yOffsetSize = tag.elementLength; break; case Z_OFFSET_IN_SLIDE: - planeOffsets[resolutionIndex][currentPlane].zOffset = out.getFilePointer(); + planeOffsets[resolutionIndex][currentPlane].zOffset = output.getFilePointer(); planeOffsets[resolutionIndex][currentPlane].zOffsetSize = tag.elementLength; break; } @@ -1617,53 +1622,53 @@ else if (tag.value != null) { case UI: case UR: case UT: - out.writeBytes(tag.value.toString()); + output.writeBytes(tag.value.toString()); break; case AT: for (short s : (short[]) tag.value) { - out.writeShort(s); + output.writeShort(s); } break; case FL: for (float f : (float[]) tag.value) { - out.writeFloat(f); + output.writeFloat(f); } break; case FD: for (double d : (double[]) tag.value) { - out.writeDouble(d); + output.writeDouble(d); } break; case OB: - out.write((byte[]) tag.value); + output.write((byte[]) tag.value); break; case SL: for (int v : (int[]) tag.value) { - out.writeInt(v); + output.writeInt(v); } break; case SS: for (short s : (short[]) tag.value) { - out.writeShort(s); + output.writeShort(s); } break; case SV: for (long v : (long[]) tag.value) { - out.writeLong(v); + output.writeLong(v); } break; case UL: for (long v : (long[]) tag.value) { - out.writeInt((int) (v & 0xffffffff)); + output.writeInt((int) (v & 0xffffffff)); } break; case US: for (short s : (short[]) tag.value) { - out.writeShort(s); + output.writeShort(s); } break; case IMPLICIT: - out.write((byte[]) tag.value); + output.write((byte[]) tag.value); break; default: throw new IllegalArgumentException(String.valueOf(tag.vr.getCode())); @@ -1784,78 +1789,86 @@ else if (r.getPixelsBinDataCount(pyramid) == 0) { */ private void writeHeader() throws IOException { StopWatch headerWatch = stopWatch(); + ByteArrayHandle buffer = new ByteArrayHandle(); + RandomAccessOutputStream headerBuffer = new RandomAccessOutputStream(buffer); boolean littleEndian = out.isLittleEndian(); + headerBuffer.order(littleEndian); if (writeDualPersonality()) { // write a TIFF header in the preamble if (littleEndian) { - out.writeByte(TiffConstants.LITTLE); - out.writeByte(TiffConstants.LITTLE); + headerBuffer.writeByte(TiffConstants.LITTLE); + headerBuffer.writeByte(TiffConstants.LITTLE); } else { - out.writeByte(TiffConstants.BIG); - out.writeByte(TiffConstants.BIG); + headerBuffer.writeByte(TiffConstants.BIG); + headerBuffer.writeByte(TiffConstants.BIG); } if (bigTiff) { - out.writeShort(TiffConstants.BIG_TIFF_MAGIC_NUMBER); - out.writeShort(8); // number of bytes in an offset - out.writeShort(0); // reserved + headerBuffer.writeShort(TiffConstants.BIG_TIFF_MAGIC_NUMBER); + headerBuffer.writeShort(8); // number of bytes in an offset + headerBuffer.writeShort(0); // reserved - nextIFDPointer[getIndex(series, resolution)] = out.getFilePointer(); - out.writeLong(-1); // placeholder to first IFD + nextIFDPointer[getIndex(series, resolution)] = headerBuffer.getFilePointer(); + headerBuffer.writeLong(-1); // placeholder to first IFD } else { - out.writeShort(TiffConstants.MAGIC_NUMBER); - nextIFDPointer[getIndex(series, resolution)] = out.getFilePointer(); - out.writeInt(-1); // placeholder to first IFD + headerBuffer.writeShort(TiffConstants.MAGIC_NUMBER); + nextIFDPointer[getIndex(series, resolution)] = headerBuffer.getFilePointer(); + headerBuffer.writeInt(-1); // placeholder to first IFD } } else { byte[] preamble = new byte[128]; - out.write(preamble); + headerBuffer.write(preamble); } // seek to end of preamble, then write DICOM header - out.seek(128); - out.order(true); - out.writeBytes("DICM"); + headerBuffer.seek(128); + headerBuffer.order(true); + headerBuffer.writeBytes("DICM"); DicomTag fileMetaLength = new DicomTag(FILE_META_INFO_GROUP_LENGTH, UL); // placeholder value, overwritten at the end of this method fileMetaLength.value = new long[] {0}; - writeTag(fileMetaLength); + writeTag(fileMetaLength, headerBuffer); DicomTag fileMetaVersion = new DicomTag(FILE_META_INFO_VERSION, OB); fileMetaVersion.value = new byte[] {0, 1}; - writeTag(fileMetaVersion); + writeTag(fileMetaVersion, headerBuffer); DicomTag mediaStorageClassUID = new DicomTag(MEDIA_SOP_CLASS_UID, UI); mediaStorageClassUID.value = padUID(SOP_CLASS_UID_VALUE); - writeTag(mediaStorageClassUID); + writeTag(mediaStorageClassUID, headerBuffer); DicomTag mediaStorageInstanceUID = new DicomTag(MEDIA_SOP_INSTANCE_UID, UI); mediaStorageInstanceUID.value = padUID(instanceUIDValue); - writeTag(mediaStorageInstanceUID); + writeTag(mediaStorageInstanceUID, headerBuffer); // placeholder, will be overwritten on the first call to saveBytes DicomTag transferSyntaxUID = new DicomTag(TRANSFER_SYNTAX_UID, UI); transferSyntaxUID.elementLength = 22; - writeTag(transferSyntaxUID); + writeTag(transferSyntaxUID, headerBuffer); DicomTag implementationClassUID = new DicomTag(IMPLEMENTATION_UID, UI); implementationClassUID.value = padUID(implementationUID); - writeTag(implementationClassUID); + writeTag(implementationClassUID, headerBuffer); DicomTag implementationVersionName = new DicomTag(IMPLEMENTATION_VERSION, SH); implementationVersionName.value = padString(FormatTools.VERSION); - writeTag(implementationVersionName); + writeTag(implementationVersionName, headerBuffer); + + int bufferBytes = (int) headerBuffer.getFilePointer(); + out.order(headerBuffer.isLittleEndian()); + headerBuffer.close(); + out.write(buffer.getBytes(), 0, bufferBytes); // count all bytes after the file meta length value int fileMetaBytes = (int) (out.getFilePointer() - fileMetaLengthPointer - 4); out.seek(fileMetaLengthPointer); out.writeInt(fileMetaBytes); fileMetaLengthPointer = 0; - out.skipBytes(fileMetaBytes); + out.skipBytes(fileMetaBytes); out.order(littleEndian); headerWatch.stop("wrote header for series = " + series + ", resolution = " + resolution); } From acd37a192a34a8e9a69be732c02cebbd305ada6f Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 18 Mar 2024 09:20:47 -0500 Subject: [PATCH 011/100] DICOM reader: better handling of nested sequences that include pixel data Fixes #4165. --- .../src/loci/formats/dicom/DicomTag.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/dicom/DicomTag.java b/components/formats-bsd/src/loci/formats/dicom/DicomTag.java index 8e5a868c0ad..3648c01ea57 100644 --- a/components/formats-bsd/src/loci/formats/dicom/DicomTag.java +++ b/components/formats-bsd/src/loci/formats/dicom/DicomTag.java @@ -310,15 +310,33 @@ else if (elementLength <= 44) { break; } else if (child.attribute == PIXEL_DATA) { - stop = fp; - break; + child.parent = this; + children.add(child); + if (child.elementLength == -1) { + // look for end of sequence + long seek = fp - 2; + int nextTag = 0; + while (seek < in.length() && (nextTag != SEQUENCE_DELIMITATION_ITEM.getTag() && nextTag != ITEM_DELIMITATION_ITEM.getTag())) { + seek += 2; + in.seek(seek); + try { + nextTag = getNextTag(in); + } + catch (Exception e) { + } + if (nextTag == 0xfeffdde0 || nextTag == 0xfeff0d0e) { + in.order(!in.isLittleEndian()); + break; + } + } + } } else if (child.attribute != ITEM && child.attribute != ITEM_DELIMITATION_ITEM) { child.parent = this; children.add(child); } } - if (elementLength == 0) { + if (elementLength <= 0) { elementLength = (int) (stop - start); } in.seek(stop); @@ -438,6 +456,7 @@ private int getLength(RandomAccessInputStream in) throws IOException { switch (vr) { case OB: + case OV: case OW: case SQ: case UN: From 4ea1fce3d7549125f1568f36d43a7341fd8160a8 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Sun, 24 Mar 2024 14:56:30 -0500 Subject: [PATCH 012/100] A few improvements to initialization and tile read time --- .../src/loci/formats/in/DicomReader.java | 333 ++++++++++-------- 1 file changed, 183 insertions(+), 150 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/in/DicomReader.java b/components/formats-bsd/src/loci/formats/in/DicomReader.java index c5916a6c3f4..5ea3bf935c9 100644 --- a/components/formats-bsd/src/loci/formats/in/DicomReader.java +++ b/components/formats-bsd/src/loci/formats/in/DicomReader.java @@ -129,6 +129,9 @@ public class DicomReader extends SubResolutionFormatReader { private List tags; + private transient String currentTileFile = null; + private transient RandomAccessInputStream currentTileStream = null; + // -- Constructor -- /** Constructs a new DICOM reader. */ @@ -295,7 +298,7 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) List tiles = tilePositions.get(getCoreIndex()); watch.stop("openBytes setup, w=" + w + ", h=" + h); watch.start(); - // TODO: stop tile scan as soon as whole requested area is read? + for (int t=0; t= stream.length()) { - LOGGER.error("attempted to read beyond end of file ({}, {})", tile.fileOffset, tile.file); - return; - } - LOGGER.debug("reading from offset = {}, file = {}", tile.fileOffset, tile.file); - stream.seek(tile.fileOffset); - if (tile.isRLE) { - // plane is compressed using run-length encoding - CodecOptions options = new CodecOptions(); - options.maxBytes = tile.region.width * tile.region.height; - for (int c=0; c 1) { - int plane = bytes / (bpp * ec); - byte[][] tmp = new byte[bpp][]; - long start = stream.getFilePointer(); - for (int i=0; i= stream.length()) { + LOGGER.error("attempted to read beyond end of file ({}, {})", tile.fileOffset, tile.file); + return; + } + LOGGER.debug("reading from offset = {}, file = {}", tile.fileOffset, tile.file); + stream.seek(tile.fileOffset); + + if (tile.isRLE) { + // plane is compressed using run-length encoding + CodecOptions options = new CodecOptions(); + options.maxBytes = tile.region.width * tile.region.height; + for (int c=0; c 1) { + int plane = bytes / (bpp * ec); + byte[][] tmp = new byte[bpp][]; + long start = stream.getFilePointer(); + for (int i=0; i 0 && tmp[i].length > options.maxBytes) { + stream.seek(start); tmp[i] = codec.decompress(stream, options); - if (i > 0 && tmp[i].length > options.maxBytes) { - stream.seek(start); - tmp[i] = codec.decompress(stream, options); - } - if (!tile.last || i < bpp - 1) { - start = stream.getFilePointer(); - while (stream.read() == 0); - long end = stream.getFilePointer(); - stream.seek(end - 1); - } } - t = new byte[bytes / ec]; - for (int i=0; i= 0 && (b[pt] != (byte) 0xff || b[pt + 1] != (byte) 0xd9)) { - pt--; - } - if (pt < 0) { - byte[] tmp = b; - b = new byte[tmp.length + 2]; - System.arraycopy(tmp, 0, b, 0, tmp.length); - b[b.length - 2] = (byte) 0xff; - b[b.length - 1] = (byte) 0xd9; - } - else if (pt < b.length - 2) { - byte[] tmp = b; - b = new byte[pt + 2]; - System.arraycopy(tmp, 0, b, 0, b.length); - } + int pt = b.length - 2; + while (pt >= 0 && (b[pt] != (byte) 0xff || b[pt + 1] != (byte) 0xd9)) { + pt--; + } + if (pt < 0) { + byte[] tmp = b; + b = new byte[tmp.length + 2]; + System.arraycopy(tmp, 0, b, 0, tmp.length); + b[b.length - 2] = (byte) 0xff; + b[b.length - 1] = (byte) 0xd9; + } + else if (pt < b.length - 2) { + byte[] tmp = b; + b = new byte[pt + 2]; + System.arraycopy(tmp, 0, b, 0, b.length); + } - Codec codec = null; - CodecOptions options = new CodecOptions(); - options.littleEndian = isLittleEndian(); - options.interleaved = isInterleaved(); - if (tile.isJPEG) codec = new JPEGCodec(); - else codec = new JPEG2000Codec(); + Codec codec = null; + CodecOptions options = new CodecOptions(); + options.littleEndian = isLittleEndian(); + options.interleaved = isInterleaved(); + if (tile.isJPEG) codec = new JPEGCodec(); + else codec = new JPEG2000Codec(); - try { - b = codec.decompress(b, options); - } - catch (NullPointerException e) { - LOGGER.debug("Could not read empty or invalid tile", e); - return; - } - finally { - jpegWatch.stop("decompressed (jpeg = " + tile.isJPEG + ")"); - } - jpegWatch.start(); + try { + b = codec.decompress(b, options); + } + catch (NullPointerException e) { + LOGGER.debug("Could not read empty or invalid tile", e); + return; + } + finally { + jpegWatch.stop("decompressed (jpeg = " + tile.isJPEG + ")"); + } + jpegWatch.start(); - int rowLen = w * bpp; - int srcRowLen = tile.region.width * bpp; + int rowLen = w * bpp; + int srcRowLen = tile.region.width * bpp; - if (isInterleaved()) { - rowLen *= ec; - srcRowLen *= ec; - for (int row=0; row currentTilePositions = tilePositions.get(getCoreIndex()); + long offset = baseOffset; + int bufferSize = 4096; for (int i=0; i 0) { - tilePositions.get(getCoreIndex()).get(i - 1).endOffset = tilePositions.get(getCoreIndex()).get(i).fileOffset; + currentTilePositions.get(i - 1).endOffset = currentTile.fileOffset; } if (i == imagesPerFile - 1) { - tilePositions.get(getCoreIndex()).get(i).endOffset = in.length(); + currentTile.endOffset = in.length(); } if (!zOffsets.containsKey(getCoreIndex())) { zOffsets.put(getCoreIndex(), new ArrayList()); } - Double z = tilePositions.get(getCoreIndex()).get(i).zOffset; + Double z = currentTile.zOffset; if (!zOffsets.get(getCoreIndex()).contains(z)) { zOffsets.get(getCoreIndex()).add(z); } - offsetWatch.stop("calculated offset #" + i); } } @@ -1888,6 +1917,10 @@ private DicomFileInfo createFileInfo(String file) throws FormatException, IOExce return new DicomFileInfo(new Location(file).getAbsolutePath()); } + private boolean encloses(Region a, Region b) { + return a.intersection(b).equals(b); + } + private void updateCoreMetadata(CoreMetadata ms) { if (ms.sizeC == 0) ms.sizeC = 1; ms.sizeT = 1; From 303b3d58caf0b91afb8954c61565c8715e2b3b8f Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 25 Mar 2024 16:44:07 -0500 Subject: [PATCH 013/100] Add `-quality` option to bfconvert This primarily affects JPEG compression with TIFF, OME-TIFF, and DICOM output. Fixes #3370. --- .../loci/formats/tools/ImageConverter.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 8f1c3816929..26676cdac5d 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -70,6 +70,7 @@ import loci.formats.MetadataTools; import loci.formats.MinMaxCalculator; import loci.formats.MissingLibraryException; +import loci.formats.codec.CodecOptions; import loci.formats.gui.Index16ColorModel; import loci.formats.in.DynamicMetadataOptions; import loci.formats.meta.IMetadata; @@ -133,6 +134,8 @@ public final class ImageConverter { private boolean precompressed = false; private boolean tryPrecompressed = false; + private Double compressionQuality = null; + private String extraMetadata = null; private IFormatReader reader; @@ -273,6 +276,9 @@ else if (args[i].equals("-fill")) { else if (args[i].equals("-extra-metadata")) { extraMetadata = args[++i]; } + else if (args[i].equals("-quality")) { + compressionQuality = DataTools.parseDouble(args[++i]); + } else if (!args[i].equals(CommandLineTools.NO_UPGRADE_CHECK)) { LOGGER.error("Found unknown command flag: {}; exiting.", args[i]); return false; @@ -349,7 +355,7 @@ private void printUsage() { " [-option key value] [-novalid] [-validate] [-tilex tileSizeX]", " [-tiley tileSizeY] [-pyramid-scale scale]", " [-swap dimensionsOrderString] [-fill color]", - " [-precompressed]", + " [-precompressed] [-quality compressionQuality]", " [-pyramid-resolutions numResolutionLevels] in_file out_file", "", " -version: print the library version and exit", @@ -398,6 +404,7 @@ private void printUsage() { " Most input and output formats do not support this option.", " Do not use -crop, -fill, or -autoscale, or pyramid generation options", " with this option.", + " -quality: double quality value for JPEG compression (0-1)", "", "The extension of the output file specifies the file format to use", "for the conversion. The list of available formats and extensions is:", @@ -774,6 +781,7 @@ else if (saveTileWidth > 0 && saveTileHeight > 0) { if (!ok) { return false; } + setCodecOptions(writer); writer.setId(outputName); if (compression != null) writer.setCompression(compression); } @@ -793,6 +801,7 @@ else if (saveTileWidth > 0 && saveTileHeight > 0) { if (!ok) { return false; } + setCodecOptions(writer); writer.setId(tileName); if (compression != null) writer.setCompression(compression); } @@ -995,6 +1004,7 @@ private long convertTilePlane(IFormatWriter writer, int index, int outputIndex, writer.setMetadataRetrieve(retrieve); overwriteCheck(tileName, true); + setCodecOptions(writer); writer.setId(tileName); if (compression != null) writer.setCompression(compression); @@ -1267,6 +1277,14 @@ private boolean overwriteCheck(String path, boolean throwOnExist) throws IOExcep return true; } + private void setCodecOptions(IFormatWriter writer) { + if (compressionQuality != null) { + CodecOptions codecOptions = CodecOptions.getDefaultOptions(); + codecOptions.quality = compressionQuality; + writer.setCodecOptions(codecOptions); + } + } + // -- Main method -- public static void main(String[] args) throws FormatException, IOException { From f0141496c3af623168a95f2ce7733ebf4d1297bf Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 25 Mar 2024 16:45:15 -0500 Subject: [PATCH 014/100] DICOM: copy provided codec options when recompressing In particular, this will make use of any provided quality value. --- components/formats-bsd/src/loci/formats/out/DicomWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index b3f25f64dd4..d0061983812 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -532,7 +532,7 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || } else { Codec codec = getCodec(); - CodecOptions options = new CodecOptions(); + CodecOptions options = new CodecOptions(getCodecOptions()); options.width = tileWidth[resolutionIndex]; options.height = tileHeight[resolutionIndex]; options.channels = getSamplesPerPixel(); From 55d48a77dbe594a7b0ef56eb3b07d2dc8e8bcb75 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 26 Mar 2024 14:00:15 -0500 Subject: [PATCH 015/100] bfconvert: remove extra channels if `-channel` was used Fixes #4149. --- .../loci/formats/tools/ImageConverter.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 8f1c3816929..a35b11752c3 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -41,6 +41,7 @@ import java.io.IOException; import java.util.Iterator; import java.util.HashMap; +import java.util.List; import java.util.TreeMap; import java.util.SortedMap; @@ -84,6 +85,7 @@ import loci.formats.services.OMEXMLServiceImpl; import ome.xml.meta.OMEXMLMetadataRoot; +import ome.xml.model.Channel; import ome.xml.model.Image; import ome.xml.model.Pixels; import ome.xml.model.enums.PixelType; @@ -591,11 +593,22 @@ public boolean testConvert(IFormatWriter writer, String[] args) String xml = service.getOMEXML(service.asRetrieve(store)); OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) store.getRoot(); IMetadata meta = service.createOMEXMLMetadata(xml); + OMEXMLMetadataRoot newRoot = (OMEXMLMetadataRoot) meta.getRoot(); if (series >= 0) { - Image exportImage = new Image(root.getImage(series)); - Pixels exportPixels = new Pixels(root.getImage(series).getPixels()); + Image exportImage = newRoot.getImage(series); + Pixels exportPixels = newRoot.getImage(series).getPixels(); + + if (channel >= 0) { + List channels = exportPixels.copyChannelList(); + + for (int c=0; c 0) { newRoot.removeImage(newRoot.getImage(0)); } @@ -639,6 +652,17 @@ public boolean testConvert(IFormatWriter writer, String[] args) store.setPixelsType(PixelType.UINT8, i); } + if (channel >= 0) { + Pixels exportPixels = newRoot.getImage(i).getPixels(); + List channels = exportPixels.copyChannelList(); + + for (int c=0; c= 0) { meta.setPixelsSizeC(new PositiveInteger(1), i); } From f7de0519cd394a97f242867e6f8634eb45577e68 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Fri, 29 Mar 2024 10:42:03 -0500 Subject: [PATCH 016/100] Fix CodecOptions construction so that JPEG2000 quality can be set --- .../src/loci/formats/tools/ImageConverter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 26676cdac5d..f3980a81ff4 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -71,6 +71,7 @@ import loci.formats.MinMaxCalculator; import loci.formats.MissingLibraryException; import loci.formats.codec.CodecOptions; +import loci.formats.codec.JPEG2000CodecOptions; import loci.formats.gui.Index16ColorModel; import loci.formats.in.DynamicMetadataOptions; import loci.formats.meta.IMetadata; @@ -1279,7 +1280,7 @@ private boolean overwriteCheck(String path, boolean throwOnExist) throws IOExcep private void setCodecOptions(IFormatWriter writer) { if (compressionQuality != null) { - CodecOptions codecOptions = CodecOptions.getDefaultOptions(); + CodecOptions codecOptions = JPEG2000CodecOptions.getDefaultOptions(); codecOptions.quality = compressionQuality; writer.setCodecOptions(codecOptions); } From daaa2f91e742e45773d3f5a0748ad90109996e80 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 1 Apr 2024 16:42:03 -0500 Subject: [PATCH 017/100] Exclude private content sequences from the original metadata table The `getTags()` method still includes these sequences, but this just keeps the original metadata table a little easier to read. Private content sequences are detected by looking for a private content creator, then excluding any sequences with a matching high word. This corresponds to https://dicom.nema.org/dicom/2013/output/chtml/part05/sect_7.8.html --- .../formats-bsd/src/loci/formats/dicom/DicomTag.java | 11 +++++++++++ .../formats-bsd/src/loci/formats/in/DicomReader.java | 12 +++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/dicom/DicomTag.java b/components/formats-bsd/src/loci/formats/dicom/DicomTag.java index 3648c01ea57..b40cefedf8c 100644 --- a/components/formats-bsd/src/loci/formats/dicom/DicomTag.java +++ b/components/formats-bsd/src/loci/formats/dicom/DicomTag.java @@ -719,6 +719,17 @@ else if (!(value instanceof long[])) { } } + /** + * See https://dicom.nema.org/dicom/2013/output/chtml/part05/sect_7.8.html + * + * @return true if this is a private content creator tag + */ + public boolean isPrivateContentCreator() { + int highWord = (tag >> 16) & 0xffff; + int lowWord = tag & 0xffff; + return highWord % 2 == 1 && lowWord == 0x0010; + } + @Override public String toString() { if (key == null) { diff --git a/components/formats-bsd/src/loci/formats/in/DicomReader.java b/components/formats-bsd/src/loci/formats/in/DicomReader.java index aba35119fd4..4b6c9afeb24 100644 --- a/components/formats-bsd/src/loci/formats/in/DicomReader.java +++ b/components/formats-bsd/src/loci/formats/in/DicomReader.java @@ -37,9 +37,11 @@ import java.util.ArrayList; import java.util.Arrays; 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 com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; @@ -127,6 +129,8 @@ public class DicomReader extends SubResolutionFormatReader { private List tags; + private Set privateContentHighWords = new HashSet(); + // -- Constructor -- /** Constructs a new DICOM reader. */ @@ -368,6 +372,7 @@ public void close(boolean fileOnly) throws IOException { concatenationNumber = null; edf = false; tags = null; + privateContentHighWords.clear(); } } @@ -1168,6 +1173,10 @@ else if (infoString.startsWith("MONOCHROME")) { * rely upon the original metadata table. */ private void addOriginalMetadata(String key, DicomTag info) { + if (info.isPrivateContentCreator()) { + privateContentHighWords.add(info.tag >> 16); + } + if (info.value != null && !(info.value instanceof byte[]) && !(info.value instanceof short[])) { @@ -1179,7 +1188,8 @@ private void addOriginalMetadata(String key, DicomTag info) { } } if (info.attribute != PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE && - info.attribute != REFERENCED_IMAGE_NAVIGATION_SEQUENCE) + info.attribute != REFERENCED_IMAGE_NAVIGATION_SEQUENCE && + !privateContentHighWords.contains(info.tag >> 16)) { for (DicomTag child : info.children) { String childKey = DicomAttribute.formatTag(child.tag); From c1c59a02ec95b8ebcca08f4fafe6874116f2b472 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 4 Apr 2024 16:15:07 -0500 Subject: [PATCH 018/100] Update JPEGTurboService to return compressed tiles, tile dimensions --- .../formats/services/JPEGTurboService.java | 71 ++++++++++++++++++- .../services/JPEGTurboServiceImpl.java | 64 ++++++++++++----- 2 files changed, 115 insertions(+), 20 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java b/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java index 85570cbaf2c..9ecc8b9c9e9 100644 --- a/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java +++ b/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java @@ -44,21 +44,90 @@ */ public interface JPEGTurboService extends Service { + /** + * @return the restart markers associated with the current JPEG stream + */ long[] getRestartMarkers(); + /** + * @param markers precalculated restart markers associated with + * the current JPEG stream + */ void setRestartMarkers(long[] markers); + /** + * Initialize the given stream, which represents an image of the given + * width and height. This service is primarily intended for very large + * JPEG images whose width and/or height exceed 65535 (the maximum + * that can be recorded in a JPEG stream). + * + * @param jpeg open stream containing JPEG data + * @param width total image width + * @param height total image height + */ void initialize(RandomAccessInputStream jpeg, int width, int height) throws ServiceException, IOException; + /** + * @return the width (in pixels) of a tile + */ + int getTileWidth(); + + /** + * @return the height (in pixels) of a tile + */ + int getTileHeight(); + + /** + * @return the number of rows of tiles + */ + int getTileRows(); + + /** + * @return the number of columns of tiles + */ + int getTileColumns(); + + /** + * Get the uncompressed bytes representing the given bounding box. + * + * @param buf array in which to store uncompressed bytes + * @param xCoordinate upper-left X coordinate of bounding box + * @param yCoordinate upper-left Y coordinate of bounding box + * @param width width of bounding box + * @param height height of bounding box + * @return uncompressed bytes + */ byte[] getTile(byte[] buf, int xCoordinate, int yCoordinate, int width, int height) throws IOException; + /** + * Get the uncompressed bytes representing the given tile index. + * + * @param xTile column index of the tile + * @param yTile row index of the tile + * @return uncompressed bytes + */ byte[] getTile(int xTile, int yTile) throws IOException; + /** + * Similar to getTile(int, int), but returns the JPEG-compressed bytes. + * + * @param xTile column index of the tile + * @param yTile row index of the tile + * @return JPEG-compressed bytes + */ + byte[] getCompressedTile(int xTile, int yTile) throws IOException; + + /** + * Free resources associated with the initialized stream. + */ void close() throws IOException; - + + /** + * @return true if the underlying native library was successfully loaded + */ boolean isLibraryLoaded(); } diff --git a/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java b/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java index cfe316b1513..2e79544413b 100644 --- a/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java +++ b/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java @@ -229,6 +229,26 @@ else if (marker == SOS) { } } + @Override + public int getTileWidth() { + return tileWidth; + } + + @Override + public int getTileHeight() { + return tileHeight; + } + + @Override + public int getTileRows() { + return yTiles; + } + + @Override + public int getTileColumns() { + return xTiles; + } + @Override public byte[] getTile(byte[] buf, int xCoordinate, int yCoordinate, int width, int height) @@ -287,6 +307,30 @@ public byte[] getTile(byte[] buf, int xCoordinate, int yCoordinate, @Override public byte[] getTile(int tileX, int tileY) throws IOException { + byte[] compressedData = getCompressedTile(tileX, tileY); + + // and here we actually decompress it... + + try { + int pixelType = TJ.PF_RGB; + int pixelSize = TJ.getPixelSize(pixelType); + + TJDecompressor decoder = new TJDecompressor(compressedData); + byte[] decompressed = decoder.decompress(tileWidth, tileWidth * pixelSize, + tileHeight, pixelType, pixelType); + compressedData = null; + decoder.close(); + return decompressed; + } + catch (Exception e) { + IOException ioe = new IOException(e.getMessage()); + ioe.initCause(e); + throw ioe; + } + } + + @Override + public byte[] getCompressedTile(int tileX, int tileY) throws IOException { if (header == null) { header = getFixedHeader(); } @@ -343,25 +387,7 @@ public byte[] getTile(int tileX, int tileY) throws IOException { } DataTools.unpackBytes(EOI, data, offset, 2, false); - - // and here we actually decompress it... - - try { - int pixelType = TJ.PF_RGB; - int pixelSize = TJ.getPixelSize(pixelType); - - TJDecompressor decoder = new TJDecompressor(data); - byte[] decompressed = decoder.decompress(tileWidth, tileWidth * pixelSize, - tileHeight, pixelType, pixelType); - data = null; - decoder.close(); - return decompressed; - } - catch (Exception e) { - IOException ioe = new IOException(e.getMessage()); - ioe.initCause(e); - throw ioe; - } + return data; } @Override From ea14b8e4627a441481013ea4d0f953906269c159 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 4 Apr 2024 16:55:02 -0500 Subject: [PATCH 019/100] Fix some Java 9+ warnings in formats-bsd --- .../src/loci/formats/FilePattern.java | 4 +- .../src/loci/formats/ImageTools.java | 12 +++--- .../src/loci/formats/MinMaxCalculator.java | 12 +++--- .../src/loci/formats/gui/CacheComponent.java | 2 +- .../src/loci/formats/gui/DataConverter.java | 2 +- .../src/loci/formats/in/AVIReader.java | 8 ++-- .../src/loci/formats/in/BaseTiffReader.java | 14 +++---- .../src/loci/formats/in/FakeReader.java | 12 +++--- .../src/loci/formats/in/ICSReader.java | 37 ++++++++++--------- .../loci/formats/in/MicromanagerReader.java | 4 +- .../src/loci/formats/in/OBFReader.java | 10 ++--- .../src/loci/formats/in/QTReader.java | 8 ++-- .../src/loci/formats/in/SlideBook7Reader.java | 2 +- .../src/loci/formats/out/AVIWriter.java | 6 +-- .../src/loci/formats/out/TiffWriter.java | 14 +++---- 15 files changed, 74 insertions(+), 73 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/FilePattern.java b/components/formats-bsd/src/loci/formats/FilePattern.java index d831dbf9a8b..1bc9f12349e 100644 --- a/components/formats-bsd/src/loci/formats/FilePattern.java +++ b/components/formats-bsd/src/loci/formats/FilePattern.java @@ -162,13 +162,13 @@ public FilePattern(String pattern) { while (true) { left = pattern.indexOf(FilePatternBlock.BLOCK_START, left + 1); if (left < 0) break; - lt.add(new Integer(left)); + lt.add(left); } int right = -1; while (true) { right = pattern.indexOf(FilePatternBlock.BLOCK_END, right + 1); if (right < 0) break; - gt.add(new Integer(right)); + gt.add(right); } // assemble numerical block indices diff --git a/components/formats-bsd/src/loci/formats/ImageTools.java b/components/formats-bsd/src/loci/formats/ImageTools.java index 70f488f5dc9..f15bb1c70d2 100644 --- a/components/formats-bsd/src/loci/formats/ImageTools.java +++ b/components/formats-bsd/src/loci/formats/ImageTools.java @@ -118,7 +118,7 @@ public static int[] make24Bits(Object pixels, int w, int h, if (pixels instanceof byte[]) b = (byte[]) pixels; else if (pixels instanceof short[]) { - if (max == null) max = new Double(0xffff); + if (max == null) max = Double.valueOf(0xffff); double range = max.doubleValue() - min.doubleValue(); double mult = newRange / range; @@ -129,7 +129,7 @@ else if (pixels instanceof short[]) { } } else if (pixels instanceof int[]) { - if (max == null) max = new Double(0xffffffffL); + if (max == null) max = Double.valueOf(0xffffffffL); double range = max.doubleValue() - min.doubleValue(); double mult = newRange / range; @@ -140,7 +140,7 @@ else if (pixels instanceof int[]) { } } else if (pixels instanceof float[]) { - if (max == null) max = new Double(Float.MAX_VALUE); + if (max == null) max = Double.valueOf(Float.MAX_VALUE); double range = max.doubleValue() - min.doubleValue(); double mult = newRange / range; @@ -151,7 +151,7 @@ else if (pixels instanceof float[]) { } } else if (pixels instanceof double[]) { - if (max == null) max = new Double(Double.MAX_VALUE); + if (max == null) max = Double.MAX_VALUE; double range = max.doubleValue() - min.doubleValue(); double mult = newRange / range; @@ -517,8 +517,8 @@ else if (bits == 32) { } Double[] rtn = new Double[2]; - rtn[0] = new Double(min); - rtn[1] = new Double(max); + rtn[0] = Double.valueOf(min); + rtn[1] = Double.valueOf(max); return rtn; } diff --git a/components/formats-bsd/src/loci/formats/MinMaxCalculator.java b/components/formats-bsd/src/loci/formats/MinMaxCalculator.java index 6cabd84fa8a..57c88324b6c 100644 --- a/components/formats-bsd/src/loci/formats/MinMaxCalculator.java +++ b/components/formats-bsd/src/loci/formats/MinMaxCalculator.java @@ -119,7 +119,7 @@ public Double getChannelGlobalMinimum(int theC) if (minMaxDone == null || minMaxDone[series] < getImageCount()) { return null; } - return new Double(chanMin[series][theC]); + return chanMin[series][theC]; } /** @@ -141,7 +141,7 @@ public Double getChannelGlobalMaximum(int theC) if (minMaxDone == null || minMaxDone[series] < getImageCount()) { return null; } - return new Double(chanMax[series][theC]); + return chanMax[series][theC]; } /** @@ -155,7 +155,7 @@ public Double getChannelKnownMinimum(int theC) throws FormatException, IOException { FormatTools.assertId(getCurrentFile(), true, 2); - return chanMin == null ? null : new Double(chanMin[getCoreIndex()][theC]); + return chanMin == null ? null : chanMin[getCoreIndex()][theC]; } /** @@ -169,7 +169,7 @@ public Double getChannelKnownMaximum(int theC) throws FormatException, IOException { FormatTools.assertId(getCurrentFile(), true, 2); - return chanMax == null ? null : new Double(chanMax[getCoreIndex()][theC]); + return chanMax == null ? null : chanMax[getCoreIndex()][theC]; } /** @@ -192,7 +192,7 @@ public Double[] getPlaneMinimum(int no) throws FormatException, IOException { Double[] min = new Double[numRGB]; for (int c=0; c 0 || bmpCompression != 0) { - offsets.add(new Long(in.getFilePointer())); - lengths.add(new Long(size)); + offsets.add(in.getFilePointer()); + lengths.add(Long.valueOf(size)); in.skipBytes(size); } } @@ -878,9 +878,9 @@ else if (type.length() < 4 || type.endsWith("JUN")) { offsets.add(offsets.get(offsets.size() - 1)); } else if (chunkSize > 0 || offsets.size() > 0) { - offsets.add(new Long(useSOM ? startOfMovi + offset : offset)); + offsets.add(Long.valueOf(useSOM ? startOfMovi + offset : offset)); } - lengths.add(new Long(chunkSize)); + lengths.add(Long.valueOf(chunkSize)); } } } diff --git a/components/formats-bsd/src/loci/formats/in/BaseTiffReader.java b/components/formats-bsd/src/loci/formats/in/BaseTiffReader.java index a2de3c8412d..0900e921c26 100644 --- a/components/formats-bsd/src/loci/formats/in/BaseTiffReader.java +++ b/components/formats-bsd/src/loci/formats/in/BaseTiffReader.java @@ -566,14 +566,14 @@ protected void put(String key, int value) { } protected void put(String key, boolean value) { - put(key, new Boolean(value)); + put(key, Boolean.valueOf(value)); } - protected void put(String key, byte value) { put(key, new Byte(value)); } - protected void put(String key, char value) { put(key, new Character(value)); } - protected void put(String key, double value) { put(key, new Double(value)); } - protected void put(String key, float value) { put(key, new Float(value)); } - protected void put(String key, long value) { put(key, new Long(value)); } - protected void put(String key, short value) { put(key, new Short(value)); } + protected void put(String key, byte value) { put(key, Byte.valueOf(value)); } + protected void put(String key, char value) { put(key, Character.valueOf(value)); } + protected void put(String key, double value) { put(key, Double.valueOf(value)); } + protected void put(String key, float value) { put(key, Float.valueOf(value)); } + protected void put(String key, long value) { put(key, Long.valueOf(value)); } + protected void put(String key, short value) { put(key, Short.valueOf(value)); } protected void put(String key, IFD ifd, int tag) { put(key, ifd.getIFDValue(tag)); diff --git a/components/formats-bsd/src/loci/formats/in/FakeReader.java b/components/formats-bsd/src/loci/formats/in/FakeReader.java index 75cb10d3eb4..3bb0b95af11 100644 --- a/components/formats-bsd/src/loci/formats/in/FakeReader.java +++ b/components/formats-bsd/src/loci/formats/in/FakeReader.java @@ -1079,11 +1079,11 @@ private void fillAnnotations(MetadataStore store, int imageIndex) { } private Double getX(int i) { - return new Double(ROI_SPACING * i % sizeX); + return (double) (ROI_SPACING * i % sizeX); } private Double getY(int i) { - return new Double(ROI_SPACING * ((int) ROI_SPACING * i / sizeX) % sizeY); + return (double) (ROI_SPACING * ((int) ROI_SPACING * i / sizeX) % sizeY); } private String getPoints(int i) { @@ -1111,8 +1111,8 @@ private void fillRegions(MetadataStore store, int imageIndex) { store.setEllipseID(SHAPE_PREFIX + roiCount, roiCount, 0); store.setEllipseX(getX(i) + ROI_SPACING / 2, roiCount, 0); store.setEllipseY(getY(i) + ROI_SPACING / 2, roiCount, 0); - store.setEllipseRadiusX(new Double(ROI_SPACING / 2), roiCount, 0); - store.setEllipseRadiusY(new Double(ROI_SPACING / 2), roiCount, 0); + store.setEllipseRadiusX(Double.valueOf(ROI_SPACING / 2), roiCount, 0); + store.setEllipseRadiusY(Double.valueOf(ROI_SPACING / 2), roiCount, 0); store.setImageROIRef(roiID, imageIndex, roiRefCount); roiCount++; roiRefCount++; @@ -1198,8 +1198,8 @@ private void fillRegions(MetadataStore store, int imageIndex) { store.setRectangleID(SHAPE_PREFIX + roiCount, roiCount, 0); store.setRectangleX(getX(i) + ROI_SPACING / 4, roiCount, 0); store.setRectangleY(getY(i) + ROI_SPACING / 4, roiCount, 0); - store.setRectangleWidth(new Double(ROI_SPACING / 2), roiCount, 0); - store.setRectangleHeight(new Double(ROI_SPACING / 2), roiCount, 0); + store.setRectangleWidth(Double.valueOf(ROI_SPACING / 2), roiCount, 0); + store.setRectangleHeight(Double.valueOf(ROI_SPACING / 2), roiCount, 0); store.setImageROIRef(roiID, imageIndex, roiRefCount); roiCount++; roiRefCount++; diff --git a/components/formats-bsd/src/loci/formats/in/ICSReader.java b/components/formats-bsd/src/loci/formats/in/ICSReader.java index 0513eac024e..d928709484f 100644 --- a/components/formats-bsd/src/loci/formats/in/ICSReader.java +++ b/components/formats-bsd/src/loci/formats/in/ICSReader.java @@ -43,6 +43,7 @@ import java.util.Vector; import java.util.zip.GZIPInputStream; +import loci.common.DataTools; import loci.common.DateTools; import loci.common.Location; import loci.common.RandomAccessInputStream; @@ -950,7 +951,7 @@ else if (key.equalsIgnoreCase("parameter units")) { if (key.equalsIgnoreCase("parameter ch")) { String[] names = value.split(" "); for (int n=0; n 1; if (getDimensionOrder().indexOf('C') == -1) { @@ -1919,7 +1920,7 @@ private Double[] splitDoubles(String v) { for (int n=0; n 0) { - major = new Integer(version[0]); + major = Integer.parseInt(version[0]); } } catch (NumberFormatException e) { diff --git a/components/formats-bsd/src/loci/formats/in/OBFReader.java b/components/formats-bsd/src/loci/formats/in/OBFReader.java index a5d4ec6447c..4b03f354174 100644 --- a/components/formats-bsd/src/loci/formats/in/OBFReader.java +++ b/components/formats-bsd/src/loci/formats/in/OBFReader.java @@ -357,7 +357,7 @@ private long initStack(long current) throws FormatException, IOException { for (int dimension = 0; dimension != MAXIMAL_NUMBER_OF_DIMENSIONS; ++ dimension) { final double length = in.readDouble(); if (dimension < numberOfDimensions) { - lengths.add(new Double(length)); + lengths.add(length); } } meta_data.seriesMetadata.put("Lengths", lengths); @@ -366,7 +366,7 @@ private long initStack(long current) throws FormatException, IOException { for (int dimension = 0; dimension != MAXIMAL_NUMBER_OF_DIMENSIONS; ++ dimension) { final double offset = in.readDouble(); if (dimension < numberOfDimensions) { - offsets.add(new Double(offset)); + offsets.add(offset); } } meta_data.seriesMetadata.put("Offsets", offsets); @@ -462,14 +462,14 @@ private long initStack(long current) throws FormatException, IOException { for (int dimension = 0; dimension != MAXIMAL_NUMBER_OF_DIMENSIONS; ++ dimension) { final int present = in.readInt(); if (dimension < numberOfDimensions) { - stepsPresent.add(new Boolean(present != 0)); + stepsPresent.add(present != 0); } } List stepLabelsPresent = new ArrayList(); for (int dimension = 0; dimension != MAXIMAL_NUMBER_OF_DIMENSIONS; ++ dimension) { final int present = in.readInt(); if (dimension < numberOfDimensions) { - stepLabelsPresent.add(new Boolean(present != 0)); + stepLabelsPresent.add(present != 0); } } @@ -536,7 +536,7 @@ else if (isFLIMLabel(label)) { if (stepsPresent.get(dimension)) { for (int position = 0; position != sizes[dimension]; ++ position) { final double step = in.readDouble(); - list.add(new Double(step)); + list.add(step); } } steps.add(list); diff --git a/components/formats-bsd/src/loci/formats/in/QTReader.java b/components/formats-bsd/src/loci/formats/in/QTReader.java index d9ebb83f485..81d4ccbe95f 100644 --- a/components/formats-bsd/src/loci/formats/in/QTReader.java +++ b/components/formats-bsd/src/loci/formats/in/QTReader.java @@ -513,19 +513,19 @@ else if (atomType.equals("stco")) { if (numPlanes != getImageCount()) { in.seek(in.getFilePointer() - 4); int off = in.readInt(); - offsets.add(new Integer(off)); + offsets.add(off); for (int i=1; i 0) && (i < chunkSizes.size())) { rawSize = chunkSizes.get(i).intValue(); } else i = getImageCount(); off += rawSize; - offsets.add(new Integer(off)); + offsets.add(off); } } else { for (int i=0; i 0 && currentTileSizeY > 0; if (usingTiling) { - ifd.put(new Integer(IFD.TILE_WIDTH), new Long(currentTileSizeX)); - ifd.put(new Integer(IFD.TILE_LENGTH), new Long(currentTileSizeY)); + ifd.put(IFD.TILE_WIDTH, Long.valueOf(currentTileSizeX)); + ifd.put(IFD.TILE_LENGTH, Long.valueOf(currentTileSizeY)); } if (usingTiling && (currentTileSizeX < w || currentTileSizeY < h)) { int numTilesX = (w + (x % currentTileSizeX) + currentTileSizeX - 1) / currentTileSizeX; @@ -355,8 +355,8 @@ else if (retrieve.getPixelsBinDataCount(series) == 0) { int width = getSizeX(); int height = getSizeY(); - ifd.put(new Integer(IFD.IMAGE_WIDTH), new Long(width)); - ifd.put(new Integer(IFD.IMAGE_LENGTH), new Long(height)); + ifd.put(IFD.IMAGE_WIDTH, Long.valueOf(width)); + ifd.put(IFD.IMAGE_LENGTH, Long.valueOf(height)); Length px = retrieve.getPixelsPhysicalSizeX(series); Double physicalSizeX = px == null || px.value(UNITS.MICROMETER) == null ? null : px.value(UNITS.MICROMETER).doubleValue(); @@ -387,7 +387,7 @@ else if (retrieve.getPixelsBinDataCount(series) == 0) { } // write the image - ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(littleEndian)); + ifd.put(IFD.LITTLE_ENDIAN, Boolean.valueOf(littleEndian)); if (!ifd.containsKey(IFD.REUSE)) { ifd.put(IFD.REUSE, out.length()); out.seek(out.length()); From 5e9d8c6bb8df57372d1deb31352d8d2e389e9bd1 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 8 Apr 2024 17:52:53 -0500 Subject: [PATCH 020/100] Fix most Java 9+ deprecation warnings in bio-formats-plugins component --- .../src/loci/plugins/config/ConfigWindow.java | 4 +- .../src/loci/plugins/config/FormatEntry.java | 2 +- .../src/loci/plugins/in/IdDialog.java | 2 +- .../src/loci/plugins/in/ImporterMetadata.java | 18 +- .../src/loci/plugins/macro/LociFunctions.java | 60 +++--- .../src/loci/plugins/out/Exporter.java | 2 +- .../src/loci/plugins/util/ROIHandler.java | 16 +- .../plugins/util/RecordedImageProcessor.java | 186 +++++++++--------- 8 files changed, 145 insertions(+), 145 deletions(-) diff --git a/components/bio-formats-plugins/src/loci/plugins/config/ConfigWindow.java b/components/bio-formats-plugins/src/loci/plugins/config/ConfigWindow.java index 6155c86f472..0c3b9d0704b 100644 --- a/components/bio-formats-plugins/src/loci/plugins/config/ConfigWindow.java +++ b/components/bio-formats-plugins/src/loci/plugins/config/ConfigWindow.java @@ -349,7 +349,7 @@ public void run() { log.println("-- Formats --"); try { Class irClass = Class.forName("loci.formats.ImageReader"); - Object ir = irClass.newInstance(); + Object ir = irClass.getDeclaredConstructor().newInstance(); Method getClasses = irClass.getMethod("getReaders"); Object[] readers = (Object[]) getClasses.invoke(ir); for (int i=0; i matlabClass = Class.forName("com.mathworks.jmi.Matlab"); - Object matlab = matlabClass.newInstance(); + Object matlab = matlabClass.getDeclaredConstructor().newInstance(); Method eval = matlabClass.getMethod("eval", new Class[] {String.class}); String ans = (String) eval.invoke(matlab, new Object[] {"version"}); diff --git a/components/bio-formats-plugins/src/loci/plugins/config/FormatEntry.java b/components/bio-formats-plugins/src/loci/plugins/config/FormatEntry.java index 2a6ac20c0da..c77cb7ffe77 100644 --- a/components/bio-formats-plugins/src/loci/plugins/config/FormatEntry.java +++ b/components/bio-formats-plugins/src/loci/plugins/config/FormatEntry.java @@ -72,7 +72,7 @@ public FormatEntry(PrintWriter log, Object reader) { String fwClassName = "loci.plugins.config." + readerName + "Widgets"; try { Class fwClass = Class.forName(fwClassName); - fw = (IFormatWidgets) fwClass.newInstance(); + fw = (IFormatWidgets) fwClass.getDeclaredConstructor().newInstance(); log.println("Initialized extra widgets for " + readerName + " reader."); } catch (Throwable t) { diff --git a/components/bio-formats-plugins/src/loci/plugins/in/IdDialog.java b/components/bio-formats-plugins/src/loci/plugins/in/IdDialog.java index 58a51f71b04..13a56ba47a7 100644 --- a/components/bio-formats-plugins/src/loci/plugins/in/IdDialog.java +++ b/components/bio-formats-plugins/src/loci/plugins/in/IdDialog.java @@ -167,7 +167,7 @@ else if (options.isOMERO()) { String group = gd.getNextString(); Long groupID = null; try { - groupID = new Long(group); + groupID = Long.parseLong(group); } catch (NumberFormatException e) { } diff --git a/components/bio-formats-plugins/src/loci/plugins/in/ImporterMetadata.java b/components/bio-formats-plugins/src/loci/plugins/in/ImporterMetadata.java index 55c894707b7..ffd0569d01d 100644 --- a/components/bio-formats-plugins/src/loci/plugins/in/ImporterMetadata.java +++ b/components/bio-formats-plugins/src/loci/plugins/in/ImporterMetadata.java @@ -82,18 +82,18 @@ public ImporterMetadata(IFormatReader r, ImportProcess process, // merge core values final String pad = " "; // puts core values first when alphabetizing - put(pad + s + "SizeX", new Integer(r.getSizeX())); - put(pad + s + "SizeY", new Integer(r.getSizeY())); - put(pad + s + "SizeZ", new Integer(r.getSizeZ())); - put(pad + s + "SizeT", new Integer(r.getSizeT())); - put(pad + s + "SizeC", new Integer(r.getSizeC())); - put(pad + s + "IsRGB", new Boolean(r.isRGB())); + put(pad + s + "SizeX", Integer.valueOf(r.getSizeX())); + put(pad + s + "SizeY", Integer.valueOf(r.getSizeY())); + put(pad + s + "SizeZ", Integer.valueOf(r.getSizeZ())); + put(pad + s + "SizeT", Integer.valueOf(r.getSizeT())); + put(pad + s + "SizeC", Integer.valueOf(r.getSizeC())); + put(pad + s + "IsRGB", Boolean.valueOf(r.isRGB())); put(pad + s + "PixelType", FormatTools.getPixelTypeString(r.getPixelType())); - put(pad + s + "LittleEndian", new Boolean(r.isLittleEndian())); + put(pad + s + "LittleEndian", Boolean.valueOf(r.isLittleEndian())); put(pad + s + "DimensionOrder", r.getDimensionOrder()); - put(pad + s + "IsInterleaved", new Boolean(r.isInterleaved())); - put(pad + s + "BitsPerPixel", new Integer(r.getBitsPerPixel())); + put(pad + s + "IsInterleaved", Boolean.valueOf(r.isInterleaved())); + put(pad + s + "BitsPerPixel", Integer.valueOf(r.getBitsPerPixel())); String seriesName = process.getOMEMetadata().getImageName(i); put(pad + "Series " + i + " Name", seriesName); diff --git a/components/bio-formats-plugins/src/loci/plugins/macro/LociFunctions.java b/components/bio-formats-plugins/src/loci/plugins/macro/LociFunctions.java index 4c6ed49cf1e..27936464a45 100644 --- a/components/bio-formats-plugins/src/loci/plugins/macro/LociFunctions.java +++ b/components/bio-formats-plugins/src/loci/plugins/macro/LociFunctions.java @@ -127,25 +127,25 @@ public void getVersionNumber(String[] version) { // -- LociFunctions API methods - loci.formats.IFormatReader -- public void getImageCount(Double[] imageCount) { - imageCount[0] = new Double(r.getImageCount()); + imageCount[0] = Double.valueOf(r.getImageCount()); } - public void getSizeX(Double[] sizeX) { sizeX[0] = new Double(r.getSizeX()); } - public void getSizeY(Double[] sizeY) { sizeY[0] = new Double(r.getSizeY()); } - public void getSizeZ(Double[] sizeZ) { sizeZ[0] = new Double(r.getSizeZ()); } - public void getSizeC(Double[] sizeC) { sizeC[0] = new Double(r.getSizeC()); } - public void getSizeT(Double[] sizeT) { sizeT[0] = new Double(r.getSizeT()); } + public void getSizeX(Double[] sizeX) { sizeX[0] = Double.valueOf(r.getSizeX()); } + public void getSizeY(Double[] sizeY) { sizeY[0] = Double.valueOf(r.getSizeY()); } + public void getSizeZ(Double[] sizeZ) { sizeZ[0] = Double.valueOf(r.getSizeZ()); } + public void getSizeC(Double[] sizeC) { sizeC[0] = Double.valueOf(r.getSizeC()); } + public void getSizeT(Double[] sizeT) { sizeT[0] = Double.valueOf(r.getSizeT()); } public void getPixelType(String[] pixelType) { pixelType[0] = FormatTools.getPixelTypeString(r.getPixelType()); } public void getEffectiveSizeC(Double[] effectiveSizeC) { - effectiveSizeC[0] = new Double(r.getEffectiveSizeC()); + effectiveSizeC[0] = Double.valueOf(r.getEffectiveSizeC()); } public void getRGBChannelCount(Double[] rgbChannelCount) { - rgbChannelCount[0] = new Double(r.getRGBChannelCount()); + rgbChannelCount[0] = Double.valueOf(r.getRGBChannelCount()); } public void isIndexed(String[] indexed) { @@ -154,33 +154,33 @@ public void isIndexed(String[] indexed) { public void getChannelDimCount(Double[] channelDimCount) { Modulo moduloC = r.getModuloC(); - channelDimCount[0] = new Double(moduloC.length() > 1 ? 2 : 1); + channelDimCount[0] = Double.valueOf(moduloC.length() > 1 ? 2 : 1); } public void getChannelDimLength(Double i, Double[] channelDimLength) { Modulo moduloC = r.getModuloC(); if (i.intValue() == 0) { // index 0 - channelDimLength[0] = new Double(moduloC.length() > 1 ? r.getSizeC() / moduloC.length() : r.getSizeC()); + channelDimLength[0] = Double.valueOf(moduloC.length() > 1 ? r.getSizeC() / moduloC.length() : r.getSizeC()); } else { // index 1 - channelDimLength[0] = new Double(moduloC.length()); + channelDimLength[0] = Double.valueOf(moduloC.length()); } } public void getChannelDimType(Double i, Double[] channelDimType) { Modulo moduloC = r.getModuloC(); if (i.intValue() == 0) { // index 0 - channelDimType[0] = new Double(moduloC.length() > 1 ? moduloC.parentType : FormatTools.CHANNEL); + channelDimType[0] = Double.valueOf(moduloC.length() > 1 ? moduloC.parentType : FormatTools.CHANNEL); } else { // index 1 - channelDimType[0] = new Double(moduloC.type); + channelDimType[0] = Double.valueOf(moduloC.type); } } // public void getThumbSizeX(Double[] thumbSizeX) { -// thumbSizeX[0] = new Double(r.getThumbSizeX()); +// thumbSizeX[0] = Double.valueOf(r.getThumbSizeX()); // } // public void getThumbSizeY(Double[] thumbSizeY) { -// thumbSizeY[0] = new Double(r.getThumbSizeY()); +// thumbSizeY[0] = Double.valueOf(r.getThumbSizeY()); // } public void isLittleEndian(String[] littleEndian) { @@ -270,7 +270,7 @@ public void openImage(String title, Double no) throws FormatException, IOException { openSubImage(title, no, 0d, 0d, - new Double(r.getSizeX()), new Double(r.getSizeY())); + Double.valueOf(r.getSizeX()), Double.valueOf(r.getSizeY())); } public void openSubImage(String title, Double no, Double x, Double y, @@ -310,7 +310,7 @@ public void openSubImage(String title, Double no, Double x, Double y, public void closeFileOnly() throws IOException { r.close(true); } public void getSeriesCount(Double[] seriesCount) { - seriesCount[0] = new Double(r.getSeriesCount()); + seriesCount[0] = Double.valueOf(r.getSeriesCount()); } public void setSeries(Double seriesNum) { @@ -323,7 +323,7 @@ public void setSeries(Double seriesNum) { } public void getSeries(Double[] seriesNum) { - seriesNum[0] = new Double(r.getSeries()); + seriesNum[0] = Double.valueOf(r.getSeries()); } public void setNormalized(Boolean normalize) { @@ -331,7 +331,7 @@ public void setNormalized(Boolean normalize) { } public void isNormalized(Boolean[] normalize) { - normalize[0] = new Boolean(r.isNormalized()); + normalize[0] = Boolean.valueOf(r.isNormalized()); } public void setOriginalMetadataPopulated(Boolean populate) { @@ -339,7 +339,7 @@ public void setOriginalMetadataPopulated(Boolean populate) { } public void isOriginalMetadataPopulated(Boolean[] populate) { - populate[0] = new Boolean(r.isOriginalMetadataPopulated()); + populate[0] = Boolean.valueOf(r.isOriginalMetadataPopulated()); } public void setGroupFiles(String groupFiles) { @@ -373,7 +373,7 @@ public void fileGroupOption(String id, String[] fileGroupOption) } public void getUsedFileCount(Double[] count) { - count[0] = new Double(r.getUsedFiles().length); + count[0] = Double.valueOf(r.getUsedFiles().length); } public void getUsedFile(Double i, String[] used) { @@ -385,14 +385,14 @@ public void getCurrentFile(String[] file) { } public void getIndex(Double z, Double c, Double t, Double[] index) { - index[0] = new Double(r.getIndex(z.intValue(), c.intValue(), t.intValue())); + index[0] = Double.valueOf(r.getIndex(z.intValue(), c.intValue(), t.intValue())); } public void getZCTCoords(Double index, Double[] z, Double[] c, Double[] t) { int[] zct = r.getZCTCoords(index.intValue()); - z[0] = new Double(zct[0]); - c[0] = new Double(zct[1]); - t[0] = new Double(zct[2]); + z[0] = Double.valueOf(zct[0]); + c[0] = Double.valueOf(zct[1]); + t[0] = Double.valueOf(zct[2]); } public void getMetadataValue(String field, String[] value) { @@ -472,7 +472,7 @@ public void getPlaneTimingExposureTime(Double[] exposureTime, Double no) { val = valTime.value(UNITS.SECOND).doubleValue(); } } - exposureTime[0] = val == null ? new Double(Double.NaN) : val; + exposureTime[0] = val == null ? Double.NaN : val; } public void getPlanePositionX(Double[] positionX, Double no) { @@ -524,7 +524,7 @@ public void getPixelsPhysicalSizeX(Double[] sizeX) { if (x != null) { sizeX[0] = x.value(UNITS.MICROMETER).doubleValue(); } - if (sizeX[0] == null) sizeX[0] = new Double(Double.NaN); + if (sizeX[0] == null) sizeX[0] = Double.NaN; } public void getPixelsPhysicalSizeY(Double[] sizeY) { @@ -534,7 +534,7 @@ public void getPixelsPhysicalSizeY(Double[] sizeY) { if (y != null) { sizeY[0] = y.value(UNITS.MICROMETER).doubleValue(); } - if (sizeY[0] == null) sizeY[0] = new Double(Double.NaN); + if (sizeY[0] == null) sizeY[0] = Double.NaN; } public void getPixelsPhysicalSizeZ(Double[] sizeZ) { @@ -544,14 +544,14 @@ public void getPixelsPhysicalSizeZ(Double[] sizeZ) { if (z != null) { sizeZ[0] = z.value(UNITS.MICROMETER).doubleValue(); } - if (sizeZ[0] == null) sizeZ[0] = new Double(Double.NaN); + if (sizeZ[0] == null) sizeZ[0] = Double.NaN; } public void getPixelsTimeIncrement(Double[] sizeT) { int imageIndex = r.getSeries(); MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore(); sizeT[0] = retrieve.getPixelsTimeIncrement(imageIndex).value(UNITS.SECOND).doubleValue(); - if (sizeT[0] == null) sizeT[0] = new Double(Double.NaN); + if (sizeT[0] == null) sizeT[0] = Double.NaN; } // -- PlugIn API methods -- diff --git a/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java b/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java index 0e614bf58e2..2a953b3fea7 100644 --- a/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java +++ b/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java @@ -517,7 +517,7 @@ else if (FormatTools.isSigned(originalType)) { store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(cal.pixelWidth, cal.getXUnit()), 0); store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(cal.pixelHeight, cal.getYUnit()), 0); store.setPixelsPhysicalSizeZ(FormatTools.getPhysicalSizeZ(cal.pixelDepth, cal.getZUnit()), 0); - store.setPixelsTimeIncrement(FormatTools.getTime(new Double(cal.frameInterval), cal.getTimeUnit()), 0); + store.setPixelsTimeIncrement(FormatTools.getTime(Double.valueOf(cal.frameInterval), cal.getTimeUnit()), 0); if (imp.getImageStackSize() != imp.getNChannels() * imp.getNSlices() * imp.getNFrames()) diff --git a/components/bio-formats-plugins/src/loci/plugins/util/ROIHandler.java b/components/bio-formats-plugins/src/loci/plugins/util/ROIHandler.java index b395f993bc4..ee90c5e1013 100644 --- a/components/bio-formats-plugins/src/loci/plugins/util/ROIHandler.java +++ b/components/bio-formats-plugins/src/loci/plugins/util/ROIHandler.java @@ -745,10 +745,10 @@ private static void storePoint(PointRoi roi, MetadataStore store, private static void storeLine(Line roi, MetadataStore store, int roiNum, int shape, int c, int z, int t) { - store.setLineX1(new Double(roi.x1), roiNum, shape); - store.setLineX2(new Double(roi.x2), roiNum, shape); - store.setLineY1(new Double(roi.y1), roiNum, shape); - store.setLineY2(new Double(roi.y2), roiNum, shape); + store.setLineX1(Double.valueOf(roi.x1), roiNum, shape); + store.setLineX2(Double.valueOf(roi.x2), roiNum, shape); + store.setLineY1(Double.valueOf(roi.y1), roiNum, shape); + store.setLineY2(Double.valueOf(roi.y2), roiNum, shape); if (c >= 0) { store.setLineTheC(unwrap(c), roiNum, shape); } @@ -787,10 +787,10 @@ private static void storeRectangle(Roi roi, MetadataStore store, int roiNum, int shape, int c, int z, int t) { Rectangle bounds = roi.getBounds(); - store.setRectangleX(new Double(bounds.x), roiNum, shape); - store.setRectangleY(new Double(bounds.y), roiNum, shape); - store.setRectangleWidth(new Double(bounds.width), roiNum, shape); - store.setRectangleHeight(new Double(bounds.height), roiNum, shape); + store.setRectangleX(Double.valueOf(bounds.x), roiNum, shape); + store.setRectangleY(Double.valueOf(bounds.y), roiNum, shape); + store.setRectangleWidth(Double.valueOf(bounds.width), roiNum, shape); + store.setRectangleHeight(Double.valueOf(bounds.height), roiNum, shape); if (c >= 0) { store.setRectangleTheC(unwrap(c), roiNum, shape); } diff --git a/components/bio-formats-plugins/src/loci/plugins/util/RecordedImageProcessor.java b/components/bio-formats-plugins/src/loci/plugins/util/RecordedImageProcessor.java index feefa9a5119..b103465aedd 100644 --- a/components/bio-formats-plugins/src/loci/plugins/util/RecordedImageProcessor.java +++ b/components/bio-formats-plugins/src/loci/plugins/util/RecordedImageProcessor.java @@ -124,19 +124,19 @@ public void abs() { @Override public void add(double value) { - record("add", new Double(value), double.class); + record("add", Double.valueOf(value), double.class); proc.add(value); } @Override public void add(int value) { - record("add", new Integer(value), int.class); + record("add", Integer.valueOf(value), int.class); proc.add(value); } @Override public void and(int value) { - record("and", new Integer(value), int.class); + record("and", Integer.valueOf(value), int.class); proc.and(value); } @@ -154,7 +154,7 @@ public void autoThreshold() { @Override public ImageProcessor convertToByte(boolean doScaling) { - record("convertToByte", new Boolean(doScaling), boolean.class); + record("convertToByte", Boolean.valueOf(doScaling), boolean.class); return proc.convertToByte(doScaling); } @@ -172,14 +172,14 @@ public ImageProcessor convertToRGB() { @Override public ImageProcessor convertToShort(boolean doScaling) { - record("convertToShort", new Boolean(doScaling), boolean.class); + record("convertToShort", Boolean.valueOf(doScaling), boolean.class); return proc.convertToShort(doScaling); } @Override public void convolve(float[] kernel, int kernelWidth, int kernelHeight) { - record("convolve", new Object[] {kernel, new Integer(kernelWidth), - new Integer(kernelHeight)}, new Class[] {float[].class, + record("convolve", new Object[] {kernel, Integer.valueOf(kernelWidth), + Integer.valueOf(kernelHeight)}, new Class[] {float[].class, int.class, int.class}); proc.convolve(kernel, kernelWidth, kernelHeight); } @@ -192,8 +192,8 @@ public void convolve3x3(int[] kernel) { @Override public void copyBits(ImageProcessor ip, int xloc, int yloc, int mode) { - record("copyBits", new Object[] {ip, new Integer(xloc), new Integer(yloc), - new Integer(mode)}, new Class[] {ImageProcessor.class, int.class, + record("copyBits", new Object[] {ip, Integer.valueOf(xloc), Integer.valueOf(yloc), + Integer.valueOf(mode)}, new Class[] {ImageProcessor.class, int.class, int.class, int.class}); proc.copyBits(ip, xloc, yloc, mode); } @@ -316,8 +316,8 @@ else if (activeProcessor instanceof FloatProcessor) { @Override public ImageProcessor createProcessor(int width, int height) { - record("createProcessor", new Object[] {new Integer(width), - new Integer(height)}, new Class[] {int.class, int.class}); + record("createProcessor", new Object[] {Integer.valueOf(width), + Integer.valueOf(height)}, new Class[] {int.class, int.class}); return proc.createProcessor(width, height); } @@ -335,30 +335,30 @@ public void dilate() { @Override public void drawDot(int xcenter, int ycenter) { - record("drawDot", new Object[] {new Integer(xcenter), - new Integer(ycenter)}, new Class[] {int.class, int.class}); + record("drawDot", new Object[] {Integer.valueOf(xcenter), + Integer.valueOf(ycenter)}, new Class[] {int.class, int.class}); proc.drawDot(xcenter, ycenter); } @Override public void drawLine(int x1, int y1, int x2, int y2) { - record("drawLine", new Object[] {new Integer(x1), new Integer(y1), - new Integer(x2), new Integer(y2)}, new Class[] {int.class, int.class, + record("drawLine", new Object[] {Integer.valueOf(x1), Integer.valueOf(y1), + Integer.valueOf(x2), Integer.valueOf(y2)}, new Class[] {int.class, int.class, int.class, int.class}); proc.drawLine(x1, y1, x2, y2); } @Override public void drawOval(int x, int y, int width, int height) { - record("drawOval", new Object[] {new Integer(x), new Integer(y), - new Integer(width), new Integer(height)}, new Class[] {int.class, + record("drawOval", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Integer.valueOf(width), Integer.valueOf(height)}, new Class[] {int.class, int.class, int.class, int.class}); proc.drawOval(x, y, width, height); } @Override public void drawPixel(int x, int y) { - record("drawPixel", new Object[] {new Integer(x), new Integer(y)}, + record("drawPixel", new Object[] {Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {int.class, int.class}); proc.drawPixel(x, y); } @@ -371,8 +371,8 @@ public void drawPolygon(Polygon p) { @Override public void drawRect(int x, int y, int width, int height) { - record("drawRect", new Object[] {new Integer(x), new Integer(y), - new Integer(width), new Integer(height)}, new Class[] {int.class, + record("drawRect", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Integer.valueOf(width), Integer.valueOf(height)}, new Class[] {int.class, int.class, int.class, int.class}); proc.drawRect(x, y, width, height); } @@ -385,7 +385,7 @@ public void drawString(String s) { @Override public void drawString(String s, int x, int y) { - record("drawString", new Object[] {s, new Integer(x), new Integer(y)}, + record("drawString", new Object[] {s, Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {String.class, int.class, int.class}); proc.drawString(s, x, y); } @@ -422,8 +422,8 @@ public void fill(ImageProcessor mask) { @Override public void fillOval(int x, int y, int width, int height) { - record("fillOval", new Object[] {new Integer(x), new Integer(y), - new Integer(width), new Integer(height)}, new Class[] {int.class, + record("fillOval", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Integer.valueOf(width), Integer.valueOf(height)}, new Class[] {int.class, int.class, int.class, int.class}); proc.fillOval(x, y, width, height); } @@ -436,7 +436,7 @@ public void fillPolygon(Polygon p) { @Override public void filter(int type) { - record("filter", new Integer(type), int.class); + record("filter", Integer.valueOf(type), int.class); proc.filter(type); } @@ -460,19 +460,19 @@ public void flipVertical() { @Override public void gamma(double value) { - record("gamma", new Double(value), double.class); + record("gamma", Double.valueOf(value), double.class); proc.gamma(value); } @Override public int get(int index) { - record("get", new Integer(index), int.class); + record("get", Integer.valueOf(index), int.class); return proc.get(index); } @Override public int get(int x, int y) { - record("get", new Object[] {new Integer(x), new Integer(y)}, + record("get", new Object[] {Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {int.class, int.class}); return proc.get(x, y); } @@ -527,8 +527,8 @@ public ColorModel getColorModel() { @Override public void getColumn(int x, int y, int[] data, int length) { - record("getColumn", new Object[] {new Integer(x), new Integer(y), data, - new Integer(length)}, new Class[] {int.class, int.class, int[].class, + record("getColumn", new Object[] {Integer.valueOf(x), Integer.valueOf(y), data, + Integer.valueOf(length)}, new Class[] {int.class, int.class, int[].class, int.class}); proc.getColumn(x, y, data, length); } @@ -547,13 +547,13 @@ public IndexColorModel getDefaultColorModel() { @Override public float getf(int index) { - record("getf", new Integer(index), int.class); + record("getf", Integer.valueOf(index), int.class); return proc.getf(index); } @Override public float getf(int x, int y) { - record("getf", new Object[] {new Integer(x), new Integer(y)}, + record("getf", new Object[] {Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {int.class, int.class}); return proc.getf(x, y); } @@ -614,15 +614,15 @@ public boolean getInterpolate() { @Override public double getInterpolatedPixel(double x, double y) { - record("getInterpolatedPixel", new Object[] {new Double(x), new Double(y)}, + record("getInterpolatedPixel", new Object[] {Double.valueOf(x), Double.valueOf(y)}, new Class[] {double.class, double.class}); return proc.getInterpolatedPixel(x, y); } @Override public double[] getLine(double x1, double y1, double x2, double y2) { - record("getLine", new Object[] {new Double(x1), new Double(y1), - new Double(x2), new Double(y2)}, new Class[] {double.class, double.class, + record("getLine", new Object[] {Double.valueOf(x1), Double.valueOf(y1), + Double.valueOf(x2), Double.valueOf(y2)}, new Class[] {double.class, double.class, double.class, double.class}); return proc.getLine(x1, y1, x2, y2); } @@ -677,21 +677,21 @@ public int getNChannels() { @Override public int getPixel(int x, int y) { - record("getPixel", new Object[] {new Integer(x), new Integer(y)}, + record("getPixel", new Object[] {Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {int.class, int.class}); return proc.getPixel(x, y); } @Override public int[] getPixel(int x, int y, int[] iArray) { - record("getPixel", new Object[] {new Integer(x), new Integer(y), iArray}, + record("getPixel", new Object[] {Integer.valueOf(x), Integer.valueOf(y), iArray}, new Class[] {int.class, int.class, int[].class}); return proc.getPixel(x, y, iArray); } @Override public int getPixelInterpolated(double x, double y) { - record("getPixelInterpolated", new Object[] {new Double(x), new Double(y)}, + record("getPixelInterpolated", new Object[] {Double.valueOf(x), Double.valueOf(y)}, new Class[] {double.class, double.class}); return proc.getPixelInterpolated(x, y); } @@ -716,7 +716,7 @@ public Object getPixelsCopy() { @Override public float getPixelValue(int x, int y) { - record("getPixelValue", new Object[] {new Integer(x), new Integer(y)}, + record("getPixelValue", new Object[] {Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {int.class, int.class}); return proc.getPixelValue(x, y); } @@ -729,8 +729,8 @@ public Rectangle getRoi() { @Override public void getRow(int x, int y, int[] data, int length) { - record("getRow", new Object[] {new Integer(x), new Integer(y), data, - new Integer(length)}, new Class[] {int.class, int.class, int[].class, + record("getRow", new Object[] {Integer.valueOf(x), Integer.valueOf(y), data, + Integer.valueOf(length)}, new Class[] {int.class, int.class, int[].class, int.class}); proc.getRow(x, y, data, length); } @@ -755,7 +755,7 @@ public int getWidth() { @Override public void insert(ImageProcessor ip, int xloc, int yloc) { - record("insert", new Object[] {ip, new Integer(xloc), new Integer(yloc)}, + record("insert", new Object[] {ip, Integer.valueOf(xloc), Integer.valueOf(yloc)}, new Class[] {ImageProcessor.class, int.class, int.class}); proc.insert(ip, xloc, yloc); } @@ -792,7 +792,7 @@ public boolean isPseudoColorLut() { @Override public void lineTo(int x2, int y2) { - record("lineTo", new Object[] {new Integer(x2), new Integer(y2)}, + record("lineTo", new Object[] {Integer.valueOf(x2), Integer.valueOf(y2)}, new Class[] {int.class, int.class}); proc.lineTo(x2, y2); } @@ -803,7 +803,7 @@ public void log() { } public void max(double value) { - record("max", new Double(value), double.class); + record("max", Double.valueOf(value), double.class); proc.max(value); } @@ -818,7 +818,7 @@ public void medianFilter() { } public void min(double value) { - record("min", new Double(value), double.class); + record("min", Double.valueOf(value), double.class); proc.min(value); } @@ -828,54 +828,54 @@ public double minValue() { } public void moveTo(int x, int y) { - record("moveTo", new Object[] {new Integer(x), new Integer(y)}, + record("moveTo", new Object[] {Integer.valueOf(x), Integer.valueOf(y)}, new Class[] {int.class, int.class}); proc.moveTo(x, y); } public void multiply(double value) { - record("multiply", new Double(value), double.class); + record("multiply", Double.valueOf(value), double.class); proc.multiply(value); } public void noise(double range) { - record("noise", new Double(range), double.class); + record("noise", Double.valueOf(range), double.class); proc.noise(range); } public void or(int value) { - record("or", new Integer(value), int.class); + record("or", Integer.valueOf(value), int.class); proc.or(value); } public void putColumn(int x, int y, int[] data, int length) { - record("putColumn", new Object[] {new Integer(x), new Integer(y), data, - new Integer(length)}, new Class[] {int.class, int.class, int[].class, + record("putColumn", new Object[] {Integer.valueOf(x), Integer.valueOf(y), data, + Integer.valueOf(length)}, new Class[] {int.class, int.class, int[].class, int.class}); proc.putColumn(x, y, data, length); } public void putPixel(int x, int y, int value) { - record("putPixel", new Object[] {new Integer(x), new Integer(y), - new Integer(value)}, new Class[] {int.class, int.class, int.class}); + record("putPixel", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Integer.valueOf(value)}, new Class[] {int.class, int.class, int.class}); proc.putPixel(x, y, value); } public void putPixel(int x, int y, int[] iArray) { - record("putPixel", new Object[] {new Integer(x), new Integer(y), iArray}, + record("putPixel", new Object[] {Integer.valueOf(x), Integer.valueOf(y), iArray}, new Class[] {int.class, int.class, int[].class}); proc.putPixel(x, y, iArray); } public void putPixelValue(int x, int y, double value) { - record("putPixelValue", new Object[] {new Integer(x), new Integer(y), - new Double(value)}, new Class[] {int.class, int.class, double.class}); + record("putPixelValue", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Double.valueOf(value)}, new Class[] {int.class, int.class, double.class}); proc.putPixelValue(x, y, value); } public void putRow(int x, int y, int[] data, int length) { - record("putRow", new Object[] {new Integer(x), new Integer(y), data, - new Integer(length)}, new Class[] {int.class, int.class, int[].class, + record("putRow", new Object[] {Integer.valueOf(x), Integer.valueOf(y), data, + Integer.valueOf(length)}, new Class[] {int.class, int.class, int[].class, int.class}); proc.putRow(x, y, data, length); } @@ -911,18 +911,18 @@ public void resetThreshold() { } public ImageProcessor resize(int dstWidth) { - record("resize", new Integer(dstWidth), int.class); + record("resize", Integer.valueOf(dstWidth), int.class); return proc.resize(dstWidth); } public ImageProcessor resize(int dstWidth, int dstHeight) { - record("resize", new Object[] {new Integer(dstWidth), - new Integer(dstHeight)}, new Class[] {int.class, int.class}); + record("resize", new Object[] {Integer.valueOf(dstWidth), + Integer.valueOf(dstHeight)}, new Class[] {int.class, int.class}); return proc.resize(dstWidth, dstHeight); } public void rotate(double angle) { - record("rotate", new Double(angle), double.class); + record("rotate", Double.valueOf(angle), double.class); proc.rotate(angle); } @@ -937,36 +937,36 @@ public ImageProcessor rotateRight() { } public void scale(double xScale, double yScale) { - record("scale", new Object[] {new Double(xScale), new Double(yScale)}, + record("scale", new Object[] {Double.valueOf(xScale), Double.valueOf(yScale)}, new Class[] {double.class, double.class}); proc.scale(xScale, yScale); } public void set(int index, int value) { - record("set", new Object[] {new Integer(index), new Integer(value)}, + record("set", new Object[] {Integer.valueOf(index), Integer.valueOf(value)}, new Class[] {int.class, int.class}); proc.set(index, value); } public void set(int x, int y, int value) { - record("set", new Object[] {new Integer(x), new Integer(y), - new Integer(value)}, new Class[] {int.class, int.class, int.class}); + record("set", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Integer.valueOf(value)}, new Class[] {int.class, int.class, int.class}); proc.set(x, y, value); } public void setAntialiasedText(boolean antialiased) { - record("setAntialiasedText", new Boolean(antialiased), boolean.class); + record("setAntialiasedText", Boolean.valueOf(antialiased), boolean.class); proc.setAntialiasedText(antialiased); } public void setAutoThreshold(int method, int lutUpdate) { - record("setAutoThreshold", new Object[] {new Integer(method), - new Integer(lutUpdate)}, new Class[] {int.class, int.class}); + record("setAutoThreshold", new Object[] {Integer.valueOf(method), + Integer.valueOf(lutUpdate)}, new Class[] {int.class, int.class}); proc.setAutoThreshold(method, lutUpdate); } public void setBackgroundValue(double value) { - record("setBackgroundValue", new Double(value), double.class); + record("setBackgroundValue", Double.valueOf(value), double.class); proc.setBackgroundValue(value); } @@ -986,7 +986,7 @@ public void setColor(Color color) { } public void setColor(int value) { - record("setColor", new Integer(value), int.class); + record("setColor", Integer.valueOf(value), int.class); proc.setColor(value); } @@ -996,14 +996,14 @@ public void setColorModel(ColorModel cm) { } public void setf(int index, float value) { - record("setf", new Object[] {new Integer(index), new Float(value)}, + record("setf", new Object[] {Integer.valueOf(index), Float.valueOf(value)}, new Class[] {int.class, float.class}); proc.setf(index, value); } public void setf(int x, int y, float value) { - record("setf", new Object[] {new Integer(x), new Integer(y), - new Float(value)}, new Class[] {int.class, int.class, float.class}); + record("setf", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Float.valueOf(value)}, new Class[] {int.class, int.class, float.class}); proc.setf(x, y, value); } @@ -1018,13 +1018,13 @@ public void setFont(Font font) { } public void setHistogramRange(double histMin, double histMax) { - record("setHistogramRange", new Object[] {new Double(histMin), - new Double(histMax)}, new Class[] {double.class, double.class}); + record("setHistogramRange", new Object[] {Double.valueOf(histMin), + Double.valueOf(histMax)}, new Class[] {double.class, double.class}); proc.setHistogramRange(histMin, histMax); } public void setHistogramSize(int size) { - record("setHistogramSize", new Integer(size), int.class); + record("setHistogramSize", Integer.valueOf(size), int.class); proc.setHistogramSize(size); } @@ -1034,22 +1034,22 @@ public void setIntArray(int[][] a) { } public void setInterpolate(boolean interpolate) { - record("setInterpolate", new Boolean(interpolate), boolean.class); + record("setInterpolate", Boolean.valueOf(interpolate), boolean.class); proc.setInterpolate(interpolate); } public void setJustification(int justification) { - record("setJustification", new Integer(justification), int.class); + record("setJustification", Integer.valueOf(justification), int.class); proc.setJustification(justification); } public void setLineWidth(int width) { - record("setLineWidth", new Integer(width), int.class); + record("setLineWidth", Integer.valueOf(width), int.class); proc.setLineWidth(width); } public void setLutAnimation(boolean lutAnimation) { - record("setLutAnimation", new Boolean(lutAnimation), boolean.class); + record("setLutAnimation", Boolean.valueOf(lutAnimation), boolean.class); proc.setLutAnimation(lutAnimation); } @@ -1059,13 +1059,13 @@ public void setMask(ImageProcessor mask) { } public void setMinAndMax(double min, double max) { - record("setMinAndMax", new Object[] {new Double(min), new Double(max)}, + record("setMinAndMax", new Object[] {Double.valueOf(min), Double.valueOf(max)}, new Class[] {double.class, double.class}); proc.setMinAndMax(min, max); } public void setPixels(int channelNumber, FloatProcessor fp) { - record("setPixels", new Object[] {new Integer(channelNumber), fp}, + record("setPixels", new Object[] {Integer.valueOf(channelNumber), fp}, new Class[] {int.class, FloatProcessor.class}); proc.setPixels(channelNumber, fp); } @@ -1081,8 +1081,8 @@ public void setProgressBar(ProgressBar pb) { } public void setRoi(int x, int y, int rwidth, int rheight) { - record("setRoi", new Object[] {new Integer(x), new Integer(y), - new Integer(rwidth), new Integer(rheight)}, new Class[] {int.class, + record("setRoi", new Object[] {Integer.valueOf(x), Integer.valueOf(y), + Integer.valueOf(rwidth), Integer.valueOf(rheight)}, new Class[] {int.class, int.class, int.class, int.class}); proc.setRoi(x, y, rwidth, rheight); } @@ -1103,7 +1103,7 @@ public void setRoi(Roi roi) { } public void setSnapshotCopyMode(boolean b) { - record("setSnapshotCopyMode", new Boolean(b), boolean.class); + record("setSnapshotCopyMode", Boolean.valueOf(b), boolean.class); proc.setSnapshotCopyMode(b); } @@ -1115,14 +1115,14 @@ public void setSnapshotPixels(Object pixels) { public void setThreshold(double minThreshold, double maxThreshold, int lutUpdate) { - record("setThreshold", new Object[] {new Double(minThreshold), - new Double(maxThreshold), new Integer(lutUpdate)}, + record("setThreshold", new Object[] {Double.valueOf(minThreshold), + Double.valueOf(maxThreshold), Integer.valueOf(lutUpdate)}, new Class[] {double.class, double.class, int.class}); proc.setThreshold(minThreshold, maxThreshold, lutUpdate); } public void setValue(double value) { - record("setValue", new Double(value), double.class); + record("setValue", Double.valueOf(value), double.class); proc.setValue(value); } @@ -1157,12 +1157,12 @@ public void swapPixelArrays() { } public void threshold(int level) { - record("threshold", new Integer(level), int.class); + record("threshold", Integer.valueOf(level), int.class); proc.threshold(level); } public FloatProcessor toFloat(int channelNumber, FloatProcessor fp) { - record("toFloat", new Object[] {new Integer(channelNumber), fp}, + record("toFloat", new Object[] {Integer.valueOf(channelNumber), fp}, new Class[] {int.class, FloatProcessor.class}); return proc.toFloat(channelNumber, fp); } @@ -1174,19 +1174,19 @@ public String toString() { public void translate(int xOffset, int yOffset) { record("translate", - new Object[] {new Integer(xOffset), new Integer(yOffset)}, + new Object[] {Integer.valueOf(xOffset), Integer.valueOf(yOffset)}, new Class[] {int.class, int.class}); proc.translate(xOffset, yOffset); } public void updateComposite(int[] rgbPixels, int channel) { - record("updateComposite", new Object[] {rgbPixels, new Integer(channel)}, + record("updateComposite", new Object[] {rgbPixels, Integer.valueOf(channel)}, new Class[] {int[].class, int.class}); proc.updateComposite(rgbPixels, channel); } public void xor(int value) { - record("xor", new Integer(value), int.class); + record("xor", Integer.valueOf(value), int.class); proc.xor(value); } From 32c9fecc09e233fb2c70cb7542b38fb6cca4444f Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 8 Apr 2024 19:36:50 -0500 Subject: [PATCH 021/100] NDPI: first version of precompressed tile reading --- .../formats/services/JPEGTurboService.java | 10 + .../services/JPEGTurboServiceImpl.java | 11 +- .../src/loci/formats/in/NDPIReader.java | 264 ++++++++++++++---- 3 files changed, 232 insertions(+), 53 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java b/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java index 9ecc8b9c9e9..bddf1be24bb 100644 --- a/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java +++ b/components/formats-bsd/src/loci/formats/services/JPEGTurboService.java @@ -120,6 +120,16 @@ byte[] getTile(byte[] buf, int xCoordinate, int yCoordinate, int width, */ byte[] getCompressedTile(int xTile, int yTile) throws IOException; + /** + * Similar to getTile(int, int), but returns the JPEG-compressed bytes. + * + * @param data preallocated array for storing tile + * @param xTile column index of the tile + * @param yTile row index of the tile + * @return JPEG-compressed bytes + */ + byte[] getCompressedTile(byte[] data, int xTile, int yTile) throws IOException; + /** * Free resources associated with the initialized stream. */ diff --git a/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java b/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java index 2e79544413b..c2e194801a5 100644 --- a/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java +++ b/components/formats-bsd/src/loci/formats/services/JPEGTurboServiceImpl.java @@ -356,12 +356,21 @@ public byte[] getCompressedTile(int tileX, int tileY) throws IOException { } byte[] data = new byte[(int) dataLength]; + return getCompressedTile(data, tileX, tileY); + } + + @Override + public byte[] getCompressedTile(byte[] data, int tileX, int tileY) throws IOException { + if (header == null) { + header = getFixedHeader(); + } int offset = 0; System.arraycopy(header, 0, data, offset, header.length); offset += header.length; - start = tileX + (tileY * xTiles * mult); + int mult = tileHeight / mcuHeight; // was restartInterval + int start = tileX + (tileY * xTiles * mult); for (int row=0; row Date: Tue, 9 Apr 2024 14:28:33 -0500 Subject: [PATCH 022/100] Fix interpretation of x and y coordinates --- .../src/loci/formats/in/NDPIReader.java | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/NDPIReader.java b/components/formats-gpl/src/loci/formats/in/NDPIReader.java index 3771cf3d829..85e6f5a0285 100644 --- a/components/formats-gpl/src/loci/formats/in/NDPIReader.java +++ b/components/formats-gpl/src/loci/formats/in/NDPIReader.java @@ -158,17 +158,7 @@ public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, initializedSeries = getCoreIndex(); initializedPlane = no; } - if ((x % service.getTileWidth()) != 0) { - throw new FormatException("Invalid x: " + x + " must be multiple of " + - service.getTileWidth()); - } - if ((y % service.getTileHeight()) != 0) { - throw new FormatException("Invalid y: " + y + " must be multiple of " + - service.getTileHeight()); - } - int tileRow = y / service.getTileHeight(); - int tileColumn = x / service.getTileWidth(); - return service.getCompressedTile(tileColumn, tileRow); + return service.getCompressedTile(x, y); } @Override @@ -188,17 +178,7 @@ public byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws Forma initializedSeries = getCoreIndex(); initializedPlane = no; } - if ((x % service.getTileWidth()) != 0) { - throw new FormatException("Invalid x: " + x + " must be multiple of " + - service.getTileWidth()); - } - if ((y % service.getTileHeight()) != 0) { - throw new FormatException("Invalid y: " + y + " must be multiple of " + - service.getTileHeight()); - } - int tileRow = y / service.getTileHeight(); - int tileColumn = x / service.getTileWidth(); - service.getCompressedTile(buf, tileColumn, tileRow); + service.getCompressedTile(buf, x, y); return buf; } From e21ed517903f80a5b093ad6ae729a9f3e8645eb7 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 9 Apr 2024 15:27:24 -0500 Subject: [PATCH 023/100] Refactor generic TIFF tile logic --- .../loci/formats/in/MinimalTiffReader.java | 69 ++++++++++++++++++ .../src/loci/formats/in/NDPIReader.java | 7 +- .../src/loci/formats/in/SVSReader.java | 72 +------------------ 3 files changed, 74 insertions(+), 74 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/in/MinimalTiffReader.java b/components/formats-bsd/src/loci/formats/in/MinimalTiffReader.java index 75eb93e728f..7e3907efe0f 100644 --- a/components/formats-bsd/src/loci/formats/in/MinimalTiffReader.java +++ b/components/formats-bsd/src/loci/formats/in/MinimalTiffReader.java @@ -705,4 +705,73 @@ protected void initTiffParser() { tiffParser.setUse64BitOffsets(use64Bit); } + /** + * Get the index of the tile corresponding to given IFD (plane) + * and tile XY indexes. + * + * @param ifd IFD for the requested tile's plane + * @param x tile X index + * @param y tile Y index + * @return corresponding tile index + */ + protected int getTileIndex(IFD ifd, int x, int y) throws FormatException { + int rows = (int) ifd.getTilesPerColumn(); + int cols = (int) ifd.getTilesPerRow(); + + if (x < 0 || x >= cols) { + throw new IllegalArgumentException("X index " + x + " not in range [0, " + cols + ")"); + } + if (y < 0 || y >= rows) { + throw new IllegalArgumentException("Y index " + y + " not in range [0, " + rows + ")"); + } + + return (cols * y) + x; + } + + protected long getCompressedByteCount(IFD ifd, int x, int y) throws FormatException, IOException { + long[] byteCounts = ifd.getStripByteCounts(); + int tileIndex = getTileIndex(ifd, x, y); + byte[] jpegTable = (byte[]) ifd.getIFDValue(IFD.JPEG_TABLES); + int jpegTableBytes = jpegTable == null ? 0 : jpegTable.length - 2; + long expectedBytes = byteCounts[tileIndex]; + if (expectedBytes > 0) { + expectedBytes += jpegTableBytes; + } + if (expectedBytes < 0 || expectedBytes > Integer.MAX_VALUE) { + throw new IOException("Invalid compressed tile size: " + expectedBytes); + } + return expectedBytes; + } + + protected byte[] copyTile(IFD ifd, byte[] buf, int x, int y) throws FormatException, IOException { + long[] offsets = ifd.getStripOffsets(); + long[] byteCounts = ifd.getStripByteCounts(); + + int tileIndex = getTileIndex(ifd, x, y); + + byte[] jpegTable = (byte[]) ifd.getIFDValue(IFD.JPEG_TABLES); + int jpegTableBytes = jpegTable == null ? 0 : jpegTable.length - 2; + long expectedBytes = getCompressedByteCount(ifd, x, y); + + if (buf.length < expectedBytes) { + throw new IllegalArgumentException("Tile buffer too small: expected >=" + + expectedBytes + ", got " + buf.length); + } + else if (expectedBytes < 0 || expectedBytes > Integer.MAX_VALUE) { + throw new IOException("Invalid compressed tile size: " + expectedBytes); + } + + if (jpegTable != null && expectedBytes > 0) { + System.arraycopy(jpegTable, 0, buf, 0, jpegTable.length - 2); + // skip over the duplicate SOI marker + tiffParser.getStream().seek(offsets[tileIndex] + 2); + tiffParser.getStream().readFully(buf, jpegTable.length - 2, (int) byteCounts[tileIndex]); + } + else if (byteCounts[tileIndex] > 0) { + tiffParser.getStream().seek(offsets[tileIndex]); + tiffParser.getStream().readFully(buf, 0, (int) byteCounts[tileIndex]); + } + return buf; + } + } diff --git a/components/formats-gpl/src/loci/formats/in/NDPIReader.java b/components/formats-gpl/src/loci/formats/in/NDPIReader.java index 85e6f5a0285..4b3611b2412 100644 --- a/components/formats-gpl/src/loci/formats/in/NDPIReader.java +++ b/components/formats-gpl/src/loci/formats/in/NDPIReader.java @@ -149,8 +149,8 @@ public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, IFD ifd = ifds.get(ifdIndex); if (useTiffParser(ifd)) { - // TODO - return null; + byte[] buf = new byte[(int) getCompressedByteCount(ifd, x, y)]; + return openCompressedBytes(no, buf, x, y); } if (initializedSeries != getCoreIndex() || initializedPlane != no) { @@ -169,8 +169,7 @@ public byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws Forma IFD ifd = ifds.get(ifdIndex); if (useTiffParser(ifd)) { - // TODO - return buf; + return copyTile(ifd, buf, x, y); } if (initializedSeries != getCoreIndex() || initializedPlane != no) { diff --git a/components/formats-gpl/src/loci/formats/in/SVSReader.java b/components/formats-gpl/src/loci/formats/in/SVSReader.java index b88b5478517..ef4ec80d074 100644 --- a/components/formats-gpl/src/loci/formats/in/SVSReader.java +++ b/components/formats-gpl/src/loci/formats/in/SVSReader.java @@ -306,21 +306,7 @@ public int getTileColumns(int no) { public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, IOException { FormatTools.assertId(currentId, true, 1); IFD ifd = getIFD(no); - long[] byteCounts = ifd.getStripByteCounts(); - int tileIndex = getTileIndex(ifd, x, y); - - byte[] jpegTable = (byte[]) ifd.getIFDValue(IFD.JPEG_TABLES); - int jpegTableBytes = jpegTable == null ? 0 : jpegTable.length - 2; - long expectedBytes = byteCounts[tileIndex]; - if (expectedBytes > 0) { - expectedBytes += jpegTableBytes; - } - - if (expectedBytes < 0 || expectedBytes > Integer.MAX_VALUE) { - throw new IOException("Invalid compressed tile size: " + expectedBytes); - } - - byte[] buf = new byte[(int) expectedBytes]; + byte[] buf = new byte[(int) getCompressedByteCount(ifd, x, y)]; return openCompressedBytes(no, buf, x, y); } @@ -328,38 +314,7 @@ public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, public byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws FormatException, IOException { FormatTools.assertId(currentId, true, 1); IFD ifd = getIFD(no); - long[] offsets = ifd.getStripOffsets(); - long[] byteCounts = ifd.getStripByteCounts(); - - int tileIndex = getTileIndex(ifd, x, y); - - byte[] jpegTable = (byte[]) ifd.getIFDValue(IFD.JPEG_TABLES); - int jpegTableBytes = jpegTable == null ? 0 : jpegTable.length - 2; - long expectedBytes = byteCounts[tileIndex]; - if (expectedBytes > 0) { - expectedBytes += jpegTableBytes; - } - - if (buf.length < expectedBytes) { - throw new IllegalArgumentException("Tile buffer too small: expected >=" + - expectedBytes + ", got " + buf.length); - } - else if (expectedBytes < 0 || expectedBytes > Integer.MAX_VALUE) { - throw new IOException("Invalid compressed tile size: " + expectedBytes); - } - - if (jpegTable != null && expectedBytes > 0) { - System.arraycopy(jpegTable, 0, buf, 0, jpegTable.length - 2); - // skip over the duplicate SOI marker - tiffParser.getStream().seek(offsets[tileIndex] + 2); - tiffParser.getStream().readFully(buf, jpegTable.length - 2, (int) byteCounts[tileIndex]); - } - else if (byteCounts[tileIndex] > 0) { - tiffParser.getStream().seek(offsets[tileIndex]); - tiffParser.getStream().readFully(buf, 0, (int) byteCounts[tileIndex]); - } - - return buf; + return copyTile(ifd, buf, x, y); } @Override @@ -873,27 +828,4 @@ protected IFD getIFD(int no) { return ifds.get(ifd); } - /** - * Get the index of the tile corresponding to given IFD (plane) - * and tile XY indexes. - * - * @param ifd IFD for the requested tile's plane - * @param x tile X index - * @param y tile Y index - * @return corresponding tile index - */ - protected int getTileIndex(IFD ifd, int x, int y) throws FormatException { - int rows = (int) ifd.getTilesPerColumn(); - int cols = (int) ifd.getTilesPerRow(); - - if (x < 0 || x >= cols) { - throw new IllegalArgumentException("X index " + x + " not in range [0, " + cols + ")"); - } - if (y < 0 || y >= rows) { - throw new IllegalArgumentException("Y index " + y + " not in range [0, " + rows + ")"); - } - - return (cols * y) + x; - } - } From aa45bed5920d0b9c5de191a49a90557b54a8c077 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 9 Apr 2024 16:01:04 -0500 Subject: [PATCH 024/100] Fix some deprecation warnings in bio-formats-tools component --- .../bio-formats-tools/src/loci/formats/tools/ImageInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index e52ccfcdc76..1fc189d209a 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -367,7 +367,7 @@ public void createReader() { // create reader of a specific format type try { Class c = Class.forName("loci.formats.in." + format + "Reader"); - reader = (IFormatReader) c.newInstance(); + reader = (IFormatReader) c.getDeclaredConstructor().newInstance(); } catch (ClassNotFoundException exc) { LOGGER.warn("Unknown reader: {}", format); @@ -377,7 +377,7 @@ public void createReader() { LOGGER.warn("Cannot instantiate reader: {}", format); LOGGER.debug("", exc); } - catch (IllegalAccessException exc) { + catch (ReflectiveOperationException exc) { LOGGER.warn("Cannot access reader: {}", format); LOGGER.debug("", exc); } From a97539856fed8f3caa85c8e008433d0459254aa2 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 9 Apr 2024 16:01:26 -0500 Subject: [PATCH 025/100] Fix some deprecation warnings in formats-api component --- components/formats-api/src/loci/formats/ImageReader.java | 5 ++--- components/formats-api/src/loci/formats/ImageWriter.java | 5 ++--- components/formats-api/src/loci/formats/ReaderWrapper.java | 5 ++--- components/formats-api/src/loci/formats/WriterWrapper.java | 5 ++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/components/formats-api/src/loci/formats/ImageReader.java b/components/formats-api/src/loci/formats/ImageReader.java index 68e02c481fa..9a87aeec5c4 100644 --- a/components/formats-api/src/loci/formats/ImageReader.java +++ b/components/formats-api/src/loci/formats/ImageReader.java @@ -134,11 +134,10 @@ public ImageReader(ClassList classList) { for (int i=0; i classList) { for (int i=0; i Date: Tue, 9 Apr 2024 16:01:46 -0500 Subject: [PATCH 026/100] Fix some deprecation warnings in test-suite component --- .../src/loci/tests/testng/Configuration.java | 32 +++++++++---------- .../loci/tests/testng/FormatWriterTest.java | 10 +++--- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/components/test-suite/src/loci/tests/testng/Configuration.java b/components/test-suite/src/loci/tests/testng/Configuration.java index 6a4b26d35a4..1494cb8ccd6 100644 --- a/components/test-suite/src/loci/tests/testng/Configuration.java +++ b/components/test-suite/src/loci/tests/testng/Configuration.java @@ -202,12 +202,12 @@ public boolean doTest() { if (delim >= 0) { test = test.substring(0, delim); } - return new Boolean(test.trim()).booleanValue(); + return Boolean.parseBoolean(test.trim()); } public boolean hasValidXML() { if (globalTable.get(HAS_VALID_XML) == null) return true; - return new Boolean(globalTable.get(HAS_VALID_XML)).booleanValue(); + return Boolean.parseBoolean(globalTable.get(HAS_VALID_XML)); } public String getReader() { @@ -261,19 +261,19 @@ public String getDimensionOrder() { } public boolean isInterleaved() { - return new Boolean(currentTable.get(IS_INTERLEAVED)).booleanValue(); + return Boolean.parseBoolean(currentTable.get(IS_INTERLEAVED)); } public boolean isIndexed() { - return new Boolean(currentTable.get(IS_INDEXED)).booleanValue(); + return Boolean.parseBoolean(currentTable.get(IS_INDEXED)); } public boolean isFalseColor() { - return new Boolean(currentTable.get(IS_FALSE_COLOR)).booleanValue(); + return Boolean.parseBoolean(currentTable.get(IS_FALSE_COLOR)); } public boolean isRGB() { - return new Boolean(currentTable.get(IS_RGB)).booleanValue(); + return Boolean.parseBoolean(currentTable.get(IS_RGB)); } public int getThumbSizeX() { @@ -289,7 +289,7 @@ public String getPixelType() { } public boolean isLittleEndian() { - return new Boolean(currentTable.get(IS_LITTLE_ENDIAN)).booleanValue(); + return Boolean.parseBoolean(currentTable.get(IS_LITTLE_ENDIAN)); } public String getMD5() { @@ -324,7 +324,7 @@ public Time getTimeIncrement() { String timeIncrement = currentTable.get(TIME_INCREMENT); String timeIncrementUnits = currentTable.get(TIME_INCREMENT_UNIT); try { - return timeIncrement == null ? null : FormatTools.getTime(new Double(timeIncrement), timeIncrementUnits); + return timeIncrement == null ? null : FormatTools.getTime(DataTools.parseDouble(timeIncrement), timeIncrementUnits); } catch (NumberFormatException e) { return null; @@ -351,7 +351,7 @@ public Time getExposureTime(int channel) { String exposure = currentTable.get(EXPOSURE_TIME + channel); String exposureUnits = currentTable.get(EXPOSURE_TIME_UNIT + channel); try { - return exposure == null ? null : FormatTools.getTime(new Double(exposure), exposureUnits); + return exposure == null ? null : FormatTools.getTime(DataTools.parseDouble(exposure), exposureUnits); } catch (NumberFormatException e) { return null; @@ -360,12 +360,12 @@ public Time getExposureTime(int channel) { public Double getDeltaT(int plane) { String deltaT = currentTable.get(DELTA_T + plane); - return deltaT == null ? null : new Double(deltaT); + return deltaT == null ? null : DataTools.parseDouble(deltaT); } public Double getPositionX(int plane) { String pos = currentTable.get(X_POSITION + plane); - return pos == null ? null : new Double(pos); + return pos == null ? null : DataTools.parseDouble(pos); } public String getPositionXUnit(int plane) { @@ -374,7 +374,7 @@ public String getPositionXUnit(int plane) { public Double getPositionY(int plane) { String pos = currentTable.get(Y_POSITION + plane); - return pos == null ? null : new Double(pos); + return pos == null ? null : DataTools.parseDouble(pos); } public String getPositionYUnit(int plane) { @@ -383,7 +383,7 @@ public String getPositionYUnit(int plane) { public Double getPositionZ(int plane) { String pos = currentTable.get(Z_POSITION + plane); - return pos == null ? null : new Double(pos); + return pos == null ? null : DataTools.parseDouble(pos); } public String getPositionZUnit(int plane) { @@ -394,7 +394,7 @@ public Length getEmissionWavelength(int channel) { String wavelength = currentTable.get(EMISSION_WAVELENGTH + channel); String emissionUnits = currentTable.get(EMISSION_WAVELENGTH_UNIT + channel); try { - return wavelength == null ? null : FormatTools.getWavelength(new Double(wavelength), emissionUnits); + return wavelength == null ? null : FormatTools.getWavelength(DataTools.parseDouble(wavelength), emissionUnits); } catch (NumberFormatException e) { return null; @@ -405,7 +405,7 @@ public Length getExcitationWavelength(int channel) { String wavelength = currentTable.get(EXCITATION_WAVELENGTH + channel); String excitationUnits = currentTable.get(EXCITATION_WAVELENGTH_UNIT + channel); try { - return wavelength == null ? null : FormatTools.getWavelength(new Double(wavelength), excitationUnits); + return wavelength == null ? null : FormatTools.getWavelength(DataTools.parseDouble(wavelength), excitationUnits); } catch (NumberFormatException e) { return null; @@ -828,7 +828,7 @@ private Length getPhysicalSize(String valueKey, String unitKey) { String units = currentTable.get(unitKey); try { UnitsLength unit = units == null ? UnitsLength.MICROMETER : UnitsLength.fromString(units); - return physicalSize == null ? null : UnitsLength.create(new Double(physicalSize), unit); + return physicalSize == null ? null : UnitsLength.create(DataTools.parseDouble(physicalSize), unit); } catch (NumberFormatException e) { } catch (EnumerationException e) { } diff --git a/components/test-suite/src/loci/tests/testng/FormatWriterTest.java b/components/test-suite/src/loci/tests/testng/FormatWriterTest.java index 5d8846d6f42..e79f0df3e36 100644 --- a/components/test-suite/src/loci/tests/testng/FormatWriterTest.java +++ b/components/test-suite/src/loci/tests/testng/FormatWriterTest.java @@ -110,16 +110,15 @@ public Object[][] getWriterList() { String[] compressionTypes = writers[i].getCompressionTypes(); if (compressionTypes == null) { try { - IFormatWriter w = (IFormatWriter) writers[i].getClass().newInstance(); + IFormatWriter w = (IFormatWriter) writers[i].getClass().getDeclaredConstructor().newInstance(); tmp.add(w); } - catch (InstantiationException ie) { } - catch (IllegalAccessException iae) { } + catch (ReflectiveOperationException roe) { } continue; } for (int q=0; q Date: Thu, 11 Apr 2024 11:01:46 -0500 Subject: [PATCH 027/100] Columbus: update to use micrometers instead of `reference frame` for positions See https://github.com/ome/bioformats/pull/4147#pullrequestreview-1989199061 --- .../src/loci/formats/in/ColumbusReader.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/ColumbusReader.java b/components/formats-gpl/src/loci/formats/in/ColumbusReader.java index fcf52845653..8d607462d62 100644 --- a/components/formats-gpl/src/loci/formats/in/ColumbusReader.java +++ b/components/formats-gpl/src/loci/formats/in/ColumbusReader.java @@ -388,8 +388,8 @@ public int compare(Plane p1, Plane p2) { store.setWellSampleIndex(new NonNegativeInteger(wellSample), 0, nextWell, field); if (p != null) { - store.setWellSamplePositionX(new Length(p.positionX, UNITS.REFERENCEFRAME), 0, nextWell, field); - store.setWellSamplePositionY(new Length(p.positionY, UNITS.REFERENCEFRAME), 0, nextWell, field); + store.setWellSamplePositionX(new Length(p.positionX, UNITS.MICROMETER), 0, nextWell, field); + store.setWellSamplePositionY(new Length(p.positionY, UNITS.MICROMETER), 0, nextWell, field); } String imageID = MetadataTools.createLSID("Image", wellSample); @@ -432,10 +432,10 @@ public int compare(Plane p1, Plane p2) { p = lookupPlane(row, col, field, t, c, z); if (p != null) { p.series = wellSample; - - store.setPlanePositionX(new Length(p.positionX, UNITS.REFERENCEFRAME), p.series, getIndex(z, c, t)); - store.setPlanePositionY(new Length(p.positionY, UNITS.REFERENCEFRAME), p.series, getIndex(z, c, t)); - store.setPlanePositionZ(new Length(p.positionZ, UNITS.REFERENCEFRAME), p.series, getIndex(z, c, t)); + + store.setPlanePositionX(new Length(p.positionX, UNITS.MICROMETER), p.series, getIndex(z, c, t)); + store.setPlanePositionY(new Length(p.positionY, UNITS.MICROMETER), p.series, getIndex(z, c, t)); + store.setPlanePositionZ(new Length(p.positionZ, UNITS.MICROMETER), p.series, getIndex(z, c, t)); } } } @@ -586,6 +586,9 @@ else if (name.equals("PositionZ")) { } + /** + * Calculate value in micrometers based on input value and units. + */ private Double correctUnits(Double v, String unit) { if (unit == null) { return v; From 4662b65c5567a25bb210353b08b8ea561123d759 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 11 Apr 2024 12:07:02 -0500 Subject: [PATCH 028/100] Fix use of DataTools.parseDouble so that empty strings are handled correctly --- .../src/loci/tests/testng/Configuration.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/components/test-suite/src/loci/tests/testng/Configuration.java b/components/test-suite/src/loci/tests/testng/Configuration.java index 1494cb8ccd6..41bf0add6d2 100644 --- a/components/test-suite/src/loci/tests/testng/Configuration.java +++ b/components/test-suite/src/loci/tests/testng/Configuration.java @@ -324,7 +324,8 @@ public Time getTimeIncrement() { String timeIncrement = currentTable.get(TIME_INCREMENT); String timeIncrementUnits = currentTable.get(TIME_INCREMENT_UNIT); try { - return timeIncrement == null ? null : FormatTools.getTime(DataTools.parseDouble(timeIncrement), timeIncrementUnits); + Double time = DataTools.parseDouble(timeIncrement); + return time == null ? null : FormatTools.getTime(time, timeIncrementUnits); } catch (NumberFormatException e) { return null; @@ -351,7 +352,8 @@ public Time getExposureTime(int channel) { String exposure = currentTable.get(EXPOSURE_TIME + channel); String exposureUnits = currentTable.get(EXPOSURE_TIME_UNIT + channel); try { - return exposure == null ? null : FormatTools.getTime(DataTools.parseDouble(exposure), exposureUnits); + Double exp = DataTools.parseDouble(exposure); + return exp == null ? null : FormatTools.getTime(exp, exposureUnits); } catch (NumberFormatException e) { return null; @@ -394,7 +396,8 @@ public Length getEmissionWavelength(int channel) { String wavelength = currentTable.get(EMISSION_WAVELENGTH + channel); String emissionUnits = currentTable.get(EMISSION_WAVELENGTH_UNIT + channel); try { - return wavelength == null ? null : FormatTools.getWavelength(DataTools.parseDouble(wavelength), emissionUnits); + Double wave = DataTools.parseDouble(wavelength); + return wave == null ? null : FormatTools.getWavelength(wave, emissionUnits); } catch (NumberFormatException e) { return null; @@ -405,7 +408,8 @@ public Length getExcitationWavelength(int channel) { String wavelength = currentTable.get(EXCITATION_WAVELENGTH + channel); String excitationUnits = currentTable.get(EXCITATION_WAVELENGTH_UNIT + channel); try { - return wavelength == null ? null : FormatTools.getWavelength(DataTools.parseDouble(wavelength), excitationUnits); + Double wave = DataTools.parseDouble(wavelength); + return wave == null ? null : FormatTools.getWavelength(wave, excitationUnits); } catch (NumberFormatException e) { return null; @@ -828,7 +832,8 @@ private Length getPhysicalSize(String valueKey, String unitKey) { String units = currentTable.get(unitKey); try { UnitsLength unit = units == null ? UnitsLength.MICROMETER : UnitsLength.fromString(units); - return physicalSize == null ? null : UnitsLength.create(DataTools.parseDouble(physicalSize), unit); + Double size = DataTools.parseDouble(physicalSize); + return size == null ? null : UnitsLength.create(size, unit); } catch (NumberFormatException e) { } catch (EnumerationException e) { } From be40e042362bb3f797a019d829d5c0e3b0b2433e Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 11 Apr 2024 13:50:39 -0500 Subject: [PATCH 029/100] Add test for number of OME-XML channels written by "bfconvert -channel 1" --- .../formats/tools/ImageConverterTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/components/bio-formats-tools/test/loci/formats/tools/ImageConverterTest.java b/components/bio-formats-tools/test/loci/formats/tools/ImageConverterTest.java index f7a3d0ba913..29f1a4c995b 100644 --- a/components/bio-formats-tools/test/loci/formats/tools/ImageConverterTest.java +++ b/components/bio-formats-tools/test/loci/formats/tools/ImageConverterTest.java @@ -42,17 +42,21 @@ import java.util.ArrayList; import java.util.Arrays; +import loci.common.services.ServiceFactory; import loci.formats.ClassList; import loci.formats.IFormatReader; import loci.formats.ImageReader; import loci.formats.ImageWriter; import loci.formats.FormatException; +import loci.formats.meta.IMetadata; import loci.formats.tools.ImageConverter; import loci.formats.in.ICSReader; import loci.formats.in.OMETiffReader; import loci.formats.in.TiffDelegateReader; import loci.formats.in.TiffReader; import loci.formats.out.OMETiffWriter; +import loci.formats.services.OMEXMLService; +import loci.formats.tiff.TiffParser; import org.apache.commons.lang.ArrayUtils; import org.testng.annotations.AfterClass; @@ -369,6 +373,27 @@ public void testConvertResolutions() throws FormatException, IOException { assertConversion(args); } + @Test + public void testConvertSingleChannel() throws FormatException, IOException { + outFile = getOutFile("single-channel.ome.tiff"); + String[] args = { + "single-channel&sizeC=3.fake", "-channel", "1", outFile.getAbsolutePath() + }; + assertConversion(args); + + try (TiffParser parser = new TiffParser(outFile.getAbsolutePath())) { + String comment = parser.getComment(); + + final OMEXMLService service = + new ServiceFactory().getInstance(OMEXMLService.class); + IMetadata meta = service.createOMEXMLMetadata(comment); + assertEquals(meta.getChannelCount(0), 1); + } + catch (Exception e) { + throw new FormatException(e); + } + } + private Path getTempSubdir() throws IOException { Path subdir = Files.createTempDirectory(tempDir, "ImageConverterTest"); subdir.toFile().deleteOnExit(); From b78a93fd0d35a828345d04761cd2b4b0f9fda194 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Fri, 12 Apr 2024 10:58:50 -0500 Subject: [PATCH 030/100] DICOM writer: allow different tile sizes for each resolution This provides better precompressed tile support for input formats that don't have a constant tile size across all resolutions. --- .../src/loci/formats/out/DicomWriter.java | 98 ++++++++++++++++--- 1 file changed, 86 insertions(+), 12 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index b3f25f64dd4..04c0c867444 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -113,6 +113,9 @@ public class DicomWriter extends FormatWriter implements IExtraMetadataWriter { private int baseTileHeight = 256; private int[] tileWidth; private int[] tileHeight; + private long[] tileWidthPointer; + private long[] tileHeightPointer; + private long[] tileCountPointer; private PlaneOffset[][] planeOffsets; private Integer currentPlane = null; private UIDCreator uids; @@ -279,6 +282,13 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) boolean first = x == 0 && y == 0; boolean last = x + w == getSizeX() && y + h == getSizeY(); + int width = getSizeX(); + int height = getSizeY(); + int sizeZ = r.getPixelsSizeZ(series).getValue().intValue(); + + int tileCountX = (int) Math.ceil((double) width / tileWidth[resolutionIndex]); + int tileCountY = (int) Math.ceil((double) height / tileHeight[resolutionIndex]); + // the compression type isn't supplied to the writer until // after setId is called, so metadata that indicates or // depends on the compression type needs to be set in @@ -296,6 +306,15 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) if (getTIFFCompression() == TiffCompression.JPEG) { ifds[resolutionIndex][no].put(IFD.PHOTOMETRIC_INTERPRETATION, PhotoInterp.Y_CB_CR.getCode()); } + + out.seek(tileWidthPointer[resolutionIndex]); + out.writeShort((short) getTileSizeX()); + out.seek(tileHeightPointer[resolutionIndex]); + out.writeShort((short) getTileSizeY()); + out.seek(tileCountPointer[resolutionIndex]); + + out.writeBytes(padString(String.valueOf( + tileCountX * tileCountY * sizeZ * r.getChannelCount(series)))); } out.seek(out.length()); @@ -334,6 +353,17 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) if (ifds[resolutionIndex][no] != null) { tileByteCounts = (long[]) ifds[resolutionIndex][no].getIFDValue(IFD.TILE_BYTE_COUNTS); tileOffsets = (long[]) ifds[resolutionIndex][no].getIFDValue(IFD.TILE_OFFSETS); + + if (tileByteCounts.length < tileCountX * tileCountY) { + long[] newTileByteCounts = new long[tileCountX * tileCountY]; + long[] newTileOffsets = new long[tileCountX * tileCountY]; + System.arraycopy(tileByteCounts, 0, newTileByteCounts, 0, tileByteCounts.length); + System.arraycopy(tileOffsets, 0, newTileOffsets, 0, tileOffsets.length); + tileByteCounts = newTileByteCounts; + tileOffsets = newTileOffsets; + ifds[resolutionIndex][no].put(IFD.TILE_BYTE_COUNTS, tileByteCounts); + ifds[resolutionIndex][no].put(IFD.TILE_OFFSETS, tileOffsets); + } } if (tileByteCounts != null) { @@ -640,6 +670,9 @@ public void setId(String id) throws FormatException, IOException { planeOffsets = new PlaneOffset[totalFiles][]; tileWidth = new int[totalFiles]; tileHeight = new int[totalFiles]; + tileWidthPointer = new long[totalFiles]; + tileHeightPointer = new long[totalFiles]; + tileCountPointer = new long[totalFiles]; // create UIDs that must be consistent across all files in the dataset String specimenUIDValue = uids.getUID(); @@ -739,8 +772,9 @@ public void setId(String id) throws FormatException, IOException { int tileCountX = (int) Math.ceil((double) width / tileWidth[resolutionIndex]); int tileCountY = (int) Math.ceil((double) height / tileHeight[resolutionIndex]); DicomTag numberOfFrames = new DicomTag(NUMBER_OF_FRAMES, IS); + // save space for up to 10 digits numberOfFrames.value = padString(String.valueOf( - tileCountX * tileCountY * sizeZ * r.getChannelCount(pyramid))); + tileCountX * tileCountY * sizeZ * r.getChannelCount(pyramid)), " ", 10); tags.add(numberOfFrames); DicomTag matrixFrames = new DicomTag(TOTAL_PIXEL_MATRIX_FOCAL_PLANES, UL); @@ -1374,6 +1408,9 @@ public void close() throws IOException { ifds = null; tiffSaver = null; validPixelCount = null; + tileWidthPointer = null; + tileHeightPointer = null; + tileCountPointer = null; tagProviders.clear(); @@ -1382,33 +1419,46 @@ public void close() throws IOException { @Override public int setTileSizeX(int tileSize) throws FormatException { - // TODO: this currently enforces the same tile size across all resolutions - // since the tile size is written during setId - // the tile size should probably be configurable per resolution, - // for better pre-compressed tile support if (currentId == null) { baseTileWidth = tileSize; + return baseTileWidth; } - return baseTileWidth; + + int resolutionIndex = getIndex(series, resolution); + tileWidth[resolutionIndex] = tileSize; + return tileWidth[resolutionIndex]; } @Override public int getTileSizeX() { - return baseTileWidth; + if (currentId == null) { + return baseTileWidth; + } + + int resolutionIndex = getIndex(series, resolution); + return tileWidth[resolutionIndex]; } @Override public int setTileSizeY(int tileSize) throws FormatException { - // TODO: see note in setTileSizeX above if (currentId == null) { baseTileHeight = tileSize; + return baseTileHeight; } - return baseTileHeight; + + int resolutionIndex = getIndex(series, resolution); + tileHeight[resolutionIndex] = tileSize; + return tileHeight[resolutionIndex]; } @Override public int getTileSizeY() { - return baseTileHeight; + if (currentId == null) { + return baseTileHeight; + } + + int resolutionIndex = getIndex(series, resolution); + return tileHeight[resolutionIndex]; } // -- DicomWriter-specific methods -- @@ -1468,15 +1518,25 @@ private void writeTag(DicomTag tag) throws IOException { out.writeShort((short) getStoredLength(tag)); } + int resolutionIndex = getIndex(series, resolution); if (tag.attribute == TRANSFER_SYNTAX_UID) { - transferSyntaxPointer[getIndex(series, resolution)] = out.getFilePointer(); + transferSyntaxPointer[resolutionIndex] = out.getFilePointer(); } else if (tag.attribute == LOSSY_IMAGE_COMPRESSION_METHOD) { - compressionMethodPointer[getIndex(series, resolution)] = out.getFilePointer(); + compressionMethodPointer[resolutionIndex] = out.getFilePointer(); } else if (tag.attribute == FILE_META_INFO_GROUP_LENGTH) { fileMetaLengthPointer = out.getFilePointer(); } + else if (tag.attribute == ROWS) { + tileHeightPointer[resolutionIndex] = out.getFilePointer(); + } + else if (tag.attribute == COLUMNS) { + tileWidthPointer[resolutionIndex] = out.getFilePointer(); + } + else if (tag.attribute == NUMBER_OF_FRAMES) { + tileCountPointer[resolutionIndex] = out.getFilePointer(); + } // sequences with no items still need to write a SequenceDelimitationItem below if (tag.children.size() == 0 && tag.value == null && tag.vr != SQ) { @@ -1665,6 +1725,17 @@ private String padString(String value, String append) { return value + append; } + private String padString(String value, String append, int length) { + String rtn = ""; + if (value != null) { + rtn += value; + } + while (rtn.length() < length) { + rtn += append; + } + return rtn; + } + /** * @return transfer syntax UID corresponding to the current compression type */ @@ -1918,6 +1989,9 @@ private void writeIFDs(int resIndex) throws IOException { out.seek(ifdStart); for (int no=0; no Date: Fri, 12 Apr 2024 10:59:41 -0500 Subject: [PATCH 031/100] NDPI: fix tile size and precompressed tile reading for extra images --- .../src/loci/formats/in/NDPIReader.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/NDPIReader.java b/components/formats-gpl/src/loci/formats/in/NDPIReader.java index 4b3611b2412..505df562974 100644 --- a/components/formats-gpl/src/loci/formats/in/NDPIReader.java +++ b/components/formats-gpl/src/loci/formats/in/NDPIReader.java @@ -169,7 +169,14 @@ public byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws Forma IFD ifd = ifds.get(ifdIndex); if (useTiffParser(ifd)) { - return copyTile(ifd, buf, x, y); + try (RandomAccessInputStream s = new RandomAccessInputStream(currentId)) { + tiffParser = new TiffParser(s); + tiffParser.setUse64BitOffsets(true); + return copyTile(ifd, buf, x, y); + } + finally { + tiffParser.getStream().close(); + } } if (initializedSeries != getCoreIndex() || initializedPlane != no) { @@ -352,8 +359,7 @@ public int getOptimalTileWidth() { IFD ifd = ifds.get(ifdIndex); try { if (useTiffParser(ifd)) { - // TODO: - return 1024; + return (int) ifd.getTileWidth(); } if (initializedSeries != getCoreIndex() || initializedPlane != no) { @@ -379,8 +385,7 @@ public int getOptimalTileHeight() { IFD ifd = ifds.get(ifdIndex); try { if (useTiffParser(ifd)) { - // TODO: - return 1024; + return (int) ifd.getTileLength(); } if (initializedSeries != getCoreIndex() || initializedPlane != no) { From 6bc132acac3676866401add2138f0c1bddda448e Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Fri, 12 Apr 2024 16:45:55 -0500 Subject: [PATCH 032/100] Fix Java 9+ warnings in formats-gpl component --- .../src/loci/formats/in/AIMReader.java | 13 +- .../src/loci/formats/in/AliconaReader.java | 7 +- .../src/loci/formats/in/BDReader.java | 12 +- .../src/loci/formats/in/BaseZeissReader.java | 34 +-- .../src/loci/formats/in/BioRadReader.java | 21 +- .../src/loci/formats/in/BioRadSCNReader.java | 19 +- .../src/loci/formats/in/BrukerReader.java | 4 +- .../src/loci/formats/in/CellSensReader.java | 44 ++-- .../src/loci/formats/in/CellWorxReader.java | 22 +- .../src/loci/formats/in/ColumbusReader.java | 22 +- .../loci/formats/in/DeltavisionReader.java | 24 +- .../src/loci/formats/in/Ecat7Reader.java | 6 +- .../src/loci/formats/in/FEITiffReader.java | 17 +- .../src/loci/formats/in/FV1000Reader.java | 4 +- .../src/loci/formats/in/FlexReader.java | 16 +- .../src/loci/formats/in/FluoviewReader.java | 21 +- .../src/loci/formats/in/GatanDM2Reader.java | 5 +- .../src/loci/formats/in/GelReader.java | 2 +- .../src/loci/formats/in/HRDGDFReader.java | 10 +- .../loci/formats/in/HamamatsuVMSReader.java | 11 +- .../src/loci/formats/in/HitachiReader.java | 4 +- .../src/loci/formats/in/IMODReader.java | 11 +- .../src/loci/formats/in/INRReader.java | 7 +- .../src/loci/formats/in/IPLabReader.java | 14 +- .../src/loci/formats/in/IPWReader.java | 2 +- .../src/loci/formats/in/ImarisHDFReader.java | 12 +- .../src/loci/formats/in/ImarisTiffReader.java | 5 +- .../src/loci/formats/in/InCellReader.java | 16 +- .../src/loci/formats/in/InveonReader.java | 15 +- .../src/loci/formats/in/IvisionReader.java | 11 +- .../src/loci/formats/in/KodakReader.java | 11 +- .../src/loci/formats/in/L2DReader.java | 2 +- .../src/loci/formats/in/LIFReader.java | 2 +- .../src/loci/formats/in/LeicaHandler.java | 53 ++-- .../src/loci/formats/in/LeicaReader.java | 16 +- .../src/loci/formats/in/LeicaSCNReader.java | 7 +- .../src/loci/formats/in/LiFlimReader.java | 10 +- .../src/loci/formats/in/MIASReader.java | 10 +- .../src/loci/formats/in/MetamorphHandler.java | 2 +- .../src/loci/formats/in/MetamorphReader.java | 8 +- .../src/loci/formats/in/MicroCTReader.java | 4 +- .../src/loci/formats/in/ND2Handler.java | 13 +- .../src/loci/formats/in/ND2Reader.java | 6 +- .../src/loci/formats/in/NDPIReader.java | 2 +- .../src/loci/formats/in/NiftiReader.java | 8 +- .../src/loci/formats/in/NikonTiffReader.java | 13 +- .../src/loci/formats/in/OIRReader.java | 4 +- .../loci/formats/in/OlympusTileReader.java | 4 +- .../src/loci/formats/in/OpenlabReader.java | 9 +- .../src/loci/formats/in/OperettaReader.java | 1 + .../src/loci/formats/in/PCORAWReader.java | 2 +- .../src/loci/formats/in/PDSReader.java | 4 +- .../loci/formats/in/PerkinElmerReader.java | 8 +- .../src/loci/formats/in/PrairieMetadata.java | 6 +- .../src/loci/formats/in/PrairieReader.java | 6 +- .../src/loci/formats/in/SBIGReader.java | 10 +- .../src/loci/formats/in/SDTInfo.java | 236 +++++++++--------- .../src/loci/formats/in/SVSReader.java | 6 +- .../src/loci/formats/in/ScanrReader.java | 12 +- .../loci/formats/in/SimplePCITiffReader.java | 5 +- .../loci/formats/in/SlidebookTiffReader.java | 5 +- .../src/loci/formats/in/SpiderReader.java | 2 +- .../src/loci/formats/in/TCSReader.java | 2 +- .../src/loci/formats/in/ZeissCZIReader.java | 125 +++++----- .../src/loci/formats/in/ZeissLSMReader.java | 10 +- 65 files changed, 547 insertions(+), 488 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/AIMReader.java b/components/formats-gpl/src/loci/formats/in/AIMReader.java index d40c79bdb66..7f291eebc2b 100644 --- a/components/formats-gpl/src/loci/formats/in/AIMReader.java +++ b/components/formats-gpl/src/loci/formats/in/AIMReader.java @@ -27,6 +27,7 @@ import java.io.IOException; +import loci.common.DataTools; import loci.common.DateTools; import loci.common.RandomAccessInputStream; import loci.formats.CoreMetadata; @@ -152,13 +153,13 @@ else if (key.equals("Orig-ISQ-Dim-p")) { token = token.trim(); if (token.length() > 0) { if (xSize == null) { - xSize = new Double(token); + xSize = DataTools.parseDouble(token); } else if (ySize == null) { - ySize = new Double(token); + ySize = DataTools.parseDouble(token); } else if (zSize == null) { - zSize = new Double(token); + zSize = DataTools.parseDouble(token); } } } @@ -169,13 +170,13 @@ else if (key.equals("Orig-ISQ-Dim-um")) { token = token.trim(); if (token.length() > 0) { if (xLength == null) { - xLength = new Double(token); + xLength = DataTools.parseDouble(token); } else if (yLength == null) { - yLength = new Double(token); + yLength = DataTools.parseDouble(token); } else if (zLength == null) { - zLength = new Double(token); + zLength = DataTools.parseDouble(token); } } } diff --git a/components/formats-gpl/src/loci/formats/in/AliconaReader.java b/components/formats-gpl/src/loci/formats/in/AliconaReader.java index fffe5538280..fa9f85129bb 100644 --- a/components/formats-gpl/src/loci/formats/in/AliconaReader.java +++ b/components/formats-gpl/src/loci/formats/in/AliconaReader.java @@ -27,6 +27,7 @@ import java.io.IOException; +import loci.common.DataTools; import loci.common.RandomAccessInputStream; import loci.formats.CoreMetadata; import loci.formats.FormatException; @@ -238,7 +239,7 @@ else if (key.equals("DepthImageOffset")) { // used when the dataset was acquired, i.e. detector settings. if (voltage != null) { store.setDetectorSettingsVoltage( - new ElectricPotential(new Double(voltage), UNITS.VOLT), 0, 0); + new ElectricPotential(DataTools.parseDouble(voltage), UNITS.VOLT), 0, 0); // link DetectorSettings to an actual Detector String detectorID = MetadataTools.createLSID("Detector", 0, 0); @@ -253,11 +254,11 @@ else if (key.equals("DepthImageOffset")) { if (magnification != null) { store.setObjectiveCalibratedMagnification( - new Double(magnification), 0, 0); + DataTools.parseDouble(magnification), 0, 0); } if (workingDistance != null) { - store.setObjectiveWorkingDistance(new Length(new Double(workingDistance), UNITS.MICROMETER), 0, 0); + store.setObjectiveWorkingDistance(new Length(DataTools.parseDouble(workingDistance), UNITS.MICROMETER), 0, 0); } store.setObjectiveCorrection(MetadataTools.getCorrection("Other"), 0, 0); diff --git a/components/formats-gpl/src/loci/formats/in/BDReader.java b/components/formats-gpl/src/loci/formats/in/BDReader.java index 0d40fede37e..75a529c11d1 100644 --- a/components/formats-gpl/src/loci/formats/in/BDReader.java +++ b/components/formats-gpl/src/loci/formats/in/BDReader.java @@ -460,11 +460,11 @@ protected void initFile(String id) throws FormatException, IOException { } } - Double magnification = new Double(mag); + Double magnification = DataTools.parseDouble(mag); store.setObjectiveNominalMagnification(magnification, 0, 0); if (na != null) { na = na.substring(0, 1) + "." + na.substring(1); - store.setObjectiveLensNA(new Double(na), 0, 0); + store.setObjectiveLensNA(DataTools.parseDouble(na), 0, 0); } if (naIndex + 1 < tokens.length) { store.setObjectiveManufacturer(tokens[naIndex + 1], 0, 0); @@ -762,10 +762,10 @@ private void parseROIs(MetadataStore store) throws IOException { if (cols[2].trim().length() > 0) { String rectangleID = MetadataTools.createLSID("Shape", i - firstRow, 0); store.setRectangleID(rectangleID, i - firstRow, 0); - store.setRectangleX(new Double(cols[2]), i - firstRow, 0); - store.setRectangleY(new Double(cols[3]), i - firstRow, 0); - store.setRectangleWidth(new Double(cols[4]), i - firstRow, 0); - store.setRectangleHeight(new Double(cols[5]), i - firstRow, 0); + store.setRectangleX(DataTools.parseDouble(cols[2]), i - firstRow, 0); + store.setRectangleY(DataTools.parseDouble(cols[3]), i - firstRow, 0); + store.setRectangleWidth(DataTools.parseDouble(cols[4]), i - firstRow, 0); + store.setRectangleHeight(DataTools.parseDouble(cols[5]), i - firstRow, 0); String roiID = MetadataTools.createLSID("ROI", i - firstRow); store.setROIID(roiID, i - firstRow); for (int s=0; s offset.size()) { offset.add(null); } - offset.add(new Double(value)); + offset.add(DataTools.parseDouble(value)); } } else if (key.endsWith("GAIN")) { @@ -684,7 +685,7 @@ else if (key.endsWith("GAIN")) { while (nextDetector > gain.size()) { gain.add(null); } - gain.add(new Double(value)); + gain.add(DataTools.parseDouble(value)); } } nextDetector++; @@ -698,7 +699,7 @@ else if (key.endsWith("GAIN")) { int type = Integer.parseInt(values[0]); if (type == 257 && values.length >= 3) { // found length of axis in um - Double pixelSize = new Double(values[2]); + Double pixelSize = DataTools.parseDouble(values[2]); if (key.equals("AXIS_2")) { Length size = FormatTools.getPhysicalSizeX(pixelSize); @@ -722,7 +723,7 @@ else if (key.equals("AXIS_3")) { } else if (n.p.startsWith("AXIS_2")) { String[] values = n.p.split(" "); - Double pixelSize = new Double(values[3]); + Double pixelSize = DataTools.parseDouble(values[3]); Length size = FormatTools.getPhysicalSizeX(pixelSize); if (size != null) { store.setPixelsPhysicalSizeX(size, 0); @@ -730,7 +731,7 @@ else if (n.p.startsWith("AXIS_2")) { } else if (n.p.startsWith("AXIS_3")) { String[] values = n.p.split(" "); - Double pixelSize = new Double(values[3]); + Double pixelSize = DataTools.parseDouble(values[3]); Length size = FormatTools.getPhysicalSizeY(pixelSize); if (size != null) { store.setPixelsPhysicalSizeY(size, 0); @@ -754,7 +755,7 @@ else if (n.p.startsWith("AXIS_3")) { Double mag = Double.parseDouble(values[11]); store.setObjectiveNominalMagnification(mag, 0, 0); - Double sizeZ = new Double(values[14]); + Double sizeZ = DataTools.parseDouble(values[14]); Length size = FormatTools.getPhysicalSizeZ(sizeZ); if (size != null) { store.setPixelsPhysicalSizeZ(size, 0); @@ -851,8 +852,8 @@ else if (n.p.startsWith("AXIS_3")) { String detectorID = MetadataTools.createLSID("Detector", 0, i); store.setDetectorID(detectorID, 0, i); - store.setDetectorOffset(new Double(values[i * 3]), 0, i); - store.setDetectorGain(new Double(values[i * 3 + 1]), 0, i); + store.setDetectorOffset(DataTools.parseDouble(values[i * 3]), 0, i); + store.setDetectorGain(DataTools.parseDouble(values[i * 3 + 1]), 0, i); store.setDetectorType(MetadataTools.getDetectorType("Other"), 0, i); } break; diff --git a/components/formats-gpl/src/loci/formats/in/BioRadSCNReader.java b/components/formats-gpl/src/loci/formats/in/BioRadSCNReader.java index 2365f8b068c..ea107fb9107 100644 --- a/components/formats-gpl/src/loci/formats/in/BioRadSCNReader.java +++ b/components/formats-gpl/src/loci/formats/in/BioRadSCNReader.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.ArrayList; +import loci.common.DataTools; import loci.common.RandomAccessInputStream; import loci.common.xml.BaseHandler; import loci.common.xml.XMLTools; @@ -245,10 +246,10 @@ else if ("channel_count".equals(key)) { core.get(0).sizeC = Integer.parseInt(value); } else if ("application_gain".equals(key)) { - gain = new Double(value); + gain = DataTools.parseDouble(value); } else if ("exposure_time".equals(key)) { - exposureTime = new Double(value); + exposureTime = DataTools.parseDouble(value); } else if ("name".equals(key)) { imageName = value; @@ -287,12 +288,18 @@ else if (value <= 65535) { } else if (key.equals("size_mm")) { if (attrKey.equals("width")) { - physicalSizeX = new Double(attrValue) / getSizeX(); - physicalSizeX *= 1000; // convert from mm to um + Double size = DataTools.parseDouble(attrValue); + if (size != null) { + physicalSizeX = size / getSizeX(); + physicalSizeX *= 1000; // convert from mm to um + } } else if (attrKey.equals("height")) { - physicalSizeY = new Double(attrValue) / getSizeY(); - physicalSizeY *= 1000; // convert from mm to um + Double size = DataTools.parseDouble(attrValue); + if (size != null) { + physicalSizeY = size / getSizeY(); + physicalSizeY *= 1000; // convert from mm to um + } } } else if (key.equals("serial_number")) { diff --git a/components/formats-gpl/src/loci/formats/in/BrukerReader.java b/components/formats-gpl/src/loci/formats/in/BrukerReader.java index 25b61f669f9..d9d6ba5ec89 100644 --- a/components/formats-gpl/src/loci/formats/in/BrukerReader.java +++ b/components/formats-gpl/src/loci/formats/in/BrukerReader.java @@ -216,12 +216,12 @@ protected void initFile(String id) throws FormatException, IOException { public int compare(String s1, String s2) { Integer i1 = 0; try { - i1 = new Integer(s1); + i1 = Integer.parseInt(s1); } catch (NumberFormatException e) { } Integer i2 = 0; try { - i2 = new Integer(s2); + i2 = Integer.parseInt(s2); } catch (NumberFormatException e) { } diff --git a/components/formats-gpl/src/loci/formats/in/CellSensReader.java b/components/formats-gpl/src/loci/formats/in/CellSensReader.java index 0884c9b4767..0abf184a7cb 100644 --- a/components/formats-gpl/src/loci/formats/in/CellSensReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellSensReader.java @@ -1746,7 +1746,7 @@ else if (extendedField && (realType == PROPERTY_SET_VOLUME || value = String.valueOf(vsi.readDouble()); break; case BOOLEAN: - value = new Boolean(vsi.readBoolean()).toString(); + value = Boolean.valueOf(vsi.readBoolean()).toString(); break; case TCHAR: case UNICODE_TCHAR: @@ -1884,72 +1884,72 @@ else if (tag == DEVICE_MANUFACTURER) { pyramid.deviceManufacturers.add(value); } else if (tag == EXPOSURE_TIME && tagPrefix.length() == 0) { - pyramid.exposureTimes.add(new Long(value)); + pyramid.exposureTimes.add(Long.parseLong(value)); } else if (tag == EXPOSURE_TIME) { - pyramid.defaultExposureTime = new Long(value); + pyramid.defaultExposureTime = Long.parseLong(value); pyramid.otherExposureTimes.add(pyramid.defaultExposureTime); } else if (tag == CREATION_TIME && pyramid.acquisitionTime == null) { - pyramid.acquisitionTime = new Long(value); + pyramid.acquisitionTime = Long.parseLong(value); } else if (tag == REFRACTIVE_INDEX) { - pyramid.refractiveIndex = new Double(value); + pyramid.refractiveIndex = DataTools.parseDouble(value); } else if (tag == OBJECTIVE_MAG) { - pyramid.magnification = new Double(value); + pyramid.magnification = DataTools.parseDouble(value); } else if (tag == NUMERICAL_APERTURE) { - pyramid.numericalAperture = new Double(value); + pyramid.numericalAperture = DataTools.parseDouble(value); } else if (tag == WORKING_DISTANCE) { - pyramid.workingDistance = new Double(value); + pyramid.workingDistance = DataTools.parseDouble(value); } else if (tag == OBJECTIVE_NAME) { pyramid.objectiveNames.add(value); } else if (tag == OBJECTIVE_TYPE) { - pyramid.objectiveTypes.add(new Integer(value)); + pyramid.objectiveTypes.add(Integer.parseInt(value)); } else if (tag == BIT_DEPTH) { - pyramid.bitDepth = new Integer(value); + pyramid.bitDepth = Integer.parseInt(value); } else if (tag == X_BINNING) { - pyramid.binningX = new Integer(value); + pyramid.binningX = Integer.parseInt(value); } else if (tag == Y_BINNING) { - pyramid.binningY = new Integer(value); + pyramid.binningY = Integer.parseInt(value); } else if (tag == CAMERA_GAIN) { - pyramid.gain = new Double(value); + pyramid.gain = DataTools.parseDouble(value); } else if (tag == CAMERA_OFFSET) { - pyramid.offset = new Double(value); + pyramid.offset = DataTools.parseDouble(value); } else if (tag == RED_GAIN) { - pyramid.redGain = new Double(value); + pyramid.redGain = DataTools.parseDouble(value); } else if (tag == GREEN_GAIN) { - pyramid.greenGain = new Double(value); + pyramid.greenGain = DataTools.parseDouble(value); } else if (tag == BLUE_GAIN) { - pyramid.blueGain = new Double(value); + pyramid.blueGain = DataTools.parseDouble(value); } else if (tag == RED_OFFSET) { - pyramid.redOffset = new Double(value); + pyramid.redOffset = DataTools.parseDouble(value); } else if (tag == GREEN_OFFSET) { - pyramid.greenOffset = new Double(value); + pyramid.greenOffset = DataTools.parseDouble(value); } else if (tag == BLUE_OFFSET) { - pyramid.blueOffset = new Double(value); + pyramid.blueOffset = DataTools.parseDouble(value); } else if (tag == VALUE) { if (tagPrefix.equals("Channel Wavelength ")) { - pyramid.channelWavelengths.add(new Double(value)); + pyramid.channelWavelengths.add(DataTools.parseDouble(value)); } else if (tagPrefix.startsWith("Objective Working Distance")) { - pyramid.workingDistance = new Double(value); + pyramid.workingDistance = DataTools.parseDouble(value); } else if (tagPrefix.equals("Z start position")) { pyramid.zStart = DataTools.parseDouble(value); diff --git a/components/formats-gpl/src/loci/formats/in/CellWorxReader.java b/components/formats-gpl/src/loci/formats/in/CellWorxReader.java index 244c81add99..1cd3593464d 100644 --- a/components/formats-gpl/src/loci/formats/in/CellWorxReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellWorxReader.java @@ -149,7 +149,7 @@ else if (key.startsWith("WellsSelection")) { int row = Integer.parseInt(key.substring(14)) - 1; String[] mapping = value.split(","); for (int col=0; col 0) { int end = value.indexOf(" ", s + 2); - Double xSize = new Double(value.substring(0, s).trim()); - Double ySize = new Double(value.substring(s + 1, end).trim()); + Double xSize = DataTools.parseDouble(value.substring(0, s).trim()); + Double ySize = DataTools.parseDouble(value.substring(s + 1, end).trim()); Length x = FormatTools.getPhysicalSizeX(xSize / getSizeX()); Length y = FormatTools.getPhysicalSizeY(ySize / getSizeY()); @@ -827,7 +827,7 @@ else if (key.startsWith("Channel")) { token = token.trim(); if (token.startsWith("gain")) { String instrumentID = MetadataTools.createLSID("Instrument", 0); - Double gain = new Double(token.replaceAll("gain ", "")); + Double gain = DataTools.parseDouble(token.replaceAll("gain ", "")); String detectorID = MetadataTools.createLSID("Detector", 0, 0); store.setInstrumentID(instrumentID, 0); @@ -854,8 +854,8 @@ else if (token.startsWith("EX")) { } } - Double emission = new Double(em); - Double excitation = new Double(ex); + Double emission = DataTools.parseDouble(em); + Double excitation = DataTools.parseDouble(ex); Length exWave = FormatTools.getExcitationWavelength(excitation); Length emWave = FormatTools.getEmissionWavelength(emission); diff --git a/components/formats-gpl/src/loci/formats/in/ColumbusReader.java b/components/formats-gpl/src/loci/formats/in/ColumbusReader.java index fcf52845653..ff22e824c02 100644 --- a/components/formats-gpl/src/loci/formats/in/ColumbusReader.java +++ b/components/formats-gpl/src/loci/formats/in/ColumbusReader.java @@ -536,7 +536,7 @@ else if (name.equals("ChannelName")) { p.channelName = value; } else if (name.equals("ChannelColor")) { - Long color = new Long(value); + Long color = Long.parseLong(value); int blue = (int) ((color >> 24) & 0xff); int green = (int) ((color >> 16) & 0xff); int red = (int) ((color >> 8) & 0xff); @@ -548,36 +548,36 @@ else if (name.equals("ChannelColor")) { //p.channelColor = new Color(red, green, blue, alpha); } else if (name.equals("MeasurementTimeOffset")) { - p.deltaT = new Double(value); + p.deltaT = DataTools.parseDouble(value); } else if (name.equals("AbsTime")) { p.deltaT = new Timestamp(value).asInstant().getMillis() / 1000d; } else if (name.equals("MainEmissionWavelength")) { - p.emWavelength = new Double(value); + p.emWavelength = DataTools.parseDouble(value); } else if (name.equals("MainExcitationWavelength")) { - p.exWavelength = new Double(value); + p.exWavelength = DataTools.parseDouble(value); } else if (name.equals("ImageResolutionX")) { String unit = attrs.getNamedItem("Unit").getNodeValue(); - p.sizeX = correctUnits(new Double(value), unit); + p.sizeX = correctUnits(DataTools.parseDouble(value), unit); } else if (name.equals("ImageResolutionY")) { String unit = attrs.getNamedItem("Unit").getNodeValue(); - p.sizeY = correctUnits(new Double(value), unit); + p.sizeY = correctUnits(DataTools.parseDouble(value), unit); } else if (name.equals("PositionX")) { String unit = attrs.getNamedItem("Unit").getNodeValue(); - p.positionX = correctUnits(new Double(value), unit); + p.positionX = correctUnits(DataTools.parseDouble(value), unit); } else if (name.equals("PositionY")) { String unit = attrs.getNamedItem("Unit").getNodeValue(); - p.positionY = correctUnits(new Double(value), unit); + p.positionY = correctUnits(DataTools.parseDouble(value), unit); } else if (name.equals("PositionZ")) { String unit = attrs.getNamedItem("Unit").getNodeValue(); - p.positionZ = correctUnits(new Double(value), unit); + p.positionZ = correctUnits(DataTools.parseDouble(value), unit); } } @@ -725,10 +725,10 @@ else if (currentName.equals("Reference")) { metadataFiles.add(new Location(value).toString()); } else if (currentName.equals("PlateRows")) { - plateRows = new Integer(value); + plateRows = Integer.parseInt(value); } else if (currentName.equals("PlateColumns")) { - plateColumns = new Integer(value); + plateColumns = Integer.parseInt(value); } currentName = null; diff --git a/components/formats-gpl/src/loci/formats/in/DeltavisionReader.java b/components/formats-gpl/src/loci/formats/in/DeltavisionReader.java index f3cc590d4d1..4d415a6f837 100644 --- a/components/formats-gpl/src/loci/formats/in/DeltavisionReader.java +++ b/components/formats-gpl/src/loci/formats/in/DeltavisionReader.java @@ -859,17 +859,17 @@ protected void initExtraMetadata() throws FormatException, IOException { } } - Double x = new Double(pixX); + Double x = Double.valueOf(pixX); Length sizeX = FormatTools.getPhysicalSizeX(x); if (sizeX != null) { store.setPixelsPhysicalSizeX(sizeX, series); } - Double y = new Double(pixY); + Double y = Double.valueOf(pixY); Length sizeY = FormatTools.getPhysicalSizeY(y); if (sizeY != null) { store.setPixelsPhysicalSizeY(sizeY, series); } - Double z = new Double(pixZ); + Double z = Double.valueOf(pixZ); Length sizeZ = FormatTools.getPhysicalSizeZ(z); if (sizeZ != null) { store.setPixelsPhysicalSizeZ(sizeZ, series); @@ -948,12 +948,12 @@ else if (backwardsStageY && xTiles == 1) { DVExtHdrFields hdr = extHdrFields[getPlaneIndex(seriesIndex, i)]; if (expTime[coords[1]] == null) { - expTime[coords[1]] = new Double(hdr.expTime); + expTime[coords[1]] = Double.valueOf(hdr.expTime); } // plane timing store.setPlaneDeltaT( - new Time(new Double(hdr.timeStampSeconds), UNITS.SECOND), series, i); + new Time(Double.valueOf(hdr.timeStampSeconds), UNITS.SECOND), series, i); store.setPlaneExposureTime(new Time(expTime[coords[1]], UNITS.SECOND), series, i); // stage position @@ -967,9 +967,9 @@ else if (backwardsStageY && xTiles == 1) { int w = coords[1]; Length emission = - FormatTools.getEmissionWavelength(new Double(waves[w])); + FormatTools.getEmissionWavelength(Double.valueOf(waves[w])); Length excitation = - FormatTools.getExcitationWavelength(new Double(hdr.exWavelen)); + FormatTools.getExcitationWavelength(Double.valueOf(hdr.exWavelen)); if (emission != null) { store.setChannelEmissionWavelength(emission, series, w); @@ -977,7 +977,7 @@ else if (backwardsStageY && xTiles == 1) { if (excitation != null) { store.setChannelExcitationWavelength(excitation, series, w); } - if (ndFilters[w] == null) ndFilters[w] = new Double(hdr.ndFilter); + if (ndFilters[w] == null) ndFilters[w] = Double.valueOf(hdr.ndFilter); store.setChannelNDFilter(ndFilters[w], series, w); } } @@ -1262,14 +1262,14 @@ private boolean parseLogFile(MetadataStore store) } try { - Double mag = new Double(magnification); + Double mag = DataTools.parseDouble(magnification); store.setObjectiveNominalMagnification(mag, 0, 0); } catch (NumberFormatException e) { LOGGER.warn("Could not parse magnification '{}'", magnification); } try { - store.setObjectiveLensNA(new Double(na), 0, 0); + store.setObjectiveLensNA(DataTools.parseDouble(na), 0, 0); } catch (NumberFormatException e) { LOGGER.warn("Could not parse N.A. '{}'", na); @@ -1308,7 +1308,7 @@ else if (key.equals("Pixel Size")) { for (int q=0; q= 0) { store.setPointTheZ(new NonNegativeInteger( (int) points[obj][contour][i][2]), obj, nextShape); @@ -347,7 +348,7 @@ protected void initFile(String id) throws FormatException, IOException { store.setPolygonID(shapeID, obj, nextShape); store.setPolygonStrokeColor( new Color(r, g, b, 0xff), obj, nextShape); - l = new Length(new Double(lineWidth2D), UNITS.PIXEL); + l = new Length(Double.valueOf(lineWidth2D), UNITS.PIXEL); store.setPolygonStrokeWidth(l, obj, nextShape); if (lineStyle == 1) { store.setPolygonStrokeDashArray("5", obj, nextShape); @@ -363,7 +364,7 @@ protected void initFile(String id) throws FormatException, IOException { store.setPolylineID(shapeID, obj, nextShape); store.setPolylineStrokeColor( new Color(r, g, b, 0xff), obj, nextShape); - l = new Length(new Double(lineWidth2D), UNITS.PIXEL); + l = new Length(Double.valueOf(lineWidth2D), UNITS.PIXEL); store.setPolylineStrokeWidth(l, obj, nextShape); if (lineStyle == 1) { store.setPolylineStrokeDashArray("5", obj, nextShape); diff --git a/components/formats-gpl/src/loci/formats/in/INRReader.java b/components/formats-gpl/src/loci/formats/in/INRReader.java index f04b8ef4923..459145c6278 100644 --- a/components/formats-gpl/src/loci/formats/in/INRReader.java +++ b/components/formats-gpl/src/loci/formats/in/INRReader.java @@ -27,6 +27,7 @@ import java.io.IOException; +import loci.common.DataTools; import loci.common.RandomAccessInputStream; import loci.formats.CoreMetadata; import loci.formats.FormatException; @@ -131,13 +132,13 @@ else if (key.equals("PIXSIZE")) { nBits = Integer.parseInt(bits); } else if (key.equals("VX")) { - physicalSizeX = new Double(value); + physicalSizeX = DataTools.parseDouble(value); } else if (key.equals("VY")) { - physicalSizeY = new Double(value); + physicalSizeY = DataTools.parseDouble(value); } else if (key.equals("VZ")) { - physicalSizeZ = new Double(value); + physicalSizeZ = DataTools.parseDouble(value); } } } diff --git a/components/formats-gpl/src/loci/formats/in/IPLabReader.java b/components/formats-gpl/src/loci/formats/in/IPLabReader.java index 922e1bade09..3c0a740f715 100644 --- a/components/formats-gpl/src/loci/formats/in/IPLabReader.java +++ b/components/formats-gpl/src/loci/formats/in/IPLabReader.java @@ -302,10 +302,10 @@ else if (tag.equals("roi ") && int numRoiPts = in.readInt(); store.setRectangleID(MetadataTools.createLSID("Shape", 0, 0), 0, 0); - store.setRectangleX(new Double(roiLeft), 0, 0); - store.setRectangleY(new Double(roiTop), 0, 0); - store.setRectangleWidth(new Double(roiRight - roiLeft), 0, 0); - store.setRectangleHeight(new Double(roiBottom - roiTop), 0, 0); + store.setRectangleX(Double.valueOf(roiLeft), 0, 0); + store.setRectangleY(Double.valueOf(roiTop), 0, 0); + store.setRectangleWidth(Double.valueOf(roiRight - roiLeft), 0, 0); + store.setRectangleHeight(Double.valueOf(roiBottom - roiTop), 0, 0); String roiID = MetadataTools.createLSID("ROI", 0, 0); store.setROIID(roiID, 0); store.setImageROIRef(roiID, 0, 0); @@ -345,7 +345,7 @@ else if (tag.equals("unit")) { break; } - if (i == 0) pixelSize = new Double(unitsPerPixel); + if (i == 0) pixelSize = Double.valueOf(unitsPerPixel); addGlobalMetaList("UnitName", xUnitName); } @@ -396,11 +396,11 @@ else if (tagBytes[0] == 0x1a && tagBytes[1] == (byte) 0xd9 && for (int c=0; c 0) { value = value.substring(0, value.indexOf(' ')); } - Double size = new Double(value); + Double size = DataTools.parseDouble(value); size = 1.0 / (size * (1.0 / 25400)); Length sizeY = FormatTools.getPhysicalSizeY(size); @@ -227,7 +228,7 @@ else if (key.equals("Horizontal Resolution")) { if (value.indexOf(' ') > 0) { value = value.substring(0, value.indexOf(' ')); } - Double size = new Double(value); + Double size = DataTools.parseDouble(value); size = 1.0 / (size * (1.0 / 25400)); Length sizeX = FormatTools.getPhysicalSizeX(size); @@ -240,11 +241,11 @@ else if (key.equals("CCD Temperature")) { Matcher hexMatcher = Pattern.compile("0x([0-9A-F]+)").matcher(value); if (hexMatcher.matches()) { // CCD temperature stored as a hexadecimal string such as "0xEB". - temp = new Double(Integer.parseInt(hexMatcher.group(1), 16)); + temp = Double.valueOf(Integer.parseInt(hexMatcher.group(1), 16)); LOGGER.debug("CCD temperature detected as {}; assumed to be invalid", temp); } else { - temp = new Double(value.substring(0, value.indexOf(' '))); + temp = DataTools.parseDouble(value.substring(0, value.indexOf(' '))); store.setImagingEnvironmentTemperature( new Temperature(temp, UNITS.CELSIUS), 0); } diff --git a/components/formats-gpl/src/loci/formats/in/L2DReader.java b/components/formats-gpl/src/loci/formats/in/L2DReader.java index a55515d06bf..3f3efd4a379 100644 --- a/components/formats-gpl/src/loci/formats/in/L2DReader.java +++ b/components/formats-gpl/src/loci/formats/in/L2DReader.java @@ -353,7 +353,7 @@ else if (key.equals("ScanChannels")) { for (int q=0; q 0) { - bytesPerAxis.put(new Integer(bytes), "C"); + bytesPerAxis.put(Integer.valueOf(bytes), "C"); } } else if (qName.equals("DimensionDescription")) { @@ -415,7 +416,7 @@ else if (unit.equals("m")) { physicalLen *= 1000000; } - Double physicalSize = new Double(physicalLen); + Double physicalSize = Double.valueOf(physicalLen); CoreMetadata coreMeta = core.get(core.size() - 1); @@ -445,11 +446,11 @@ else if (unit.equals("m")) { if (coreMeta.sizeY != 0) { if (coreMeta.sizeZ == 1) { coreMeta.sizeZ = len; - bytesPerAxis.put(new Integer(nBytes), "Z"); + bytesPerAxis.put(Integer.valueOf(nBytes), "Z"); } else if (coreMeta.sizeT == 1) { coreMeta.sizeT = len; - bytesPerAxis.put(new Integer(nBytes), "T"); + bytesPerAxis.put(Integer.valueOf(nBytes), "T"); } } else { @@ -471,11 +472,11 @@ else if (coreMeta.sizeT == 1) { if (sizeY != null) { store.setPixelsPhysicalSizeY(sizeY, numDatasets); } - bytesPerAxis.put(new Integer(nBytes), "Y"); + bytesPerAxis.put(Integer.valueOf(nBytes), "Y"); } else { coreMeta.sizeZ = len; - bytesPerAxis.put(new Integer(nBytes), "Z"); + bytesPerAxis.put(Integer.valueOf(nBytes), "Z"); } break; case 4: // T axis @@ -488,11 +489,11 @@ else if (coreMeta.sizeT == 1) { if (sizeY != null) { store.setPixelsPhysicalSizeY(sizeY, numDatasets); } - bytesPerAxis.put(new Integer(nBytes), "Y"); + bytesPerAxis.put(Integer.valueOf(nBytes), "Y"); } else { coreMeta.sizeT = len; - bytesPerAxis.put(new Integer(nBytes), "T"); + bytesPerAxis.put(Integer.valueOf(nBytes), "T"); } break; default: @@ -511,10 +512,10 @@ else if (qName.equals("ScannerSettingRecord") && store.setMicroscopeType(MicroscopeType.OTHER, numDatasets); } else if (id.equals("dblPinhole")) { - pinhole = new Double(Double.parseDouble(value) * 1000000); + pinhole = Double.valueOf(Double.parseDouble(value) * 1000000); } else if (id.equals("dblZoom")) { - zoom = new Double(value); + zoom = DataTools.parseDouble(value); } else if (id.equals("dblStepSize")) { double zStep = Double.parseDouble(value) * 1000000; @@ -524,7 +525,7 @@ else if (id.equals("dblStepSize")) { } } else if (id.equals("nDelayTime_s")) { - Double timeIncrement = new Double(value); + Double timeIncrement = DataTools.parseDouble(value); if (timeIncrement != null) { store.setPixelsTimeIncrement(new Time(timeIncrement, UNITS.SECOND), numDatasets); } @@ -542,7 +543,7 @@ else if (id.indexOf("WFC") == 1) { if (channel == null) channel = new Channel(); if (id.endsWith("ExposureTime") && c < numChannels) { try { - Double exposureTime = new Double(value); + Double exposureTime = DataTools.parseDouble(value); if (exposureTime != null) { store.setPlaneExposureTime(new Time(exposureTime, UNITS.SECOND), numDatasets, c); } @@ -550,7 +551,7 @@ else if (id.indexOf("WFC") == 1) { catch (IndexOutOfBoundsException e) { } } else if (id.endsWith("Gain")) { - channel.gain = new Double(value); + channel.gain = DataTools.parseDouble(value); String detectorID = MetadataTools.createLSID("Detector", numDatasets, 0); @@ -559,7 +560,7 @@ else if (id.endsWith("Gain")) { store.setDetectorType(DetectorType.CCD, numDatasets, 0); } else if (id.endsWith("WaveLength")) { - Double exWave = new Double(value); + Double exWave = DataTools.parseDouble(value); Length ex = FormatTools.getExcitationWavelength(exWave); if (ex != null) { channel.exWave = ex; @@ -582,7 +583,7 @@ else if (qName.equals("FilterSettingRecord") && CoreMetadata coreMeta = core.get(numDatasets); if (attribute.equals("NumericalAperture")) { - store.setObjectiveLensNA(new Double(variant), numDatasets, 0); + store.setObjectiveLensNA(DataTools.parseDouble(variant), numDatasets, 0); } else if (attribute.equals("OrderNumber")) { store.setObjectiveSerialNumber(variant, numDatasets, 0); @@ -601,11 +602,11 @@ else if (objectClass.equals("CDetectionUnit")) { } else if (attribute.equals("HighVoltage")) { Detector d = detectors.get(detectors.size() - 1); - d.voltage = new Double(variant); + d.voltage = DataTools.parseDouble(variant); } else if (attribute.equals("VideoOffset")) { Detector d = detectors.get(detectors.size() - 1); - d.offset = new Double(variant); + d.offset = DataTools.parseDouble(variant); } } else if (attribute.equals("Objective")) { @@ -622,7 +623,7 @@ else if (attribute.equals("Objective")) { String na = token.substring(x + 1); store.setObjectiveNominalMagnification(mag, numDatasets, 0); - store.setObjectiveLensNA(new Double(na), numDatasets, 0); + store.setObjectiveLensNA(DataTools.parseDouble(na), numDatasets, 0); } else { model.append(token); @@ -664,7 +665,7 @@ else if (attribute.equals("RefractionIndex")) { String id = MetadataTools.createLSID("Objective", numDatasets, 0); store.setObjectiveID(id, numDatasets, 0); store.setObjectiveSettingsID(id, numDatasets); - store.setObjectiveSettingsRefractiveIndex(new Double(variant), + store.setObjectiveSettingsRefractiveIndex(DataTools.parseDouble(variant), numDatasets); } else if (attribute.equals("XPos")) { @@ -725,9 +726,9 @@ else if (attributes.getValue("Description").endsWith("(right)")) { } else if (qName.equals("Detector") && level != MetadataLevel.MINIMUM) { String v = attributes.getValue("Gain"); - Double gain = v == null ? null : new Double(v); + Double gain = v == null ? null : DataTools.parseDouble(v); v = attributes.getValue("Offset"); - Double offset = v == null ? null : new Double(v); + Double offset = v == null ? null : DataTools.parseDouble(v); boolean active = "1".equals(attributes.getValue("IsActive")); if (active) { @@ -832,7 +833,7 @@ else if (qName.equals("LaserLineSetting") && level != MetadataLevel.MINIMUM) l.index += (2 - (qualifier / 10)); if (l.index < 0) l.index = 0; l.id = MetadataTools.createLSID("LightSource", numDatasets, l.index); - l.wavelength = new Double(attributes.getValue("LaserLine")); + l.wavelength = DataTools.parseDouble(attributes.getValue("LaserLine")); while (l.index > laserCount) { String lsid = MetadataTools.createLSID("LightSource", numDatasets, laserCount); @@ -890,7 +891,7 @@ else if (qName.equals("RelTimeStamp") && level != MetadataLevel.MINIMUM) { CoreMetadata coreMeta = core.get(numDatasets); int nImages = coreMeta.sizeZ * coreMeta.sizeT * coreMeta.sizeC; if (count < nImages) { - Double time = new Double(attributes.getValue("Time")); + Double time = DataTools.parseDouble(attributes.getValue("Time")); if (time != null) { store.setPlaneDeltaT(new Time(time, UNITS.SECOND), numDatasets, count++); } @@ -919,11 +920,11 @@ else if (qName.equals("Vertex") && level != MetadataLevel.MINIMUM) { String y = attributes.getValue("y"); if (x != null) { x = x.replaceAll(",", "."); - roi.x.add(new Double(x)); + roi.x.add(DataTools.parseDouble(x)); } if (y != null) { y = y.replaceAll(",", "."); - roi.y.add(new Double(y)); + roi.y.add(DataTools.parseDouble(y)); } } else if (qName.equals("ROI")) { @@ -1038,7 +1039,7 @@ public void storeROI(MetadataStore store, int series, int roi) { store.setLabelFontSize(fontSize, roi, 0); } } - Length l = new Length(new Double(linewidth), UNITS.PIXEL); + Length l = new Length(Double.valueOf(linewidth), UNITS.PIXEL); store.setLabelStrokeWidth(l, roi, 0); if (!normalized) normalize(); diff --git a/components/formats-gpl/src/loci/formats/in/LeicaReader.java b/components/formats-gpl/src/loci/formats/in/LeicaReader.java index 2ec4d813d53..5f890fb32f5 100644 --- a/components/formats-gpl/src/loci/formats/in/LeicaReader.java +++ b/components/formats-gpl/src/loci/formats/in/LeicaReader.java @@ -211,7 +211,7 @@ public boolean isThisType(RandomAccessInputStream stream) throws IOException { TiffParser tp = new TiffParser(stream); IFD ifd = tp.getFirstIFD(); if (ifd == null) return false; - return ifd.containsKey(new Integer(LEICA_MAGIC_TAG)); + return ifd.containsKey(Integer.valueOf(LEICA_MAGIC_TAG)); } /* @see loci.formats.IFormatReader#get8BitLookupTable() */ @@ -1339,10 +1339,10 @@ private void parseInstrumentData(MetadataStore store, int blockNum) try { if (tokens[2].equals("VideoOffset")) { - detector.offset = new Double(data); + detector.offset = DataTools.parseDouble(data); } else if (tokens[2].equals("HighVoltage")) { - detector.voltage = new Double(data); + detector.voltage = DataTools.parseDouble(data); } else if (tokens[2].equals("State")) { detector.active = data.equals("Active"); @@ -1369,7 +1369,7 @@ else if (tokens[0].startsWith("CTurret")) { int objective = Integer.parseInt(tokens[3]); if (tokens[2].equals("NumericalAperture")) { - store.setObjectiveLensNA(new Double(data), series, objective); + store.setObjectiveLensNA(DataTools.parseDouble(data), series, objective); } else if (tokens[2].equals("Objective")) { String[] objectiveData = data.split(" "); @@ -1420,7 +1420,7 @@ else if (immersion == null) { store.setObjectiveCorrection( MetadataTools.getCorrection(correction), series, objective); store.setObjectiveModel(model.toString().trim(), series, objective); - store.setObjectiveLensNA(new Double(na), series, objective); + store.setObjectiveLensNA(DataTools.parseDouble(na), series, objective); Double magnification = Double.parseDouble(mag); store.setObjectiveNominalMagnification( @@ -1430,7 +1430,7 @@ else if (tokens[2].equals("OrderNumber")) { store.setObjectiveSerialNumber(data, series, objective); } else if (tokens[2].equals("RefractionIndex")) { - store.setObjectiveSettingsRefractiveIndex(new Double(data), series); + store.setObjectiveSettingsRefractiveIndex(DataTools.parseDouble(data), series); } // link Objective to Image @@ -1609,14 +1609,14 @@ else if (contentID.startsWith("nDelayTime")) { } } if (channel < emWaves[i].size()) { - Double wave = new Double(emWaves[i].get(channel).toString()); + Double wave = DataTools.parseDouble(emWaves[i].get(channel).toString()); Length emission = FormatTools.getEmissionWavelength(wave); if (emission != null) { store.setChannelEmissionWavelength(emission, i, channel); } } if (channel < exWaves[i].size()) { - Double wave = new Double(exWaves[i].get(channel).toString()); + Double wave = DataTools.parseDouble(exWaves[i].get(channel).toString()); Length ex = FormatTools.getExcitationWavelength(wave); if (ex != null) { store.setChannelExcitationWavelength(ex, i, channel); diff --git a/components/formats-gpl/src/loci/formats/in/LeicaSCNReader.java b/components/formats-gpl/src/loci/formats/in/LeicaSCNReader.java index f6e76d32afc..276cedf8c27 100644 --- a/components/formats-gpl/src/loci/formats/in/LeicaSCNReader.java +++ b/components/formats-gpl/src/loci/formats/in/LeicaSCNReader.java @@ -45,6 +45,7 @@ import ome.xml.model.enums.IlluminationType; import ome.xml.model.primitives.Timestamp; +import loci.common.DataTools; import loci.common.RandomAccessInputStream; import loci.common.xml.XMLTools; import loci.formats.CoreMetadata; @@ -395,8 +396,8 @@ protected void initMetadataStore() throws FormatException { // Leica units are nanometres; convert to µm double sizeX = i.vSizeX / 1000.0; double sizeY = i.vSizeY / 1000.0; - final Length offsetX = new Length(i.vOffsetX, UNITS.NM); - final Length offsetY = new Length(i.vOffsetY, UNITS.NM); + final Length offsetX = new Length(i.vOffsetX, UNITS.NANOMETER); + final Length offsetY = new Length(i.vOffsetY, UNITS.NANOMETER); double sizeZ = i.vSpacingZ / 1000.0; store.setPixelsPhysicalSizeX( @@ -422,7 +423,7 @@ protected void initMetadataStore() throws FormatException { Double mag = Double.parseDouble(i.objMag); store.setObjectiveNominalMagnification(mag, inst, objectiveidno); store.setObjectiveCalibratedMagnification(mag, inst, objectiveidno); - store.setObjectiveLensNA(new Double(i.illumNA), inst, objectiveidno); + store.setObjectiveLensNA(DataTools.parseDouble(i.illumNA), inst, objectiveidno); objectiveidno++; } diff --git a/components/formats-gpl/src/loci/formats/in/LiFlimReader.java b/components/formats-gpl/src/loci/formats/in/LiFlimReader.java index c3b5aaee6c2..828861b8095 100644 --- a/components/formats-gpl/src/loci/formats/in/LiFlimReader.java +++ b/components/formats-gpl/src/loci/formats/in/LiFlimReader.java @@ -390,7 +390,7 @@ else if (version.equals("2.0")){ addGlobalMeta(metaKey, value); if (metaKey.startsWith(TIMESTAMP_KEY)) { - Integer index = new Integer(metaKey.replaceAll(TIMESTAMP_KEY, "")); + Integer index = Integer.parseInt(metaKey.replaceAll(TIMESTAMP_KEY, "")); stampValues.put(index, value); } else if (metaKey.equals("ROI: INFO - numregions")) { @@ -401,7 +401,7 @@ else if (metaKey.startsWith("ROI: ROI") && { int start = metaKey.lastIndexOf("ROI") + 3; int end = metaKey.indexOf(" ", start); - Integer index = new Integer(metaKey.substring(start, end)); + Integer index = Integer.parseInt(metaKey.substring(start, end)); ROI roi = rois.get(index); if (roi == null) roi = new ROI(); @@ -410,7 +410,7 @@ else if (metaKey.startsWith("ROI: ROI") && } else if (metaKey.indexOf(" - p") >= 0) { String p = metaKey.substring(metaKey.indexOf(" - p") + 4); - roi.points.put(new Integer(p), value.replaceAll(" ", ",")); + roi.points.put(Integer.parseInt(p), value.replaceAll(" ", ",")); } rois.put(index, roi); } @@ -423,7 +423,7 @@ else if (metaKey.equals("ExposureTime")) { } else { exposureTimeUnit = UNITS.SECOND; } - exposureTime = new Double(expTime); + exposureTime = Double.valueOf(expTime); } } } @@ -567,7 +567,7 @@ private void initOMEMetadata() { } else { long ms = stamp - firstStamp; - deltaT = new Double(ms / 1000.0); + deltaT = Double.valueOf(ms / 1000.0); } for (int c=0; c columns, String[] data, int series, store.setEllipseID(MetadataTools.createLSID("Shape", roi, 0), roi, 0); store.setEllipseTheT(new NonNegativeInteger(time), roi, 0); store.setEllipseTheZ(new NonNegativeInteger(z), roi, 0); - store.setEllipseX(new Double(data[columns.indexOf("Col")]), roi, 0); - store.setEllipseY(new Double(data[columns.indexOf("Row")]), roi, 0); + store.setEllipseX(DataTools.parseDouble(data[columns.indexOf("Col")]), roi, 0); + store.setEllipseY(DataTools.parseDouble(data[columns.indexOf("Row")]), roi, 0); store.setEllipseText(data[columns.indexOf("Label")], roi, 0); double diam = Double.parseDouble(data[columns.indexOf("Cell Diam.")]); @@ -1085,10 +1085,10 @@ else if (key.equals("Carrier")) { store.setPlateName(value, 0); } else if (key.equals("Pixel_X")) { - physicalSizeX = new Double(value); + physicalSizeX = DataTools.parseDouble(value); } else if (key.equals("Pixel_Y")) { - physicalSizeY = new Double(value); + physicalSizeY = DataTools.parseDouble(value); } else if (key.equals("Objective_ID")) { store.setObjectiveID( @@ -1109,7 +1109,7 @@ else if (key.equals("Time")) { date += " " + value; } else if (key.equals("Exposure")) { - exposure = new Double(value); + exposure = DataTools.parseDouble(value); } } } diff --git a/components/formats-gpl/src/loci/formats/in/MetamorphHandler.java b/components/formats-gpl/src/loci/formats/in/MetamorphHandler.java index 8eff5190b52..e6bd7408ae3 100644 --- a/components/formats-gpl/src/loci/formats/in/MetamorphHandler.java +++ b/components/formats-gpl/src/loci/formats/in/MetamorphHandler.java @@ -256,7 +256,7 @@ else if (key.equals("stage-position-y")) { } } if (key.equals("wavelength")) { - wavelengths.add(new Integer(value)); + wavelengths.add(Integer.parseInt(value)); } else if (key.equals("acquisition-time-local")) { date = value; diff --git a/components/formats-gpl/src/loci/formats/in/MetamorphReader.java b/components/formats-gpl/src/loci/formats/in/MetamorphReader.java index 82b27902d0c..fa789935731 100644 --- a/components/formats-gpl/src/loci/formats/in/MetamorphReader.java +++ b/components/formats-gpl/src/loci/formats/in/MetamorphReader.java @@ -1170,7 +1170,7 @@ else if (commentEntry instanceof TiffIFDEntry) { line.lastIndexOf("\"", lastQuote - 1) + 1, lastQuote); if (key.equals("z-position")) { - xmlZPosition = new Double(value); + xmlZPosition = DataTools.parseDouble(value); } else if (key.equals("acquisition-time-local")) { timestamps.add(value); @@ -1473,7 +1473,7 @@ else if (key.equals("Gain")) { nextSpace = value.length(); } try { - gain = new Double(value.substring(space, nextSpace)); + gain = DataTools.parseDouble(value.substring(space, nextSpace)); } catch (NumberFormatException e) { } } @@ -2004,13 +2004,13 @@ else if (valOrOffset == 0 && getSizeZ() < mmPlanes) { if (value instanceof TiffRational) { sizeX = ((TiffRational) value).doubleValue(); } - else sizeX = new Double(value.toString()); + else sizeX = DataTools.parseDouble(value.toString()); } if ("YCalibration".equals(key) && value != null) { if (value instanceof TiffRational) { sizeY = ((TiffRational) value).doubleValue(); } - else sizeY = new Double(value.toString()); + else sizeY = DataTools.parseDouble(value.toString()); } } in.seek(saveLoc); diff --git a/components/formats-gpl/src/loci/formats/in/MicroCTReader.java b/components/formats-gpl/src/loci/formats/in/MicroCTReader.java index ab3b5cac95d..490d7143be2 100644 --- a/components/formats-gpl/src/loci/formats/in/MicroCTReader.java +++ b/components/formats-gpl/src/loci/formats/in/MicroCTReader.java @@ -236,7 +236,7 @@ else if (key.equals("bits")) { ms.pixelType = FormatTools.pixelTypeFromBytes(bits / 8, true, false); } else if (key.equals("elementsize")) { - Double size = new Double(value); + Double size = DataTools.parseDouble(value); // physical size is stored in mm, not um physicalSize = new PositiveFloat(size * 1000); } @@ -328,7 +328,7 @@ private void processKey(String key, String value) { addGlobalMeta(key, value); if (key.equals("Exposure Time (ms)")) { - exposureTime = new Double(value); + exposureTime = DataTools.parseDouble(value); exposureTime /= 1000.0; } else if (key.equals("Description.txt")) { diff --git a/components/formats-gpl/src/loci/formats/in/ND2Handler.java b/components/formats-gpl/src/loci/formats/in/ND2Handler.java index 53ec64c10cf..7a4dc80740f 100644 --- a/components/formats-gpl/src/loci/formats/in/ND2Handler.java +++ b/components/formats-gpl/src/loci/formats/in/ND2Handler.java @@ -154,7 +154,7 @@ public void populateROIs(MetadataStore store) { store.setLabelFontSize(new Length(fontSize, UNITS.POINT), r, 0); } store.setLabelText(roi.get("eval-text"), r, 0); - Length l = new Length(new Double(roi.get("line-width")), UNITS.PIXEL); + Length l = new Length(DataTools.parseDouble(roi.get("line-width")), UNITS.PIXEL); store.setLabelStrokeWidth(l, r, 0); String rectangle = roi.get("rectangle"); @@ -568,7 +568,7 @@ else if (qName.equals("dPinholeRadius")) { } else if (qName.endsWith("ChannelColor")) { String name = qName.substring(0, qName.indexOf("Channel")); - colors.put(name, new Integer(value)); + colors.put(name, Integer.parseInt(value)); } else if (qName.endsWith("DyeName")) { int channelIndex = qName.indexOf("Channel"); @@ -885,11 +885,11 @@ else if (key.equals("Line")) { } else if (key.equalsIgnoreCase("Emission wavelength")) { String[] v = value.split(" "); - emWave.add(new Double(v[0])); + emWave.add(DataTools.parseDouble(v[0])); } else if (key.equalsIgnoreCase("Excitation wavelength")) { String[] v = value.split(" "); - exWave.add(new Double(v[0])); + exWave.add(DataTools.parseDouble(v[0])); } else if (key.equals("Power")) { power.add(DataTools.parseDouble(value).intValue()); @@ -898,7 +898,10 @@ else if (key.equals("CameraUniqueName")) { cameraModel = value; } else if (key.equals("ExposureTime")) { - exposureTime.add(new Double(value) / 1000d); + Double time = DataTools.parseDouble(value); + if (time != null) { + exposureTime.add(time / 1000d); + } } else if (key.equals("sDate")) { date = DateTools.formatDate(value, DATE_FORMAT); diff --git a/components/formats-gpl/src/loci/formats/in/ND2Reader.java b/components/formats-gpl/src/loci/formats/in/ND2Reader.java index 01e7ce6ccdd..77b03b0cc64 100644 --- a/components/formats-gpl/src/loci/formats/in/ND2Reader.java +++ b/components/formats-gpl/src/loci/formats/in/ND2Reader.java @@ -713,7 +713,7 @@ else if (trueSizeY == 0) { lastImage = entry; - imageOffsets.add(new Long(entry.position + 16)); + imageOffsets.add(Long.valueOf(entry.position + 16)); int realLength = (int) Math.max(entry.name.length() + 1, nameLength); imageLengths.add(new long[] {realLength, entry.length - nameLength - 16, getSizeX() * getSizeY()}); imageNames.add(entry.name.substring(12)); @@ -2188,7 +2188,7 @@ private ArrayList iterateIn(RandomAccessInputStream in, Long stop, boole name = name.trim(); if (name.equals("bUseZ")) { - useZ = new Boolean(value.toString()); + useZ = Boolean.parseBoolean(value.toString()); } else if (name.equals("sDescription")) { if (currentColor != null) { @@ -2209,7 +2209,7 @@ else if (name.equals("EmWavelength")) { textEmissionWavelengths.add(wave); } else if (name.equals("dZStep")) { - trueSizeZ = new Double(value.toString()); + trueSizeZ = DataTools.parseDouble(value.toString()); } else if (name.equals("dZHigh")) { zHigh = DataTools.parseDouble(value.toString()); diff --git a/components/formats-gpl/src/loci/formats/in/NDPIReader.java b/components/formats-gpl/src/loci/formats/in/NDPIReader.java index 32fc44d20df..b17548bf03c 100644 --- a/components/formats-gpl/src/loci/formats/in/NDPIReader.java +++ b/components/formats-gpl/src/loci/formats/in/NDPIReader.java @@ -551,7 +551,7 @@ else if (s < pyramidHeight) { // key name not a typo if (key.equals("Objective.Lens.Magnificant") && magnification == null) { - magnification = new Double(value); + magnification = DataTools.parseDouble(value); } else if (key.equals("NDP.S/N")) { serialNumber = value; diff --git a/components/formats-gpl/src/loci/formats/in/NiftiReader.java b/components/formats-gpl/src/loci/formats/in/NiftiReader.java index b353b0d6171..7373933c23a 100644 --- a/components/formats-gpl/src/loci/formats/in/NiftiReader.java +++ b/components/formats-gpl/src/loci/formats/in/NiftiReader.java @@ -303,11 +303,11 @@ else if (checkSuffix(id, "nii")) { store.setImageDescription(description, 0); Length sizeX = - FormatTools.getPhysicalSizeX(new Double(voxelWidth), spatialUnit); + FormatTools.getPhysicalSizeX(Double.valueOf(voxelWidth), spatialUnit); Length sizeY = - FormatTools.getPhysicalSizeY(new Double(voxelHeight), spatialUnit); + FormatTools.getPhysicalSizeY(Double.valueOf(voxelHeight), spatialUnit); Length sizeZ = - FormatTools.getPhysicalSizeZ(new Double(sliceThickness), spatialUnit); + FormatTools.getPhysicalSizeZ(Double.valueOf(sliceThickness), spatialUnit); if (sizeX != null) { store.setPixelsPhysicalSizeX(sizeX, 0); @@ -318,7 +318,7 @@ else if (checkSuffix(id, "nii")) { if (sizeZ != null) { store.setPixelsPhysicalSizeZ(sizeZ, 0); } - store.setPixelsTimeIncrement(new Time(new Double(deltaT), timeUnit), 0); + store.setPixelsTimeIncrement(new Time(Double.valueOf(deltaT), timeUnit), 0); } } diff --git a/components/formats-gpl/src/loci/formats/in/NikonTiffReader.java b/components/formats-gpl/src/loci/formats/in/NikonTiffReader.java index 94f70bde608..737f282bcd6 100644 --- a/components/formats-gpl/src/loci/formats/in/NikonTiffReader.java +++ b/components/formats-gpl/src/loci/formats/in/NikonTiffReader.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; +import loci.common.DataTools; import loci.common.RandomAccessInputStream; import loci.formats.FormatException; import loci.formats.FormatTools; @@ -167,7 +168,7 @@ else if (key.equals("history objective Type")) { correction = value; } else if (key.equals("history objective Magnification")) { - magnification = new Double(value); + magnification = DataTools.parseDouble(value); } else if (key.equals("history objective NA")) { lensNA = Double.parseDouble(value); @@ -179,25 +180,25 @@ else if (key.equals("history objective Immersion")) { immersion = value; } else if (key.startsWith("history gain")) { - gain.add(new Double(value)); + gain.add(DataTools.parseDouble(value)); } else if (key.equals("history pinhole")) { - pinholeSize = new Double(value.substring(0, value.indexOf(' '))); + pinholeSize = DataTools.parseDouble(value.substring(0, value.indexOf(' '))); } else if (key.startsWith("history laser") && key.endsWith("wavelength")) { - wavelength.add(new Double(value.replaceAll("\\D", ""))); + wavelength.add(DataTools.parseDouble(value.replaceAll("\\D", ""))); } else if (key.startsWith("history laser") && key.endsWith("name")) { laserIDs.add(value); } else if (key.equals("sensor s_params LambdaEx")) { for (int i=nTokensInKey; i 0) { store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(size), 0); store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(size), 0); @@ -252,7 +253,7 @@ protected void initMetadataStore() throws FormatException { store.setObjectiveID(MetadataTools.createLSID("Objective", 0, 0), 0, 0); store.setObjectiveCorrection(MetadataTools.getCorrection("Other"), 0, 0); store.setObjectiveImmersion(MetadataTools.getImmersion("Other"), 0, 0); - store.setObjectiveNominalMagnification(new Double(mag), 0, 0); + store.setObjectiveNominalMagnification(DataTools.parseDouble(mag), 0, 0); } final Double xn = Double.valueOf(ifd.getIFDTextValue(X_POS_TAG)); diff --git a/components/formats-gpl/src/loci/formats/in/SpiderReader.java b/components/formats-gpl/src/loci/formats/in/SpiderReader.java index 1db9ed62015..f3e2d98e097 100644 --- a/components/formats-gpl/src/loci/formats/in/SpiderReader.java +++ b/components/formats-gpl/src/loci/formats/in/SpiderReader.java @@ -274,7 +274,7 @@ protected void initFile(String id) throws FormatException, IOException { } if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { - Double size = new Double(pixelSize); + Double size = Double.valueOf(pixelSize); Length sizeX = FormatTools.getPhysicalSizeX(size, UNITS.ANGSTROM); Length sizeY = FormatTools.getPhysicalSizeY(size, UNITS.ANGSTROM); if (sizeX != null) { diff --git a/components/formats-gpl/src/loci/formats/in/TCSReader.java b/components/formats-gpl/src/loci/formats/in/TCSReader.java index 951a5fe05d2..e05296595f5 100644 --- a/components/formats-gpl/src/loci/formats/in/TCSReader.java +++ b/components/formats-gpl/src/loci/formats/in/TCSReader.java @@ -568,7 +568,7 @@ private void groupFiles() throws FormatException, IOException { String software = ifd.getIFDStringValue(IFD.SOFTWARE); if (software != null && software.trim().startsWith("TCS")) { - timestamps.put(file, new Long(stamp)); + timestamps.put(file, Long.valueOf(stamp)); } } } diff --git a/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java b/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java index c05d47da625..c84e5beb003 100644 --- a/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java +++ b/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java @@ -1424,7 +1424,7 @@ else if (extraIndex >= 0 && extraIndex < extraImages.size()) { if (airPressure != null) { store.setImagingEnvironmentAirPressure( - new Pressure(new Double(airPressure), UNITS.MILLIBAR), i); + new Pressure(DataTools.parseDouble(airPressure), UNITS.MILLIBAR), i); } if (co2Percent != null) { store.setImagingEnvironmentCO2Percent( @@ -1436,21 +1436,21 @@ else if (extraIndex >= 0 && extraIndex < extraImages.size()) { } if (temperature != null) { store.setImagingEnvironmentTemperature(new Temperature( - new Double(temperature), UNITS.CELSIUS), i); + DataTools.parseDouble(temperature), UNITS.CELSIUS), i); } if (objectiveSettingsID != null) { store.setObjectiveSettingsID(objectiveSettingsID, i); if (correctionCollar != null) { store.setObjectiveSettingsCorrectionCollar( - new Double(correctionCollar), i); + DataTools.parseDouble(correctionCollar), i); } if (medium != null) { store.setObjectiveSettingsMedium(MetadataTools.getMedium(medium), i); } if (refractiveIndex != null) { store.setObjectiveSettingsRefractiveIndex( - new Double(refractiveIndex), i); + DataTools.parseDouble(refractiveIndex), i); } } @@ -1687,7 +1687,7 @@ else if (getZCTCoords(plane)[2] < timestamps.size()) { String emWave = channels.get(c).emission; if (emWave != null) { - Double wave = new Double(emWave); + Double wave = DataTools.parseDouble(emWave); Length em = FormatTools.getEmissionWavelength(wave); if (em != null) { store.setChannelEmissionWavelength(em, i, c); @@ -1695,7 +1695,7 @@ else if (getZCTCoords(plane)[2] < timestamps.size()) { } String exWave = channels.get(c).excitation; if (exWave != null) { - Double wave = new Double(exWave); + Double wave = DataTools.parseDouble(exWave); Length ex = FormatTools.getExcitationWavelength(wave); if (ex != null) { store.setChannelExcitationWavelength(ex, i, c); @@ -1709,7 +1709,7 @@ else if (getZCTCoords(plane)[2] < timestamps.size()) { if (channels.get(c).pinhole != null) { store.setChannelPinholeSize( - new Length(new Double(channels.get(c).pinhole), UNITS.MICROMETER), i, c); + new Length(DataTools.parseDouble(channels.get(c).pinhole), UNITS.MICROMETER), i, c); } if (channels.get(c).acquisitionMode != null) { @@ -2509,7 +2509,7 @@ private void translateInformation(Element root) throws FormatException { String power = getFirstNodeValue(lightSource, "Power"); if ("Laser".equals(type)) { if (power != null) { - store.setLaserPower(new Power(new Double(power), UNITS.MILLIWATT), 0, i); + store.setLaserPower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setLaserLotNumber(lotNumber, 0, i); store.setLaserManufacturer(manufacturer, 0, i); @@ -2518,7 +2518,7 @@ private void translateInformation(Element root) throws FormatException { } else if ("Arc".equals(type)) { if (power != null) { - store.setArcPower(new Power(new Double(power), UNITS.MILLIWATT), 0, i); + store.setArcPower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setArcLotNumber(lotNumber, 0, i); store.setArcManufacturer(manufacturer, 0, i); @@ -2527,7 +2527,7 @@ else if ("Arc".equals(type)) { } else if ("LightEmittingDiode".equals(type)) { if (power != null) { - store.setLightEmittingDiodePower(new Power(new Double(power), UNITS.MILLIWATT), 0, i); + store.setLightEmittingDiodePower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setLightEmittingDiodeLotNumber(lotNumber, 0, i); store.setLightEmittingDiodeManufacturer(manufacturer, 0, i); @@ -2536,7 +2536,7 @@ else if ("LightEmittingDiode".equals(type)) { } else if ("Filament".equals(type)) { if (power != null) { - store.setFilamentPower(new Power(new Double(power), UNITS.MILLIWATT), 0, i); + store.setFilamentPower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setFilamentLotNumber(lotNumber, 0, i); store.setFilamentManufacturer(manufacturer, 0, i); @@ -2594,7 +2594,7 @@ else if ("Filament".equals(type)) { String offset = getFirstNodeValue(detector, "Offset"); if (offset != null && !offset.equals("")) { - store.setDetectorOffset(new Double(offset), 0, detectorIndex); + store.setDetectorOffset(DataTools.parseDouble(offset), 0, detectorIndex); } zoom = getFirstNodeValue(detector, "Zoom"); @@ -2609,7 +2609,7 @@ else if ("Filament".equals(type)) { String ampGain = getFirstNodeValue(detector, "AmplificationGain"); if (ampGain != null && !ampGain.equals("")) { - store.setDetectorAmplificationGain(new Double(ampGain), 0, detectorIndex); + store.setDetectorAmplificationGain(DataTools.parseDouble(ampGain), 0, detectorIndex); } String detectorType = getFirstNodeValue(detector, "Type"); @@ -2725,8 +2725,8 @@ else if ("Filament".equals(type)) { String cutIn = getFirstNodeValue(transmittance, "CutIn"); String cutOut = getFirstNodeValue(transmittance, "CutOut"); - Double inWave = cutIn == null ? 0 : new Double(cutIn); - Double outWave = cutOut == null ? 0 : new Double(cutOut); + Double inWave = cutIn == null ? 0 : DataTools.parseDouble(cutIn); + Double outWave = cutOut == null ? 0 : DataTools.parseDouble(cutOut); Length in = FormatTools.getCutIn(inWave); Length out = FormatTools.getCutOut(outWave); @@ -2743,13 +2743,13 @@ else if ("Filament".equals(type)) { getFirstNodeValue(transmittance, "CutOutTolerance"); if (inTolerance != null) { - Double cutInTolerance = new Double(inTolerance); + Double cutInTolerance = DataTools.parseDouble(inTolerance); store.setTransmittanceRangeCutInTolerance( new Length(cutInTolerance, UNITS.NANOMETER), 0, i); } if (outTolerance != null) { - Double cutOutTolerance = new Double(outTolerance); + Double cutOutTolerance = DataTools.parseDouble(outTolerance); store.setTransmittanceRangeCutOutTolerance( new Length(cutOutTolerance, UNITS.NANOMETER), 0, i); } @@ -2813,7 +2813,13 @@ private void translateScaling(Element root) { if (originalValue == null) { continue; } - Double value = new Double(originalValue) * 1000000; + Double value = DataTools.parseDouble(originalValue); + if (value != null) { + value *= 1000000; + } + else { + value = 0d; + } if (value > 0) { PositiveFloat size = new PositiveFloat(value); @@ -2940,20 +2946,23 @@ private void translateLayers(Element root) { String centerY = getFirstNodeValue(geometry, "CenterY"); if (length != null) { - Double halfLen = new Double(length) / 2; - if (centerX != null) { - store.setLineX1(new Double(centerX) - halfLen, roiCount, shape); - store.setLineX2(new Double(centerX) + halfLen, roiCount, shape); - - store.setLineX1(new Double(centerX), roiCount, shape + 1); - store.setLineX2(new Double(centerX), roiCount, shape + 1); - } - if (centerY != null) { - store.setLineY1(new Double(centerY), roiCount, shape); - store.setLineY2(new Double(centerY), roiCount, shape); + Double halfLen = DataTools.parseDouble(length); + if (halfLen != null) { + halfLen /= 2; + if (centerX != null) { + store.setLineX1(DataTools.parseDouble(centerX) - halfLen, roiCount, shape); + store.setLineX2(DataTools.parseDouble(centerX) + halfLen, roiCount, shape); + + store.setLineX1(DataTools.parseDouble(centerX), roiCount, shape + 1); + store.setLineX2(DataTools.parseDouble(centerX), roiCount, shape + 1); + } + if (centerY != null) { + store.setLineY1(DataTools.parseDouble(centerY), roiCount, shape); + store.setLineY2(DataTools.parseDouble(centerY), roiCount, shape); - store.setLineY1(new Double(centerY) - halfLen, roiCount, shape + 1); - store.setLineY2(new Double(centerY) + halfLen, roiCount, shape + 1); + store.setLineY1(DataTools.parseDouble(centerY) - halfLen, roiCount, shape + 1); + store.setLineY2(DataTools.parseDouble(centerY) + halfLen, roiCount, shape + 1); + } } } store.setLineText(getFirstNodeValue(textElements, "Text"), roiCount, shape); @@ -2983,16 +2992,16 @@ private void translateLayers(Element root) { String centerY = getFirstNodeValue(geometry, "CenterY"); if (radiusX != null) { - store.setEllipseRadiusX(new Double(radiusX), roiCount, shape); + store.setEllipseRadiusX(DataTools.parseDouble(radiusX), roiCount, shape); } if (radiusY != null) { - store.setEllipseRadiusY(new Double(radiusY), roiCount, shape); + store.setEllipseRadiusY(DataTools.parseDouble(radiusY), roiCount, shape); } if (centerX != null) { - store.setEllipseX(new Double(centerX), roiCount, shape); + store.setEllipseX(DataTools.parseDouble(centerX), roiCount, shape); } if (centerY != null) { - store.setEllipseY(new Double(centerY), roiCount, shape); + store.setEllipseY(DataTools.parseDouble(centerY), roiCount, shape); } store.setEllipseText( getFirstNodeValue(textElements, "Text"), roiCount, shape); @@ -3165,7 +3174,7 @@ private void translateHardwareSettings(Element root) throws FormatException { if (magnification != null) { try { store.setObjectiveNominalMagnification( - new Double(magnification), 0, i); + DataTools.parseDouble(magnification), 0, i); } catch (NumberFormatException e) { LOGGER.debug("Could not parse magnification", e); @@ -3173,7 +3182,7 @@ private void translateHardwareSettings(Element root) throws FormatException { } if (na != null) { try { - store.setObjectiveLensNA(new Double(na), 0, i); + store.setObjectiveLensNA(DataTools.parseDouble(na), 0, i); } catch (NumberFormatException e) { LOGGER.debug("Could not parse numerical aperture", e); @@ -3181,7 +3190,7 @@ private void translateHardwareSettings(Element root) throws FormatException { } if (wd != null) { try { - store.setObjectiveWorkingDistance(new Length(new Double(wd), UNITS.MICROMETER), 0, i); + store.setObjectiveWorkingDistance(new Length(DataTools.parseDouble(wd), UNITS.MICROMETER), 0, i); } catch (NumberFormatException e) { LOGGER.debug("Could not parse working distance", e); @@ -3209,10 +3218,10 @@ private int populateRectangles(NodeList rectangles, int roi, int shape) { if (left != null && top != null && width != null && height != null) { store.setRectangleID( MetadataTools.createLSID("Shape", roi, shape), roi, shape); - store.setRectangleX(new Double(left), roi, shape); - store.setRectangleY(new Double(top), roi, shape); - store.setRectangleWidth(new Double(width), roi, shape); - store.setRectangleHeight(new Double(height), roi, shape); + store.setRectangleX(DataTools.parseDouble(left), roi, shape); + store.setRectangleY(DataTools.parseDouble(top), roi, shape); + store.setRectangleWidth(DataTools.parseDouble(width), roi, shape); + store.setRectangleHeight(DataTools.parseDouble(height), roi, shape); String name = getFirstNodeValue(attributes, "Name"); String label = getFirstNodeValue(textElements, "Text"); @@ -3272,16 +3281,16 @@ private int populateLines(NodeList lines, int roi, int shape) { MetadataTools.createLSID("Shape", roi, shape), roi, shape); if (x1 != null) { - store.setLineX1(new Double(x1), roi, shape); + store.setLineX1(DataTools.parseDouble(x1), roi, shape); } if (x2 != null) { - store.setLineX2(new Double(x2), roi, shape); + store.setLineX2(DataTools.parseDouble(x2), roi, shape); } if (y1 != null) { - store.setLineY1(new Double(y1), roi, shape); + store.setLineY1(DataTools.parseDouble(y1), roi, shape); } if (y2 != null) { - store.setLineY2(new Double(y2), roi, shape); + store.setLineY2(DataTools.parseDouble(y2), roi, shape); } store.setLineText(getFirstNodeValue(textElements, "Text"), roi, shape); } @@ -3302,14 +3311,14 @@ private int populateCircles(NodeList circles, int roi, int shape) { String centerY = getFirstNodeValue(geometry, "CenterY"); if (radius != null) { - store.setEllipseRadiusX(new Double(radius), roi, shape); - store.setEllipseRadiusY(new Double(radius), roi, shape); + store.setEllipseRadiusX(DataTools.parseDouble(radius), roi, shape); + store.setEllipseRadiusY(DataTools.parseDouble(radius), roi, shape); } if (centerX != null) { - store.setEllipseX(new Double(centerX), roi, shape); + store.setEllipseX(DataTools.parseDouble(centerX), roi, shape); } if (centerY != null) { - store.setEllipseY(new Double(centerY), roi, shape); + store.setEllipseY(DataTools.parseDouble(centerY), roi, shape); } store.setEllipseText(getFirstNodeValue(textElements, "Text"), roi, shape); } @@ -3535,7 +3544,7 @@ private void translateExperiment(Element root) throws FormatException { try { if (exposure != null) { - channels.get(i).exposure = new Double(exposure); + channels.get(i).exposure = DataTools.parseDouble(exposure); } } catch (NumberFormatException e) { @@ -3543,7 +3552,7 @@ private void translateExperiment(Element root) throws FormatException { } try { if (gain != null) { - channels.get(i).gain = new Double(gain); + channels.get(i).gain = DataTools.parseDouble(gain); } } catch (NumberFormatException e) { @@ -3825,7 +3834,7 @@ private void parseObjectives(NodeList objectives) throws FormatException { String lensNA = getFirstNodeValue(objective, "LensNA"); if (lensNA != null) { - store.setObjectiveLensNA(new Double(lensNA), 0, i); + store.setObjectiveLensNA(DataTools.parseDouble(lensNA), 0, i); } String magnification = @@ -3833,7 +3842,7 @@ private void parseObjectives(NodeList objectives) throws FormatException { if (magnification == null) { magnification = getFirstNodeValue(objective, "Magnification"); } - Double mag = magnification == null ? null : new Double(magnification); + Double mag = magnification == null ? null : DataTools.parseDouble(magnification); if (mag != null) { store.setObjectiveNominalMagnification(mag, 0, i); @@ -3842,15 +3851,15 @@ private void parseObjectives(NodeList objectives) throws FormatException { getFirstNodeValue(objective, "CalibratedMagnification"); if (calibratedMag != null) { store.setObjectiveCalibratedMagnification( - new Double(calibratedMag), 0, i); + DataTools.parseDouble(calibratedMag), 0, i); } String wd = getFirstNodeValue(objective, "WorkingDistance"); if (wd != null) { - store.setObjectiveWorkingDistance(new Length(new Double(wd), UNITS.MICROMETER), 0, i); + store.setObjectiveWorkingDistance(new Length(DataTools.parseDouble(wd), UNITS.MICROMETER), 0, i); } String iris = getFirstNodeValue(objective, "Iris"); if (iris != null) { - store.setObjectiveIris(new Boolean(iris), 0, i); + store.setObjectiveIris(Boolean.parseBoolean(iris), 0, i); } } } @@ -4286,7 +4295,7 @@ else if (tagNode.getNodeName().equals("AcquisitionTime")) { timestamp = t.asInstant().getMillis() / 1000d; } else if (tagNode.getNodeName().equals("ExposureTime")) { - exposureTime = new Double(text); + exposureTime = DataTools.parseDouble(text); } } } diff --git a/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java b/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java index ed22ac83ba9..cf7e82bdce1 100644 --- a/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java +++ b/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java @@ -1486,7 +1486,7 @@ nextDetectChannel < getSizeC() && channel.acquire) String transmittance = channel.filter.substring(space + 1).trim(); String[] v = transmittance.split("-"); try { - final Double cutIn = new Double(v[0].trim()); + final Double cutIn = DataTools.parseDouble(v[0].trim()); Length in = FormatTools.getCutIn(cutIn); if (in != null) { store.setTransmittanceRangeCutIn(in, instrument, nextFilter); @@ -1495,7 +1495,7 @@ nextDetectChannel < getSizeC() && channel.acquire) catch (NumberFormatException e) { } if (v.length > 1) { try { - final Double cutOut = new Double(v[1].trim()); + final Double cutOut = DataTools.parseDouble(v[1].trim()); Length out = FormatTools.getCutOut(cutOut); if (out != null) { store.setTransmittanceRangeCutOut(out, instrument, nextFilter); @@ -2410,13 +2410,13 @@ protected void read() throws IOException { int slash = p.indexOf('/'); if (slash > 0) { try { - magnification = new Double(p.substring(0, slash - 1)); + magnification = DataTools.parseDouble(p.substring(0, slash - 1)); } catch (NumberFormatException e) { } } if (slash >= 0 && slash < p.length() - 1) { try { - lensNA = new Double(p.substring(slash + 1)); + lensNA = DataTools.parseDouble(p.substring(slash + 1)); } catch (NumberFormatException e) { } } @@ -2519,7 +2519,7 @@ protected void read() throws IOException { name = getStringValue(ILLUM_CHANNEL_NAME); try { - wavelength = new Double(name); + wavelength = DataTools.parseDouble(name); } catch (NumberFormatException e) { } } From 3d94d34bccd84a52bd16139a2259e5f491ae6252 Mon Sep 17 00:00:00 2001 From: David Gault Date: Tue, 16 Apr 2024 16:19:12 +0100 Subject: [PATCH 033/100] Bump lower level component versions prior to 7.3.0 --- pom.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 0d863ad4661..561d37f51e6 100644 --- a/pom.xml +++ b/pom.xml @@ -41,20 +41,20 @@ 1.54c 1.7.2 1.3.14 - 6.0.1 + 6.0.2 ${ome-stubs.version} - 5.3.5 + 5.3.6 ${ome-metakit.version} 2.0.9 5.4.0 6.8 - 6.0.21 + 6.0.22 org.openmicroscopy - 6.3.4 - 5.3.7 - 5.3.2 - 0.1.3 - 1.0.1 + 6.3.5 + 5.3.8 + 5.3.3 + 0.1.4 + 1.0.2 0.2.4 2.7.3 3.28.0 From 0333cc2051dba0f09ffe25b0ba15dccc8ce9ecbb Mon Sep 17 00:00:00 2001 From: David Gault Date: Tue, 16 Apr 2024 16:44:03 +0100 Subject: [PATCH 034/100] Bump ome-codecs and 0me-model versions --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 561d37f51e6..6c4c71b446e 100644 --- a/pom.xml +++ b/pom.xml @@ -50,11 +50,11 @@ 6.8 6.0.22 org.openmicroscopy - 6.3.5 + 6.3.6 5.3.8 5.3.3 0.1.4 - 1.0.2 + 1.0.3 0.2.4 2.7.3 3.28.0 From 894444bc548a2109c45319f4c7b33989ea7327e5 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 16 Apr 2024 16:24:08 -0500 Subject: [PATCH 035/100] DICOM: initial precompressed tile reading --- .../src/loci/formats/in/DicomReader.java | 200 ++++++++++++++---- 1 file changed, 164 insertions(+), 36 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/in/DicomReader.java b/components/formats-bsd/src/loci/formats/in/DicomReader.java index 4b6c9afeb24..22702106b48 100644 --- a/components/formats-bsd/src/loci/formats/in/DicomReader.java +++ b/components/formats-bsd/src/loci/formats/in/DicomReader.java @@ -63,6 +63,7 @@ import loci.formats.codec.JPEG2000Codec; import loci.formats.codec.JPEGCodec; import loci.formats.codec.PackbitsCodec; +import loci.formats.codec.PassthroughCodec; import loci.formats.meta.MetadataStore; import ome.xml.model.primitives.Timestamp; import ome.units.quantity.Length; @@ -145,6 +146,91 @@ public DicomReader() { hasCompanionFiles = true; } + // -- ICompressedTileReader API methods -- + + @Override + public int getTileRows(int no) { + FormatTools.assertId(currentId, true, 1); + + return (int) Math.ceil((double) getSizeY() / originalY); + } + + @Override + public int getTileColumns(int no) { + FormatTools.assertId(currentId, true, 1); + + return (int) Math.ceil((double) getSizeX() / originalY); + } + + @Override + public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, IOException { + FormatTools.assertId(currentId, true, 1); + + Region boundingBox = new Region(x * originalX, y * originalY, originalX, originalY); + + List tiles = getTileList(no, boundingBox, true); + if (tiles == null || tiles.size() == 0) { + throw new FormatException("Could not find valid tile; no=" + no + ", x=" + x + ", y=" + y); + } + DicomTile tile = tiles.get(0); + byte[] buf = new byte[(int) (tile.endOffset - tile.fileOffset)]; + try (RandomAccessInputStream stream = new RandomAccessInputStream(tile.file)) { + if (tile.fileOffset >= stream.length()) { + LOGGER.error("attempted to read beyond end of file ({}, {})", tile.fileOffset, tile.file); + return buf; + } + LOGGER.debug("reading from offset = {}, file = {}", tile.fileOffset, tile.file); + stream.seek(tile.fileOffset); + stream.read(buf, 0, (int) (tile.endOffset - tile.fileOffset)); + } + return buf; + } + + @Override + public byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws FormatException, IOException { + FormatTools.assertId(currentId, true, 1); + + Region boundingBox = new Region(x * originalX, y * originalY, originalX, originalY); + + List tiles = getTileList(no, boundingBox, true); + if (tiles == null || tiles.size() == 0) { + throw new FormatException("Could not find valid tile; no=" + no + ", x=" + x + ", y=" + y); + } + DicomTile tile = tiles.get(0); + try (RandomAccessInputStream stream = new RandomAccessInputStream(tile.file)) { + if (tile.fileOffset >= stream.length()) { + LOGGER.error("attempted to read beyond end of file ({}, {})", tile.fileOffset, tile.file); + return buf; + } + LOGGER.debug("reading from offset = {}, file = {}", tile.fileOffset, tile.file); + stream.seek(tile.fileOffset); + stream.read(buf, 0, (int) (tile.endOffset - tile.fileOffset)); + } + return buf; + } + + @Override + public Codec getTileCodec(int no) throws FormatException, IOException { + FormatTools.assertId(currentId, true, 1); + + List tiles = getTileList(no, null, true); + if (tiles == null || tiles.size() == 0) { + throw new FormatException("Could not find valid tile; no=" + no); + } + return getTileCodec(tiles.get(0)); + } + + @Override + public CodecOptions getTileCodecOptions(int no, int x, int y) throws FormatException, IOException { + FormatTools.assertId(currentId, true, 1); + + List tiles = getTileList(no, null, true); + if (tiles == null || tiles.size() == 0) { + throw new FormatException("Could not find valid tile; no=" + no + ", x=" + x + ", y=" + y); + } + return getTileCodecOptions(tiles.get(0)); + } + // -- IFormatReader API methods -- /* @see loci.formats.IFormatReader#isThisType(String, boolean) */ @@ -282,33 +368,18 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) int bpp = FormatTools.getBytesPerPixel(getPixelType()); int pixel = bpp * getRGBChannelCount(); Region currentRegion = new Region(x, y, w, h); - int z = getZCTCoords(no)[0]; - int c = getZCTCoords(no)[1]; - - if (!tilePositions.containsKey(getCoreIndex())) { - LOGGER.warn("No tiles for core index = {}", getCoreIndex()); - return buf; - } - // look for any tiles that match the requested tile and plane - List zs = zOffsets.get(getCoreIndex()); - List tiles = tilePositions.get(getCoreIndex()); - for (int t=0; t tiles = getTileList(no, currentRegion, false); + for (DicomTile tile : tiles) { + byte[] tileBuf = new byte[tile.region.width * tile.region.height * pixel]; + Region intersection = tile.region.intersection(currentRegion); + getTile(tile, tileBuf, intersection.x - tile.region.x, intersection.y - tile.region.y, + intersection.width, intersection.height); + + for (int row=0; row getTileList(int no, Region boundingBox, boolean firstTileOnly) { + int z = getZCTCoords(no)[0]; + int c = getZCTCoords(no)[1]; + + List tileList = new ArrayList(); + if (!tilePositions.containsKey(getCoreIndex())) { + LOGGER.warn("No tiles for core index = {}", getCoreIndex()); + return tileList; + } + + // look for any tiles that match the requested tile and plane + List zs = zOffsets.get(getCoreIndex()); + List tiles = tilePositions.get(getCoreIndex()); + for (int t=0; t 1) { @@ -1611,13 +1746,6 @@ else if (pt < b.length - 2) { System.arraycopy(tmp, 0, b, 0, b.length); } - Codec codec = null; - CodecOptions options = new CodecOptions(); - options.littleEndian = isLittleEndian(); - options.interleaved = isInterleaved(); - if (tile.isJPEG) codec = new JPEGCodec(); - else codec = new JPEG2000Codec(); - try { b = codec.decompress(b, options); } From 5f0462194df41b6d8a80c54d879ccc9a1ef85adb Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 17 Apr 2024 13:52:49 -0500 Subject: [PATCH 036/100] Fix a few string comparisons, fixes #4184 --- .../formats-bsd/src/loci/formats/gui/PreviewPane.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/gui/PreviewPane.java b/components/formats-bsd/src/loci/formats/gui/PreviewPane.java index cdab9d45e4d..f51ac4993b5 100644 --- a/components/formats-bsd/src/loci/formats/gui/PreviewPane.java +++ b/components/formats-bsd/src/loci/formats/gui/PreviewPane.java @@ -215,7 +215,9 @@ public void run() { try { // catch-all for unanticipated exceptions final String id = loadId; - if (id == lastId) continue; + if ((id == null && lastId == null) || (id != null && id.equals(lastId))) { + continue; + } if (id != null && lastId != null) { String[] files = reader.getUsedFiles(); boolean found = false; @@ -260,7 +262,7 @@ public void run() { lastId = null; continue; } - if (id != loadId) { + if (!id.equals(loadId)) { SwingUtilities.invokeLater(refresher); continue; } From e0ca281cceb32b0dc8034534a60f5af290528df4 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 18 Apr 2024 10:37:47 +0100 Subject: [PATCH 037/100] Bump ome-poi to 5.3.9 and ome-metakit to 5.3.7 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6c4c71b446e..657633e77da 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ 1.3.14 6.0.2 ${ome-stubs.version} - 5.3.6 + 5.3.7 ${ome-metakit.version} 2.0.9 5.4.0 @@ -51,7 +51,7 @@ 6.0.22 org.openmicroscopy 6.3.6 - 5.3.8 + 5.3.9 5.3.3 0.1.4 1.0.3 From ea3327a513b74ceb15ea15aba4a52878835cd0c1 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 18 Apr 2024 11:03:45 +0100 Subject: [PATCH 038/100] Bump version to 7.3.0 --- components/bio-formats-plugins/pom.xml | 2 +- components/bio-formats-tools/pom.xml | 2 +- components/bundles/bioformats_package/pom.xml | 2 +- components/forks/turbojpeg/pom.xml | 2 +- components/formats-api/pom.xml | 2 +- components/formats-bsd/pom.xml | 2 +- components/formats-gpl/pom.xml | 2 +- components/test-suite/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-plugins/pom.xml b/components/bio-formats-plugins/pom.xml index db8e47910ca..4a8affd6319 100644 --- a/components/bio-formats-plugins/pom.xml +++ b/components/bio-formats-plugins/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../.. diff --git a/components/bio-formats-tools/pom.xml b/components/bio-formats-tools/pom.xml index 7bf17d46f04..f8f48bd3ba5 100644 --- a/components/bio-formats-tools/pom.xml +++ b/components/bio-formats-tools/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../.. diff --git a/components/bundles/bioformats_package/pom.xml b/components/bundles/bioformats_package/pom.xml index 74c06caa741..b1b2b61da6c 100644 --- a/components/bundles/bioformats_package/pom.xml +++ b/components/bundles/bioformats_package/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../../../ diff --git a/components/forks/turbojpeg/pom.xml b/components/forks/turbojpeg/pom.xml index c7806a96dfd..56920272452 100644 --- a/components/forks/turbojpeg/pom.xml +++ b/components/forks/turbojpeg/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../../../ diff --git a/components/formats-api/pom.xml b/components/formats-api/pom.xml index 760c677c14b..f6ab465b1a6 100644 --- a/components/formats-api/pom.xml +++ b/components/formats-api/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../.. diff --git a/components/formats-bsd/pom.xml b/components/formats-bsd/pom.xml index 44bc0a8ad27..334bfd5c36f 100644 --- a/components/formats-bsd/pom.xml +++ b/components/formats-bsd/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../.. diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index baa8401d9cb..cc8f276dd78 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../.. diff --git a/components/test-suite/pom.xml b/components/test-suite/pom.xml index 2ad76017821..0cc0c32e01b 100644 --- a/components/test-suite/pom.xml +++ b/components/test-suite/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 ../.. diff --git a/pom.xml b/pom.xml index 657633e77da..8db1792e238 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.0 pom Bio-Formats projects @@ -34,7 +34,7 @@ When possible, we advise using the relevant groupId and version properties for your dependencies rather than hardcoding them. --> - 8.0.0-SNAPSHOT + 7.3.0 ${maven.build.timestamp} 2017 ${basedir} From 5b72e21b791d37ef2428c44ebc7a40efea2f5118 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 18 Apr 2024 11:49:58 +0100 Subject: [PATCH 039/100] Bump version to 8.0.0-SNAPSHOT --- components/bio-formats-plugins/pom.xml | 2 +- components/bio-formats-tools/pom.xml | 2 +- components/bundles/bioformats_package/pom.xml | 2 +- components/forks/turbojpeg/pom.xml | 2 +- components/formats-api/pom.xml | 2 +- components/formats-bsd/pom.xml | 2 +- components/formats-gpl/pom.xml | 2 +- components/test-suite/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-plugins/pom.xml b/components/bio-formats-plugins/pom.xml index 4a8affd6319..db8e47910ca 100644 --- a/components/bio-formats-plugins/pom.xml +++ b/components/bio-formats-plugins/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../.. diff --git a/components/bio-formats-tools/pom.xml b/components/bio-formats-tools/pom.xml index f8f48bd3ba5..7bf17d46f04 100644 --- a/components/bio-formats-tools/pom.xml +++ b/components/bio-formats-tools/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../.. diff --git a/components/bundles/bioformats_package/pom.xml b/components/bundles/bioformats_package/pom.xml index b1b2b61da6c..74c06caa741 100644 --- a/components/bundles/bioformats_package/pom.xml +++ b/components/bundles/bioformats_package/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../../../ diff --git a/components/forks/turbojpeg/pom.xml b/components/forks/turbojpeg/pom.xml index 56920272452..c7806a96dfd 100644 --- a/components/forks/turbojpeg/pom.xml +++ b/components/forks/turbojpeg/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../../../ diff --git a/components/formats-api/pom.xml b/components/formats-api/pom.xml index f6ab465b1a6..760c677c14b 100644 --- a/components/formats-api/pom.xml +++ b/components/formats-api/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../.. diff --git a/components/formats-bsd/pom.xml b/components/formats-bsd/pom.xml index 334bfd5c36f..44bc0a8ad27 100644 --- a/components/formats-bsd/pom.xml +++ b/components/formats-bsd/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../.. diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index cc8f276dd78..baa8401d9cb 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../.. diff --git a/components/test-suite/pom.xml b/components/test-suite/pom.xml index 0cc0c32e01b..2ad76017821 100644 --- a/components/test-suite/pom.xml +++ b/components/test-suite/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT ../.. diff --git a/pom.xml b/pom.xml index 8db1792e238..657633e77da 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ome pom-bio-formats - 7.3.0 + 8.0.0-SNAPSHOT pom Bio-Formats projects @@ -34,7 +34,7 @@ When possible, we advise using the relevant groupId and version properties for your dependencies rather than hardcoding them. --> - 7.3.0 + 8.0.0-SNAPSHOT ${maven.build.timestamp} 2017 ${basedir} From 52ab11d08ba8201d5dc2eaae8f460ca012cc8a69 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 18 Apr 2024 14:58:23 -0500 Subject: [PATCH 040/100] Add basic precompressed TIFF tile writing Only "plain" TIFF, OME-TIFF not supported yet. --- .../src/loci/formats/out/TiffWriter.java | 84 +++++++++++++++++-- .../src/loci/formats/tiff/TiffSaver.java | 4 +- 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/TiffWriter.java b/components/formats-bsd/src/loci/formats/out/TiffWriter.java index 9f0bc132cdc..668c46e07b2 100644 --- a/components/formats-bsd/src/loci/formats/out/TiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/TiffWriter.java @@ -39,6 +39,7 @@ import loci.formats.FormatTools; import loci.formats.FormatWriter; import loci.formats.ImageTools; +import loci.formats.codec.Codec; import loci.formats.codec.CompressionType; import loci.formats.gui.AWTImageTools; import loci.formats.meta.MetadataRetrieve; @@ -100,13 +101,10 @@ public class TiffWriter extends FormatWriter { protected int tileSizeY; /** - * Sets the compression code for the specified IFD. - * - * @param ifd The IFD table to handle. + * Get the TIFF compression enum value that corresponds to + * the current compression type. */ - private void formatCompression(IFD ifd) - throws FormatException - { + private TiffCompression getTIFFCompression() { if (compression == null) compression = ""; TiffCompression compressType = TiffCompression.UNCOMPRESSED; if (compression.equals(COMPRESSION_LZW)) { @@ -124,6 +122,18 @@ else if (compression.equals(COMPRESSION_JPEG)) { else if (compression.equals(COMPRESSION_ZLIB)) { compressType = TiffCompression.DEFLATE; } + return compressType; + } + + /** + * Sets the compression code for the specified IFD. + * + * @param ifd The IFD table to handle. + */ + private void formatCompression(IFD ifd) + throws FormatException + { + TiffCompression compressType = getTIFFCompression(); Object v = ifd.get(new Integer(IFD.COMPRESSION)); if (v == null) ifd.put(new Integer(IFD.COMPRESSION), compressType.getCode()); @@ -149,6 +159,68 @@ public TiffWriter(String format, String[] exts) { isBigTiff = false; } + // -- ICompressedTileWriter API methods -- + + @Override + public Codec getCodec() { + return getTIFFCompression().getCodec(); + } + + @Override + public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) + throws FormatException, IOException + { + if (!sequential) { + throw new UnsupportedOperationException( + "Sequential tile writing must be enabled to write precompressed tiles"); + } + + LOGGER.warn("saveCompressedBytes(series={}, resolution={}, no={}, x={}, y={})", + series, resolution, no, x, y); + + IFD ifd = new IFD(); + MetadataRetrieve retrieve = getMetadataRetrieve(); + int type = FormatTools.pixelTypeFromString( + retrieve.getPixelsType(series).toString()); + int index = no; + int currentTileSizeX = getTileSizeX(); + int currentTileSizeY = getTileSizeY(); + + if (x % currentTileSizeX != 0 || y % currentTileSizeY != 0 || + (currentTileSizeX != w && x + w != getSizeX()) || + (currentTileSizeY != h && y + h != getSizeY())) + { + throw new IllegalArgumentException("Compressed tile dimensions must match tile size"); + } + + boolean usingTiling = currentTileSizeX > 0 && currentTileSizeY > 0; + if (usingTiling) { + ifd.put(new Integer(IFD.TILE_WIDTH), new Long(currentTileSizeX)); + ifd.put(new Integer(IFD.TILE_LENGTH), new Long(currentTileSizeY)); + } + + // This operation is synchronized + synchronized (this) { + // This operation is synchronized against the TIFF saver. + synchronized (tiffSaver) { + index = prepareToWriteImage(no, buf, ifd, x, y, w, h); + if (index == -1) { + return; + } + } + } + + boolean lastPlane = no == getPlaneCount() - 1; + boolean lastSeries = getSeries() == retrieve.getImageCount() - 1; + boolean lastResolution = getResolution() == getResolutionCount() - 1; + + int nChannels = getSamplesPerPixel(); + + tiffSaver.makeValidIFD(ifd, type, nChannels); + tiffSaver.writeImageIFD(ifd, index, new byte[][] {buf}, + nChannels, lastPlane && lastSeries && lastResolution, x, y); + } + // -- FormatWriter API methods -- /* @see loci.formats.FormatWriter#setId(String) */ diff --git a/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java b/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java index 8a683cc1d44..f803895bca2 100644 --- a/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java +++ b/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java @@ -450,7 +450,7 @@ public void writeImage(byte[] buf, IFD ifd, int no, int pixelType, int x, * @throws FormatException * @throws IOException */ - private void writeImageIFD(IFD ifd, int no, byte[][] strips, + public void writeImageIFD(IFD ifd, int no, byte[][] strips, int nChannels, boolean last, int x, int y) throws FormatException, IOException { LOGGER.debug("Attempting to write image IFD."); @@ -1003,7 +1003,7 @@ private void writeIntValue(RandomAccessOutputStream out, long offset) * @param pixelType The pixel type. * @param nChannels The number of channels. */ - private void makeValidIFD(IFD ifd, int pixelType, int nChannels) { + public void makeValidIFD(IFD ifd, int pixelType, int nChannels) { int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType); int bps = 8 * bytesPerPixel; int[] bpsArray = new int[nChannels]; From f63aa7bb413e99a0b6b6110e7facaf61e97be3e3 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 22 Apr 2024 15:49:16 -0500 Subject: [PATCH 041/100] Use Double.parseDouble instead of DataTools.parseDouble to prevent test failures --- .../src/loci/tests/testng/Configuration.java | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/components/test-suite/src/loci/tests/testng/Configuration.java b/components/test-suite/src/loci/tests/testng/Configuration.java index 41bf0add6d2..a4d65ba6523 100644 --- a/components/test-suite/src/loci/tests/testng/Configuration.java +++ b/components/test-suite/src/loci/tests/testng/Configuration.java @@ -324,8 +324,7 @@ public Time getTimeIncrement() { String timeIncrement = currentTable.get(TIME_INCREMENT); String timeIncrementUnits = currentTable.get(TIME_INCREMENT_UNIT); try { - Double time = DataTools.parseDouble(timeIncrement); - return time == null ? null : FormatTools.getTime(time, timeIncrementUnits); + return timeIncrement == null ? null : FormatTools.getTime(Double.parseDouble(timeIncrement), timeIncrementUnits); } catch (NumberFormatException e) { return null; @@ -352,8 +351,7 @@ public Time getExposureTime(int channel) { String exposure = currentTable.get(EXPOSURE_TIME + channel); String exposureUnits = currentTable.get(EXPOSURE_TIME_UNIT + channel); try { - Double exp = DataTools.parseDouble(exposure); - return exp == null ? null : FormatTools.getTime(exp, exposureUnits); + return exposure == null ? null : FormatTools.getTime(Double.parseDouble(exposure), exposureUnits); } catch (NumberFormatException e) { return null; @@ -362,12 +360,12 @@ public Time getExposureTime(int channel) { public Double getDeltaT(int plane) { String deltaT = currentTable.get(DELTA_T + plane); - return deltaT == null ? null : DataTools.parseDouble(deltaT); + return deltaT == null ? null : Double.parseDouble(deltaT); } public Double getPositionX(int plane) { String pos = currentTable.get(X_POSITION + plane); - return pos == null ? null : DataTools.parseDouble(pos); + return pos == null ? null : Double.parseDouble(pos); } public String getPositionXUnit(int plane) { @@ -376,7 +374,7 @@ public String getPositionXUnit(int plane) { public Double getPositionY(int plane) { String pos = currentTable.get(Y_POSITION + plane); - return pos == null ? null : DataTools.parseDouble(pos); + return pos == null ? null : Double.parseDouble(pos); } public String getPositionYUnit(int plane) { @@ -385,7 +383,7 @@ public String getPositionYUnit(int plane) { public Double getPositionZ(int plane) { String pos = currentTable.get(Z_POSITION + plane); - return pos == null ? null : DataTools.parseDouble(pos); + return pos == null ? null : Double.parseDouble(pos); } public String getPositionZUnit(int plane) { @@ -396,8 +394,7 @@ public Length getEmissionWavelength(int channel) { String wavelength = currentTable.get(EMISSION_WAVELENGTH + channel); String emissionUnits = currentTable.get(EMISSION_WAVELENGTH_UNIT + channel); try { - Double wave = DataTools.parseDouble(wavelength); - return wave == null ? null : FormatTools.getWavelength(wave, emissionUnits); + return wavelength == null ? null : FormatTools.getWavelength(Double.parseDouble(wavelength), emissionUnits); } catch (NumberFormatException e) { return null; @@ -408,8 +405,7 @@ public Length getExcitationWavelength(int channel) { String wavelength = currentTable.get(EXCITATION_WAVELENGTH + channel); String excitationUnits = currentTable.get(EXCITATION_WAVELENGTH_UNIT + channel); try { - Double wave = DataTools.parseDouble(wavelength); - return wave == null ? null : FormatTools.getWavelength(wave, excitationUnits); + return wavelength == null ? null : FormatTools.getWavelength(Double.parseDouble(wavelength), excitationUnits); } catch (NumberFormatException e) { return null; @@ -832,8 +828,7 @@ private Length getPhysicalSize(String valueKey, String unitKey) { String units = currentTable.get(unitKey); try { UnitsLength unit = units == null ? UnitsLength.MICROMETER : UnitsLength.fromString(units); - Double size = DataTools.parseDouble(physicalSize); - return size == null ? null : UnitsLength.create(size, unit); + return physicalSize == null ? null : UnitsLength.create(Double.parseDouble(physicalSize), unit); } catch (NumberFormatException e) { } catch (EnumerationException e) { } From 7865d78773015abbea3a5fd5c04eeec021949dd8 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 22 Apr 2024 15:51:50 -0500 Subject: [PATCH 042/100] Use Double.parseDouble instead of DataTools.parseDouble to fix test failures --- .../src/loci/formats/in/BaseZeissReader.java | 21 ++- .../src/loci/formats/in/CellWorxReader.java | 14 +- .../src/loci/formats/in/ND2Handler.java | 11 +- .../src/loci/formats/in/ZeissCZIReader.java | 123 ++++++++---------- 4 files changed, 77 insertions(+), 92 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/BaseZeissReader.java b/components/formats-gpl/src/loci/formats/in/BaseZeissReader.java index 4e116091e1b..6327b32f2e6 100644 --- a/components/formats-gpl/src/loci/formats/in/BaseZeissReader.java +++ b/components/formats-gpl/src/loci/formats/in/BaseZeissReader.java @@ -36,7 +36,6 @@ import java.util.ArrayList; import java.lang.Math; -import loci.common.DataTools; import loci.common.DateTools; import loci.formats.CoreMetadata; import loci.formats.FormatTools; @@ -401,12 +400,10 @@ protected void fillMetadataPass7(MetadataStore store) throws FormatException, IO exposure = exposureTime.values().iterator().next(); } Double exp = 0d; - try { exp = DataTools.parseDouble(exposure); } + try { exp = Double.parseDouble(exposure); } catch (NumberFormatException e) { } catch (NullPointerException e) { } - if (exp != null) { - store.setPlaneExposureTime(new Time(exp, UNITS.SECOND), i, plane); - } + store.setPlaneExposureTime(new Time(exp, UNITS.SECOND), i, plane); int posIndex = i * getImageCount() + plane; @@ -913,7 +910,7 @@ else if (key.startsWith("NumberOfRawImages") && rawCount == 0) } else if (key.startsWith("Emission Wavelength")) { if (cIndex != -1) { - Double wave = DataTools.parseDouble(value); + Double wave = Double.parseDouble(value); Length emission = FormatTools.getEmissionWavelength(wave); if (emission != null) { emWavelength.put(cIndex, emission); @@ -922,7 +919,7 @@ else if (key.startsWith("Emission Wavelength")) { } else if (key.startsWith("Excitation Wavelength")) { if (cIndex != -1) { - Double wave = DataTools.parseDouble(value); + Double wave = Double.parseDouble(value); Length excitation = FormatTools.getExcitationWavelength(wave); if (excitation != null) { exWavelength.put(cIndex, excitation); @@ -964,7 +961,7 @@ else if (key.startsWith("Objective ID")) { store.setObjectiveImmersion(MetadataTools.getImmersion("Other"), 0, 0); } else if (key.startsWith("Objective N.A.")) { - store.setObjectiveLensNA(DataTools.parseDouble(value), 0, 0); + store.setObjectiveLensNA(Double.parseDouble(value), 0, 0); } else if (key.startsWith("Objective Name")) { String[] tokens = value.split(" "); @@ -975,14 +972,14 @@ else if (key.startsWith("Objective Name")) { Double.parseDouble(tokens[q].substring(0, slash - q)); String na = tokens[q].substring(slash + 1); store.setObjectiveNominalMagnification(mag, 0, 0); - store.setObjectiveLensNA(DataTools.parseDouble(na), 0, 0); + store.setObjectiveLensNA(Double.parseDouble(na), 0, 0); store.setObjectiveCorrection(MetadataTools.getCorrection(tokens[q - 1]), 0, 0); break; } } } else if (key.startsWith("Objective Working Distance")) { - store.setObjectiveWorkingDistance(new Length(DataTools.parseDouble(value), UNITS.MICROMETER), 0, 0); + store.setObjectiveWorkingDistance(new Length(Double.parseDouble(value), UNITS.MICROMETER), 0, 0); } else if (key.startsWith("Objective Immersion Type")) { String immersion = "Other"; @@ -1008,10 +1005,10 @@ else if (key.startsWith("Stage Position Y")) { addGlobalMetaList("Y position for position", value); } else if (key.startsWith("Orca Analog Gain")) { - detectorGain.put(cIndex, DataTools.parseDouble(value)); + detectorGain.put(cIndex, Double.parseDouble(value)); } else if (key.startsWith("Orca Analog Offset")) { - detectorOffset.put(cIndex, DataTools.parseDouble(value)); + detectorOffset.put(cIndex, Double.parseDouble(value)); } else if (key.startsWith("Comments")) { imageDescription = value; diff --git a/components/formats-gpl/src/loci/formats/in/CellWorxReader.java b/components/formats-gpl/src/loci/formats/in/CellWorxReader.java index 1cd3593464d..4b603927a4d 100644 --- a/components/formats-gpl/src/loci/formats/in/CellWorxReader.java +++ b/components/formats-gpl/src/loci/formats/in/CellWorxReader.java @@ -778,8 +778,8 @@ protected void parseWellLogFile(int wellIndex, MetadataStore store) } else if (key.equals("Scan Origin")) { String[] axes = value.split(","); - Double posX = DataTools.parseDouble(axes[0]); - Double posY = DataTools.parseDouble(axes[1]); + Double posX = Double.parseDouble(axes[0]); + Double posY = Double.parseDouble(axes[1]); for (int fieldRow=0; fieldRow 0) { int end = value.indexOf(" ", s + 2); - Double xSize = DataTools.parseDouble(value.substring(0, s).trim()); - Double ySize = DataTools.parseDouble(value.substring(s + 1, end).trim()); + Double xSize = Double.parseDouble(value.substring(0, s).trim()); + Double ySize = Double.parseDouble(value.substring(s + 1, end).trim()); Length x = FormatTools.getPhysicalSizeX(xSize / getSizeX()); Length y = FormatTools.getPhysicalSizeY(ySize / getSizeY()); @@ -827,7 +827,7 @@ else if (key.startsWith("Channel")) { token = token.trim(); if (token.startsWith("gain")) { String instrumentID = MetadataTools.createLSID("Instrument", 0); - Double gain = DataTools.parseDouble(token.replaceAll("gain ", "")); + Double gain = Double.parseDouble(token.replaceAll("gain ", "")); String detectorID = MetadataTools.createLSID("Detector", 0, 0); store.setInstrumentID(instrumentID, 0); @@ -854,8 +854,8 @@ else if (token.startsWith("EX")) { } } - Double emission = DataTools.parseDouble(em); - Double excitation = DataTools.parseDouble(ex); + Double emission = Double.parseDouble(em); + Double excitation = Double.parseDouble(ex); Length exWave = FormatTools.getExcitationWavelength(excitation); Length emWave = FormatTools.getEmissionWavelength(emission); diff --git a/components/formats-gpl/src/loci/formats/in/ND2Handler.java b/components/formats-gpl/src/loci/formats/in/ND2Handler.java index 7a4dc80740f..48d11f30895 100644 --- a/components/formats-gpl/src/loci/formats/in/ND2Handler.java +++ b/components/formats-gpl/src/loci/formats/in/ND2Handler.java @@ -154,7 +154,7 @@ public void populateROIs(MetadataStore store) { store.setLabelFontSize(new Length(fontSize, UNITS.POINT), r, 0); } store.setLabelText(roi.get("eval-text"), r, 0); - Length l = new Length(DataTools.parseDouble(roi.get("line-width")), UNITS.PIXEL); + Length l = new Length(Double.parseDouble(roi.get("line-width")), UNITS.PIXEL); store.setLabelStrokeWidth(l, r, 0); String rectangle = roi.get("rectangle"); @@ -885,11 +885,11 @@ else if (key.equals("Line")) { } else if (key.equalsIgnoreCase("Emission wavelength")) { String[] v = value.split(" "); - emWave.add(DataTools.parseDouble(v[0])); + emWave.add(Double.parseDouble(v[0])); } else if (key.equalsIgnoreCase("Excitation wavelength")) { String[] v = value.split(" "); - exWave.add(DataTools.parseDouble(v[0])); + exWave.add(Double.parseDouble(v[0])); } else if (key.equals("Power")) { power.add(DataTools.parseDouble(value).intValue()); @@ -898,10 +898,7 @@ else if (key.equals("CameraUniqueName")) { cameraModel = value; } else if (key.equals("ExposureTime")) { - Double time = DataTools.parseDouble(value); - if (time != null) { - exposureTime.add(time / 1000d); - } + exposureTime.add(Double.parseDouble(value) / 1000d); } else if (key.equals("sDate")) { date = DateTools.formatDate(value, DATE_FORMAT); diff --git a/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java b/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java index c84e5beb003..db5d505a895 100644 --- a/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java +++ b/components/formats-gpl/src/loci/formats/in/ZeissCZIReader.java @@ -1424,7 +1424,7 @@ else if (extraIndex >= 0 && extraIndex < extraImages.size()) { if (airPressure != null) { store.setImagingEnvironmentAirPressure( - new Pressure(DataTools.parseDouble(airPressure), UNITS.MILLIBAR), i); + new Pressure(Double.parseDouble(airPressure), UNITS.MILLIBAR), i); } if (co2Percent != null) { store.setImagingEnvironmentCO2Percent( @@ -1436,21 +1436,21 @@ else if (extraIndex >= 0 && extraIndex < extraImages.size()) { } if (temperature != null) { store.setImagingEnvironmentTemperature(new Temperature( - DataTools.parseDouble(temperature), UNITS.CELSIUS), i); + Double.parseDouble(temperature), UNITS.CELSIUS), i); } if (objectiveSettingsID != null) { store.setObjectiveSettingsID(objectiveSettingsID, i); if (correctionCollar != null) { store.setObjectiveSettingsCorrectionCollar( - DataTools.parseDouble(correctionCollar), i); + Double.parseDouble(correctionCollar), i); } if (medium != null) { store.setObjectiveSettingsMedium(MetadataTools.getMedium(medium), i); } if (refractiveIndex != null) { store.setObjectiveSettingsRefractiveIndex( - DataTools.parseDouble(refractiveIndex), i); + Double.parseDouble(refractiveIndex), i); } } @@ -1687,7 +1687,7 @@ else if (getZCTCoords(plane)[2] < timestamps.size()) { String emWave = channels.get(c).emission; if (emWave != null) { - Double wave = DataTools.parseDouble(emWave); + Double wave = Double.parseDouble(emWave); Length em = FormatTools.getEmissionWavelength(wave); if (em != null) { store.setChannelEmissionWavelength(em, i, c); @@ -1695,7 +1695,7 @@ else if (getZCTCoords(plane)[2] < timestamps.size()) { } String exWave = channels.get(c).excitation; if (exWave != null) { - Double wave = DataTools.parseDouble(exWave); + Double wave = Double.parseDouble(exWave); Length ex = FormatTools.getExcitationWavelength(wave); if (ex != null) { store.setChannelExcitationWavelength(ex, i, c); @@ -1709,7 +1709,7 @@ else if (getZCTCoords(plane)[2] < timestamps.size()) { if (channels.get(c).pinhole != null) { store.setChannelPinholeSize( - new Length(DataTools.parseDouble(channels.get(c).pinhole), UNITS.MICROMETER), i, c); + new Length(Double.parseDouble(channels.get(c).pinhole), UNITS.MICROMETER), i, c); } if (channels.get(c).acquisitionMode != null) { @@ -2509,7 +2509,7 @@ private void translateInformation(Element root) throws FormatException { String power = getFirstNodeValue(lightSource, "Power"); if ("Laser".equals(type)) { if (power != null) { - store.setLaserPower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); + store.setLaserPower(new Power(Double.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setLaserLotNumber(lotNumber, 0, i); store.setLaserManufacturer(manufacturer, 0, i); @@ -2518,7 +2518,7 @@ private void translateInformation(Element root) throws FormatException { } else if ("Arc".equals(type)) { if (power != null) { - store.setArcPower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); + store.setArcPower(new Power(Double.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setArcLotNumber(lotNumber, 0, i); store.setArcManufacturer(manufacturer, 0, i); @@ -2527,7 +2527,7 @@ else if ("Arc".equals(type)) { } else if ("LightEmittingDiode".equals(type)) { if (power != null) { - store.setLightEmittingDiodePower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); + store.setLightEmittingDiodePower(new Power(Double.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setLightEmittingDiodeLotNumber(lotNumber, 0, i); store.setLightEmittingDiodeManufacturer(manufacturer, 0, i); @@ -2536,7 +2536,7 @@ else if ("LightEmittingDiode".equals(type)) { } else if ("Filament".equals(type)) { if (power != null) { - store.setFilamentPower(new Power(DataTools.parseDouble(power), UNITS.MILLIWATT), 0, i); + store.setFilamentPower(new Power(Double.parseDouble(power), UNITS.MILLIWATT), 0, i); } store.setFilamentLotNumber(lotNumber, 0, i); store.setFilamentManufacturer(manufacturer, 0, i); @@ -2594,7 +2594,7 @@ else if ("Filament".equals(type)) { String offset = getFirstNodeValue(detector, "Offset"); if (offset != null && !offset.equals("")) { - store.setDetectorOffset(DataTools.parseDouble(offset), 0, detectorIndex); + store.setDetectorOffset(Double.parseDouble(offset), 0, detectorIndex); } zoom = getFirstNodeValue(detector, "Zoom"); @@ -2609,7 +2609,7 @@ else if ("Filament".equals(type)) { String ampGain = getFirstNodeValue(detector, "AmplificationGain"); if (ampGain != null && !ampGain.equals("")) { - store.setDetectorAmplificationGain(DataTools.parseDouble(ampGain), 0, detectorIndex); + store.setDetectorAmplificationGain(Double.parseDouble(ampGain), 0, detectorIndex); } String detectorType = getFirstNodeValue(detector, "Type"); @@ -2725,8 +2725,8 @@ else if ("Filament".equals(type)) { String cutIn = getFirstNodeValue(transmittance, "CutIn"); String cutOut = getFirstNodeValue(transmittance, "CutOut"); - Double inWave = cutIn == null ? 0 : DataTools.parseDouble(cutIn); - Double outWave = cutOut == null ? 0 : DataTools.parseDouble(cutOut); + Double inWave = cutIn == null ? 0 : Double.parseDouble(cutIn); + Double outWave = cutOut == null ? 0 : Double.parseDouble(cutOut); Length in = FormatTools.getCutIn(inWave); Length out = FormatTools.getCutOut(outWave); @@ -2743,13 +2743,13 @@ else if ("Filament".equals(type)) { getFirstNodeValue(transmittance, "CutOutTolerance"); if (inTolerance != null) { - Double cutInTolerance = DataTools.parseDouble(inTolerance); + Double cutInTolerance = Double.parseDouble(inTolerance); store.setTransmittanceRangeCutInTolerance( new Length(cutInTolerance, UNITS.NANOMETER), 0, i); } if (outTolerance != null) { - Double cutOutTolerance = DataTools.parseDouble(outTolerance); + Double cutOutTolerance = Double.parseDouble(outTolerance); store.setTransmittanceRangeCutOutTolerance( new Length(cutOutTolerance, UNITS.NANOMETER), 0, i); } @@ -2813,13 +2813,7 @@ private void translateScaling(Element root) { if (originalValue == null) { continue; } - Double value = DataTools.parseDouble(originalValue); - if (value != null) { - value *= 1000000; - } - else { - value = 0d; - } + Double value = Double.parseDouble(originalValue) * 1000000; if (value > 0) { PositiveFloat size = new PositiveFloat(value); @@ -2946,23 +2940,20 @@ private void translateLayers(Element root) { String centerY = getFirstNodeValue(geometry, "CenterY"); if (length != null) { - Double halfLen = DataTools.parseDouble(length); - if (halfLen != null) { - halfLen /= 2; - if (centerX != null) { - store.setLineX1(DataTools.parseDouble(centerX) - halfLen, roiCount, shape); - store.setLineX2(DataTools.parseDouble(centerX) + halfLen, roiCount, shape); - - store.setLineX1(DataTools.parseDouble(centerX), roiCount, shape + 1); - store.setLineX2(DataTools.parseDouble(centerX), roiCount, shape + 1); - } - if (centerY != null) { - store.setLineY1(DataTools.parseDouble(centerY), roiCount, shape); - store.setLineY2(DataTools.parseDouble(centerY), roiCount, shape); + Double halfLen = Double.parseDouble(length) / 2; + if (centerX != null) { + store.setLineX1(Double.parseDouble(centerX) - halfLen, roiCount, shape); + store.setLineX2(Double.parseDouble(centerX) + halfLen, roiCount, shape); - store.setLineY1(DataTools.parseDouble(centerY) - halfLen, roiCount, shape + 1); - store.setLineY2(DataTools.parseDouble(centerY) + halfLen, roiCount, shape + 1); - } + store.setLineX1(Double.parseDouble(centerX), roiCount, shape + 1); + store.setLineX2(Double.parseDouble(centerX), roiCount, shape + 1); + } + if (centerY != null) { + store.setLineY1(Double.parseDouble(centerY), roiCount, shape); + store.setLineY2(Double.parseDouble(centerY), roiCount, shape); + + store.setLineY1(Double.parseDouble(centerY) - halfLen, roiCount, shape + 1); + store.setLineY2(Double.parseDouble(centerY) + halfLen, roiCount, shape + 1); } } store.setLineText(getFirstNodeValue(textElements, "Text"), roiCount, shape); @@ -2992,16 +2983,16 @@ private void translateLayers(Element root) { String centerY = getFirstNodeValue(geometry, "CenterY"); if (radiusX != null) { - store.setEllipseRadiusX(DataTools.parseDouble(radiusX), roiCount, shape); + store.setEllipseRadiusX(Double.parseDouble(radiusX), roiCount, shape); } if (radiusY != null) { - store.setEllipseRadiusY(DataTools.parseDouble(radiusY), roiCount, shape); + store.setEllipseRadiusY(Double.parseDouble(radiusY), roiCount, shape); } if (centerX != null) { - store.setEllipseX(DataTools.parseDouble(centerX), roiCount, shape); + store.setEllipseX(Double.parseDouble(centerX), roiCount, shape); } if (centerY != null) { - store.setEllipseY(DataTools.parseDouble(centerY), roiCount, shape); + store.setEllipseY(Double.parseDouble(centerY), roiCount, shape); } store.setEllipseText( getFirstNodeValue(textElements, "Text"), roiCount, shape); @@ -3174,7 +3165,7 @@ private void translateHardwareSettings(Element root) throws FormatException { if (magnification != null) { try { store.setObjectiveNominalMagnification( - DataTools.parseDouble(magnification), 0, i); + Double.parseDouble(magnification), 0, i); } catch (NumberFormatException e) { LOGGER.debug("Could not parse magnification", e); @@ -3182,7 +3173,7 @@ private void translateHardwareSettings(Element root) throws FormatException { } if (na != null) { try { - store.setObjectiveLensNA(DataTools.parseDouble(na), 0, i); + store.setObjectiveLensNA(Double.parseDouble(na), 0, i); } catch (NumberFormatException e) { LOGGER.debug("Could not parse numerical aperture", e); @@ -3190,7 +3181,7 @@ private void translateHardwareSettings(Element root) throws FormatException { } if (wd != null) { try { - store.setObjectiveWorkingDistance(new Length(DataTools.parseDouble(wd), UNITS.MICROMETER), 0, i); + store.setObjectiveWorkingDistance(new Length(Double.parseDouble(wd), UNITS.MICROMETER), 0, i); } catch (NumberFormatException e) { LOGGER.debug("Could not parse working distance", e); @@ -3218,10 +3209,10 @@ private int populateRectangles(NodeList rectangles, int roi, int shape) { if (left != null && top != null && width != null && height != null) { store.setRectangleID( MetadataTools.createLSID("Shape", roi, shape), roi, shape); - store.setRectangleX(DataTools.parseDouble(left), roi, shape); - store.setRectangleY(DataTools.parseDouble(top), roi, shape); - store.setRectangleWidth(DataTools.parseDouble(width), roi, shape); - store.setRectangleHeight(DataTools.parseDouble(height), roi, shape); + store.setRectangleX(Double.parseDouble(left), roi, shape); + store.setRectangleY(Double.parseDouble(top), roi, shape); + store.setRectangleWidth(Double.parseDouble(width), roi, shape); + store.setRectangleHeight(Double.parseDouble(height), roi, shape); String name = getFirstNodeValue(attributes, "Name"); String label = getFirstNodeValue(textElements, "Text"); @@ -3281,16 +3272,16 @@ private int populateLines(NodeList lines, int roi, int shape) { MetadataTools.createLSID("Shape", roi, shape), roi, shape); if (x1 != null) { - store.setLineX1(DataTools.parseDouble(x1), roi, shape); + store.setLineX1(Double.parseDouble(x1), roi, shape); } if (x2 != null) { - store.setLineX2(DataTools.parseDouble(x2), roi, shape); + store.setLineX2(Double.parseDouble(x2), roi, shape); } if (y1 != null) { - store.setLineY1(DataTools.parseDouble(y1), roi, shape); + store.setLineY1(Double.parseDouble(y1), roi, shape); } if (y2 != null) { - store.setLineY2(DataTools.parseDouble(y2), roi, shape); + store.setLineY2(Double.parseDouble(y2), roi, shape); } store.setLineText(getFirstNodeValue(textElements, "Text"), roi, shape); } @@ -3311,14 +3302,14 @@ private int populateCircles(NodeList circles, int roi, int shape) { String centerY = getFirstNodeValue(geometry, "CenterY"); if (radius != null) { - store.setEllipseRadiusX(DataTools.parseDouble(radius), roi, shape); - store.setEllipseRadiusY(DataTools.parseDouble(radius), roi, shape); + store.setEllipseRadiusX(Double.parseDouble(radius), roi, shape); + store.setEllipseRadiusY(Double.parseDouble(radius), roi, shape); } if (centerX != null) { - store.setEllipseX(DataTools.parseDouble(centerX), roi, shape); + store.setEllipseX(Double.parseDouble(centerX), roi, shape); } if (centerY != null) { - store.setEllipseY(DataTools.parseDouble(centerY), roi, shape); + store.setEllipseY(Double.parseDouble(centerY), roi, shape); } store.setEllipseText(getFirstNodeValue(textElements, "Text"), roi, shape); } @@ -3544,7 +3535,7 @@ private void translateExperiment(Element root) throws FormatException { try { if (exposure != null) { - channels.get(i).exposure = DataTools.parseDouble(exposure); + channels.get(i).exposure = Double.parseDouble(exposure); } } catch (NumberFormatException e) { @@ -3552,7 +3543,7 @@ private void translateExperiment(Element root) throws FormatException { } try { if (gain != null) { - channels.get(i).gain = DataTools.parseDouble(gain); + channels.get(i).gain = Double.parseDouble(gain); } } catch (NumberFormatException e) { @@ -3834,7 +3825,7 @@ private void parseObjectives(NodeList objectives) throws FormatException { String lensNA = getFirstNodeValue(objective, "LensNA"); if (lensNA != null) { - store.setObjectiveLensNA(DataTools.parseDouble(lensNA), 0, i); + store.setObjectiveLensNA(Double.parseDouble(lensNA), 0, i); } String magnification = @@ -3842,7 +3833,7 @@ private void parseObjectives(NodeList objectives) throws FormatException { if (magnification == null) { magnification = getFirstNodeValue(objective, "Magnification"); } - Double mag = magnification == null ? null : DataTools.parseDouble(magnification); + Double mag = magnification == null ? null : Double.parseDouble(magnification); if (mag != null) { store.setObjectiveNominalMagnification(mag, 0, i); @@ -3851,11 +3842,11 @@ private void parseObjectives(NodeList objectives) throws FormatException { getFirstNodeValue(objective, "CalibratedMagnification"); if (calibratedMag != null) { store.setObjectiveCalibratedMagnification( - DataTools.parseDouble(calibratedMag), 0, i); + Double.parseDouble(calibratedMag), 0, i); } String wd = getFirstNodeValue(objective, "WorkingDistance"); if (wd != null) { - store.setObjectiveWorkingDistance(new Length(DataTools.parseDouble(wd), UNITS.MICROMETER), 0, i); + store.setObjectiveWorkingDistance(new Length(Double.parseDouble(wd), UNITS.MICROMETER), 0, i); } String iris = getFirstNodeValue(objective, "Iris"); if (iris != null) { @@ -4295,7 +4286,7 @@ else if (tagNode.getNodeName().equals("AcquisitionTime")) { timestamp = t.asInstant().getMillis() / 1000d; } else if (tagNode.getNodeName().equals("ExposureTime")) { - exposureTime = DataTools.parseDouble(text); + exposureTime = Double.parseDouble(text); } } } From af483e7f79fc011c4adea0ab05918f374f6df348 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 24 Apr 2024 11:09:35 -0500 Subject: [PATCH 043/100] Use Double.parseDouble instead of DataTools.parseDouble to fix one more test failure --- .../formats-gpl/src/loci/formats/in/FlexReader.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/FlexReader.java b/components/formats-gpl/src/loci/formats/in/FlexReader.java index 01c9f06de9c..fa52973495f 100644 --- a/components/formats-gpl/src/loci/formats/in/FlexReader.java +++ b/components/formats-gpl/src/loci/formats/in/FlexReader.java @@ -1552,7 +1552,7 @@ else if (qName.equals("Barcode")) { else if (qName.equals("Wavelength") && populateCore) { String lsid = MetadataTools.createLSID("LightSource", 0, nextLaser); store.setLaserID(lsid, 0, nextLaser); - Double wavelength = DataTools.parseDouble(value); + Double wavelength = Double.parseDouble(value); Length wave = FormatTools.getWavelength(wavelength); if (wave != null) { store.setLaserWavelength(wave, 0, nextLaser); @@ -1566,11 +1566,11 @@ else if (qName.equals("Wavelength") && populateCore) { } } else if (qName.equals("Magnification") && populateCore) { - store.setObjectiveCalibratedMagnification(DataTools.parseDouble(value), 0, + store.setObjectiveCalibratedMagnification(Double.parseDouble(value), 0, nextObjective); } else if (qName.equals("NumAperture") && populateCore) { - store.setObjectiveLensNA(DataTools.parseDouble(value), 0, nextObjective); + store.setObjectiveLensNA(Double.parseDouble(value), 0, nextObjective); } else if (qName.equals("Immersion") && populateCore) { String immersion = "Other"; @@ -1656,10 +1656,10 @@ else if (qName.equals("PositionZ")) { } } else if (qName.equals("TimepointOffsetUsed")) { - planeDeltaT.add(DataTools.parseDouble(value)); + planeDeltaT.add(Double.parseDouble(value)); } else if (qName.equals("CameraExposureTime")) { - planeExposureTime.add(DataTools.parseDouble(value)); + planeExposureTime.add(Double.parseDouble(value)); } else if (qName.equals("LightSourceCombinationRef")) { lightSourceCombinationRefs.add(value); From d1c0e13036c4e87f3d04bb9299552da65841da2e Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 1 May 2024 18:05:10 -0500 Subject: [PATCH 044/100] bfconvert: always do tiled conversion when a pyramid is present Instead of requiring DICOM output and a pyramid. This makes sure that the smaller resolutions of a pyramid are written tile-wise when writing OME-TIFF. --- .../src/loci/formats/tools/ImageConverter.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index ad50dcf9b85..b249f3e88cf 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -1260,11 +1260,9 @@ private boolean isTiledWriter(IFormatWriter writer, String outputFile) private boolean doTileConversion(IFormatWriter writer, String outputFile) throws FormatException { - if (writer instanceof DicomWriter || - (writer instanceof ImageWriter && ((ImageWriter) writer).getWriter(outputFile) instanceof DicomWriter)) - { - MetadataStore r = reader.getMetadataStore(); - return !(r instanceof IPyramidStore) || ((IPyramidStore) r).getResolutionCount(reader.getSeries()) > 1; + MetadataStore r = reader.getMetadataStore(); + if ((r instanceof IPyramidStore) && ((IPyramidStore) r).getResolutionCount(reader.getSeries()) > 1) { + return true; } return DataTools.safeMultiply64(width, height) >= DataTools.safeMultiply64(4096, 4096) || saveTileWidth > 0 || saveTileHeight > 0; From 3146c90ae6ef143ae2798331022fbde8bf0d33f0 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 1 May 2024 18:07:02 -0500 Subject: [PATCH 045/100] DICOM reader: fix optimal tile size calculation Different resolutions may have different tile sizes. --- .../src/loci/formats/in/DicomReader.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/in/DicomReader.java b/components/formats-bsd/src/loci/formats/in/DicomReader.java index 22702106b48..f4c0a4cf841 100644 --- a/components/formats-bsd/src/loci/formats/in/DicomReader.java +++ b/components/formats-bsd/src/loci/formats/in/DicomReader.java @@ -166,11 +166,14 @@ public int getTileColumns(int no) { public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, IOException { FormatTools.assertId(currentId, true, 1); - Region boundingBox = new Region(x * originalX, y * originalY, originalX, originalY); + // TODO: this will result in a lot of redundant lookups, and should be optimized + int tileWidth = getOptimalTileWidth(); + int tileHeight = getOptimalTileHeight(); + Region boundingBox = new Region(x * tileWidth, y * tileHeight, tileWidth, tileHeight); List tiles = getTileList(no, boundingBox, true); if (tiles == null || tiles.size() == 0) { - throw new FormatException("Could not find valid tile; no=" + no + ", x=" + x + ", y=" + y); + throw new FormatException("Could not find valid tile; no=" + no + ", boundingBox=" + boundingBox); } DicomTile tile = tiles.get(0); byte[] buf = new byte[(int) (tile.endOffset - tile.fileOffset)]; @@ -336,7 +339,10 @@ public int fileGroupOption(String id) throws FormatException, IOException { public int getOptimalTileWidth() { FormatTools.assertId(currentId, true, 1); if (tilePositions.containsKey(getCoreIndex())) { - return tilePositions.get(getCoreIndex()).get(0).region.width; + List tile = getTileList(0, null, true); + if (tile != null && tile.size() >= 1) { + return tile.get(0).region.width; + } } if (originalX < getSizeX() && originalX > 0) { return originalX; @@ -348,7 +354,10 @@ public int getOptimalTileWidth() { public int getOptimalTileHeight() { FormatTools.assertId(currentId, true, 1); if (tilePositions.containsKey(getCoreIndex())) { - return tilePositions.get(getCoreIndex()).get(0).region.height; + List tile = getTileList(0, null, true); + if (tile != null && tile.size() >= 1) { + return tile.get(0).region.height; + } } if (originalY < getSizeY() && originalY > 0) { return originalY; From 92ec5815b9393b8e1d273c2aed6409f187575230 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 1 May 2024 18:07:50 -0500 Subject: [PATCH 046/100] Extend precompressed tile writing to OME-TIFF Mostly this reuses logic in the basic TIFF writer. --- .../src/loci/formats/out/OMETiffWriter.java | 18 ++++++++++++++++++ .../loci/formats/out/PyramidOMETiffWriter.java | 13 +++++++++++++ .../src/loci/formats/out/TiffWriter.java | 18 +++++++++++------- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/OMETiffWriter.java b/components/formats-bsd/src/loci/formats/out/OMETiffWriter.java index eb4afa8fe55..e0785aeb443 100644 --- a/components/formats-bsd/src/loci/formats/out/OMETiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/OMETiffWriter.java @@ -199,6 +199,24 @@ public void close() throws IOException { // -- IFormatWriter API methods -- + @Override + public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) + throws FormatException, IOException + { + super.saveCompressedBytes(no, buf, x, y, w, h); + + int index = no; + while (imageLocations[series][index] != null) { + if (index < imageLocations[series].length - 1) { + index++; + } + else { + break; + } + } + imageLocations[series][index] = currentId; + } + /** * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) */ diff --git a/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java b/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java index a1da832176f..d287493b8ac 100644 --- a/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java @@ -70,6 +70,19 @@ public boolean isThisType(String name) { // -- IFormatWriter API methods -- + protected IFD makeIFD() throws FormatException, IOException { + IFD ifd = super.makeIFD(); + if (getResolution() > 0) { + ifd.put(IFD.NEW_SUBFILE_TYPE, 1); + } + else { + if (!ifd.containsKey(IFD.SUB_IFD)) { + ifd.put(IFD.SUB_IFD, (long) 0); + } + } + return ifd; + } + @Override public void saveBytes(int no, byte[] buf, IFD ifd, int x, int y, int w, int h) throws FormatException, IOException diff --git a/components/formats-bsd/src/loci/formats/out/TiffWriter.java b/components/formats-bsd/src/loci/formats/out/TiffWriter.java index 668c46e07b2..a58842114b9 100644 --- a/components/formats-bsd/src/loci/formats/out/TiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/TiffWriter.java @@ -178,7 +178,7 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) LOGGER.warn("saveCompressedBytes(series={}, resolution={}, no={}, x={}, y={})", series, resolution, no, x, y); - IFD ifd = new IFD(); + IFD ifd = makeIFD(); MetadataRetrieve retrieve = getMetadataRetrieve(); int type = FormatTools.pixelTypeFromString( retrieve.getPixelsType(series).toString()); @@ -193,12 +193,6 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) throw new IllegalArgumentException("Compressed tile dimensions must match tile size"); } - boolean usingTiling = currentTileSizeX > 0 && currentTileSizeY > 0; - if (usingTiling) { - ifd.put(new Integer(IFD.TILE_WIDTH), new Long(currentTileSizeX)); - ifd.put(new Integer(IFD.TILE_LENGTH), new Long(currentTileSizeY)); - } - // This operation is synchronized synchronized (this) { // This operation is synchronized against the TIFF saver. @@ -221,6 +215,16 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) nChannels, lastPlane && lastSeries && lastResolution, x, y); } + protected IFD makeIFD() throws FormatException, IOException { + IFD ifd = new IFD(); + boolean usingTiling = getTileSizeX() > 0 && getTileSizeY() > 0; + if (usingTiling) { + ifd.put(new Integer(IFD.TILE_WIDTH), new Long(getTileSizeX())); + ifd.put(new Integer(IFD.TILE_LENGTH), new Long(getTileSizeY())); + } + return ifd; + } + // -- FormatWriter API methods -- /* @see loci.formats.FormatWriter#setId(String) */ From fd17421bbfb0c7693645bc1f6e8f54e476a7ca67 Mon Sep 17 00:00:00 2001 From: David Gault Date: Tue, 4 Jun 2024 13:50:19 +0100 Subject: [PATCH 047/100] Imaris: For non 0 indexed colors remove null entries --- components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java b/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java index 96ce60737f9..39a0b3e6189 100644 --- a/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java +++ b/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java @@ -408,6 +408,7 @@ protected void initFile(String id) throws FormatException, IOException { catch (NumberFormatException e) { } } + colors.remove(null); if (i < colors.size()) { double[] color = colors.get(i); Color realColor = new Color( From 30dc860b6ccb600aa185bde8bf99a5587a4d660b Mon Sep 17 00:00:00 2001 From: David Gault Date: Fri, 14 Jun 2024 14:06:07 +0100 Subject: [PATCH 048/100] ICS: Fix NPE when image name is empty --- .../formats-bsd/src/loci/formats/in/ICSReader.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/in/ICSReader.java b/components/formats-bsd/src/loci/formats/in/ICSReader.java index 0513eac024e..c6260c20f29 100644 --- a/components/formats-bsd/src/loci/formats/in/ICSReader.java +++ b/components/formats-bsd/src/loci/formats/in/ICSReader.java @@ -1478,10 +1478,12 @@ else if (labels.equalsIgnoreCase("x y t")) { MetadataTools.populatePixels(store, this, true); // populate Image data - imageName = imageName.replace('/', File.separatorChar); - imageName = imageName.replace('\\', File.separatorChar); - imageName = imageName.substring(imageName.lastIndexOf(File.separator) + 1); - store.setImageName(imageName, 0); + if (imageName != null) { + imageName = imageName.replace('/', File.separatorChar); + imageName = imageName.replace('\\', File.separatorChar); + imageName = imageName.substring(imageName.lastIndexOf(File.separator) + 1); + store.setImageName(imageName, 0); + } if (date != null) store.setImageAcquisitionDate(new Timestamp(date), 0); From 6136fb3806b683f1ae0d359ba945cc995ff53370 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Sun, 16 Jun 2024 13:00:14 -0500 Subject: [PATCH 049/100] Fix typos --- .../formats-api/src/loci/formats/ICompressedTileReader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/formats-api/src/loci/formats/ICompressedTileReader.java b/components/formats-api/src/loci/formats/ICompressedTileReader.java index b90fc44a4d0..ad7baee3b7c 100644 --- a/components/formats-api/src/loci/formats/ICompressedTileReader.java +++ b/components/formats-api/src/loci/formats/ICompressedTileReader.java @@ -66,7 +66,7 @@ default int getTileColumns(int no) { * * @param no plane index * @param x tile X index (indexed from 0, @see getTileColumns(int)) - * @param y tile Y index (indexed frmo 0, @see getTileRows(int)) + * @param y tile Y index (indexed from 0, @see getTileRows(int)) * @return compressed tile bytes */ default byte[] openCompressedBytes(int no, int x, int y) throws FormatException, IOException { @@ -79,7 +79,7 @@ default byte[] openCompressedBytes(int no, int x, int y) throws FormatException, * @param no plane index * @param buf pre-allocated buffer in which to store compressed bytes * @param x tile X index (indexed from 0, @see getTileColumns(int)) - * @param y tile Y index (indexed frmo 0, @see getTileRows(int)) + * @param y tile Y index (indexed from 0, @see getTileRows(int)) * @return compressed tile bytes */ default byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws FormatException, IOException { @@ -102,7 +102,7 @@ default Codec getTileCodec(int no) throws FormatException, IOException { * * @param no plane index * @param x tile X index (indexed from 0, @see getTileColumns(int)) - * @param y tile Y index (indexed frmo 0, @see getTileRows(int)) + * @param y tile Y index (indexed from 0, @see getTileRows(int)) * @return codec options * @see getTileCodec(int) */ From 93e38d8ec6b073168852ebac09edf502b28ee19b Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Sun, 16 Jun 2024 13:31:35 -0500 Subject: [PATCH 050/100] If `-precompressed` specified without `-compression`, use reader compression type automatically This doesn't yet completely support mixed compression types within the same dataset, but something like: $ bfconvert -noflat -precompressed CMU-1.svs CMU-1.dcm should run without error and convert the pyramid without recompressing. --- .../loci/formats/tools/ImageConverter.java | 20 ++++++++++++++++ .../loci/formats/codec/CompressionType.java | 24 ++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index b249f3e88cf..2b88165fbb6 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -62,6 +62,7 @@ import loci.formats.FileStitcher; import loci.formats.FormatException; import loci.formats.FormatTools; +import loci.formats.ICompressedTileReader; import loci.formats.IFormatReader; import loci.formats.IFormatWriter; import loci.formats.ImageReader; @@ -71,7 +72,9 @@ import loci.formats.MetadataTools; import loci.formats.MinMaxCalculator; import loci.formats.MissingLibraryException; +import loci.formats.codec.Codec; import loci.formats.codec.CodecOptions; +import loci.formats.codec.CompressionType; import loci.formats.codec.JPEG2000CodecOptions; import loci.formats.gui.Index16ColorModel; import loci.formats.in.DynamicMetadataOptions; @@ -558,6 +561,11 @@ public boolean testConvert(IFormatWriter writer, String[] args) reader.setId(in); + if (compression == null && precompressed) { + compression = getReaderCodecName(); + LOGGER.info("Implicitly using compression = {}", compression); + } + if (swapOrder != null) { dimSwapper.swapDimensions(swapOrder); } @@ -1308,6 +1316,18 @@ private void setCodecOptions(IFormatWriter writer) { } } + private String getReaderCodecName() throws FormatException, IOException { + if (reader instanceof ICompressedTileReader) { + ICompressedTileReader r = (ICompressedTileReader) reader; + Codec c = r.getTileCodec(0); + CompressionType type = CompressionType.get(c); + if (type != null) { + return type.getCompression(); + } + } + return null; + } + // -- Main method -- public static void main(String[] args) throws FormatException, IOException { diff --git a/components/formats-bsd/src/loci/formats/codec/CompressionType.java b/components/formats-bsd/src/loci/formats/codec/CompressionType.java index 01b595a7727..de9e8fa0111 100644 --- a/components/formats-bsd/src/loci/formats/codec/CompressionType.java +++ b/components/formats-bsd/src/loci/formats/codec/CompressionType.java @@ -115,5 +115,27 @@ public int getCode() { public String getCompression() { return compression; } - + + /** + * Look up the compression type by Codec instance. + */ + public static CompressionType get(Codec c) { + if (c instanceof ZlibCodec) { + return ZLIB; + } + if (c instanceof LZWCodec) { + return LZW; + } + if (c instanceof JPEGCodec) { + return JPEG; + } + if (c instanceof JPEG2000Codec) { + return J2K; + } + if (c instanceof PassthroughCodec) { + return UNCOMPRESSED; + } + return null; + } + } From 0e842f99a52878f86123c56ca37e212dbf20a495 Mon Sep 17 00:00:00 2001 From: Chen Qian Date: Tue, 18 Jun 2024 15:42:13 +0200 Subject: [PATCH 051/100] SDT: fix java.lang.NegativeArraySizeException when reading files recorded with SPCM 9.90 --- components/formats-gpl/src/loci/formats/in/SDTInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/SDTInfo.java b/components/formats-gpl/src/loci/formats/in/SDTInfo.java index 8dfa24f227f..e9dbfdbe52f 100644 --- a/components/formats-gpl/src/loci/formats/in/SDTInfo.java +++ b/components/formats-gpl/src/loci/formats/in/SDTInfo.java @@ -106,7 +106,7 @@ public class SDTInfo { public int setupOffs; /** Length of the setup data. */ - public short setupLength; + public int setupLength; /** Offset of the first data block. */ public int dataBlockOffs; @@ -443,7 +443,7 @@ public SDTInfo(RandomAccessInputStream in, Hashtable meta) infoOffs = in.readInt(); infoLength = in.readShort(); setupOffs = in.readInt(); - setupLength = in.readShort(); + setupLength = in.readUnsignedShort(); dataBlockOffs = in.readInt(); noOfDataBlocks = in.readShort(); dataBlockLength = in.readInt(); From ec5f8c26ae5f2342e920c3a9fa88f11111de8199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20St=C3=B6ter?= Date: Thu, 20 Jun 2024 11:25:08 +0200 Subject: [PATCH 052/100] Allow processing multiple files sequentially in a single run, with file names read from stdin. This reduces JVM startup overhead when processing thousands of files. If -- is passed as file argument then file names are read line by line from stdin and processed sequentially. --- .../src/loci/formats/tools/ImageInfo.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index 1fc189d209a..54c7d1ad264 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -37,6 +37,9 @@ import java.io.File; import java.util.Hashtable; import java.util.StringTokenizer; +import java.util.Scanner; +import java.util.Arrays; +import java.util.List; import loci.common.ByteArrayHandle; import loci.common.DataTools; @@ -1126,7 +1129,23 @@ private void printDimension(String dim, int size, int effectiveSize, public static void main(String[] args) throws Exception { DebugTools.enableLogging("INFO"); - if (!new ImageInfo().testRead(args)) System.exit(1); + + List argsList = Arrays.asList(args); + int idx = argsList.indexOf("--"); + + if (idx >= 0) { + Scanner scanner = new Scanner(System.in); + String[] newArgs = argsList.toArray(new String[0]); + + while (scanner.hasNext()) { + newArgs[idx] = scanner.nextLine(); + if (!new ImageInfo().testRead(newArgs)) System.exit(1); + } + scanner.close(); + } + else { + if (!new ImageInfo().testRead(args)) System.exit(1); + } } } From 41922a83b6202667bc7e91ed765a2fef14ddb5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20St=C3=B6ter?= Date: Thu, 20 Jun 2024 11:43:25 +0200 Subject: [PATCH 053/100] Add usage information for reading file names from stdin. --- .../bio-formats-tools/src/loci/formats/tools/ImageInfo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index 54c7d1ad264..16ab96d47f3 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -314,6 +314,7 @@ public void printUsage() { "", " -version: print the library version and exit", " file: the image file to read", + " reads file names line-wise from stdin if -- is passed", " -nopix: read metadata only, not pixels", " -nocore: do not output core metadata", " -nometa: do not parse format-specific metadata table", From 23780deb20faba5b66f7f07b647a069ac3987164 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 20 Jun 2024 18:35:56 -0500 Subject: [PATCH 054/100] Fix tile size/count writing when calling saveBytes --- .../src/loci/formats/out/DicomWriter.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index 04c0c867444..275986a606a 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -415,6 +415,10 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || boolean first = x == 0 && y == 0; boolean last = x + w == getSizeX() && y + h == getSizeY(); + int xTiles = (int) Math.ceil((double) getSizeX() / thisTileWidth); + int yTiles = (int) Math.ceil((double) getSizeY() / thisTileHeight); + int sizeZ = r.getPixelsSizeZ(series).getValue().intValue(); + // the compression type isn't supplied to the writer until // after setId is called, so metadata that indicates or // depends on the compression type needs to be set in @@ -436,6 +440,15 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || ifds[resolutionIndex][no].put(IFD.PHOTOMETRIC_INTERPRETATION, PhotoInterp.Y_CB_CR.getCode()); } } + + out.seek(tileWidthPointer[resolutionIndex]); + out.writeShort((short) getTileSizeX()); + out.seek(tileHeightPointer[resolutionIndex]); + out.writeShort((short) getTileSizeY()); + out.seek(tileCountPointer[resolutionIndex]); + + out.writeBytes(padString(String.valueOf( + xTiles * yTiles * sizeZ * r.getChannelCount(series)))); } // TILED_SPARSE, so the tile coordinates must be written @@ -528,7 +541,6 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || // in the IFD // this tries to calculate the index without assuming sequential tile // writing, but maybe there is a better way to calculate this? - int xTiles = (int) Math.ceil((double) getSizeX() / tileWidth[resolutionIndex]); int xTile = x / tileWidth[resolutionIndex]; int yTile = y / tileHeight[resolutionIndex]; int tileIndex = (yTile * xTiles) + xTile; @@ -538,6 +550,17 @@ else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || if (ifds[resolutionIndex][no] != null) { tileByteCounts = (long[]) ifds[resolutionIndex][no].getIFDValue(IFD.TILE_BYTE_COUNTS); tileOffsets = (long[]) ifds[resolutionIndex][no].getIFDValue(IFD.TILE_OFFSETS); + + if (tileByteCounts.length < xTiles * yTiles) { + long[] newTileByteCounts = new long[xTiles * yTiles]; + long[] newTileOffsets = new long[xTiles * yTiles]; + System.arraycopy(tileByteCounts, 0, newTileByteCounts, 0, tileByteCounts.length); + System.arraycopy(tileOffsets, 0, newTileOffsets, 0, tileOffsets.length); + tileByteCounts = newTileByteCounts; + tileOffsets = newTileOffsets; + ifds[resolutionIndex][no].put(IFD.TILE_BYTE_COUNTS, tileByteCounts); + ifds[resolutionIndex][no].put(IFD.TILE_OFFSETS, tileOffsets); + } } if (compression == null || compression.equals(CompressionType.UNCOMPRESSED.getCompression())) { From 37348d9f287138714f7a1f60c63668caa6887be0 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 26 Jun 2024 12:28:27 -0500 Subject: [PATCH 055/100] SVS: update isThisType to reject files with a single IFD See https://github.com/IDR/idr-metadata/issues/699 --- components/formats-gpl/src/loci/formats/in/SVSReader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/SVSReader.java b/components/formats-gpl/src/loci/formats/in/SVSReader.java index d3231b5bfdf..d9820b62dd7 100644 --- a/components/formats-gpl/src/loci/formats/in/SVSReader.java +++ b/components/formats-gpl/src/loci/formats/in/SVSReader.java @@ -174,7 +174,9 @@ else if (description instanceof String) { } if (imageDescription != null && imageDescription.startsWith(APERIO_IMAGE_DESCRIPTION_PREFIX)) { - return true; + // reject anything with just one IFD, as that indicates there is + // no pyramid, thumbnail, label, or macro + return tiffParser.getIFDOffsets().length > 1; } } return false; From d8303880bd77f3b5623dca7f5b26402c03a00a56 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 18 Jun 2024 11:11:39 -0500 Subject: [PATCH 056/100] CV7000/8000: fix used files list when TIFFs are in a subdirectory --- .../src/loci/formats/in/CV7000Reader.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/CV7000Reader.java b/components/formats-gpl/src/loci/formats/in/CV7000Reader.java index 0d2a65c707a..7ba74411d73 100644 --- a/components/formats-gpl/src/loci/formats/in/CV7000Reader.java +++ b/components/formats-gpl/src/loci/formats/in/CV7000Reader.java @@ -81,7 +81,7 @@ public class CV7000Reader extends FormatReader { // -- Fields -- - private String[] allFiles; + private List allFiles = new ArrayList(); private MinimalTiffReader reader; private String wppPath; private String detailPath; @@ -223,6 +223,7 @@ public void close(boolean fileOnly) throws IOException { reversePlaneLookup = null; extraFiles = null; acquiredWells.clear(); + allFiles.clear(); } } @@ -269,15 +270,12 @@ protected void initFile(String id) throws FormatException, IOException { XMLTools.parseXML(wpiXML, plate); Location parent = new Location(id).getAbsoluteFile().getParentFile(); - allFiles = parent.list(true); - Arrays.sort(allFiles); - for (int i=0; i Date: Wed, 26 Jun 2024 17:47:13 -0500 Subject: [PATCH 057/100] bfconvert: convert DICOM data tile-wise any time `-precompressed` is used This makes sure that the tiles actually saved match the tile sizes supplied to the writer. --- .../src/loci/formats/tools/ImageConverter.java | 8 ++++++++ .../src/loci/formats/out/DicomWriter.java | 15 +-------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 8f1c3816929..29cb160d8fd 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -1228,6 +1228,14 @@ private boolean doTileConversion(IFormatWriter writer, String outputFile) if (writer instanceof DicomWriter || (writer instanceof ImageWriter && ((ImageWriter) writer).getWriter(outputFile) instanceof DicomWriter)) { + // if we asked to try a precompressed conversion, + // then the writer's tile sizes will have been set automatically + // according to the input data + // the conversion must then be performed tile-wise to match the tile sizes, + // even if precompression doesn't end up being possible + if (precompressed) { + return true; + } MetadataStore r = reader.getMetadataStore(); return !(r instanceof IPyramidStore) || ((IPyramidStore) r).getResolutionCount(reader.getSeries()) > 1; } diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index 275986a606a..96b4d6fcfee 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -235,14 +235,7 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) LOGGER.debug("savePrecompressedBytes(series={}, resolution={}, no={}, x={}, y={})", series, resolution, no, x, y); - // TODO: may want better handling of non-tiled "extra" images (e.g. label, macro) MetadataRetrieve r = getMetadataRetrieve(); - if ((!(r instanceof IPyramidStore) || - ((IPyramidStore) r).getResolutionCount(series) == 1) && - !isFullPlane(x, y, w, h)) - { - throw new FormatException("DicomWriter does not allow tiles for non-pyramid images"); - } int bytesPerPixel = FormatTools.getBytesPerPixel( FormatTools.pixelTypeFromString( @@ -397,13 +390,7 @@ public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) int thisTileHeight = tileHeight[resolutionIndex]; MetadataRetrieve r = getMetadataRetrieve(); - if ((!(r instanceof IPyramidStore) || - ((IPyramidStore) r).getResolutionCount(series) == 1) && - !isFullPlane(x, y, w, h)) - { - throw new FormatException("DicomWriter does not allow tiles for non-pyramid images"); - } - else if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || + if (x % thisTileWidth != 0 || y % thisTileHeight != 0 || (w != thisTileWidth && x + w != getSizeX()) || (h != thisTileHeight && y + h != getSizeY())) { From a569f5a9ddcd54a98f904e64d2344d17c94163a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20St=C3=B6ter?= Date: Thu, 27 Jun 2024 14:18:01 +0200 Subject: [PATCH 058/100] Use `-` instead of `--` to read files from stdin. Adhere to GNU utils convention of using `-` for reading from stdin. Also expand and adapt usage information. --- .../src/loci/formats/tools/ImageInfo.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index 16ab96d47f3..f8a90ae2141 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -314,7 +314,8 @@ public void printUsage() { "", " -version: print the library version and exit", " file: the image file to read", - " reads file names line-wise from stdin if -- is passed", + " if - is passed, process multiple files", + " with file names read line-wise from stdin", " -nopix: read metadata only, not pixels", " -nocore: do not output core metadata", " -nometa: do not parse format-specific metadata table", @@ -1132,7 +1133,7 @@ public static void main(String[] args) throws Exception { DebugTools.enableLogging("INFO"); List argsList = Arrays.asList(args); - int idx = argsList.indexOf("--"); + int idx = argsList.indexOf("-"); if (idx >= 0) { Scanner scanner = new Scanner(System.in); @@ -1140,6 +1141,7 @@ public static void main(String[] args) throws Exception { while (scanner.hasNext()) { newArgs[idx] = scanner.nextLine(); + System.out.println("====% " + newArgs[idx]); if (!new ImageInfo().testRead(newArgs)) System.exit(1); } scanner.close(); @@ -1150,3 +1152,4 @@ public static void main(String[] args) throws Exception { } } + From 27db3eaa01b02f4b0ad91dc40887ac9b475152b2 Mon Sep 17 00:00:00 2001 From: Nicolas Chiaruttini Date: Sat, 29 Jun 2024 16:28:40 +0200 Subject: [PATCH 059/100] Changes an exhaustive listing through all OIR PixelBlock with a map containing a CZT Key object --- .../src/loci/formats/in/OIRReader.java | 127 +++++++++--------- 1 file changed, 61 insertions(+), 66 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index a432b0d6c8c..08a053920ff 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -28,10 +28,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Objects; import javax.xml.parsers.ParserConfigurationException; import loci.common.DataTools; @@ -80,7 +82,7 @@ public class OIRReader extends FormatReader { private Timestamp acquisitionDate; private int defaultXMLSkip = 36; private int blocksPerPlane = 0; - private String[] pixelUIDs = null; + private final Map> cztToPixelBlocks = new HashMap<>(); private String baseName; private int lastChannel = -1; @@ -182,23 +184,9 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) int[] zct = getZCTCoords(no); lastChannel = zct[1]; - int first = 0; - int startIndex = -1; - int end = 0; - while (first < pixelUIDs.length) { - if (getZ(pixelUIDs[first]) - minZ == zct[0] && - getT(pixelUIDs[first]) - minT == zct[2] && - pixelUIDs[first].indexOf(channels.get(zct[1] % channels.size()).id) > 0) - { - if (startIndex < 0) { - startIndex = first; - } - end = first; - } - first++; - } + List blocks = cztToPixelBlocks.get(new CZTKey(zct[1], zct[0], zct[2])); - if (startIndex < 0) { + if ((blocks == null) || (blocks.isEmpty())) { LOGGER.warn("No pixel blocks for plane #{}", no); Arrays.fill(buf, getFillColor()); return buf; @@ -214,8 +202,7 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) RandomAccessInputStream s = null; String openFile = null; try { - for (int i=startIndex; i<=end; i++) { - PixelBlock block = pixelBlocks.get(pixelUIDs[i]); + for (PixelBlock block : blocks) { if (bufferPointer + block.length < bufferOffset || bufferPointer >= bufferEnd) @@ -274,7 +261,7 @@ public void close(boolean fileOnly) throws IOException { acquisitionDate = null; defaultXMLSkip = 36; blocksPerPlane = 0; - pixelUIDs = null; + cztToPixelBlocks.clear(); baseName = null; lastChannel = -1; minZ = Integer.MAX_VALUE; @@ -412,51 +399,15 @@ else if (!checkSuffix(id, "oir")) { } } - pixelUIDs = pixelBlocks.keySet().toArray(new String[pixelBlocks.size()]); - Arrays.sort(pixelUIDs, new Comparator() { - @Override - public int compare(String s1, String s2) { - int lastUnderscore1 = s1.lastIndexOf("_"); - int lastUnderscore2 = s2.lastIndexOf("_"); - - Integer block1 = Integer.parseInt(s1.substring(lastUnderscore1 + 1)); - Integer block2 = Integer.parseInt(s2.substring(lastUnderscore2 + 1)); - - int underscore1 = s1.lastIndexOf("_", lastUnderscore1 - 1); - int underscore2 = s2.lastIndexOf("_", lastUnderscore2 - 1); - - String prefix1 = s1.substring(0, underscore1); - String prefix2 = s2.substring(0, underscore2); - - String channel1 = s1.substring(underscore1 + 1, lastUnderscore1); - String channel2 = s2.substring(underscore2 + 1, lastUnderscore2); - - if (!prefix1.equals(prefix2)) { - return s1.compareTo(s2); - } - - if (!channel1.equals(channel2)) { - Integer index1 = -1; - Integer index2 = -2; - for (int i=0; i()); + PixelBlock pb = pixelBlocks.get(uid); + cztToPixelBlocks.get(key).add(b, pb); } // populate original metadata @@ -1514,6 +1465,16 @@ private int getT(String uid) { return Integer.parseInt(tSubString.substring(0, tSubString.indexOf("_"))) - 1; } + private int getC(String uid) { + String toParse = uid.substring(0,uid.lastIndexOf("_")); + String channelSignature = toParse.substring(toParse.lastIndexOf("_")+1); + for (int iCh = 0; iCh + * It's used to create a Map from CZTKey to PixelBlocks + */ + private static class CZTKey { + public final int c,z,t; + public final int hashCode; + public CZTKey(int c, int z, int t) { + this.c = c; + this.z = z; + this.t = t; + hashCode = Objects.hash(c,z,t); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CZTKey that = (CZTKey) o; + return (that.z == this.z)&&(that.c == this.c)&&(that.t == this.t); + } + @Override + public int hashCode() { + return hashCode; + } + + @Override + public String toString() { + return "C:"+c+"; Z:"+z+"; T:"+t; + } + } + } From e266c08908d4363312cd5e21ca7b0f1399c67a70 Mon Sep 17 00:00:00 2001 From: Nicolas Chiaruttini Date: Sat, 29 Jun 2024 21:34:12 +0200 Subject: [PATCH 060/100] Major performance improvement when reading a ROI within a plane in the OIRReader: - prevents reading fully all PixelBlocks when one needs to read a ROI within them - overrides getOptimalTile size methods to match the underlying PixelBlock size (or crops at 2048 pixels) --- .../src/loci/formats/in/OIRReader.java | 181 +++++++++++------- 1 file changed, 113 insertions(+), 68 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index 08a053920ff..5c03634ffc7 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -85,6 +85,7 @@ public class OIRReader extends FormatReader { private final Map> cztToPixelBlocks = new HashMap<>(); private String baseName; private int lastChannel = -1; + private int optimalTileHeight; private int minZ = Integer.MAX_VALUE; private int minT = Integer.MAX_VALUE; @@ -171,6 +172,15 @@ public short[][] get16BitLookupTable() throws FormatException, IOException { return (short[][]) channels.get(lastChannel).lut; } + @Override + public int getOptimalTileHeight() { + return Math.min(2048, optimalTileHeight); + } + + @Override + public int getOptimalTileWidth() { + return Math.min(2048, getSizeX()); + } /** * @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) @@ -184,6 +194,7 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) int[] zct = getZCTCoords(no); lastChannel = zct[1]; + // Gets all the PixelBlock potentially contained within c, z and t List blocks = cztToPixelBlocks.get(new CZTKey(zct[1], zct[0], zct[2])); if ((blocks == null) || (blocks.isEmpty())) { @@ -193,53 +204,44 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) } int bpp = FormatTools.getBytesPerPixel(getPixelType()); - int bufferOffset = bpp * ((y * getSizeX()) + x); - int rowLen = bpp * w; - int imageWidth = bpp * getSizeX(); - int bufferEnd = bpp * (((y + h) * getSizeX()) + x + w); - int bufferPointer = 0; - - RandomAccessInputStream s = null; - String openFile = null; - try { - for (PixelBlock block : blocks) { - - if (bufferPointer + block.length < bufferOffset || - bufferPointer >= bufferEnd) - { - bufferPointer += block.length; - continue; - } - - byte[] pixels = null; - if (s == null || !block.file.equals(openFile)) { - if (s != null) { - s.close(); - } - s = new RandomAccessInputStream(block.file, BUFFER_SIZE); - openFile = block.file; - } - pixels = readPixelBlock(s, block.offset); - if (pixels != null) { - int blockY = bufferPointer / imageWidth; - int blockH = pixels.length / imageWidth; - - for (int yy=blockY; yy= y + h) { - continue; - } - int blockOffset = (yy - blockY) * imageWidth + x * bpp; - int bufOffset = (yy - y) * rowLen; - System.arraycopy(pixels, blockOffset, buf, bufOffset, rowLen); - } - } - bufferPointer += block.length; - } - } - finally { - if (s != null) { - s.close(); - } + int nBytesPerLineInBuf = w * bpp; // number of bytes for one line within the exported buffer + int nBytesPerLineInBlock = getSizeX() * bpp; // number of bytes for one line within a PixelBlock + + // Iterators: y position + int yOffsetInBuffer = 0; // current y offset within the exported buffer + + for (PixelBlock block : blocks) { // This list is sorted along y + // Skips blocks positioned fully outside [y, y+h[ + if (block.yEndy+h) break; // The pixel block is completely below the requested region - skip all remaining blocks + + // At this point of the code we know for sure that this PixelBlock overlaps with the requested region, + // We need to copy lines from this PixelBlock to the buffer, cropping properly the PixelBlock + // and taking into account the x and y offset + + // Skips the first lines of the block if necessary - the result will be non-zero only for the first PixelBlock + // that lies within the buffer region + skips the bytes according to the x offset + int blockOffset = + ((y+yOffsetInBuffer)-block.yStart)*nBytesPerLineInBlock // y Offset + + (x * bpp); // x offset + + // Number of lines to be copied within the PixelBlock + // The stop condition happens either: + // - if we reach the end of the bytes to be read within the requested region + // - or if we reach the end of the current PixelBlock + int nLines = Math.min(h-yOffsetInBuffer, block.yEnd-(y+yOffsetInBuffer)); + + // Perform the copy + copyPixelBlock(block, buf, + yOffsetInBuffer * nBytesPerLineInBuf, // Current position within the exported buffer + blockOffset, // Current position within the PixelBlock, taking into account the x offset + nBytesPerLineInBuf, // number of bytes within a line of the exported buffer + nBytesPerLineInBlock, // number of bytes within a line of a PixelBlock + nLines + ); + + // Updates new position within the exported buffer + yOffsetInBuffer+=nLines; // nLines filled } return buf; @@ -410,6 +412,33 @@ else if (!checkSuffix(id, "oir")) { cztToPixelBlocks.get(key).add(b, pb); } + int bpp = FormatTools.getBytesPerPixel(getPixelType()); + int bytesPerLine = m.sizeX*bpp; + optimalTileHeight = 32; + + // Let's compute the coordinates of the pixel blocks in y + // We also make the optimal tile height match the max size of a block in Y + for (List blocks : cztToPixelBlocks.values()) { + int yStart = 0; + for (PixelBlock block: blocks) { + block.yStart = yStart; + if ((block.length % bytesPerLine)!=0) { + LOGGER.error("A pixel block contains a partial line."); + } + int nLines = block.length/bytesPerLine; + if (nLines > optimalTileHeight) { + optimalTileHeight = nLines; + } + yStart+=block.length/bytesPerLine; + block.yEnd = yStart; // start of the next block = end (excluded) of the previous block + } + } + + // Make sure that an optimal tile does not go beyond 2 Gbytes -> that probably shouldn't happen + if ((long)optimalTileHeight*(long)m.sizeX*(long)bpp > Integer.MAX_VALUE) { + optimalTileHeight = Integer.MAX_VALUE / (bpp * m.sizeX) - 1; + } + // populate original metadata Hashtable tmpMeta = new Hashtable(); @@ -1417,34 +1446,48 @@ else if (pixelBytes <= 0) { return true; } - private byte[] readPixelBlock(RandomAccessInputStream s, long offset) throws IOException { - s.order(true); - s.seek(offset); + private void copyPixelBlock(PixelBlock block, + byte[] buf, int offsetBuf, int offsetBlock, + int nBytesPerLinesBuf, int nBytesPerLineBlock, int nLines) throws IOException { - int checkLength = s.readInt(); - int check = s.readInt(); - if (check != 3) { + try (RandomAccessInputStream s = new RandomAccessInputStream(block.file, BUFFER_SIZE)) { + + long offset = block.offset; + s.order(true); s.seek(offset); - return null; - } - s.skipBytes(8); // currently unknown + int checkLength = s.readInt(); + int check = s.readInt(); + if (check != 3) { + s.seek(offset); + return; + } - int uidLength = s.readInt(); - String uid = s.readString(uidLength); - LOGGER.debug("reading pixel block with uid = {}", uid); - if (checkLength != uidLength + 12) { - s.seek(offset); - return null; - } + s.skipBytes(8); // currently unknown - int pixelBytes = s.readInt(); + int uidLength = s.readInt(); + String uid = s.readString(uidLength); + LOGGER.debug("reading pixel block with uid = {}", uid); + if (checkLength != uidLength + 12) { + s.seek(offset); + return; + } - s.skipBytes(4); // currently unknown + int pixelBytes = s.readInt(); + s.skipBytes(4); // currently unknown + s.skipBytes(offsetBlock); - byte[] pixels = new byte[pixelBytes]; - s.readFully(pixels); - return pixels; + if (nBytesPerLineBlock==nBytesPerLinesBuf) { + // Full line copy, no skip needed + s.read(buf, offsetBuf, nBytesPerLineBlock*nLines); + } else { + for (int i = 0; i < nLines; i++) { + s.read(buf, offsetBuf, nBytesPerLinesBuf); + s.skipBytes(nBytesPerLineBlock-nBytesPerLinesBuf); + offsetBuf += nBytesPerLinesBuf; + } + } + } } private int getZ(String uid) { @@ -1531,6 +1574,8 @@ class PixelBlock { public String file; public long offset; public int length; + public int yStart; + public int yEnd; } /** From 7f52992a24a4a698c686de0ec30e72f95e0269c5 Mon Sep 17 00:00:00 2001 From: Nicolas Chiaruttini Date: Sun, 30 Jun 2024 19:12:47 +0200 Subject: [PATCH 061/100] OIRReader: changes List to PixelBlock[] in order to fill the array in a random order --- .../src/loci/formats/in/OIRReader.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index 5c03634ffc7..352bd649f64 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -82,7 +82,7 @@ public class OIRReader extends FormatReader { private Timestamp acquisitionDate; private int defaultXMLSkip = 36; private int blocksPerPlane = 0; - private final Map> cztToPixelBlocks = new HashMap<>(); + private final Map cztToPixelBlocks = new HashMap<>(); private String baseName; private int lastChannel = -1; private int optimalTileHeight; @@ -195,9 +195,9 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) lastChannel = zct[1]; // Gets all the PixelBlock potentially contained within c, z and t - List blocks = cztToPixelBlocks.get(new CZTKey(zct[1], zct[0], zct[2])); + PixelBlock[] blocks = cztToPixelBlocks.get(new CZTKey(zct[1], zct[0], zct[2])); - if ((blocks == null) || (blocks.isEmpty())) { + if ((blocks == null) || (blocks.length == 0)) { LOGGER.warn("No pixel blocks for plane #{}", no); Arrays.fill(buf, getFillColor()); return buf; @@ -401,15 +401,23 @@ else if (!checkSuffix(id, "oir")) { } } + int maxNumberOfBlocks = -1; + + // Get max number of blocks + for (String uid: pixelBlocks.keySet()) { + int b = getBlock(uid); + if (b>maxNumberOfBlocks) maxNumberOfBlocks = b+1; + } + for (String uid: pixelBlocks.keySet()) { int z = getZ(uid)-minZ; int t = getT(uid)-minT; int c = getC(uid); int b = getBlock(uid); CZTKey key = new CZTKey(c,z,t); - if (!cztToPixelBlocks.containsKey(key)) cztToPixelBlocks.put(key, new ArrayList<>()); + if (!cztToPixelBlocks.containsKey(key)) cztToPixelBlocks.put(key, new PixelBlock[maxNumberOfBlocks]); PixelBlock pb = pixelBlocks.get(uid); - cztToPixelBlocks.get(key).add(b, pb); + cztToPixelBlocks.get(key)[b] = pb; } int bpp = FormatTools.getBytesPerPixel(getPixelType()); @@ -418,7 +426,7 @@ else if (!checkSuffix(id, "oir")) { // Let's compute the coordinates of the pixel blocks in y // We also make the optimal tile height match the max size of a block in Y - for (List blocks : cztToPixelBlocks.values()) { + for (PixelBlock[] blocks : cztToPixelBlocks.values()) { int yStart = 0; for (PixelBlock block: blocks) { block.yStart = yStart; From 6f370eb81b9eb6c997ef90d449ea71fee22ada57 Mon Sep 17 00:00:00 2001 From: Jean-Marie Burel Date: Fri, 5 Jul 2024 13:06:46 +0100 Subject: [PATCH 062/100] test push to artifactory2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 657633e77da..342eae2a5e7 100644 --- a/pom.xml +++ b/pom.xml @@ -476,7 +476,7 @@ ome.snapshots OME Snapshots Repository - https://artifacts.openmicroscopy.org/artifactory/ome.snapshots + https://artifacts2.openmicroscopy.org/artifactory/ome.snapshots ome.releases From bbf72af23480c4ba7e3cc4387b6bf6d71f37c077 Mon Sep 17 00:00:00 2001 From: Jean-Marie Burel Date: Fri, 5 Jul 2024 13:31:20 +0100 Subject: [PATCH 063/100] roll back to artifactory --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 342eae2a5e7..657633e77da 100644 --- a/pom.xml +++ b/pom.xml @@ -476,7 +476,7 @@ ome.snapshots OME Snapshots Repository - https://artifacts2.openmicroscopy.org/artifactory/ome.snapshots + https://artifacts.openmicroscopy.org/artifactory/ome.snapshots ome.releases From d3181fa86d03e6c6a90b7d36820581713c02a878 Mon Sep 17 00:00:00 2001 From: Jean-Marie Burel Date: Fri, 5 Jul 2024 20:32:30 +0100 Subject: [PATCH 064/100] test artifactory2 after reset --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 657633e77da..342eae2a5e7 100644 --- a/pom.xml +++ b/pom.xml @@ -476,7 +476,7 @@ ome.snapshots OME Snapshots Repository - https://artifacts.openmicroscopy.org/artifactory/ome.snapshots + https://artifacts2.openmicroscopy.org/artifactory/ome.snapshots ome.releases From 718b2955c883f9419678c99a148c7de81f43c0e2 Mon Sep 17 00:00:00 2001 From: Jean-Marie Burel Date: Fri, 5 Jul 2024 20:56:13 +0100 Subject: [PATCH 065/100] revert to artifacts --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 342eae2a5e7..657633e77da 100644 --- a/pom.xml +++ b/pom.xml @@ -476,7 +476,7 @@ ome.snapshots OME Snapshots Repository - https://artifacts2.openmicroscopy.org/artifactory/ome.snapshots + https://artifacts.openmicroscopy.org/artifactory/ome.snapshots ome.releases From c72a71b5f9f7e66f8c78b82390665ff7c7633995 Mon Sep 17 00:00:00 2001 From: Nicolas Chiaruttini Date: Sun, 7 Jul 2024 14:55:42 +0200 Subject: [PATCH 066/100] Update OIRReader.java Fix wrong max number of blocks counts --- components/formats-gpl/src/loci/formats/in/OIRReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index 352bd649f64..8a7cdceb4b9 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -406,7 +406,7 @@ else if (!checkSuffix(id, "oir")) { // Get max number of blocks for (String uid: pixelBlocks.keySet()) { int b = getBlock(uid); - if (b>maxNumberOfBlocks) maxNumberOfBlocks = b+1; + if (b>=maxNumberOfBlocks) maxNumberOfBlocks = b+1; } for (String uid: pixelBlocks.keySet()) { From a5d90ad9f84d1c3d9cc989fca66fe8abd9c81d8e Mon Sep 17 00:00:00 2001 From: David Gault Date: Tue, 9 Jul 2024 11:14:55 +0100 Subject: [PATCH 067/100] ImarisHDF: Handle null color rather than removing it --- .../formats-gpl/src/loci/formats/in/ImarisHDFReader.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java b/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java index 39a0b3e6189..172ec0cb69b 100644 --- a/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java +++ b/components/formats-gpl/src/loci/formats/in/ImarisHDFReader.java @@ -130,7 +130,7 @@ public short[][] get16BitLookupTable() { FormatTools.assertId(currentId, true, 1); if (getPixelType() != FormatTools.UINT16 || !isIndexed()) return null; - if (lastChannel < 0 || lastChannel >= colors.size()) { + if (lastChannel < 0 || lastChannel >= colors.size() || colors.get(lastChannel) == null) { return null; } @@ -408,8 +408,7 @@ protected void initFile(String id) throws FormatException, IOException { catch (NumberFormatException e) { } } - colors.remove(null); - if (i < colors.size()) { + if (i < colors.size() && colors.get(i) != null) { double[] color = colors.get(i); Color realColor = new Color( (int) (color[0] * 255), (int) (color[1] * 255), From 42a91ab499f9a6379dc612c1268971dda53301df Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 11 Jul 2024 10:45:12 +0100 Subject: [PATCH 068/100] Bump version to 7.3.1 --- components/bio-formats-plugins/pom.xml | 2 +- components/bio-formats-tools/pom.xml | 2 +- components/bundles/bioformats_package/pom.xml | 2 +- components/forks/turbojpeg/pom.xml | 2 +- components/formats-api/pom.xml | 2 +- components/formats-bsd/pom.xml | 2 +- components/formats-gpl/pom.xml | 2 +- components/test-suite/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-plugins/pom.xml b/components/bio-formats-plugins/pom.xml index db8e47910ca..bac6c78c3ea 100644 --- a/components/bio-formats-plugins/pom.xml +++ b/components/bio-formats-plugins/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../.. diff --git a/components/bio-formats-tools/pom.xml b/components/bio-formats-tools/pom.xml index 7bf17d46f04..7d7047d812b 100644 --- a/components/bio-formats-tools/pom.xml +++ b/components/bio-formats-tools/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../.. diff --git a/components/bundles/bioformats_package/pom.xml b/components/bundles/bioformats_package/pom.xml index 74c06caa741..0916170caec 100644 --- a/components/bundles/bioformats_package/pom.xml +++ b/components/bundles/bioformats_package/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../../../ diff --git a/components/forks/turbojpeg/pom.xml b/components/forks/turbojpeg/pom.xml index c7806a96dfd..1602ad79046 100644 --- a/components/forks/turbojpeg/pom.xml +++ b/components/forks/turbojpeg/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../../../ diff --git a/components/formats-api/pom.xml b/components/formats-api/pom.xml index 760c677c14b..8e3790fdedb 100644 --- a/components/formats-api/pom.xml +++ b/components/formats-api/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../.. diff --git a/components/formats-bsd/pom.xml b/components/formats-bsd/pom.xml index 44bc0a8ad27..4f87b0412de 100644 --- a/components/formats-bsd/pom.xml +++ b/components/formats-bsd/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../.. diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index baa8401d9cb..8ab98610e78 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../.. diff --git a/components/test-suite/pom.xml b/components/test-suite/pom.xml index 2ad76017821..8fed511da6f 100644 --- a/components/test-suite/pom.xml +++ b/components/test-suite/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 ../.. diff --git a/pom.xml b/pom.xml index 657633e77da..3a3f84142ec 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 7.3.1 pom Bio-Formats projects @@ -34,7 +34,7 @@ When possible, we advise using the relevant groupId and version properties for your dependencies rather than hardcoding them. --> - 8.0.0-SNAPSHOT + 7.3.1 ${maven.build.timestamp} 2017 ${basedir} From 6e9f5c013415438574abef0f4763821339eeb154 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 11 Jul 2024 11:12:01 +0100 Subject: [PATCH 069/100] Bump version to 8.0.0-SNAPSHOT --- components/bio-formats-plugins/pom.xml | 2 +- components/bio-formats-tools/pom.xml | 2 +- components/bundles/bioformats_package/pom.xml | 2 +- components/forks/turbojpeg/pom.xml | 2 +- components/formats-api/pom.xml | 2 +- components/formats-bsd/pom.xml | 2 +- components/formats-gpl/pom.xml | 2 +- components/test-suite/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-plugins/pom.xml b/components/bio-formats-plugins/pom.xml index bac6c78c3ea..db8e47910ca 100644 --- a/components/bio-formats-plugins/pom.xml +++ b/components/bio-formats-plugins/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../.. diff --git a/components/bio-formats-tools/pom.xml b/components/bio-formats-tools/pom.xml index 7d7047d812b..7bf17d46f04 100644 --- a/components/bio-formats-tools/pom.xml +++ b/components/bio-formats-tools/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../.. diff --git a/components/bundles/bioformats_package/pom.xml b/components/bundles/bioformats_package/pom.xml index 0916170caec..74c06caa741 100644 --- a/components/bundles/bioformats_package/pom.xml +++ b/components/bundles/bioformats_package/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../../../ diff --git a/components/forks/turbojpeg/pom.xml b/components/forks/turbojpeg/pom.xml index 1602ad79046..c7806a96dfd 100644 --- a/components/forks/turbojpeg/pom.xml +++ b/components/forks/turbojpeg/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../../../ diff --git a/components/formats-api/pom.xml b/components/formats-api/pom.xml index 8e3790fdedb..760c677c14b 100644 --- a/components/formats-api/pom.xml +++ b/components/formats-api/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../.. diff --git a/components/formats-bsd/pom.xml b/components/formats-bsd/pom.xml index 4f87b0412de..44bc0a8ad27 100644 --- a/components/formats-bsd/pom.xml +++ b/components/formats-bsd/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../.. diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index 8ab98610e78..baa8401d9cb 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../.. diff --git a/components/test-suite/pom.xml b/components/test-suite/pom.xml index 8fed511da6f..2ad76017821 100644 --- a/components/test-suite/pom.xml +++ b/components/test-suite/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT ../.. diff --git a/pom.xml b/pom.xml index 3a3f84142ec..657633e77da 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ome pom-bio-formats - 7.3.1 + 8.0.0-SNAPSHOT pom Bio-Formats projects @@ -34,7 +34,7 @@ When possible, we advise using the relevant groupId and version properties for your dependencies rather than hardcoding them. --> - 7.3.1 + 8.0.0-SNAPSHOT ${maven.build.timestamp} 2017 ${basedir} From 7fbe98d67bc08a7527c8086403aaf81909dd09f2 Mon Sep 17 00:00:00 2001 From: David Gault Date: Mon, 15 Jul 2024 16:43:33 +0100 Subject: [PATCH 070/100] OIRReader: Add null check for block --- .../src/loci/formats/in/OIRReader.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index 8a7cdceb4b9..cda2e7f3cce 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -429,16 +429,18 @@ else if (!checkSuffix(id, "oir")) { for (PixelBlock[] blocks : cztToPixelBlocks.values()) { int yStart = 0; for (PixelBlock block: blocks) { - block.yStart = yStart; - if ((block.length % bytesPerLine)!=0) { - LOGGER.error("A pixel block contains a partial line."); - } - int nLines = block.length/bytesPerLine; - if (nLines > optimalTileHeight) { - optimalTileHeight = nLines; + if (block != null) { + block.yStart = yStart; + if ((block.length % bytesPerLine)!=0) { + LOGGER.error("A pixel block contains a partial line."); + } + int nLines = block.length/bytesPerLine; + if (nLines > optimalTileHeight) { + optimalTileHeight = nLines; + } + yStart+=block.length/bytesPerLine; + block.yEnd = yStart; // start of the next block = end (excluded) of the previous block } - yStart+=block.length/bytesPerLine; - block.yEnd = yStart; // start of the next block = end (excluded) of the previous block } } From 0bd9fa9d49c765e7e0eef66dac775ac0bf817ac2 Mon Sep 17 00:00:00 2001 From: David Gault Date: Tue, 16 Jul 2024 13:58:34 +0100 Subject: [PATCH 071/100] OIRReader: Update zct block indexing for modulo C --- components/formats-gpl/src/loci/formats/in/OIRReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index cda2e7f3cce..cb5b0883427 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -195,7 +195,7 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) lastChannel = zct[1]; // Gets all the PixelBlock potentially contained within c, z and t - PixelBlock[] blocks = cztToPixelBlocks.get(new CZTKey(zct[1], zct[0], zct[2])); + PixelBlock[] blocks = cztToPixelBlocks.get(new CZTKey((zct[1] % channels.size()), zct[0], zct[2])); if ((blocks == null) || (blocks.length == 0)) { LOGGER.warn("No pixel blocks for plane #{}", no); From d7ccc565991461aaa72c9de997b1ca36b7de0621 Mon Sep 17 00:00:00 2001 From: Nicolas Chiaruttini Date: Fri, 19 Jul 2024 17:40:18 +0200 Subject: [PATCH 072/100] OIRReader: fix reading of oir spectral (lambda) images --- .../formats-gpl/src/loci/formats/in/OIRReader.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index cb5b0883427..7fae5bc34f2 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -195,7 +195,7 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) lastChannel = zct[1]; // Gets all the PixelBlock potentially contained within c, z and t - PixelBlock[] blocks = cztToPixelBlocks.get(new CZTKey((zct[1] % channels.size()), zct[0], zct[2])); + PixelBlock[] blocks = cztToPixelBlocks.get(new CZTKey(zct[1], zct[0], zct[2])); if ((blocks == null) || (blocks.length == 0)) { LOGGER.warn("No pixel blocks for plane #{}", no); @@ -412,8 +412,9 @@ else if (!checkSuffix(id, "oir")) { for (String uid: pixelBlocks.keySet()) { int z = getZ(uid)-minZ; int t = getT(uid)-minT; - int c = getC(uid); + int c = getC(uid) + getL(uid); // Channel index or lambda index (We suppose there's no multichannel + lambda); int b = getBlock(uid); + CZTKey key = new CZTKey(c,z,t); if (!cztToPixelBlocks.containsKey(key)) cztToPixelBlocks.put(key, new PixelBlock[maxNumberOfBlocks]); PixelBlock pb = pixelBlocks.get(uid); @@ -1536,6 +1537,14 @@ private int getBlock(String uid) { return Integer.parseInt(uid.substring(index + 1)); } + private int getL(String uid) { + // for example l001z001t001_0_1_93e4632f-0342-4d98-bdc1-4ce305b92525_46 + // Assumes l is always first is the uid... + if (!uid.startsWith("l")) return 0; + // ... and has 3 digits + return Integer.parseInt(uid.substring(1, 4)) - 1; + } + private boolean isCurrentFile(String file) { String currentPath = new Location(currentId).getAbsolutePath(); return currentPath.equals(new Location(file).getAbsolutePath()); From cad5a4fc4fc117a3752941e068b446ec9b67b643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Besson?= Date: Mon, 22 Jul 2024 08:40:42 +0100 Subject: [PATCH 073/100] ZeissLSMReader: replace assignment operator by logical and operator --- components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java b/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java index cf7e82bdce1..b33d2a042b4 100644 --- a/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java +++ b/components/formats-gpl/src/loci/formats/in/ZeissLSMReader.java @@ -1134,7 +1134,7 @@ else if (zCoordinates.size() == i) { // if this is not the first channel, copy the color from the // previous channel (necessary for SIM data) // otherwise set the color to white, as this will display better - if (red == 0 && green == 0 & blue == 0) { + if (red == 0 && green == 0 && blue == 0) { if (i > 0 && isSIM) { red = channelColor[i - 1].getRed(); green = channelColor[i - 1].getGreen(); From 198c4a6e45ee5e958571344c7dd55a742faa56ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Besson?= Date: Mon, 22 Jul 2024 08:43:15 +0100 Subject: [PATCH 074/100] OMEXMLReader: replace assignment operator by logical or operator --- components/formats-bsd/src/loci/formats/in/OMEXMLReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/in/OMEXMLReader.java b/components/formats-bsd/src/loci/formats/in/OMEXMLReader.java index 6ce56250894..617ccdca02b 100644 --- a/components/formats-bsd/src/loci/formats/in/OMEXMLReader.java +++ b/components/formats-bsd/src/loci/formats/in/OMEXMLReader.java @@ -290,7 +290,7 @@ protected void initFile(String id) throws FormatException, IOException { Integer t = omexmlMeta.getPixelsSizeT(i).getValue(); Integer z = omexmlMeta.getPixelsSizeZ(i).getValue(); Integer c = omexmlMeta.getPixelsSizeC(i).getValue(); - if (w == null || h == null || t == null || z == null | c == null) { + if (w == null || h == null || t == null || z == null || c == null) { throw new FormatException("Image dimensions not found"); } From e818377881dfbadc46ee7f7fd3cd066f8c230ddc Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 23 Jul 2024 16:35:32 -0500 Subject: [PATCH 075/100] Exporter: fix typo when setting Channel.SamplesPerPixel This caused a problem when exporting DICOM with multiple channels from ImageJ, as the DICOM writer strictly requires non-null SamplesPerPixel on every Channel. --- .../bio-formats-plugins/src/loci/plugins/out/Exporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java b/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java index 2a953b3fea7..7395b38fcfd 100644 --- a/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java +++ b/components/bio-formats-plugins/src/loci/plugins/out/Exporter.java @@ -505,7 +505,7 @@ else if (FormatTools.isSigned(originalType)) { String lsid = MetadataTools.createLSID("Channel", 0, c); store.setChannelID(lsid, 0, c); } - store.setChannelSamplesPerPixel(new PositiveInteger(channels), 0, 0); + store.setChannelSamplesPerPixel(new PositiveInteger(channels), 0, c); if (imp instanceof CompositeImage) { luts[c] = ((CompositeImage) imp).getChannelLut(c + 1); From cd22cb9739059edb89d16a0cb12abeb061fadef8 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 23 Jul 2024 16:36:39 -0500 Subject: [PATCH 076/100] DICOM writer: don't throw NPE if close was already called Shouldn't affect bfconvert, but does affect ImageJ export which calls close() twice. --- components/formats-bsd/src/loci/formats/out/DicomWriter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index 23c6921f81a..4b26e2e8dc7 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -1383,6 +1383,11 @@ public void close() throws IOException { for (int res=0; res Date: Tue, 6 Aug 2024 16:48:15 -0500 Subject: [PATCH 077/100] Fix float casting when autoscaling int values to byte Fixes #4210. --- components/formats-bsd/src/loci/formats/gui/AWTImageTools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/gui/AWTImageTools.java b/components/formats-bsd/src/loci/formats/gui/AWTImageTools.java index 791fd4a2b02..4de6cafd205 100644 --- a/components/formats-bsd/src/loci/formats/gui/AWTImageTools.java +++ b/components/formats-bsd/src/loci/formats/gui/AWTImageTools.java @@ -1655,7 +1655,7 @@ else if (pixels instanceof int[][]) { else if (ints[i][j] <= min) out[i][j] = 0; else { int diff = max - min; - float dist = (ints[i][j] - min) / diff; + float dist = (float) (ints[i][j] - min) / diff; out[i][j] = (byte) (dist * 256); } } From d341f4c9ea4fe5fff1c3fd6013f7e21d74cca8c1 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 8 Aug 2024 13:28:04 -0500 Subject: [PATCH 078/100] Fix strip padding when working with planar strips --- .../src/loci/formats/tiff/TiffSaver.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java b/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java index f803895bca2..06c01da240b 100644 --- a/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java +++ b/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java @@ -350,15 +350,22 @@ public void writeImage(byte[] buf, IFD ifd, int no, int pixelType, int x, stripOut[strip].write(buf, strip * stripSize, stripSize); } } else { - for (int strip = 0; strip < nStrips - 1; strip++) { - stripOut[strip].write(buf, strip * stripSize, stripSize); - } - // Sigh. Need to pad the last strip. - int pos = (nStrips - 1) * stripSize; - int len = buf.length - pos; - stripOut[nStrips - 1].write(buf, pos, len); - for (int n = len; n < stripSize; n++) { - stripOut[nStrips - 1].writeByte(0); + int effectiveStrips = !interleaved ? nStrips / nChannels : nStrips; + int planarChannels = !interleaved ? nChannels : 1; + int totalBytesPerChannel = buf.length / planarChannels; + for (int p=0; p Date: Thu, 8 Aug 2024 13:58:44 -0500 Subject: [PATCH 079/100] One more fix to tile-wise conversion check Always perform tile-wise conversion if precompressed conversion was requested, independent of the format and presence of image pyramid. --- .../src/loci/formats/tools/ImageConverter.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 746b6080a70..934691e072a 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -1268,16 +1268,13 @@ private boolean isTiledWriter(IFormatWriter writer, String outputFile) private boolean doTileConversion(IFormatWriter writer, String outputFile) throws FormatException { - MetadataStore r = reader.getMetadataStore(); - if ((r instanceof IPyramidStore) && ((IPyramidStore) r).getResolutionCount(reader.getSeries()) > 1) { - // if we asked to try a precompressed conversion, - // then the writer's tile sizes will have been set automatically - // according to the input data - // the conversion must then be performed tile-wise to match the tile sizes, - // even if precompression doesn't end up being possible - if (precompressed) { - return true; - } + // if we asked to try a precompressed conversion, + // then the writer's tile sizes will have been set automatically + // according to the input data + // the conversion must then be performed tile-wise to match the tile sizes, + // even if precompression doesn't end up being possible + if (precompressed) { + return true; } return DataTools.safeMultiply64(width, height) >= DataTools.safeMultiply64(4096, 4096) || saveTileWidth > 0 || saveTileHeight > 0; From 117078ead882510f88996eb4376249dd0daeaf8a Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Fri, 9 Aug 2024 15:55:44 -0500 Subject: [PATCH 080/100] Override writer's interleaved setting if precompressed JPEG tiles are supplied --- .../src/loci/formats/tools/ImageConverter.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 934691e072a..0ff352a2b7b 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -767,7 +767,9 @@ else if (writer instanceof ImageWriter) { int writerSeries = series == -1 ? q : 0; writer.setSeries(writerSeries); writer.setResolution(res); + writer.setInterleaved(reader.isInterleaved() && !autoscale); + writer.setValidBitsPerPixel(reader.getBitsPerPixel()); int numImages = writer.canDoStacks() ? reader.getImageCount() : 1; @@ -840,6 +842,12 @@ else if (saveTileWidth > 0 && saveTileHeight > 0) { } } + if (precompressed && FormatTools.canUsePrecompressedTiles(reader, writer, writer.getSeries(), writer.getResolution())) { + if (getReaderCodecName().startsWith("JPEG")) { + writer.setInterleaved(true); + } + } + int outputIndex = 0; if (nextOutputIndex.containsKey(outputName)) { outputIndex = nextOutputIndex.get(outputName); From f6a0c75fd88e54efa3ba98c601194ff589ee34ab Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Fri, 9 Aug 2024 15:56:14 -0500 Subject: [PATCH 081/100] Turn down log level for saveCompressedBytes logging --- components/formats-bsd/src/loci/formats/out/TiffWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/out/TiffWriter.java b/components/formats-bsd/src/loci/formats/out/TiffWriter.java index bd2bf785c0f..8bc78476238 100644 --- a/components/formats-bsd/src/loci/formats/out/TiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/TiffWriter.java @@ -176,7 +176,7 @@ public void saveCompressedBytes(int no, byte[] buf, int x, int y, int w, int h) "Sequential tile writing must be enabled to write precompressed tiles"); } - LOGGER.warn("saveCompressedBytes(series={}, resolution={}, no={}, x={}, y={})", + LOGGER.debug("saveCompressedBytes(series={}, resolution={}, no={}, x={}, y={})", series, resolution, no, x, y); IFD ifd = makeIFD(); From 29e8c05f22b9b647efa6899d95969edf204c9762 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 13 Aug 2024 10:49:11 -0500 Subject: [PATCH 082/100] One more check for performing tile-wise conversion --- .../src/loci/formats/tools/ImageConverter.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java index 0ff352a2b7b..77d0c2b316c 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageConverter.java @@ -1284,6 +1284,14 @@ private boolean doTileConversion(IFormatWriter writer, String outputFile) if (precompressed) { return true; } + // tile size has already been set in the writer, + // so tile-wise conversion should be performed + // independent of image size + if ((writer.getTileSizeX() > 0 && writer.getTileSizeX() < width) || + (writer.getTileSizeY() > 0 && writer.getTileSizeY() < height)) + { + return true; + } return DataTools.safeMultiply64(width, height) >= DataTools.safeMultiply64(4096, 4096) || saveTileWidth > 0 || saveTileHeight > 0; } From 5ae98f6020ac1d537023070a085d9f6cfb00e9b0 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 14 Aug 2024 14:21:24 -0500 Subject: [PATCH 083/100] LIF: fix offset calculation for certain datasets with multiple unstitched tiles --- .../src/loci/formats/in/LIFReader.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/LIFReader.java b/components/formats-gpl/src/loci/formats/in/LIFReader.java index 9ea3f61c73c..c3a65c40ec5 100644 --- a/components/formats-gpl/src/loci/formats/in/LIFReader.java +++ b/components/formats-gpl/src/loci/formats/in/LIFReader.java @@ -573,23 +573,48 @@ protected void initFile(String id) throws FormatException, IOException { // correct offsets, if necessary if (offsets.size() > getSeriesCount()) { + LOGGER.debug("Adjusting image offsets; found {} expected {}", + offsets.size(), getSeriesCount()); Long[] storedOffsets = offsets.toArray(new Long[offsets.size()]); + for (int i=0; i Date: Mon, 14 Nov 2022 19:38:54 -0600 Subject: [PATCH 084/100] Add data for objective ID 18112 --- .../formats-gpl/src/loci/formats/in/RCPNLReader.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/formats-gpl/src/loci/formats/in/RCPNLReader.java b/components/formats-gpl/src/loci/formats/in/RCPNLReader.java index 0859748725e..2554847e5aa 100644 --- a/components/formats-gpl/src/loci/formats/in/RCPNLReader.java +++ b/components/formats-gpl/src/loci/formats/in/RCPNLReader.java @@ -99,6 +99,16 @@ protected void populateObjective(MetadataStore store, int lensID) MetadataTools.getCorrection("PlanApo"), 0, 0); store.setObjectiveManufacturer("Nikon", 0, 0); break; + case 18112: + store.setObjectiveNominalMagnification(20.0, 0, 0); + store.setObjectiveLensNA(0.8, 0, 0); + store.setObjectiveWorkingDistance( + new Length(0.8, UNITS.MILLIMETER), 0, 0); + store.setObjectiveImmersion(MetadataTools.getImmersion("Air"), 0, 0); + store.setObjectiveCorrection( + MetadataTools.getCorrection("PlanApo"), 0, 0); + store.setObjectiveManufacturer("Nikon", 0, 0); + break; } } From 99462118cc80f1f8e9c6407f4f8825c82b301c24 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 29 Aug 2024 17:19:45 -0500 Subject: [PATCH 085/100] Reduce number of calls to getSamplesPerPixel() Especially when repacking tiles, many duplicate calls to this method can get expensive. --- .../src/loci/formats/out/DicomWriter.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index de3850248ea..d578d10e06c 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -500,6 +500,7 @@ public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) int bytesPerPixel = FormatTools.getBytesPerPixel( FormatTools.pixelTypeFromString( r.getPixelsType(series).toString())); + int samplesPerPixel = getSamplesPerPixel(); out.seek(out.length()); long start = out.getFilePointer(); @@ -512,9 +513,9 @@ public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) if ((x + w == getSizeX() && w < thisTileWidth) || (y + h == getSizeY() && h < thisTileHeight)) { - if (interleaved || getSamplesPerPixel() == 1) { - int srcRowLen = w * bytesPerPixel * getSamplesPerPixel(); - int destRowLen = thisTileWidth * bytesPerPixel * getSamplesPerPixel(); + if (interleaved || samplesPerPixel == 1) { + int srcRowLen = w * bytesPerPixel * samplesPerPixel; + int destRowLen = thisTileWidth * bytesPerPixel * samplesPerPixel; paddedBuf = new byte[thisTileHeight * destRowLen]; for (int row=0; row Date: Mon, 9 Sep 2024 10:11:15 +0200 Subject: [PATCH 086/100] OIRReader - improve safety: * set optimalTileHeight to 0 in close * check reader initialisation in optimal tile size method calls * checks and warns in case of null PixelBlocks --- components/formats-gpl/src/loci/formats/in/OIRReader.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/components/formats-gpl/src/loci/formats/in/OIRReader.java b/components/formats-gpl/src/loci/formats/in/OIRReader.java index 7fae5bc34f2..447ae76aa70 100644 --- a/components/formats-gpl/src/loci/formats/in/OIRReader.java +++ b/components/formats-gpl/src/loci/formats/in/OIRReader.java @@ -174,11 +174,13 @@ public short[][] get16BitLookupTable() throws FormatException, IOException { @Override public int getOptimalTileHeight() { + FormatTools.assertId(currentId, true, 1); return Math.min(2048, optimalTileHeight); } @Override public int getOptimalTileWidth() { + FormatTools.assertId(currentId, true, 1); return Math.min(2048, getSizeX()); } @@ -211,6 +213,10 @@ public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) int yOffsetInBuffer = 0; // current y offset within the exported buffer for (PixelBlock block : blocks) { // This list is sorted along y + if (block == null) { + LOGGER.warn("Block not found."); + continue; + } // Skips blocks positioned fully outside [y, y+h[ if (block.yEndy+h) break; // The pixel block is completely below the requested region - skip all remaining blocks @@ -264,6 +270,7 @@ public void close(boolean fileOnly) throws IOException { defaultXMLSkip = 36; blocksPerPlane = 0; cztToPixelBlocks.clear(); + optimalTileHeight = 0; baseName = null; lastChannel = -1; minZ = Integer.MAX_VALUE; From dd500c8bc45acd52ecaeaf21bee182a755f1fdc5 Mon Sep 17 00:00:00 2001 From: Torsten Stoeter Date: Mon, 9 Sep 2024 12:01:47 +0200 Subject: [PATCH 087/100] Handle UnknownFormatException for batch processing multiple files. When sequentially processing many files the unhandled exception terminates the program and no further files will be processed that may still be readable. This commit catches the exception, provides a warning message and continues processing. --- .../src/loci/formats/tools/ImageInfo.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index f8a90ae2141..a42c13b1d29 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -77,6 +77,7 @@ import loci.formats.meta.MetadataStore; import loci.formats.services.OMEXMLService; import loci.formats.services.OMEXMLServiceImpl; +import loci.formats.UnknownFormatException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1141,8 +1142,14 @@ public static void main(String[] args) throws Exception { while (scanner.hasNext()) { newArgs[idx] = scanner.nextLine(); - System.out.println("====% " + newArgs[idx]); - if (!new ImageInfo().testRead(newArgs)) System.exit(1); + System.out.println("====% " + newArgs[idx]); + try { + new ImageInfo().testRead(newArgs); + } + catch (UnknownFormatException e) { + LOGGER.warn("Unknown file format: " + newArgs[idx]); + continue; + } } scanner.close(); } From 9e3c38b986e6e56e0f0c16beeea759e44972c74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Besson?= Date: Mon, 9 Sep 2024 08:51:59 +0100 Subject: [PATCH 088/100] CV7000: handle NullPointerException when resetting allFiles in close() While the reader should initialize this field as an empty ArrayList, there are scenarios where allFiles will be null when calling close(). A use case would be a reader initialized from a memo file created with a previous release of Bio-Formats since this field was formerly a string array set to null by default. --- .../formats-gpl/src/loci/formats/in/CV7000Reader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/formats-gpl/src/loci/formats/in/CV7000Reader.java b/components/formats-gpl/src/loci/formats/in/CV7000Reader.java index 7ba74411d73..66b745a1c9e 100644 --- a/components/formats-gpl/src/loci/formats/in/CV7000Reader.java +++ b/components/formats-gpl/src/loci/formats/in/CV7000Reader.java @@ -223,7 +223,11 @@ public void close(boolean fileOnly) throws IOException { reversePlaneLookup = null; extraFiles = null; acquiredWells.clear(); - allFiles.clear(); + if (allFiles != null) { + allFiles.clear(); + } else { + allFiles = new ArrayList(); + } } } From 88b846d5101d023a7c30a82d3ad1789f92da9c69 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Tue, 10 Sep 2024 18:29:21 -0500 Subject: [PATCH 089/100] Don't recalculate IFD offsets in close() See #4204. --- .../formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java b/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java index d287493b8ac..aa98a1037fd 100644 --- a/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java @@ -155,7 +155,7 @@ public void close() throws IOException { long nextPointer = index < allOffsets.length ? allOffsets[index] : 0; saver.overwriteIFDOffset(in, allOffsets[mainIFDIndex], nextPointer); - saver.overwriteIFDValue(in, currentFullResolution, IFD.SUB_IFD, subIFDOffsets); + saver.overwriteIFDValue(in, allOffsets[mainIFDIndex], IFD.SUB_IFD, subIFDOffsets, true); } mainIFDIndex++; From f104b762a0922c939810de8eddfba2e28df271fa Mon Sep 17 00:00:00 2001 From: Torsten Stoeter Date: Wed, 11 Sep 2024 12:55:58 +0200 Subject: [PATCH 090/100] Handle also other possible exceptions when batch processing multiple files. If an exception occurs batch processing should continue, but now an exit code is returned when the program terminates, indicating there was an error. The logger level for messages was elevated to error was well. --- .../src/loci/formats/tools/ImageInfo.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index a42c13b1d29..ecacf22ee82 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -77,7 +77,6 @@ import loci.formats.meta.MetadataStore; import loci.formats.services.OMEXMLService; import loci.formats.services.OMEXMLServiceImpl; -import loci.formats.UnknownFormatException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1133,6 +1132,7 @@ private void printDimension(String dim, int size, int effectiveSize, public static void main(String[] args) throws Exception { DebugTools.enableLogging("INFO"); + int exitCode = 0; List argsList = Arrays.asList(args); int idx = argsList.indexOf("-"); @@ -1144,11 +1144,22 @@ public static void main(String[] args) throws Exception { newArgs[idx] = scanner.nextLine(); System.out.println("====% " + newArgs[idx]); try { - new ImageInfo().testRead(newArgs); + new ImageInfo().testRead(newArgs); } - catch (UnknownFormatException e) { - LOGGER.warn("Unknown file format: " + newArgs[idx]); - continue; + catch (FormatException e) { + LOGGER.error("Caught FormatException. " + e.getMessage()); + exitCode = 1; + continue; + } + catch (IOException e) { + LOGGER.error("Caught IOException. " + e.getMessage()); + exitCode = 1; + continue; + } + catch (ServiceException e) { + LOGGER.error("Caught ServiceException. " + e.getMessage()); + exitCode = 1; + continue; } } scanner.close(); @@ -1156,7 +1167,8 @@ public static void main(String[] args) throws Exception { else { if (!new ImageInfo().testRead(args)) System.exit(1); } - } + System.exit(exitCode); + } } From ab8234f870221f6e56ddec8688a16de4d00f85e0 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 11 Sep 2024 11:59:00 -0500 Subject: [PATCH 091/100] Don't try to convert lengths with pixel/referenceframe units to physical units --- .../src/loci/formats/out/DicomWriter.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index 4b26e2e8dc7..05d27e26de6 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -988,7 +988,7 @@ public void setId(String id) throws FormatException, IOException { opticalSequence.children.add(illuminationTypeCodes); DicomTag wavelength = new DicomTag(ILLUMINATION_WAVELENGTH, FL); - Length wave = r.getChannelEmissionWavelength(pyramid, c); + Length wave = fixUnits(r.getChannelEmissionWavelength(pyramid, c)); wavelength.value = new float[] {wave == null ? 1f : wave.value(UNITS.NM).floatValue()}; opticalSequence.children.add(wavelength); @@ -1019,7 +1019,7 @@ public void setId(String id) throws FormatException, IOException { DicomTag sliceThickness = new DicomTag(SLICE_THICKNESS, DS); DicomTag sliceSpace = new DicomTag(SLICE_SPACING, DS); - Length physicalZ = r.getPixelsPhysicalSizeZ(pyramid); + Length physicalZ = fixUnits(r.getPixelsPhysicalSizeZ(pyramid)); if (physicalZ != null) { sliceThickness.value = padString(String.valueOf(physicalZ.value(UNITS.MM))); } @@ -1032,8 +1032,8 @@ public void setId(String id) throws FormatException, IOException { pixelMeasuresSequence.children.add(sliceSpace); DicomTag pixelSpacing = new DicomTag(PIXEL_SPACING, DS); - Length physicalX = r.getPixelsPhysicalSizeX(pyramid); - Length physicalY = r.getPixelsPhysicalSizeY(pyramid); + Length physicalX = fixUnits(r.getPixelsPhysicalSizeX(pyramid)); + Length physicalY = fixUnits(r.getPixelsPhysicalSizeY(pyramid)); String px = physicalX == null ? "1" : String.valueOf(physicalX.value(UNITS.MM)); String py = physicalY == null ? "1" : String.valueOf(physicalY.value(UNITS.MM)); pixelSpacing.value = padString(px + "\\" + py); @@ -2076,6 +2076,18 @@ private short[] makeShortArray(int v) { return s; } + /** + * Check if the unit for the given Length is "pixel" + * or "referenceframe". These two units cannot be assigned to + * proper physical units (e.g. mm), so need to be handled specially. + */ + private Length fixUnits(Length size) { + if (size == null || size.unit() == UNITS.PIXEL || size.unit() == UNITS.REFERENCEFRAME) { + return null; + } + return size; + } + private TiffRational getPhysicalSize(Length size) { if (size == null || size.value(UNITS.MICROMETER) == null) { return new TiffRational(0, 1000); From 2c3f72ad0016ec04a25ef134ace8c0c0335af47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20St=C3=B6ter?= Date: Wed, 11 Sep 2024 21:39:32 +0200 Subject: [PATCH 092/100] Fix indentation. --- .../src/loci/formats/tools/ImageInfo.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index ecacf22ee82..bab4de127fa 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -1144,31 +1144,31 @@ public static void main(String[] args) throws Exception { newArgs[idx] = scanner.nextLine(); System.out.println("====% " + newArgs[idx]); try { - new ImageInfo().testRead(newArgs); + new ImageInfo().testRead(newArgs); } catch (FormatException e) { - LOGGER.error("Caught FormatException. " + e.getMessage()); - exitCode = 1; - continue; + LOGGER.error("Caught FormatException. " + e.getMessage()); + exitCode = 1; + continue; } catch (IOException e) { - LOGGER.error("Caught IOException. " + e.getMessage()); - exitCode = 1; - continue; + LOGGER.error("Caught IOException. " + e.getMessage()); + exitCode = 1; + continue; } catch (ServiceException e) { - LOGGER.error("Caught ServiceException. " + e.getMessage()); - exitCode = 1; - continue; + LOGGER.error("Caught ServiceException. " + e.getMessage()); + exitCode = 1; + continue; } } scanner.close(); } else { if (!new ImageInfo().testRead(args)) System.exit(1); - } + } - System.exit(exitCode); + System.exit(exitCode); } } From c7e916197cafd5820993320198be315a50c1abfb Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 12 Sep 2024 20:45:47 -0500 Subject: [PATCH 093/100] Warn if relative units are encountered for a physical length --- .../formats-bsd/src/loci/formats/out/DicomWriter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/components/formats-bsd/src/loci/formats/out/DicomWriter.java b/components/formats-bsd/src/loci/formats/out/DicomWriter.java index 05d27e26de6..808f81ea87b 100644 --- a/components/formats-bsd/src/loci/formats/out/DicomWriter.java +++ b/components/formats-bsd/src/loci/formats/out/DicomWriter.java @@ -2082,7 +2082,12 @@ private short[] makeShortArray(int v) { * proper physical units (e.g. mm), so need to be handled specially. */ private Length fixUnits(Length size) { - if (size == null || size.unit() == UNITS.PIXEL || size.unit() == UNITS.REFERENCEFRAME) { + if (size == null) { + return null; + } + if (size.unit() == UNITS.PIXEL || size.unit() == UNITS.REFERENCEFRAME) { + LOGGER.warn("Found physical length '{}' in relative units '{}'; this value will be lost", + size.value(), size.unit()); return null; } return size; From e39e422069448331fc2896949b7fa08ebc697333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20St=C3=B6ter?= Date: Tue, 17 Sep 2024 22:01:01 +0200 Subject: [PATCH 094/100] Unify exception handling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalize to catch all exceptions and condense exception handling code and error messages. Co-authored-by: Melissa Linkert Co-authored-by: Sébastien Besson --- .../src/loci/formats/tools/ImageInfo.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java index bab4de127fa..9a2e93f564b 100644 --- a/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java +++ b/components/bio-formats-tools/src/loci/formats/tools/ImageInfo.java @@ -1146,18 +1146,8 @@ public static void main(String[] args) throws Exception { try { new ImageInfo().testRead(newArgs); } - catch (FormatException e) { - LOGGER.error("Caught FormatException. " + e.getMessage()); - exitCode = 1; - continue; - } - catch (IOException e) { - LOGGER.error("Caught IOException. " + e.getMessage()); - exitCode = 1; - continue; - } - catch (ServiceException e) { - LOGGER.error("Caught ServiceException. " + e.getMessage()); + catch (Exception e) { + LOGGER.error("Caught " + e.getClass().getSimpleName(), e); exitCode = 1; continue; } From 0b42e1be22cae8c26e85ab09d8a67a352417cd32 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Sun, 22 Sep 2024 12:17:51 -0500 Subject: [PATCH 095/100] TiffSaver: reduce seeks and buffer strip writing See #3983. --- .../formats-bsd/src/loci/formats/tiff/TiffSaver.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java b/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java index 06c01da240b..c61851a05b0 100644 --- a/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java +++ b/components/formats-bsd/src/loci/formats/tiff/TiffSaver.java @@ -1176,15 +1176,13 @@ else if (isTiled) { // return to original position out.seek(stripStartPos); + ByteArrayOutputStream stripBuffer = new ByteArrayOutputStream(); long stripOffset = 0; for (int i=0; i Date: Fri, 4 Oct 2024 15:20:40 -0500 Subject: [PATCH 096/100] Remove unused variable --- .../formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java b/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java index aa98a1037fd..911d72a3161 100644 --- a/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java +++ b/components/formats-bsd/src/loci/formats/out/PyramidOMETiffWriter.java @@ -131,7 +131,6 @@ public void close() throws IOException { } int mainIFDIndex = 0; - int currentFullResolution = 0; for (int i=0; i Date: Mon, 7 Oct 2024 08:51:08 -0500 Subject: [PATCH 097/100] Upgrade cdm-core (netcdf Java) to 5.6.0 --- components/formats-gpl/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index baa8401d9cb..89468428974 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -66,7 +66,7 @@ edu.ucar cdm-core - 5.3.3 + 5.6.0 com.amazonaws From fcc5d13366f4cbd4c4772ad963e1c7d33ad8339e Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 10 Oct 2024 10:13:24 -0500 Subject: [PATCH 098/100] Upgrade ome-common to 6.0.24 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 657633e77da..209e42a43ea 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 2.0.9 5.4.0 6.8 - 6.0.22 + 6.0.24 org.openmicroscopy 6.3.6 5.3.9 From b28636177d456992bf1b7199a7ce61d8af7c020b Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 24 Oct 2024 07:38:12 -0500 Subject: [PATCH 099/100] Bump release version to 8.0.0 --- components/bio-formats-plugins/pom.xml | 2 +- components/bio-formats-tools/pom.xml | 2 +- components/bundles/bioformats_package/pom.xml | 2 +- components/forks/turbojpeg/pom.xml | 2 +- components/formats-api/pom.xml | 2 +- components/formats-bsd/pom.xml | 2 +- components/formats-gpl/pom.xml | 2 +- components/test-suite/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-plugins/pom.xml b/components/bio-formats-plugins/pom.xml index db8e47910ca..d6d0aa7c257 100644 --- a/components/bio-formats-plugins/pom.xml +++ b/components/bio-formats-plugins/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../.. diff --git a/components/bio-formats-tools/pom.xml b/components/bio-formats-tools/pom.xml index 7bf17d46f04..aa9f93e70c3 100644 --- a/components/bio-formats-tools/pom.xml +++ b/components/bio-formats-tools/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../.. diff --git a/components/bundles/bioformats_package/pom.xml b/components/bundles/bioformats_package/pom.xml index 74c06caa741..aa053c53648 100644 --- a/components/bundles/bioformats_package/pom.xml +++ b/components/bundles/bioformats_package/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../../../ diff --git a/components/forks/turbojpeg/pom.xml b/components/forks/turbojpeg/pom.xml index c7806a96dfd..117357e528b 100644 --- a/components/forks/turbojpeg/pom.xml +++ b/components/forks/turbojpeg/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../../../ diff --git a/components/formats-api/pom.xml b/components/formats-api/pom.xml index 760c677c14b..af0d529b5b3 100644 --- a/components/formats-api/pom.xml +++ b/components/formats-api/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../.. diff --git a/components/formats-bsd/pom.xml b/components/formats-bsd/pom.xml index 44bc0a8ad27..17cb5306761 100644 --- a/components/formats-bsd/pom.xml +++ b/components/formats-bsd/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../.. diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index 89468428974..2a5718e91ed 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../.. diff --git a/components/test-suite/pom.xml b/components/test-suite/pom.xml index 2ad76017821..1d981da8896 100644 --- a/components/test-suite/pom.xml +++ b/components/test-suite/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 ../.. diff --git a/pom.xml b/pom.xml index 209e42a43ea..8d43735e3b5 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ome pom-bio-formats - 8.0.0-SNAPSHOT + 8.0.0 pom Bio-Formats projects @@ -34,7 +34,7 @@ When possible, we advise using the relevant groupId and version properties for your dependencies rather than hardcoding them. --> - 8.0.0-SNAPSHOT + 8.0.0 ${maven.build.timestamp} 2017 ${basedir} From df36e69198b0d83cb68f2f83e23dd943d86656fd Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 24 Oct 2024 07:40:23 -0500 Subject: [PATCH 100/100] Bump version to 8.1.0-SNAPSHOT --- components/bio-formats-plugins/pom.xml | 2 +- components/bio-formats-tools/pom.xml | 2 +- components/bundles/bioformats_package/pom.xml | 2 +- components/forks/turbojpeg/pom.xml | 2 +- components/formats-api/pom.xml | 2 +- components/formats-bsd/pom.xml | 2 +- components/formats-gpl/pom.xml | 2 +- components/test-suite/pom.xml | 2 +- pom.xml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bio-formats-plugins/pom.xml b/components/bio-formats-plugins/pom.xml index d6d0aa7c257..0f273084a31 100644 --- a/components/bio-formats-plugins/pom.xml +++ b/components/bio-formats-plugins/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../.. diff --git a/components/bio-formats-tools/pom.xml b/components/bio-formats-tools/pom.xml index aa9f93e70c3..6f69965f018 100644 --- a/components/bio-formats-tools/pom.xml +++ b/components/bio-formats-tools/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../.. diff --git a/components/bundles/bioformats_package/pom.xml b/components/bundles/bioformats_package/pom.xml index aa053c53648..9f9e6a56b55 100644 --- a/components/bundles/bioformats_package/pom.xml +++ b/components/bundles/bioformats_package/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../../../ diff --git a/components/forks/turbojpeg/pom.xml b/components/forks/turbojpeg/pom.xml index 117357e528b..d3c86cc6bb7 100644 --- a/components/forks/turbojpeg/pom.xml +++ b/components/forks/turbojpeg/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../../../ diff --git a/components/formats-api/pom.xml b/components/formats-api/pom.xml index af0d529b5b3..ac13b855ca9 100644 --- a/components/formats-api/pom.xml +++ b/components/formats-api/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../.. diff --git a/components/formats-bsd/pom.xml b/components/formats-bsd/pom.xml index 17cb5306761..d95773cf07e 100644 --- a/components/formats-bsd/pom.xml +++ b/components/formats-bsd/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../.. diff --git a/components/formats-gpl/pom.xml b/components/formats-gpl/pom.xml index 2a5718e91ed..70f7336c8ac 100644 --- a/components/formats-gpl/pom.xml +++ b/components/formats-gpl/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../.. diff --git a/components/test-suite/pom.xml b/components/test-suite/pom.xml index 1d981da8896..74c5dcd3dec 100644 --- a/components/test-suite/pom.xml +++ b/components/test-suite/pom.xml @@ -8,7 +8,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT ../.. diff --git a/pom.xml b/pom.xml index 8d43735e3b5..e28b604844a 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ome pom-bio-formats - 8.0.0 + 8.1.0-SNAPSHOT pom Bio-Formats projects @@ -34,7 +34,7 @@ When possible, we advise using the relevant groupId and version properties for your dependencies rather than hardcoding them. --> - 8.0.0 + 8.1.0-SNAPSHOT ${maven.build.timestamp} 2017 ${basedir}