From bf2005f5cb506e53de987ef8dc3b895e879ee932 Mon Sep 17 00:00:00 2001 From: "matthiasch@googlemail.com" Date: Thu, 21 Apr 2011 10:36:30 +0000 Subject: [PATCH] Import of source and license files git-svn-id: http://imagej-hdf.googlecode.com/svn/trunk@2 1917c786-bb84-a533-1332-c8e2925cefa8 --- LICENSE | 202 +++ NOTICE | 14 + src/HDF5_Batch_.java | 73 + src/HDF5_Config.java | 236 +++ src/HDF5_GroupedVarnames.java | 363 +++++ src/HDF5_Reader_.java | 2750 +++++++++++++++++++++++++++++++++ src/HDF5_Writer_.java | 877 +++++++++++ src/TimeFrame.java | 104 ++ 8 files changed, 4619 insertions(+) create mode 100644 LICENSE create mode 100644 NOTICE create mode 100644 src/HDF5_Batch_.java create mode 100644 src/HDF5_Config.java create mode 100644 src/HDF5_GroupedVarnames.java create mode 100644 src/HDF5_Reader_.java create mode 100644 src/HDF5_Writer_.java create mode 100644 src/TimeFrame.java diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..09d60de --- /dev/null +++ b/NOTICE @@ -0,0 +1,14 @@ + ========================================================================= + == NOTICE file corresponding to the section 4 d of == + == the Apache License, Version 2.0, == + == in this case for the ImageJ HDF Plugin distribution. == + ========================================================================= + + ImageJ HDF Plugin + Copyright 2011 Matthias Schlachter + + This product includes software developed by Matthias Schlachter. + + The initial release of this software was developed by Matthias Schlachter + at the Chair of Pattern Recognition and Image Processing, University of + Freiburg, Germany. diff --git a/src/HDF5_Batch_.java b/src/HDF5_Batch_.java new file mode 100644 index 0000000..95d3279 --- /dev/null +++ b/src/HDF5_Batch_.java @@ -0,0 +1,73 @@ +/* ========================================================================= + * + * Copyright 2011 Matthias Schlachter + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + + +import ij.*; +import ij.io.*; +import ij.plugin.*; +import ij.plugin.filter.PlugInFilter; +import ij.process.*; +import ij.gui.*; +import java.awt.*; +import java.lang.Math; + +import java.io.IOException; +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.tree.DefaultMutableTreeNode; + +import ncsa.hdf.object.*; // the common object package +import ncsa.hdf.object.h5.*; // the HDF5 implementation +import ncsa.hdf.hdf5lib.exceptions.HDF5Exception; +import ncsa.hdf.hdflib.HDFException; + +public class HDF5_Batch_ +{ + public static void run(String arg) + { + parseArgs(arg); + System.out.println("filename"); + System.out.println(_filename); + System.out.println("varnames"); + for(int i=0; i<_varnames.length; i++) + System.out.println(_varnames[i]); + HDF5_Writer_ w = new HDF5_Writer_(); + w.setToBatchMode(_filename,_varnames); + w.run(null); + } + + + private static void parseArgs(String arg) + { + String[] result = arg.split("]\\s"); + _filename = result[0].replaceAll("file=\\[",""); + String[] splitVars = result[1].split("\\s"); + _varnames = new String[splitVars.length]; + for (int x=0; x -1) + return frameList.get(i); + else + return null; + } + + private void splitGroupedVarnames() + { + Iterator vars = matchedVarNames.iterator(); + while(vars.hasNext()) + { + String varName = vars.next(); + String[] tokens = null; + if(formatTokens.length == 2) + { + tokens = varName.split(formatTokens[1]); + } + else if(formatTokens.length == 3) + { + tokens = varName.split(formatTokens[2]); + varName = tokens[0]; + tokens = varName.split(formatTokens[1]); + } + + if(tokens.length < 2 || tokens.length > 3) + { + System.out.println("Error parsing varname!"); + } + else + { + Integer channelIndex = new Integer(tokens[1]); + System.out.println("channelIndex: " + channelIndex.toString()); + System.out.println("left token: " + tokens[0]); + tokens = tokens[0].split("/t"); + Integer frameIndex = new Integer(tokens[1]); + System.out.println("frameIndex: " + frameIndex.toString()); + + if(minFrameIndex == -1) + minFrameIndex = frameIndex.intValue(); + minFrameIndex = Math.min(minFrameIndex,frameIndex.intValue()); + + if(maxFrameIndex == -1) + maxFrameIndex = frameIndex.intValue(); + maxFrameIndex = Math.max(maxFrameIndex,frameIndex.intValue()); + + if(minChannelIndex == -1) + minChannelIndex = channelIndex.intValue(); + minChannelIndex = Math.min(minChannelIndex,channelIndex.intValue()); + + if(maxChannelIndex == -1) + maxChannelIndex = channelIndex.intValue(); + maxChannelIndex = Math.max(maxChannelIndex,channelIndex.intValue()); + + TimeFrame frame = new TimeFrame(frameIndex.intValue()); + int idx = frameList.indexOf(frame); + if(idx != -1) + { + frame = (TimeFrame) frameList.get(idx); + frame.addChannel(channelIndex.intValue()); + } + else + { + frame.addChannel(channelIndex.intValue()); + frameList.add(frame); + } + //System.out.println(frame.toString()); + } + } + } + + public int getMinFrameIndex() + { + return minFrameIndex; + } + public int getMaxFrameIndex() + { + return maxFrameIndex; + } + public int getMinChannelIndex() + { + return minChannelIndex; + } + public int getMaxChannelIndex() + { + return maxChannelIndex; + } + public int getNFrames() + { + return frameList.size(); + } + public int getNChannels() + { + // TODO: check all frames for min/max of channels not index + if(nChannels == -1) + return maxChannelIndex-minChannelIndex+1; + else + return nChannels; + } + public boolean hasAllFramesInRange() + { + return frameList.size() == (maxFrameIndex-minFrameIndex+1); + } + public String toString() + { + String s = "Data set statistics\n"; + s = s + "----------------------------------\n"; + s = s + "nFrames: " + Integer.toString(frameList.size()) + "\n"; + s = s + "minFrameIndex: " + Integer.toString(minFrameIndex) + "\n"; + s = s + "maxFrameIndex: " + Integer.toString(maxFrameIndex) + "\n"; + s = s + + "hasAllFramesInRange: " + + Boolean.toString(hasAllFramesInRange()) + "\n"; + s = s + "minChannelIndex: " + Integer.toString(minChannelIndex) + "\n"; + s = s + "maxChannelIndex: " + Integer.toString(maxChannelIndex) + "\n"; + + // String[] toks = getFormatTokens(); + Iterator frames = frameList.iterator(); + while(frames.hasNext()) + { + TimeFrame f = frames.next(); + s = s + f.toString() + "\n"; + // s = s + "(" + toks[0] + + // Integer.toString(f.getFrameIndex()) + // + toks[1] + "$C"; + // if(toks.length>2) + // s = s + toks[2] + "\n"; + // else + // s = s + "\n"; + } + s = s + "----------------------------------"; + return s; + } + + public List getUnmatchedVarNames() + { + return unMatchedVarNames; + } + + public String[] getFormatTokens() + { + return formatTokens; + } + + public String getFormatString() + { + return formatString; + } + + public void setFrameAndChannelRange(int minFrame, + int skipFrame, + int maxFrame, + int minChannel, + int skipChannel, + int maxChannel) + { + System.out.println("Setting frame range: " + + Integer.toString(minFrame) + ":" + + Integer.toString(skipFrame) + ":" + + Integer.toString(maxFrame)); + System.out.println("Setting channel range: " + + Integer.toString(minChannel) + ":" + + Integer.toString(skipChannel) + ":" + + Integer.toString(maxChannel)); + if(hasAllFramesInRange()) + { + // copy frames + List completeFrameList = new ArrayList(frameList); + // clear frames + frameList.clear(); + // insert wanted frames and channels + for(int f=minFrame;f completeFrameList = new ArrayList(frameList); + // clear frames + frameList.clear(); + // insert wanted frames and channels + for(int f=minFrame;f matchedVarNames = new ArrayList(); + private final List unMatchedVarNames = new ArrayList(); + private final List frameList = new ArrayList(); + private String[] formatTokens = null; + private String formatString = null; + private int minFrameIndex = -1; + private int maxFrameIndex = -1; + private int minChannelIndex = -1; + private int maxChannelIndex = -1; + private int nChannels = -1; +} diff --git a/src/HDF5_Reader_.java b/src/HDF5_Reader_.java new file mode 100644 index 0000000..4572b8b --- /dev/null +++ b/src/HDF5_Reader_.java @@ -0,0 +1,2750 @@ +/* ========================================================================= + * + * Copyright 2011 Matthias Schlachter + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + + +import ij.IJ; +import ij.Prefs; +import ij.ImagePlus; +import ij.CompositeImage; +import ij.ImageStack; +import ij.gui.GenericDialog; +import ij.io.OpenDialog; +import ij.plugin.PlugIn; +import ij.process.ColorProcessor; +import ij.process.ImageProcessor; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +// for scrollbar +import java.awt.*; +import java.awt.image.*; +import java.io.*; + +import ncsa.hdf.object.*; // the common object package +import ncsa.hdf.object.h5.*; // the HDF5 implementation +import ncsa.hdf.hdf5lib.exceptions.HDF5Exception; +import ncsa.hdf.hdflib.HDFException; + +public class HDF5_Reader_ implements PlugIn +{ + public void run(String arg) + { + // make sure default values for config are written + // HDF5_Config.setDefaultsIfNoValueExists(); + + // run plugin + String directory = ""; + String name = ""; + boolean tryAgain; + String openMSG = "Open HDF5..."; + do + { + tryAgain = false; + OpenDialog od; + if (directory.equals("")) + od = new OpenDialog(openMSG, arg); + else + od = new OpenDialog(openMSG, directory, arg); + + directory = od.getDirectory(); + name = od.getFileName(); + if (name == null) + return; + if (name == "") + return; + + File testFile = new File(directory + name); + if (!testFile.exists() || !testFile.canRead()) + return; + + if (testFile.isDirectory()) + { + directory = directory + name; + tryAgain = true; + } + } while (tryAgain); + + IJ.showStatus("Loading HDF5 File: " + directory + name); + + H5File inFile = null; + + + // define grouping class + HDF5_GroupedVarnames groupedVarnames = new HDF5_GroupedVarnames(); + boolean loadGroupedVarNames = true; + + try + { + inFile = new H5File(directory + name, H5File.READ); + inFile.open(); + + /*------------------------------------------------------------------- + * read HDF5_Config prefs + *-------------------------------------------------------------------*/ + boolean groupVarsByName = + Boolean.getBoolean(HDF5_Config. + getDefaultValue("HDF5.groupVarsByName")); + groupVarsByName = Prefs.get("HDF5.groupVarsByName", groupVarsByName); + + boolean showUnmatchedDataSetNames = + Boolean.getBoolean(HDF5_Config. + getDefaultValue("HDF5.showUnmatchedDataSetNames")); + showUnmatchedDataSetNames = Prefs.get("HDF5.showUnmatchedDataSetNames", + showUnmatchedDataSetNames); + + String groupVarsByNameFormatGroup = + HDF5_Config.getDefaultValue("HDF5.groupVarsByNameFormatGroup"); + groupVarsByNameFormatGroup + = Prefs.get("HDF5.groupVarsByNameFormatGroup", + groupVarsByNameFormatGroup); + + // TODO: try to read attribute containing format String + String groupVarsByNameFormat = null; + try + { + HObject gr = inFile.get(groupVarsByNameFormatGroup); + String attrName = ""; // this will throw an error + + if(gr != null) + { + // get the attr list and make a selection dialog if necessary + List hintsAttrList = getAttrList(gr); + if(hintsAttrList.size() == 1) + attrName = hintsAttrList.get(0).getName(); + else if(hintsAttrList.size() > 1) + { + String[] hintsAttrNames = new String[hintsAttrList.size()]; + for(int a=0;a varList = getDataSetList(rootNode, + new ArrayList()); + + GenericDialog gd = new GenericDialog("Variable Name Selection"); + gd.addMessage("Please select variables to be loaded.\n"); + + if (varList.size() < 1) + { + IJ.error("The file did not contain variables. (broken?)"); + inFile.close(); + return; + } + // else if (varList.size() < 2) + // { + // gd.addCheckbox("single variable", true); + // } + else if(groupVarsByName) + { + // parse file structure + String[] varNames = new String[varList.size()]; + for (int i = 0; i < varList.size(); i++) + { + varNames[i] = varList.get(i).getFullName(); + } + groupedVarnames.parseVarNames(varNames, + groupVarsByNameFormat, + dollarRegexpForGrouping); + System.out.println(groupedVarnames.toString()); + + // make the data set selection dialog + minFrameIndex = groupedVarnames.getMinFrameIndex(); + maxFrameIndex = groupedVarnames.getMaxFrameIndex(); + minChannelIndex = groupedVarnames.getMinChannelIndex(); + maxChannelIndex = groupedVarnames.getMaxChannelIndex(); + + + gd = new GenericDialog("Variable Name Selection"); + // check if we have matched var names + if(groupedVarnames.getNFrames()>0) + { + gd.addCheckbox("Load grouped data sets", + loadGroupedVarNames); + + gd.addMessage("Select frames and channels you want to read"); + gd.addMessage("Frame selection (start/step/end): "); + + gd.addStringField("Frame selection (start:[step:]end): ", + Integer.toString(minFrameIndex) + ":" + + Integer.toString(skipFrameIndex) + ":" + + Integer.toString(maxFrameIndex)); + + gd.addStringField("Channel selection (start:[step:]end): ", + Integer.toString(minChannelIndex) + ":" + + Integer.toString(skipChannelIndex) + ":" + + Integer.toString(maxChannelIndex)); + } + + // get unmatched names + List unmatchedVarNames + = groupedVarnames.getUnmatchedVarNames(); + if(showUnmatchedDataSetNames) + { + // add all unmatched data set names to the dialog + String[] varSelections = new String[unmatchedVarNames.size()]; + boolean[] defaultValues = new boolean[unmatchedVarNames.size()]; + for (int i = 0; i < unmatchedVarNames.size(); i++) + { + Dataset var = (Dataset) inFile.get(unmatchedVarNames.get(i)); + int rank = var.getRank(); + String title = rank + "D: " + var.getFullName() + " " + + var.getDatatype().getDatatypeDescription() + "( "; + long[] extent = var.getDims(); + for (int d = 0; d < rank; ++d) + { + if (d != 0) + title += "x"; + title += extent[d]; + } + title += ")"; + varSelections[i] = title; + defaultValues[i] = false; + } + System.out.println("addcheckboxgroup with " + + unmatchedVarNames.size() + " rows"); + gd.addCheckboxGroup(unmatchedVarNames.size(), 1, + varSelections, defaultValues); + addScrollBars(gd); + } + gd.showDialog(); + if (gd.wasCanceled()) + { + return; + } + + // load grouped var names ? + if(groupedVarnames.getNFrames()>0) + loadGroupedVarNames = gd.getNextBoolean(); + + // read range selections if we have matched varnames + String frameRange = null; + String channelRange = null; + if(groupedVarnames.getNFrames()>0) + { + frameRange = gd.getNextString(); + channelRange = gd.getNextString(); + } + // parse the range selection + String[] frameRangeToks = null; + String[] channelRangeToks = null; + boolean wrongFrameRange = true; + boolean wrongChannelRange = true; + // check if the parsed values are in range + if(groupedVarnames.getNFrames()>0 && loadGroupedVarNames) + while(wrongFrameRange || wrongChannelRange) + { + // check frame range + frameRangeToks = frameRange.split(":"); + if(frameRangeToks.length == 1) + { + // single frame + try + { + System.out.println("single frame"); + minFrameIndex = Integer.parseInt(frameRangeToks[0]); + maxFrameIndex = minFrameIndex; + wrongFrameRange = false; + } + catch(Exception e) + { + wrongFrameRange = true; + } + } + else if(frameRangeToks.length == 2) + { + // frame range with skipFrameIndex=1 + try + { + System.out.println("frame range with skipFrameIndex=1"); + minFrameIndex = Integer.parseInt(frameRangeToks[0]); + maxFrameIndex = Integer.parseInt(frameRangeToks[1]); + wrongFrameRange = false; + } + catch(Exception e) + { + wrongFrameRange = true; + } + } + else if(frameRangeToks.length == 3) + { + // frame range with skipFrameIndex + try + { + System.out.println("frame range with skipFrameIndex"); + minFrameIndex = Integer.parseInt(frameRangeToks[0]); + skipFrameIndex = Integer.parseInt(frameRangeToks[1]); + maxFrameIndex = Integer.parseInt(frameRangeToks[2]); + wrongFrameRange = false; + } + catch(Exception e) + { + wrongFrameRange = true; + } + } + else + { + // wrong format + System.out.println("wrong format"); + wrongFrameRange = true; + } + + // check channel range + channelRangeToks = channelRange.split(":"); + if(channelRangeToks.length == 1) + { + // single channel + try + { + minChannelIndex = Integer.parseInt(channelRangeToks[0]); + maxChannelIndex = minChannelIndex; + wrongChannelRange = false; + } + catch(Exception e) + { + wrongChannelRange = true; + } + } + else if(channelRangeToks.length == 2) + { + // channel range with skipChannelIndex=1 + try + { + minChannelIndex = Integer.parseInt(channelRangeToks[0]); + maxChannelIndex = Integer.parseInt(channelRangeToks[1]); + wrongChannelRange = false; + } + catch(Exception e) + { + wrongChannelRange = true; + } + } + else if(channelRangeToks.length == 3) + { + // channel range with skipChannelIndex + try + { + minChannelIndex = Integer.parseInt(channelRangeToks[0]); + skipChannelIndex = Integer.parseInt(channelRangeToks[1]); + maxChannelIndex = Integer.parseInt(channelRangeToks[2]); + wrongChannelRange = false; + } + catch(Exception e) + { + wrongChannelRange = true; + } + } + else + { + // wrong format + wrongChannelRange = true; + } + if(wrongFrameRange || wrongChannelRange) + { + // show dialog again + System.out.println("show dialog again"); + // TODO reset dialog when possible + gd = new GenericDialog("Range Selection"); + gd.addMessage("Select frames and channels you want to read"); + gd.addMessage("Frame selection (start/step/end): "); + + gd.addStringField("Frame selection (start:[step:]end): ", + Integer.toString(minFrameIndex) + ":" + + Integer.toString(skipFrameIndex) + ":" + + Integer.toString(maxFrameIndex)); + + gd.addStringField("Channel selection (start:[step:]end): ", + Integer.toString(minChannelIndex) + ":" + + Integer.toString(skipChannelIndex) + ":" + + Integer.toString(maxChannelIndex)); + gd.showDialog(); + System.out.println("read ranges again"); + frameRange = gd.getNextString(); + channelRange = gd.getNextString(); + + } + if (gd.wasCanceled()) + { + return; + } + // the parameters for the range have correct format + } + + if(showUnmatchedDataSetNames) + { + varList = new ArrayList(); + // fill varList with unmatched var names + for (int i = 0; i < unmatchedVarNames.size(); i++) + { + String dsName = unmatchedVarNames.get(i); + try + { + HObject ds = inFile.get(dsName); + if(ds != null && ds instanceof Dataset) + { + varList.add((Dataset) ds); + } + } + catch(Exception e) + { + System.out.println("The file does not contain a variable " + + "with name " + "`" + dsName + "`!"); + } + } + } + else + { + // set varList=empty if we dont want unmatched var names + varList = new ArrayList(); + } + + } + else if(varList.size() > 1000) + { + /*----------------------------------------------------------------- + * FIXME: quick an dirty hack for files with more than 1000 + * datasets + *-----------------------------------------------------------------*/ + gd = new GenericDialog("Variable Name Selection"); + gd.addMessage("Too many variables in your file! " + + "(More than 1000)\n\n" + + "Please enter the full name of your desired dataset."); + gd.addStringField("dataset name", ""); + gd.showDialog(); + + if (gd.wasCanceled()) + { + return; + } + + String dsName = gd.getNextString(); + varList = new ArrayList(); + try + { + HObject ds = inFile.get(dsName); + if(ds != null && ds instanceof Dataset) + { + varList.add((Dataset) ds); + gd.addCheckbox("single variable", true); + } + else + { + IJ.error("The file does not contain a variable with name " + + "`" + dsName + "`!"); + inFile.close(); + return; + } + } + catch(Exception e) + { + IJ.error("The file does not contain a variable with name " + + "`" + dsName + "`!"); + inFile.close(); + return; + } + } + else + { + String[] varSelections = new String[varList.size()]; + boolean[] defaultValues = new boolean[varList.size()]; + for (int i = 0; i < varList.size(); i++) + { + Dataset var = varList.get(i); + int rank = var.getRank(); + String title = rank + "D: " + var.getFullName() + " " + + var.getDatatype().getDatatypeDescription() + "( "; + long[] extent = var.getDims(); + for (int d = 0; d < rank; ++d) + { + if (d != 0) + title += "x"; + title += extent[d]; + } + title += ")"; + varSelections[i] = title; + defaultValues[i] = false; + } + System.out.println("addcheckboxgroup with " + + varList.size() + " rows"); + gd.addCheckboxGroup(varList.size(), 1, + varSelections, defaultValues); + addScrollBars(gd); + gd.showDialog(); + + if (gd.wasCanceled()) + { + return; + } + } + /*------------------------------------------------------------------- + * now reading data sets + *-------------------------------------------------------------------*/ + if(groupVarsByName && + groupedVarnames.getNFrames()>0 && + loadGroupedVarNames) + { + groupedVarnames.setFrameAndChannelRange(minFrameIndex, + skipFrameIndex, + maxFrameIndex, + minChannelIndex, + skipChannelIndex, + maxChannelIndex); + // TODO implement hyperstack reading + int nFrames = groupedVarnames.getNFrames(); + int nChannels = groupedVarnames.getNChannels(); + + // get extents of first data set + long[] extent = null; + int rank = -1; + double[] elem_sizes = new double[3]; + String dsName = ""; + String[] formatTokens = groupedVarnames.getFormatTokens(); + Dataset var = null; + boolean isSigned16Bit = false; + int unsignedConvSelec = 0; // cut off values + try + { + TimeFrame f = groupedVarnames.getFrame(0); + if(f == null) + System.out.println("frame is null"); + if(formatTokens.length == 2) + dsName = formatTokens[0] + + Integer.toString(f.getFrameIndex()) + + formatTokens[1] + + Integer.toString(f.getChannelIndices()[0]); + else if(formatTokens.length == 3) + dsName = formatTokens[0] + + Integer.toString(f.getFrameIndex()) + + formatTokens[1] + + Integer.toString(f.getChannelIndices()[0]) + + formatTokens[2]; + System.out.println("VarName: " + dsName); + HObject ds = inFile.get(dsName); + if(ds != null && ds instanceof Dataset) + { + var = (Dataset) ds; + Datatype dType = var.getDatatype(); + isSigned16Bit = !dType.isUnsigned() && + (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && + (dType.getDatatypeSize() == 2); + if(isSigned16Bit) + { + GenericDialog convDiag + = new GenericDialog("Unsigned to signed conversion"); + convDiag.addMessage("Detected unsigned datatype, which "+ + "is not supported."); + String[] convOptions = new String[2]; + convOptions[0] = "cut off values"; + convOptions[1] = "convert to float"; + convDiag.addChoice("Please select an conversion option:", + convOptions, + convOptions[0]); + convDiag.showDialog(); + if(convDiag.wasCanceled()) + return; + unsignedConvSelec = convDiag.getNextChoiceIndex(); + } + // TODO check for unsupported datatypes int,long + rank = var.getRank(); + extent = var.getDims(); + Attribute elemsize_att = getAttribute(var, "element_size_um"); + + if (elemsize_att == null) + { + elem_sizes[0] = 1.0; + elem_sizes[1] = 1.0; + elem_sizes[2] = 1.0; + } + else + { + System.out.println("Reading element_size_um"); + float[] tmp = null; + try + { + tmp = ((float[]) elemsize_att.getValue()); + elem_sizes[0] = tmp[0]; + elem_sizes[1] = tmp[1]; + elem_sizes[2] = tmp[2]; + } + catch(java.lang.ClassCastException e) + { + String title = "Error Reading Element Size"; + String msg = "The element_size_um attribute " + + "has wrong format!\n"; + msg += "Setting to default size of (1,1,1)..."; + ij.gui.MessageDialog errMsg = new ij.gui.MessageDialog(null, + title, + msg); + elem_sizes[0] = 1; + elem_sizes[1] = 1; + elem_sizes[2] = 1; + } + } + } + else + { + IJ.error("The file does not contain a variable with name " + + "`" + dsName + "`!"); + inFile.close(); + return; + } + } + catch(Exception e) + { + IJ.error("The file does not contain a variable with name " + + "`" + dsName + "`!"); + inFile.close(); + return; + } + // String title = rank + "D: " + var.getFullName() + " " + // + var.getDatatype().getDatatypeDescription() + "( "; + + // read 3D or 2D dataset + if(rank == 3 || rank == 2) + { + int nRows = -1; // height + int nCols = -1; // width + int nSlices = 1; // if rank == 2 + if(rank == 3) + { + nSlices = (int) extent[0]; + nRows = (int) extent[1]; + nCols = (int) extent[2]; + } + else + { + nRows = (int) extent[0]; + nCols = (int) extent[1]; + } + + + // create a new image stack and fill in the data + ImageStack stack = new ImageStack(nCols, + nRows, + nFrames*nSlices*nChannels); + System.out.println("stackSize: " + + Integer.toString(stack.getSize())); + + ImagePlus imp = new ImagePlus(); + // to get getFrameIndex() working + imp.setDimensions(nChannels,nSlices,nFrames); + + long stackSize = nCols*nRows; + // global min max values of all data sets + double[] minValChannel = new double[nChannels]; + double[] maxValChannel = new double[nChannels]; + + // TODO implement frame and channel ranges + // now read frame by frame + for(int fIdx=0; fIdx2) + selected[2] = extent[2]; + + Object wholeDataset = var.read(); + if(isSigned16Bit) + wholeDataset = convertToUnsigned(wholeDataset, + unsignedConvSelec); + + long wholeDatasetSize = 1; + for(int d=0;d1) + { + System.out.println("Creating composite hyperstack with " + + Integer.toString(nChannels) + + " channels."); + imp = new CompositeImage(imp, CompositeImage.COMPOSITE); + } + else + { + System.out.println("Creating grayscale hyperstack."); + //imp = new CompositeImage(imp, CompositeImage.GRAYSCALE); + } + + + System.out.println("nFrames: " + Integer.toString(nFrames)); + System.out.println("nSlices: " + Integer.toString(nSlices)); + + System.out.println("stackSize: " + + Integer.toString(stack.getSize())); + + // set element_size_um + imp.getCalibration().pixelDepth = elem_sizes[0]; + imp.getCalibration().pixelHeight = elem_sizes[1]; + imp.getCalibration().pixelWidth = elem_sizes[2]; + + + // System.out.println(" Min = " + minMaxVal[0] + + // ", Max = " + minMaxVal[1]); + //imp.setDisplayRange(1.5*minMaxVal[0], 0.5*minMaxVal[1]); + //imp.resetDisplayRange(); + int[] channelsIJ = {4,2,1}; + for(int c=0;c + getDataSetList(Group g, List datasets) throws Exception + { + if (g == null) + return datasets; + + List members = g.getMemberList(); + int n = members.size(); + HObject obj = null; + for (int i = 0; i < n; i++) + { + obj = (HObject) members.get(i); + if (obj instanceof Dataset) + { + ((Dataset) obj).init(); + datasets.add((Dataset) obj); + //System.out.println(obj.getFullName()); + } + else if (obj instanceof Group) + { + datasets = (getDataSetList((Group) obj, datasets)); + } + } + return datasets; + } + + private static List getAttrList(HObject ds) throws Exception + { + if (ds == null) + return null; + + List attributes = new ArrayList(); + List members = ds.getMetadata(); + int n = members.size(); + Metadata obj = null; + for (int i = 0; i < n; i++) + { + obj = (Metadata) members.get(i); + if (obj instanceof Attribute) + { + try + { + System.out.println(((Attribute) obj).getName()); + attributes.add((Attribute) obj); + } + catch (java.lang.UnsupportedOperationException e) + { + System.out + .println("Caught UnsupportedOperationException datasets2.add((Dataset) obj)"); + System.out.println(e.getMessage()); + } + } + } + return attributes; + } + + private static Attribute + getAttribute(Dataset ds, String attrName) throws Exception + { + List attrList = getAttrList((HObject)ds); + Iterator attrIter = attrList.iterator(); + + while (attrIter.hasNext()) + { + Attribute attr = attrIter.next(); + if (attr.getName().equals(attrName)) + { + return attr; + } + } + return null; + } + + private static Attribute + getAttribute(HObject ds, String attrName) throws Exception + { + List attrList = getAttrList(ds); + Iterator attrIter = attrList.iterator(); + + while (attrIter.hasNext()) + { + Attribute attr = attrIter.next(); + System.out.println(attr.getName()); + if (attr.getName().equals(attrName)) + { + return attr; + } + } + return null; + } + /*----------------------------------------------------------------------- + * minmax of array + *-----------------------------------------------------------------------*/ + private double[] getMinMax(Object data, long stackSize) + { + double[] minmax = new double[2]; + + if (data instanceof byte[]) + { + byte[] tmp = (byte[]) data; + minmax[0]=tmp[0]; + minmax[1]=tmp[0]; + for(int i=1; iminmax[1]) + minmax[1]=val; + } + } + else if (data instanceof short[]) + { + short[] tmp = (short[]) data; + minmax[0]=tmp[0]; + minmax[1]=tmp[0]; + for(int i=1; iminmax[1]) + minmax[1]=val; + } + } + else if (data instanceof int[]) + { + int[] tmp = (int[]) data; + minmax[0]=tmp[0]; + minmax[1]=tmp[0]; + for(int i=1; iminmax[1]) + minmax[1]=tmp[i]; + } + } + else if (data instanceof long[]) + { + long[] tmp = (long[]) data; + minmax[0]=tmp[0]; + minmax[1]=tmp[0]; + for(int i=1; iminmax[1]) + minmax[1]=tmp[i]; + } + } + else if (data instanceof float[]) + { + float[] tmp = (float[]) data; + minmax[0]=tmp[0]; + minmax[1]=tmp[0]; + for(int i=1; iminmax[1]) + minmax[1]=tmp[i]; + } + } + else if (data instanceof double[]) + { + double[] tmp = (double[]) data; + minmax[0]=tmp[0]; + minmax[1]=tmp[0]; + for(int i=1; iminmax[1]) + minmax[1]=tmp[i]; + } + } + System.out.println("min: " + minmax[0] + ", max: " + minmax[1]); + return minmax; + } + /*----------------------------------------------------------------------- + * converter functions + *-----------------------------------------------------------------------*/ + private float[] convertDoubleToFloat(double[] dataIn) + { + float[] dataOut = new float[dataIn.length]; + for (int index = 0; index < dataIn.length; index++) + { + dataOut[index] = (float) dataIn[index]; + } + return dataOut; + } + + private float[] convertInt32ToFloat(int[] dataIn) + { + float[] dataOut = new float[dataIn.length]; + for (int index = 0; index < dataIn.length; index++) + { + dataOut[index] = dataIn[index]; + } + return dataOut; + } + + private short[] convertInt32ToShort(int[] dataIn) + { + short[] dataOut = new short[dataIn.length]; + for (int index = 0; index < dataIn.length; index++) + { + dataOut[index] = (short) dataIn[index]; + } + return dataOut; + } + + private float[] convertInt64ToFloat(long[] dataIn) + { + float[] dataOut = new float[dataIn.length]; + for (int index = 0; index < dataIn.length; index++) + { + dataOut[index] = dataIn[index]; + } + return dataOut; + } + + private short[] convertInt64ToShort(long[] dataIn) + { + short[] dataOut = new short[dataIn.length]; + for (int index = 0; index < dataIn.length; index++) + { + dataOut[index] = (short) dataIn[index]; + } + return dataOut; + } + + + private Object convertToUnsigned(Object dataIn, + int unsignedConvSelec) + { + Object dataOut = null; + if(unsignedConvSelec == 0) + { + // cut off values + if(dataIn instanceof short[]) + { + short[] tmp = (short[]) dataIn; + for(int i=0;i maxWidth) size.width = maxWidth; + if (size.height > maxHeight) size.height = maxHeight; + + // create scroll pane + ScrollPane scroll = new ScrollPane() { + public Dimension getPreferredSize() { + return size; + } + }; + scroll.add(newPane); + + // add scroll pane to original container + GridBagConstraints constraints = new GridBagConstraints(); + constraints.anchor = GridBagConstraints.WEST; + constraints.fill = GridBagConstraints.BOTH; + constraints.weightx = 1.0; + constraints.weighty = 1.0; + layout.setConstraints(scroll, constraints); + pane.add(scroll); + } +} + diff --git a/src/HDF5_Writer_.java b/src/HDF5_Writer_.java new file mode 100644 index 0000000..1f530c5 --- /dev/null +++ b/src/HDF5_Writer_.java @@ -0,0 +1,877 @@ +/* ========================================================================= + * + * Copyright 2011 Matthias Schlachter + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + + +import ij.*; +import ij.io.*; +import ij.plugin.*; +import ij.plugin.filter.PlugInFilter; +import ij.process.*; +import ij.gui.*; +import java.awt.*; +import java.lang.Math; + +import java.io.IOException; +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.tree.DefaultMutableTreeNode; + +import ncsa.hdf.object.*; // the common object package +import ncsa.hdf.object.h5.*; // the HDF5 implementation +import ncsa.hdf.hdf5lib.exceptions.HDF5Exception; +import ncsa.hdf.hdflib.HDFException; + +public class HDF5_Writer_ implements PlugInFilter +{ + private Boolean _batchMode = false; + private String[] _batchVarNames = null; + private String _batchFileName = null; + public int setup(String arg, ImagePlus imp) + { + if (arg.equals("about")) + { + showAbout(); + return DONE; + } + // FIXME: set DOES_xx for image type here: + // currently RGB-Types are still missing + // see + // http://rsb.info.nih.gov/ij/developer/api/ij/plugin/filter/PlugInFilter.html + return DOES_8G + DOES_16 + DOES_32 + DOES_RGB + + NO_CHANGES; + } + + public void setToBatchMode(String filename, String [] varnames) + { + _batchMode = true; + _batchFileName = filename; + _batchVarNames = varnames; + } + + public void run(ImageProcessor ip) + { + int[] wList = WindowManager.getIDList(); + + if (wList == null) + { + IJ.error("No windows are open."); + return; + } + + String filename = null; + if(_batchMode) + { + filename = _batchFileName; + } + else + { + SaveDialog sd = new SaveDialog("Save HDF5 ...", "", ".h5"); + String directory = sd.getDirectory(); + String name = sd.getFileName(); + filename = directory + name; + + if (name == null) + return; + if (name == "") + return; + } + + + // Retrieve an instance of the implementing class for the HDF5 format + FileFormat fileFormat = + FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5); + + // If the implementing class wasn't found, it's an error. + if (fileFormat == null) + { + System.err.println("Cannot find HDF5 FileFormat."); + return; + } + + String[] varNames = null; + if(_batchMode) + { + varNames = _batchVarNames; + } + + ImagePlus imp = WindowManager.getCurrentImage(); + + GenericDialog gd = null; + gd = new GenericDialog("Variable Name Selection"); + + // check for hyperstack + if(imp.getOpenAsHyperStack() || imp.isHyperStack()) + { + System.out.println("This is a hyperstack"); + boolean splitChannels = true; + gd.addCheckbox("Split frames and channels",splitChannels); + gd.addStringField(imp.getTitle(), "/t$T/channel$C"); + String title = imp.getTitle(); + int nDims = imp.getNDimensions(); + int nFrames = imp.getNFrames(); + int nChannels = imp.getNChannels(); + int nLevs = imp.getNSlices(); + int nRows = imp.getHeight(); + int nCols = imp.getWidth(); + boolean isComposite = imp.isComposite() ; + System.out.println("isComposite: "+Boolean.toString(isComposite)); + System.out.println("Saving image \""+title+"\""); + System.out.println("nDims: "+Integer.toString(nDims)); + System.out.println("nFrames: "+Integer.toString(nFrames)); + System.out.println("nChannels: "+Integer.toString(nChannels)); + System.out.println("nSlices: "+Integer.toString(nLevs)); + System.out.println("nRows: "+Integer.toString(nRows)); + System.out.println("nCols: "+Integer.toString(nCols)); + gd.showDialog(); + if (gd.wasCanceled()) + { + IJ.error("Plugin canceled!"); + return; + } + splitChannels = gd.getNextBoolean(); + String formatString = gd.getNextString(); + System.out.println("formatString: "+formatString); + System.out.println("Bitdepth: "+ imp.getBitDepth()); + System.out.println("Saving HDF5 File: " + filename); + + int imgColorDepth = imp.getBitDepth(); + int imgColorType = imp.getType(); + Datatype type = null; + if (imgColorType == ImagePlus.GRAY8) + { + System.out.println(" bit depth: " + imgColorDepth + + ", type: GRAY8"); + type = new H5Datatype(Datatype.CLASS_CHAR, Datatype.NATIVE, + Datatype.NATIVE, Datatype.SIGN_NONE); + } + else if (imgColorType == ImagePlus.GRAY16) + { + System.out.println(" bit depth: " + imgColorDepth + + ", type: GRAY16"); + int typeSizeInByte = 2; + type = new H5Datatype(Datatype.CLASS_INTEGER, typeSizeInByte, + Datatype.NATIVE, Datatype.SIGN_NONE); + } + else if (imgColorType == ImagePlus.GRAY32) + { + System.out.println(" bit depth: " + imgColorDepth + + ", type: GRAY32"); + int typeSizeInByte = 4; + type = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, + Datatype.NATIVE, -1); + } + + // open the outfile + H5File outFile = null; + try + { + outFile = (H5File) fileFormat.createFile(filename, + FileFormat.FILE_CREATE_OPEN); + if (!outFile.canWrite()) + { + IJ.error("File `" + filename + "`is readonly!"); + return; + } + // open the file + outFile.open(); + + if(splitChannels) + { + // parse format string + String[] formatTokens = + HDF5_GroupedVarnames. + parseFormatString(formatString, + "[0-9]+"); // dummy regexp + long[] channelDims = null; + if(nLevs>1) + { + channelDims = new long[3]; + channelDims[0] = nLevs; + channelDims[1] = nRows; + channelDims[2] = nCols; + } + else + { + channelDims = new long[2]; + channelDims[0] = nRows; + channelDims[1] = nCols; + } + // iterate over frames and channels + ImageStack stack = imp.getStack(); + for(int f=0;f getAttrList(Dataset ds) throws Exception + { + if (ds == null) + return null; + + List attributes = new ArrayList(); + List members = ds.getMetadata(); + int n = members.size(); + Metadata obj = null; + for (int i = 0; i < n; i++) + { + obj = (Metadata) members.get(i); + if (obj instanceof Attribute) + { + try + { + System.out.println(((Attribute) obj).getName()); + attributes.add((Attribute) obj); + } + catch (java.lang.UnsupportedOperationException e) + { + System.out + .println("Caught UnsupportedOperationException datasets2.add((Dataset) obj)"); + System.out.println(e.getMessage()); + } + } + } + return attributes; + } + + private static Attribute + getAttribute(Dataset ds, String attrName) throws Exception + { + List attrList = getAttrList(ds); + Iterator attrIter = attrList.iterator(); + + while (attrIter.hasNext()) + { + Attribute attr = attrIter.next(); + if (attr.getName().equals(attrName)) + { + return attr; + } + } + return null; + } + + private Object computeRgbSlice(Object pixels) + { + byte rgbslice[]; + int size = ((int[])pixels).length; + rgbslice = new byte[size*3]; + for(int i=0;i> 16; + int green= (((int[]) pixels)[i] & 0x00ff00) >> 8; + int blue= ((int[]) pixels)[i] & 0x0000ff; + rgbslice[3*i + 0] = (byte) red; + rgbslice[3*i + 1] = (byte) green; + rgbslice[3*i + 2] =(byte) blue; + } + return rgbslice; + } + + private String makeDataSetName(String[] toks,int frame,int channel) + { + String dName = + toks[0] + + Integer.toString(frame) + + toks[1] + + Integer.toString(channel); + if(toks.length>2) + dName = dName + toks[2]; + return dName; + } + +// end of class +} diff --git a/src/TimeFrame.java b/src/TimeFrame.java new file mode 100644 index 0000000..9e6da3e --- /dev/null +++ b/src/TimeFrame.java @@ -0,0 +1,104 @@ +/* ========================================================================= + * + * Copyright 2011 Matthias Schlachter + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + +import java.util.ArrayList; +import java.util.Arrays; +//import java.util.Iterator; +//import java.util.List; + + +public class TimeFrame implements Comparable +{ + public TimeFrame(int index) + { + frameIndex = index; + } + + public TimeFrame(String index) + { + frameIndex = Integer.parseInt(index); + } + + public void addChannel(int index) + { + Integer channelIndex = new Integer(index); + if(!channels.contains(channelIndex)) + channels.add(new Integer(index)); + else + System.out.println("channel" + channelIndex.toString() + + " already in list!"); + } + + public void addChannel(String index) + { + addChannel(Integer.parseInt(index)); + } + + public boolean equals(Object obj) + { + TimeFrame f = (TimeFrame) obj; + if(f.frameIndex == frameIndex) + return true; + return false; + } + + public String toString() + { + String s = "FrameIdx: " + Integer.toString(frameIndex) + "; "; + s = s + "nChannels: " + Integer.toString(channels.size()) + "; "; + s = s + "channels: "; + for(int i=0;if.frameIndex) + return 1; + else + return 0; + } + + private final int frameIndex; + private final ArrayList channels = new ArrayList(); +} \ No newline at end of file