Changeset 6130


Ignore:
Timestamp:
04/16/10 15:34:12 (10 years ago)
Author:
curtis
Message:

Progress on Bio-Formats Importer refactoring.

Location:
trunk/components/loci-plugins
Files:
7 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/components/loci-plugins/src/loci/plugins/importer/ImagePlusReader.java

    r6128 r6130  
    2424*/ 
    2525 
    26 package loci.plugins.util; 
    27  
     26package loci.plugins.importer; 
     27 
     28import ij.IJ; 
     29import ij.ImagePlus; 
     30import ij.ImageStack; 
     31import ij.WindowManager; 
     32import ij.io.FileInfo; 
     33import ij.plugin.filter.PlugInFilterRunner; 
    2834import ij.process.ByteProcessor; 
     35import ij.process.ColorProcessor; 
    2936import ij.process.FloatProcessor; 
    3037import ij.process.ImageProcessor; 
     
    3340import java.awt.Rectangle; 
    3441import java.awt.image.IndexColorModel; 
     42import java.io.File; 
    3543import java.io.IOException; 
    36  
    37 import loci.common.DataTools; 
    38 import loci.formats.ClassList; 
     44import java.util.ArrayList; 
     45 
     46import loci.common.Location; 
     47import loci.common.ReflectException; 
     48import loci.common.ReflectedUniverse; 
     49import loci.common.services.DependencyException; 
     50import loci.common.services.ServiceException; 
     51import loci.common.services.ServiceFactory; 
     52import loci.formats.ChannelMerger; 
     53import loci.formats.FilePattern; 
    3954import loci.formats.FormatException; 
    4055import loci.formats.FormatTools; 
    4156import loci.formats.IFormatReader; 
    42 import loci.formats.ImageReader; 
    43 import loci.formats.ImageTools; 
    44 import loci.formats.MinMaxCalculator; 
    45 import loci.formats.in.ND2Reader; 
    46 import loci.formats.in.PictReader; 
    47 import loci.formats.in.QTReader; 
    48 import loci.formats.in.SDTReader; 
    49 import loci.formats.in.TiffDelegateReader; 
     57import loci.formats.meta.IMetadata; 
     58import loci.formats.services.OMEXMLService; 
     59import loci.plugins.Colorizer; 
     60import loci.plugins.util.BFVirtualStack; 
     61import loci.plugins.util.DataBrowser; 
     62import loci.plugins.util.ImagePlusTools; 
     63import loci.plugins.util.ImageProcessorReader; 
     64import loci.plugins.util.VirtualImagePlus; 
     65import loci.plugins.util.VirtualReader; 
     66import loci.plugins.util.WindowTools; 
    5067 
    5168/** 
    52  * Bio-Formats reader for reading ImagePlus objects. 
     69 * A high-level reader for {@link ij.ImagePlus} objects. 
    5370 * 
    5471 * <dl><dt><b>Source code:</b></dt> 
    55  * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/loci-plugins/src/loci/plugins/util/ImagePlusReader.java">Trac</a>, 
    56  * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/components/loci-plugins/src/loci/plugins/util/ImagePlusReader.java">SVN</a></dd></dl> 
     72 * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/loci-plugins/src/loci/plugins/importer/ImagePlusReader.java">Trac</a>, 
     73 * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/components/loci-plugins/src/loci/plugins/importer/ImagePlusReader.java">SVN</a></dd></dl> 
    5774 */ 
    58 public class ImagePlusReader extends MinMaxCalculator { 
    59  
    60   // -- Utility methods -- 
    61  
    62   /** Converts the given reader into a ImagePlusReader, wrapping if needed. */ 
    63   public static ImagePlusReader makeImagePlusReader(IFormatReader r) { 
    64     if (r instanceof ImagePlusReader) return (ImagePlusReader) r; 
    65     return new ImagePlusReader(r); 
     75public class ImagePlusReader { 
     76 
     77  // -- Fields -- 
     78 
     79  /** Importer options that control the reader's behavior. */ 
     80  protected ImporterOptions options; 
     81 
     82  // -- Constructors -- 
     83 
     84  /** 
     85   * Constructs an ImagePlusReader with the default options. 
     86   * @throws IOException if the default options cannot be determined. 
     87   */ 
     88  public ImagePlusReader() throws IOException { 
     89    this(new ImporterOptions()); 
    6690  } 
    6791 
    68   /** 
    69    * Creates an image reader according to the current configuration settings, 
    70    * including which format readers are currently enabled, as well as 
    71    * format-specific configuration settings. 
    72    */ 
    73   public static ImageReader makeImageReader() { 
    74     // include only enabled classes 
    75     Class[] c = null; 
    76     try { 
    77       ClassList defaultClasses = 
    78         new ClassList("readers.txt", IFormatReader.class); 
    79       c = defaultClasses.getClasses(); 
    80     } 
    81     catch (IOException exc) { 
    82       return new ImageReader(); 
    83     } 
    84     ClassList enabledClasses = new ClassList(IFormatReader.class); 
    85     for (int i=0; i<c.length; i++) { 
    86       boolean on = LociPrefs.isReaderEnabled(c[i]); 
    87       if (on) { 
    88         try { 
    89           enabledClasses.addClass(c[i]); 
    90         } 
    91         catch (FormatException exc) { 
    92           exc.printStackTrace(); 
    93         } 
    94       } 
    95     } 
    96     ImageReader reader = new ImageReader(enabledClasses); 
    97  
    98     // toggle reader-specific options 
    99     boolean nd2Nikon = LociPrefs.isND2Nikon(); 
    100     boolean pictQTJava = LociPrefs.isPictQTJava(); 
    101     boolean qtQTJava = LociPrefs.isQTQTJava(); 
    102     boolean sdtIntensity = LociPrefs.isSDTIntensity(); 
    103     boolean tiffImageIO = LociPrefs.isTiffImageIO(); 
    104     IFormatReader[] r = reader.getReaders(); 
    105     for (int i=0; i<r.length; i++) { 
    106       if (r[i] instanceof ND2Reader) { 
    107         ND2Reader nd2 = (ND2Reader) r[i]; 
    108         nd2.setLegacy(nd2Nikon); 
    109       } 
    110       else if (r[i] instanceof PictReader) { 
    111         PictReader pict = (PictReader) r[i]; 
    112         pict.setLegacy(pictQTJava); 
    113       } 
    114       else if (r[i] instanceof QTReader) { 
    115         QTReader qt = (QTReader) r[i]; 
    116         qt.setLegacy(qtQTJava); 
    117       } 
    118       else if (r[i] instanceof SDTReader) { 
    119         SDTReader sdt = (SDTReader) r[i]; 
    120         sdt.setIntensity(sdtIntensity); 
    121       } 
    122       else if (r[i] instanceof TiffDelegateReader) { 
    123         TiffDelegateReader tiff = (TiffDelegateReader) r[i]; 
    124         tiff.setLegacy(tiffImageIO); 
    125       } 
    126     } 
    127  
    128     return reader; 
     92  /** Constructs an ImagePlusReader with the given reader. */ 
     93  public ImagePlusReader(ImporterOptions options) { 
     94    this.options = options; 
    12995  } 
    130  
    131   // -- Constructors -- 
    132  
    133   /** Constructs an ImagePlusReader around a new image reader. */ 
    134   public ImagePlusReader() { super(makeImageReader()); } 
    135  
    136   /** Constructs an ImagePlusReader with the given reader. */ 
    137   public ImagePlusReader(IFormatReader r) { super(r); } 
    13896 
    13997  // -- ImagePlusReader methods -- 
     
    142100   * Creates an ImageJ image processor object 
    143101   * for the image plane at the given position. 
    144    * 
    145    * @param no Position of image plane. 
    146102   */ 
    147   public ImageProcessor[] openProcessors(int no) 
     103  public ImagePlus[] openImagePlus() 
    148104    throws FormatException, IOException 
    149105  { 
    150     return openProcessors(no, null); 
     106    readPixelData(); 
     107    // TODO - disentangle data and display logic 
     108    return null; 
    151109  } 
    152110 
     111  private void readPixelData() throws FormatException, IOException 
     112  { 
     113    ImageProcessorReader r = options.getReader(); 
     114    ArrayList<ImagePlus> imps = new ArrayList<ImagePlus>(); 
     115    String stackOrder = null; 
     116    IndexColorModel[] colorModels = null; 
     117 
     118    if (options.isVirtual()) { 
     119      int totalSeries = 0; 
     120      for (int s=0; s<r.getSeriesCount(); s++) { 
     121        if (options.isSeriesOn(s)) totalSeries++; 
     122      } 
     123      ((VirtualReader) r.getReader()).setRefCount(totalSeries); 
     124    } 
     125 
     126    for (int s=0; s<r.getSeriesCount(); s++) { 
     127      if (!options.isSeriesOn(s)) continue; 
     128      r.setSeries(s); 
     129 
     130      boolean[] load = new boolean[r.getImageCount()]; 
     131      int cBegin = options.getCBegin(s); 
     132      int cEnd = options.getCEnd(s); 
     133      int cStep = options.getCStep(s); 
     134      int zBegin = options.getZBegin(s); 
     135      int zEnd = options.getZEnd(s); 
     136      int zStep = options.getZStep(s); 
     137      int tBegin = options.getTBegin(s); 
     138      int tEnd = options.getTEnd(s); 
     139      int tStep = options.getTStep(s); 
     140      for (int c=cBegin; c<=cEnd; c+=cStep) { 
     141        for (int z=zBegin; z<=zEnd; z+=zStep) { 
     142          for (int t=tBegin; t<=tEnd; t+=tStep) { 
     143            //int index = r.isOrderCertain() ? r.getIndex(z, c, t) : c; 
     144            int index = r.getIndex(z, c, t); 
     145            load[index] = true; 
     146          } 
     147        } 
     148      } 
     149      int total = 0; 
     150      for (int j=0; j<r.getImageCount(); j++) if (load[j]) total++; 
     151 
     152      FileInfo fi = new FileInfo(); 
     153 
     154      // populate other common FileInfo fields 
     155      String idDir = options.getIdLocation() == null ? 
     156        null : options.getIdLocation().getParent(); 
     157      if (idDir != null && !idDir.endsWith(File.separator)) { 
     158        idDir += File.separator; 
     159      } 
     160      fi.fileName = options.getIdName(); 
     161      fi.directory = idDir; 
     162 
     163      long startTime = System.currentTimeMillis(); 
     164      long time = startTime; 
     165 
     166      ImageStack stackB = null; // for byte images (8-bit) 
     167      ImageStack stackS = null; // for short images (16-bit) 
     168      ImageStack stackF = null; // for floating point images (32-bit) 
     169      ImageStack stackO = null; // for all other images (24-bit RGB) 
     170 
     171      Rectangle cropRegion = options.getCropRegion(s); 
     172      int w = options.doCrop() ? cropRegion.width : r.getSizeX(); 
     173      int h = options.doCrop() ? cropRegion.height : r.getSizeY(); 
     174      int c = r.getRGBChannelCount(); 
     175      int type = r.getPixelType(); 
     176 
     177      int q = 0; 
     178      stackOrder = options.getStackOrder(); 
     179      if (stackOrder.equals(ImporterOptions.ORDER_DEFAULT)) { 
     180        stackOrder = r.getDimensionOrder(); 
     181      } 
     182      ((VirtualReader) r.getReader()).setOutputOrder(stackOrder); 
     183 
     184      options.getOMEMetadata().setPixelsDimensionOrder(stackOrder, s, 0); 
     185 
     186      // dump OME-XML to ImageJ's description field, if available 
     187 
     188      try { 
     189        ServiceFactory factory = new ServiceFactory(); 
     190        OMEXMLService service = factory.getInstance(OMEXMLService.class); 
     191        fi.description = service.getOMEXML(options.getOMEMetadata()); 
     192      } 
     193      catch (DependencyException de) { } 
     194      catch (ServiceException se) { } 
     195 
     196      if (options.isVirtual()) { 
     197        int cSize = r.getSizeC(); 
     198        int pt = r.getPixelType(); 
     199        boolean doMerge = options.isMergeChannels(); 
     200        boolean eight = pt != FormatTools.UINT8 && pt != FormatTools.INT8; 
     201        boolean needComposite = doMerge && (cSize > 3 || eight); 
     202        int merge = (needComposite || !doMerge) ? 1 : cSize; 
     203 
     204        r.setSeries(s); 
     205        // NB: ImageJ 1.39+ is required for VirtualStack 
     206        BFVirtualStack virtualStackB = new BFVirtualStack(options.getId(), 
     207          r, options.isColorize(), doMerge, options.isRecord()); 
     208        stackB = virtualStackB; 
     209        if (doMerge) { 
     210          for (int j=0; j<r.getImageCount(); j++) { 
     211            int[] pos = r.getZCTCoords(j); 
     212            if (pos[1] > 0) continue; 
     213            String label = constructSliceLabel( 
     214              new ChannelMerger(r).getIndex(pos[0], pos[1], pos[2]), 
     215              new ChannelMerger(r), options.getOMEMetadata(), s, 
     216              options.getZCount(s), options.getCCount(s), 
     217              options.getTCount(s)); 
     218            virtualStackB.addSlice(label); 
     219          } 
     220        } 
     221        else { 
     222          for (int j=0; j<r.getImageCount(); j++) { 
     223            String label = constructSliceLabel(j, r, 
     224              options.getOMEMetadata(), s, options.getZCount(s), 
     225              options.getCCount(s), options.getTCount(s)); 
     226            virtualStackB.addSlice(label); 
     227          } 
     228        } 
     229      } 
     230      else { 
     231        if (r.isIndexed()) colorModels = new IndexColorModel[r.getSizeC()]; 
     232 
     233        for (int i=0; i<r.getImageCount(); i++) { 
     234          if (!load[i]) continue; 
     235 
     236          // limit message update rate 
     237          long clock = System.currentTimeMillis(); 
     238          if (clock - time >= 100) { 
     239            String sLabel = r.getSeriesCount() > 1 ? 
     240              ("series " + (s + 1) + ", ") : ""; 
     241            String pLabel = "plane " + (i + 1) + "/" + total; 
     242            IJ.showStatus("Reading " + sLabel + pLabel); 
     243            time = clock; 
     244          } 
     245          IJ.showProgress((double) q++ / total); 
     246 
     247          String label = constructSliceLabel(i, r, 
     248            options.getOMEMetadata(), s, options.getZCount(s), 
     249            options.getCCount(s), options.getTCount(s)); 
     250 
     251          // get image processor for ith plane 
     252          ImageProcessor[] p = r.openProcessors(i, cropRegion); 
     253          ImageProcessor ip = p[0]; 
     254          if (p.length > 1) { 
     255            ip = ImagePlusTools.makeRGB(p).getProcessor(); 
     256          } 
     257          if (ip == null) { 
     258            throw new FormatException("Cannot read ImageProcessor #" + i); 
     259          } 
     260 
     261          int channel = r.getZCTCoords(i)[1]; 
     262          if (colorModels != null && p.length == 1) { 
     263            colorModels[channel] = (IndexColorModel) ip.getColorModel(); 
     264          } 
     265 
     266          // add plane to image stack 
     267          if (ip instanceof ByteProcessor) { 
     268            if (stackB == null) stackB = new ImageStack(w, h); 
     269            stackB.addSlice(label, ip); 
     270          } 
     271          else if (ip instanceof ShortProcessor) { 
     272            if (stackS == null) stackS = new ImageStack(w, h); 
     273            stackS.addSlice(label, ip); 
     274          } 
     275          else if (ip instanceof FloatProcessor) { 
     276            // merge image plane into existing stack if possible 
     277            if (stackB != null) { 
     278              ip = ip.convertToByte(true); 
     279              stackB.addSlice(label, ip); 
     280            } 
     281            else if (stackS != null) { 
     282              ip = ip.convertToShort(true); 
     283              stackS.addSlice(label, ip); 
     284            } 
     285            else { 
     286              if (stackF == null) stackF = new ImageStack(w, h); 
     287              stackF.addSlice(label, ip); 
     288            } 
     289          } 
     290          else if (ip instanceof ColorProcessor) { 
     291            if (stackO == null) stackO = new ImageStack(w, h); 
     292            stackO.addSlice(label, ip); 
     293          } 
     294        } 
     295      } 
     296 
     297      IJ.showStatus("Creating image"); 
     298      IJ.showProgress(1); 
     299 
     300      showStack(stackB, s, fi, options, imps, stackOrder, colorModels); 
     301      showStack(stackS, s, fi, options, imps, stackOrder, colorModels); 
     302      showStack(stackF, s, fi, options, imps, stackOrder, colorModels); 
     303      showStack(stackO, s, fi, options, imps, stackOrder, colorModels); 
     304 
     305      long endTime = System.currentTimeMillis(); 
     306      double elapsed = (endTime - startTime) / 1000.0; 
     307      if (r.getImageCount() == 1) { 
     308        IJ.showStatus("Bio-Formats: " + elapsed + " seconds"); 
     309      } 
     310      else { 
     311        long average = (endTime - startTime) / r.getImageCount(); 
     312        IJ.showStatus("Bio-Formats: " + elapsed + " seconds (" + 
     313          average + " ms per plane)"); 
     314      } 
     315    } 
     316 
     317    if (options.isConcatenate()) { 
     318      ArrayList<Integer> widths = new ArrayList<Integer>(); 
     319      ArrayList<Integer> heights = new ArrayList<Integer>(); 
     320      ArrayList<Integer> types = new ArrayList<Integer>(); 
     321      ArrayList<ImagePlus> newImps = new ArrayList<ImagePlus>(); 
     322 
     323      for (int j=0; j<imps.size(); j++) { 
     324        ImagePlus imp = imps.get(j); 
     325        int wj = imp.getWidth(); 
     326        int hj = imp.getHeight(); 
     327        int tj = imp.getBitDepth(); 
     328        boolean append = false; 
     329        for (int k=0; k<widths.size(); k++) { 
     330          int wk = ((Integer) widths.get(k)).intValue(); 
     331          int hk = ((Integer) heights.get(k)).intValue(); 
     332          int tk = ((Integer) types.get(k)).intValue(); 
     333 
     334          if (wj == wk && hj == hk && tj == tk) { 
     335            ImagePlus oldImp = newImps.get(k); 
     336            ImageStack is = oldImp.getStack(); 
     337            ImageStack newStack = imp.getStack(); 
     338            for (int s=0; s<newStack.getSize(); s++) { 
     339              is.addSlice(newStack.getSliceLabel(s + 1), 
     340                newStack.getProcessor(s + 1)); 
     341            } 
     342            oldImp.setStack(oldImp.getTitle(), is); 
     343            newImps.set(k, oldImp); 
     344            append = true; 
     345            k = widths.size(); 
     346          } 
     347        } 
     348        if (!append) { 
     349          widths.add(new Integer(wj)); 
     350          heights.add(new Integer(hj)); 
     351          types.add(new Integer(tj)); 
     352          newImps.add(imp); 
     353        } 
     354      } 
     355 
     356      boolean splitC = options.isSplitChannels(); 
     357      boolean splitZ = options.isSplitFocalPlanes(); 
     358      boolean splitT = options.isSplitTimepoints(); 
     359 
     360      for (int j=0; j<newImps.size(); j++) { 
     361        ImagePlus imp = (ImagePlus) newImps.get(j); 
     362        imp.show(); 
     363        if (splitC || splitZ || splitT) { 
     364          IJ.runPlugIn("loci.plugins.Slicer", "slice_z=" + splitZ + 
     365            " slice_c=" + splitC + " slice_t=" + splitT + 
     366            " stack_order=" + stackOrder + " keep_original=false " + 
     367            "hyper_stack=" + options.isViewHyperstack() + " "); 
     368          imp.close(); 
     369        } 
     370        if (options.isMergeChannels() && options.isWindowless()) { 
     371          IJ.runPlugIn("loci.plugins.Colorizer", "stack_order=" + stackOrder + 
     372            " merge=true merge_option=[" + options.getMergeOption() + "] " + 
     373            "series=" + r.getSeries() + " hyper_stack=" + 
     374            options.isViewHyperstack() + " "); 
     375          imp.close(); 
     376        } 
     377        else if (options.isMergeChannels()) { 
     378          IJ.runPlugIn("loci.plugins.Colorizer", "stack_order=" + stackOrder + 
     379            " merge=true series=" + r.getSeries() + " hyper_stack=" + 
     380            options.isViewHyperstack() + " "); 
     381          imp.close(); 
     382        } 
     383      } 
     384    } 
     385  } 
     386   
     387  /** Constructs slice label. */ 
     388  private String constructSliceLabel(int ndx, IFormatReader r, 
     389    IMetadata meta, int series, int zCount, int cCount, int tCount) 
     390  { 
     391    r.setSeries(series); 
     392    int[] zct = r.getZCTCoords(ndx); 
     393    int[] subC = r.getChannelDimLengths(); 
     394    String[] subCTypes = r.getChannelDimTypes(); 
     395    StringBuffer sb = new StringBuffer(); 
     396    boolean first = true; 
     397    if (cCount > 1) { 
     398      if (first) first = false; 
     399      else sb.append("; "); 
     400      int[] subCPos = FormatTools.rasterToPosition(subC, zct[1]); 
     401      for (int i=0; i<subC.length; i++) { 
     402        boolean ch = subCTypes[i].equals(FormatTools.CHANNEL); 
     403        sb.append(ch ? "c" : subCTypes[i]); 
     404        sb.append(":"); 
     405        sb.append(subCPos[i] + 1); 
     406        sb.append("/"); 
     407        sb.append(subC[i]); 
     408        if (i < subC.length - 1) sb.append(", "); 
     409      } 
     410    } 
     411    if (zCount > 1) { 
     412      if (first) first = false; 
     413      else sb.append("; "); 
     414      sb.append("z:"); 
     415      sb.append(zct[0] + 1); 
     416      sb.append("/"); 
     417      sb.append(r.getSizeZ()); 
     418    } 
     419    if (tCount > 1) { 
     420      if (first) first = false; 
     421      else sb.append("; "); 
     422      sb.append("t:"); 
     423      sb.append(zct[2] + 1); 
     424      sb.append("/"); 
     425      sb.append(r.getSizeT()); 
     426    } 
     427    // put image name at the end, in case it is long 
     428    String imageName = meta.getImageName(series); 
     429    if (imageName != null && !imageName.trim().equals("")) { 
     430      sb.append(" - "); 
     431      sb.append(imageName); 
     432    } 
     433    return sb.toString(); 
     434  } 
     435 
     436   
    153437  /** 
    154    * Returns an array of ImageProcessors that represent the given slice. 
    155    * There is one ImageProcessor per RGB channel; 
    156    * i.e., length of returned array == getRGBChannelCount(). 
    157    * 
    158    * @param no Position of image plane. 
    159    * @param crop Image cropping specifications, or null if no cropping 
    160    *   is to be done. 
     438   * Displays the given image stack according to 
     439   * the specified parameters and import options. 
    161440   */ 
    162   public ImageProcessor[] openProcessors(int no, Rectangle crop) 
     441  private void showStack(ImageStack stack, int series, FileInfo fi, 
     442    ImporterOptions options, ArrayList<ImagePlus> imps, 
     443    String stackOrder, IndexColorModel[] colorModels) 
    163444    throws FormatException, IOException 
    164445  { 
    165     // read byte array 
    166     byte[] b = null; 
    167     boolean first = true; 
    168     if (crop == null) crop = new Rectangle(0, 0, getSizeX(), getSizeY()); 
    169     while (true) { 
    170       // read LuraWave license code, if available 
    171       String code = LuraWave.initLicenseCode(); 
     446    if (stack == null) return; 
     447 
     448    String seriesName = options.getOMEMetadata().getImageName(series); 
     449    String file = options.getCurrentFile(); 
     450    IMetadata meta = options.getOMEMetadata(); 
     451    int cCount = options.getCCount(series); 
     452    int zCount = options.getZCount(series); 
     453    int tCount = options.getTCount(series); 
     454    IFormatReader r = options.getReader(); 
     455    int sizeZ = r.getSizeZ(); 
     456    int sizeC = r.getEffectiveSizeC(); 
     457    int sizeT = r.getSizeT(); 
     458    boolean windowless = options.isWindowless(); 
     459 
     460    String title = getTitle(r, file, seriesName, options.isGroupFiles()); 
     461    ImagePlus imp = null; 
     462    if (options.isVirtual()) { 
     463      imp = new VirtualImagePlus(title, stack); 
     464      ((VirtualImagePlus) imp).setReader(r); 
     465    } 
     466    else imp = new ImagePlus(title, stack); 
     467 
     468    // place metadata key/value pairs in ImageJ's info field 
     469    String metadata = options.getOriginalMetadata().toString(); 
     470    imp.setProperty("Info", metadata); 
     471 
     472    // retrieve the spatial calibration information, if available 
     473    ImagePlusTools.applyCalibration(meta, imp, r.getSeries()); 
     474    imp.setFileInfo(fi); 
     475    imp.setDimensions(cCount, zCount, tCount); 
     476 
     477    // display the image stack using the appropriate plugin 
     478 
     479    boolean hyper = options.isViewHyperstack() || options.isViewBrowser(); 
     480    imp.setOpenAsHyperStack(hyper); 
     481    int nSlices = imp.getNSlices(); 
     482    int nFrames = imp.getNFrames(); 
     483 
     484    if (options.isAutoscale() && !options.isVirtual()) { 
     485      ImagePlusTools.adjustColorRange(imp, r); 
     486    } 
     487    else if (!(imp.getProcessor() instanceof ColorProcessor)) { 
     488      // ImageJ may autoscale the images anyway, so we need to manually 
     489      // set the display range to the min/max values allowed for 
     490      // this pixel type 
     491      imp.setDisplayRange(0, Math.pow(2, imp.getBitDepth()) - 1); 
     492    } 
     493 
     494    boolean splitC = options.isSplitChannels(); 
     495    boolean splitZ = options.isSplitFocalPlanes(); 
     496    boolean splitT = options.isSplitTimepoints(); 
     497 
     498    int z = r.getSizeZ(); 
     499    int c = r.getSizeC(); 
     500    int t = r.getSizeT(); 
     501 
     502    if (!options.isConcatenate() && options.isMergeChannels()) imp.show(); 
     503 
     504    if (imp.isVisible() && !options.isVirtual()) { 
     505      String arg = "stack_order=" + stackOrder + " merge=true series=" + 
     506        r.getSeries() + " hyper_stack=" + options.isViewHyperstack(); 
     507      if (windowless) arg += " merge_option=[" + options.getMergeOption() + "]"; 
     508      arg += " "; 
     509      IJ.runPlugIn("loci.plugins.Colorizer", arg); 
     510      if (WindowManager.getCurrentImage().getID() != imp.getID()) { 
     511        imp.close(); 
     512      } 
     513    } 
     514 
     515    imp.setDimensions(imp.getStackSize() / (nSlices * nFrames), 
     516      nSlices, nFrames); 
     517 
     518    if (options.isViewVisBio()) { 
     519      // NB: avoid dependency on optional loci.visbio packages 
     520      ReflectedUniverse ru = new ReflectedUniverse(); 
    172521      try { 
    173         b = openBytes(no, crop.x, crop.y, crop.width, crop.height); 
    174         break; 
    175       } 
    176       catch (FormatException exc) { 
    177         if (LuraWave.isLicenseCodeException(exc)) { 
    178           // prompt user for LuraWave license code 
    179           code = LuraWave.promptLicenseCode(code, first); 
    180           if (code == null) return null; 
    181           if (first) first = false; 
    182         } 
    183         else throw exc; 
    184       } 
    185     } 
    186  
    187     int w = crop.width; 
    188     int h = crop.height; 
    189     int c = getRGBChannelCount(); 
    190     int type = getPixelType(); 
    191     int bpp = FormatTools.getBytesPerPixel(type); 
    192     boolean interleave = isInterleaved(); 
    193  
    194     if (b.length != w * h * c * bpp && b.length != w * h * bpp) { 
    195       throw new FormatException("Invalid byte array length: " + b.length + 
    196         " (expected w=" + w + ", h=" + h + ", c=" + c + ", bpp=" + bpp + ")"); 
    197     } 
    198  
    199     // convert byte array to appropriate primitive array type 
    200     boolean isFloat = FormatTools.isFloatingPoint(type); 
    201     boolean isLittle = isLittleEndian(); 
    202     boolean isSigned = FormatTools.isSigned(type); 
    203  
    204     IndexColorModel cm = null; 
    205     if (isIndexed()) { 
    206       byte[][] byteTable = get8BitLookupTable(); 
    207       if (byteTable != null) { 
    208         cm = new IndexColorModel(8, byteTable[0].length, byteTable[0], 
    209           byteTable[1], byteTable[2]); 
    210       } 
    211       short[][] shortTable = get16BitLookupTable(); 
    212       if (shortTable != null) { 
    213         byteTable = new byte[3][256]; 
    214  
    215         for (int i=0; i<byteTable[0].length; i++) { 
    216           byteTable[0][i] = (byte) shortTable[0][i]; 
    217           byteTable[1][i] = (byte) shortTable[1][i]; 
    218           byteTable[2][i] = (byte) shortTable[2][i]; 
    219         } 
    220  
    221         cm = new IndexColorModel(8, byteTable[0].length, byteTable[0], 
    222           byteTable[1], byteTable[2]); 
    223       } 
    224     } 
    225  
    226     // construct image processors 
    227     ImageProcessor[] ip = new ImageProcessor[c]; 
    228     for (int i=0; i<c; i++) { 
    229       byte[] channel = 
    230         ImageTools.splitChannels(b, i, c, bpp, false, interleave); 
    231       Object pixels = DataTools.makeDataArray(channel, bpp, isFloat, isLittle); 
    232       if (pixels instanceof byte[]) { 
    233         byte[] q = (byte[]) pixels; 
    234         if (q.length != w * h) { 
    235           byte[] tmp = q; 
    236           q = new byte[w * h]; 
    237           System.arraycopy(tmp, 0, q, 0, (int) Math.min(q.length, tmp.length)); 
    238         } 
    239         if (isSigned) q = DataTools.makeSigned(q); 
    240  
    241         ip[i] = new ByteProcessor(w, h, q, null); 
    242         if (cm != null) ip[i].setColorModel(cm); 
    243       } 
    244       else if (pixels instanceof short[]) { 
    245         short[] q = (short[]) pixels; 
    246         if (q.length != w * h) { 
    247           short[] tmp = q; 
    248           q = new short[w * h]; 
    249           System.arraycopy(tmp, 0, q, 0, (int) Math.min(q.length, tmp.length)); 
    250         } 
    251         if (isSigned) q = DataTools.makeSigned(q); 
    252  
    253         ip[i] = new ShortProcessor(w, h, q, cm); 
    254       } 
    255       else if (pixels instanceof int[]) { 
    256         int[] q = (int[]) pixels; 
    257         if (q.length != w * h) { 
    258           int[] tmp = q; 
    259           q = new int[w * h]; 
    260           System.arraycopy(tmp, 0, q, 0, (int) Math.min(q.length, tmp.length)); 
    261         } 
    262  
    263         ip[i] = new FloatProcessor(w, h, q); 
    264       } 
    265       else if (pixels instanceof float[]) { 
    266         float[] q = (float[]) pixels; 
    267         if (q.length != w * h) { 
    268           float[] tmp = q; 
    269           q = new float[w * h]; 
    270           System.arraycopy(tmp, 0, q, 0, (int) Math.min(q.length, tmp.length)); 
    271         } 
    272         ip[i] = new FloatProcessor(w, h, q, null); 
    273       } 
    274       else if (pixels instanceof double[]) { 
    275         double[] q = (double[]) pixels; 
    276         if (q.length != w * h) { 
    277           double[] tmp = q; 
    278           q = new double[w * h]; 
    279           System.arraycopy(tmp, 0, q, 0, (int) Math.min(q.length, tmp.length)); 
    280         } 
    281         ip[i] = new FloatProcessor(w, h, q); 
    282       } 
    283     } 
    284  
    285     return ip; 
     522        ru.exec("import loci.visbio.data.Dataset"); 
     523        //ru.setVar("name", name); 
     524        //ru.setVar("pattern", pattern); 
     525        ru.exec("dataset = new Dataset(name, pattern)"); 
     526        // TODO: finish VisBio logic 
     527      } 
     528      catch (ReflectException exc) { 
     529        WindowTools.reportException(exc, options.isQuiet(), 
     530          "Sorry, there was a problem interfacing with VisBio"); 
     531        return; 
     532      } 
     533    } 
     534    else if (options.isViewImage5D()) { 
     535      ReflectedUniverse ru = new ReflectedUniverse(); 
     536      try { 
     537        ru.exec("import i5d.Image5D"); 
     538        ru.setVar("title", imp.getTitle()); 
     539        ru.setVar("stack", imp.getStack()); 
     540        ru.setVar("sizeC", c); 
     541        ru.setVar("sizeZ", z); 
     542        ru.setVar("sizeT", t); 
     543        ru.exec("i5d = new Image5D(title, stack, sizeC, sizeZ, sizeT)"); 
     544        ru.setVar("cal", imp.getCalibration()); 
     545        ru.setVar("fi", imp.getOriginalFileInfo()); 
     546        ru.exec("i5d.setCalibration(cal)"); 
     547        ru.exec("i5d.setFileInfo(fi)"); 
     548        //ru.exec("i5d.setDimensions(sizeC, sizeZ, sizeT)"); 
     549        ru.exec("i5d.show()"); 
     550      } 
     551      catch (ReflectException exc) { 
     552        WindowTools.reportException(exc, options.isQuiet(), 
     553          "Sorry, there was a problem interfacing with Image5D"); 
     554        return; 
     555      } 
     556    } 
     557    else if (options.isViewView5D()) { 
     558      WindowManager.setTempCurrentImage(imp); 
     559      IJ.run("start viewer", ""); 
     560    } 
     561    else { 
     562      // NB: ImageJ 1.39+ is required for hyperstacks 
     563 
     564      if (!options.isConcatenate()) { 
     565        if (options.isViewBrowser()) { 
     566          DataBrowser dataBrowser = new DataBrowser(imp, null, 
     567            r.getChannelDimTypes(), r.getChannelDimLengths()); 
     568          if (options.isShowOMEXML()) dataBrowser.showMetadataWindow(); 
     569        } 
     570        else if (!imp.isVisible()) imp.show(); 
     571 
     572        boolean customColorize = options.isCustomColorize(); 
     573        boolean browser = options.isViewBrowser(); 
     574        boolean virtual = options.isVirtual(); 
     575 
     576        if (options.isColorize() || customColorize) { 
     577          IJ.runPlugIn("loci.plugins.Colorizer", "stack_order=" + stackOrder + 
     578            " merge=false colorize=true ndx=" + (customColorize ? "-1" : "0") + 
     579            " series=" + r.getSeries() + " hyper_stack=" + 
     580            options.isViewHyperstack() + " "); 
     581          imp.close(); 
     582        } 
     583        else if (colorModels != null && !browser && !virtual) { 
     584          Colorizer colorizer = new Colorizer(); 
     585          String arg = "stack_order=" + stackOrder + " merge=false " + 
     586            "colorize=true series=" + r.getSeries() + " hyper_stack=" + 
     587            hyper + " "; 
     588          colorizer.setup(arg, imp); 
     589          for (int channel=0; channel<colorModels.length; channel++) { 
     590            byte[][] lut = new byte[3][256]; 
     591            colorModels[channel].getReds(lut[0]); 
     592            colorModels[channel].getGreens(lut[1]); 
     593            colorModels[channel].getBlues(lut[2]); 
     594            colorizer.setLookupTable(lut, channel); 
     595          } 
     596          new PlugInFilterRunner(colorizer, "", arg); 
     597          imp.close(); 
     598        } 
     599 
     600        if (splitC || splitZ || splitT) { 
     601          IJ.runPlugIn("loci.plugins.Slicer", "slice_z=" + splitZ + 
     602            " slice_c=" + splitC + " slice_t=" + splitT + 
     603            " stack_order=" + stackOrder + " keep_original=false " + 
     604            "hyper_stack=" + hyper + " "); 
     605          imp.close(); 
     606        } 
     607      } 
     608      imps.add(imp); 
     609    } 
    286610  } 
    287611 
     612  /** Get an appropriate stack title, given the file name. */ 
     613  private String getTitle(IFormatReader r, String file, String seriesName, 
     614    boolean groupFiles) 
     615  { 
     616    String[] used = r.getUsedFiles(); 
     617    String title = file.substring(file.lastIndexOf(File.separator) + 1); 
     618    if (used.length > 1 && groupFiles) { 
     619      FilePattern fp = new FilePattern(new Location(file)); 
     620      if (fp != null) { 
     621        title = fp.getPattern(); 
     622        if (title == null) { 
     623          title = file; 
     624          if (title.indexOf(".") != -1) { 
     625            title = title.substring(0, title.lastIndexOf(".")); 
     626          } 
     627        } 
     628        title = title.substring(title.lastIndexOf(File.separator) + 1); 
     629      } 
     630    } 
     631    if (seriesName != null && !file.endsWith(seriesName) && 
     632      r.getSeriesCount() > 1) 
     633    { 
     634      title += " - " + seriesName; 
     635    } 
     636    if (title.length() > 128) { 
     637      String a = title.substring(0, 62); 
     638      String b = title.substring(title.length() - 62); 
     639      title = a + "..." + b; 
     640    } 
     641    return title; 
     642  } 
     643 
    288644} 
  • trunk/components/loci-plugins/src/loci/plugins/importer/Importer.java

    r6128 r6130  
    2929import ij.ImageJ; 
    3030import ij.ImagePlus; 
    31 import ij.ImageStack; 
    32 import ij.WindowManager; 
    33 import ij.io.FileInfo; 
    34 import ij.plugin.filter.PlugInFilterRunner; 
    35 import ij.process.ByteProcessor; 
    36 import ij.process.ColorProcessor; 
    37 import ij.process.FloatProcessor; 
    38 import ij.process.ImageProcessor; 
    39 import ij.process.ShortProcessor; 
    40  
    41 import java.awt.Rectangle; 
     31 
    4232import java.awt.image.IndexColorModel; 
    43 import java.io.File; 
    4433import java.io.IOException; 
    4534import java.util.ArrayList; 
     
    4736import javax.xml.parsers.ParserConfigurationException; 
    4837 
    49 import loci.common.Location; 
    50 import loci.common.ReflectException; 
    51 import loci.common.ReflectedUniverse; 
    5238import loci.common.services.DependencyException; 
    5339import loci.common.services.ServiceException; 
    5440import loci.common.services.ServiceFactory; 
    55 import loci.formats.ChannelMerger; 
    56 import loci.formats.FilePattern; 
    5741import loci.formats.FormatException; 
    58 import loci.formats.FormatTools; 
    59 import loci.formats.IFormatReader; 
    6042import loci.formats.gui.XMLWindow; 
    61 import loci.formats.meta.IMetadata; 
    6243import loci.formats.services.OMEXMLService; 
    63 import loci.plugins.Colorizer; 
    6444import loci.plugins.LociImporter; 
    6545import loci.plugins.util.BF; 
    66 import loci.plugins.util.BFVirtualStack; 
    67 import loci.plugins.util.DataBrowser; 
    68 import loci.plugins.util.ImagePlusReader; 
    69 import loci.plugins.util.ImagePlusTools; 
    7046import loci.plugins.util.ROIHandler; 
    71 import loci.plugins.util.VirtualImagePlus; 
    72 import loci.plugins.util.VirtualReader; 
    7347import loci.plugins.util.WindowTools; 
    7448 
     
    221195    throws FormatException, IOException 
    222196  { 
    223     ImagePlusReader r = options.getReader(); 
    224  
    225     if (options.isVirtual()) { 
    226       int totalSeries = 0; 
    227       for (int s=0; s<r.getSeriesCount(); s++) { 
    228         if (options.isSeriesOn(s)) totalSeries++; 
    229       } 
    230       ((VirtualReader) r.getReader()).setRefCount(totalSeries); 
    231     } 
    232  
    233     for (int s=0; s<r.getSeriesCount(); s++) { 
    234       if (!options.isSeriesOn(s)) continue; 
    235       r.setSeries(s); 
    236  
    237       boolean[] load = new boolean[r.getImageCount()]; 
    238       int cBegin = options.getCBegin(s); 
    239       int cEnd = options.getCEnd(s); 
    240       int cStep = options.getCStep(s); 
    241       int zBegin = options.getZBegin(s); 
    242       int zEnd = options.getZEnd(s); 
    243       int zStep = options.getZStep(s); 
    244       int tBegin = options.getTBegin(s); 
    245       int tEnd = options.getTEnd(s); 
    246       int tStep = options.getTStep(s); 
    247       for (int c=cBegin; c<=cEnd; c+=cStep) { 
    248         for (int z=zBegin; z<=zEnd; z+=zStep) { 
    249           for (int t=tBegin; t<=tEnd; t+=tStep) { 
    250             //int index = r.isOrderCertain() ? r.getIndex(z, c, t) : c; 
    251             int index = r.getIndex(z, c, t); 
    252             load[index] = true; 
    253           } 
    254         } 
    255       } 
    256       int total = 0; 
    257       for (int j=0; j<r.getImageCount(); j++) if (load[j]) total++; 
    258  
    259       FileInfo fi = new FileInfo(); 
    260  
    261       // populate other common FileInfo fields 
    262       String idDir = options.getIdLocation() == null ? 
    263         null : options.getIdLocation().getParent(); 
    264       if (idDir != null && !idDir.endsWith(File.separator)) { 
    265         idDir += File.separator; 
    266       } 
    267       fi.fileName = options.getIdName(); 
    268       fi.directory = idDir; 
    269  
    270       long startTime = System.currentTimeMillis(); 
    271       long time = startTime; 
    272  
    273       ImageStack stackB = null; // for byte images (8-bit) 
    274       ImageStack stackS = null; // for short images (16-bit) 
    275       ImageStack stackF = null; // for floating point images (32-bit) 
    276       ImageStack stackO = null; // for all other images (24-bit RGB) 
    277  
    278       Rectangle cropRegion = options.getCropRegion(s); 
    279       int w = options.doCrop() ? cropRegion.width : r.getSizeX(); 
    280       int h = options.doCrop() ? cropRegion.height : r.getSizeY(); 
    281       int c = r.getRGBChannelCount(); 
    282       int type = r.getPixelType(); 
    283  
    284       int q = 0; 
    285       stackOrder = options.getStackOrder(); 
    286       if (stackOrder.equals(ImporterOptions.ORDER_DEFAULT)) { 
    287         stackOrder = r.getDimensionOrder(); 
    288       } 
    289       ((VirtualReader) r.getReader()).setOutputOrder(stackOrder); 
    290  
    291       options.getOMEMetadata().setPixelsDimensionOrder(stackOrder, s, 0); 
    292  
    293       // dump OME-XML to ImageJ's description field, if available 
    294  
    295       try { 
    296         ServiceFactory factory = new ServiceFactory(); 
    297         OMEXMLService service = factory.getInstance(OMEXMLService.class); 
    298         fi.description = service.getOMEXML(options.getOMEMetadata()); 
    299       } 
    300       catch (DependencyException de) { } 
    301       catch (ServiceException se) { } 
    302  
    303       if (options.isVirtual()) { 
    304         int cSize = r.getSizeC(); 
    305         int pt = r.getPixelType(); 
    306         boolean doMerge = options.isMergeChannels(); 
    307         boolean eight = pt != FormatTools.UINT8 && pt != FormatTools.INT8; 
    308         boolean needComposite = doMerge && (cSize > 3 || eight); 
    309         int merge = (needComposite || !doMerge) ? 1 : cSize; 
    310  
    311         r.setSeries(s); 
    312         // NB: ImageJ 1.39+ is required for VirtualStack 
    313         BFVirtualStack virtualStackB = new BFVirtualStack(options.getId(), 
    314           r, options.isColorize(), doMerge, options.isRecord()); 
    315         stackB = virtualStackB; 
    316         if (doMerge) { 
    317           for (int j=0; j<r.getImageCount(); j++) { 
    318             int[] pos = r.getZCTCoords(j); 
    319             if (pos[1] > 0) continue; 
    320             String label = constructSliceLabel( 
    321               new ChannelMerger(r).getIndex(pos[0], pos[1], pos[2]), 
    322               new ChannelMerger(r), options.getOMEMetadata(), s, 
    323               options.getZCount(s), options.getCCount(s), 
    324               options.getTCount(s)); 
    325             virtualStackB.addSlice(label); 
    326           } 
    327         } 
    328         else { 
    329           for (int j=0; j<r.getImageCount(); j++) { 
    330             String label = constructSliceLabel(j, r, 
    331               options.getOMEMetadata(), s, options.getZCount(s), 
    332               options.getCCount(s), options.getTCount(s)); 
    333             virtualStackB.addSlice(label); 
    334           } 
    335         } 
    336       } 
    337       else { 
    338         if (r.isIndexed()) colorModels = new IndexColorModel[r.getSizeC()]; 
    339  
    340         for (int i=0; i<r.getImageCount(); i++) { 
    341           if (!load[i]) continue; 
    342  
    343           // limit message update rate 
    344           long clock = System.currentTimeMillis(); 
    345           if (clock - time >= 100) { 
    346             String sLabel = r.getSeriesCount() > 1 ? 
    347               ("series " + (s + 1) + ", ") : ""; 
    348             String pLabel = "plane " + (i + 1) + "/" + total; 
    349             IJ.showStatus("Reading " + sLabel + pLabel); 
    350             time = clock; 
    351           } 
    352           IJ.showProgress((double) q++ / total); 
    353  
    354           String label = constructSliceLabel(i, r, 
    355             options.getOMEMetadata(), s, options.getZCount(s), 
    356             options.getCCount(s), options.getTCount(s)); 
    357  
    358           // get image processor for ith plane 
    359           ImageProcessor[] p = r.openProcessors(i, cropRegion); 
    360           ImageProcessor ip = p[0]; 
    361           if (p.length > 1) { 
    362             ip = ImagePlusTools.makeRGB(p).getProcessor(); 
    363           } 
    364           if (ip == null) { 
    365             plugin.canceled = true; 
    366             return; 
    367           } 
    368  
    369           int channel = r.getZCTCoords(i)[1]; 
    370           if (colorModels != null && p.length == 1) { 
    371             colorModels[channel] = (IndexColorModel) ip.getColorModel(); 
    372           } 
    373  
    374           // add plane to image stack 
    375           if (ip instanceof ByteProcessor) { 
    376             if (stackB == null) stackB = new ImageStack(w, h); 
    377             stackB.addSlice(label, ip); 
    378           } 
    379           else if (ip instanceof ShortProcessor) { 
    380             if (stackS == null) stackS = new ImageStack(w, h); 
    381             stackS.addSlice(label, ip); 
    382           } 
    383           else if (ip instanceof FloatProcessor) { 
    384             // merge image plane into existing stack if possible 
    385             if (stackB != null) { 
    386               ip = ip.convertToByte(true); 
    387               stackB.addSlice(label, ip); 
    388             } 
    389             else if (stackS != null) { 
    390               ip = ip.convertToShort(true); 
    391               stackS.addSlice(label, ip); 
    392             } 
    393             else { 
    394               if (stackF == null) stackF = new ImageStack(w, h); 
    395               stackF.addSlice(label, ip); 
    396             } 
    397           } 
    398           else if (ip instanceof ColorProcessor) { 
    399             if (stackO == null) stackO = new ImageStack(w, h); 
    400             stackO.addSlice(label, ip); 
    401           } 
    402         } 
    403       } 
    404  
    405       IJ.showStatus("Creating image"); 
    406       IJ.showProgress(1); 
    407  
    408       showStack(stackB, s, fi, options); 
    409       showStack(stackS, s, fi, options); 
    410       showStack(stackF, s, fi, options); 
    411       showStack(stackO, s, fi, options); 
    412  
    413       long endTime = System.currentTimeMillis(); 
    414       double elapsed = (endTime - startTime) / 1000.0; 
    415       if (r.getImageCount() == 1) { 
    416         IJ.showStatus("Bio-Formats: " + elapsed + " seconds"); 
    417       } 
    418       else { 
    419         long average = (endTime - startTime) / r.getImageCount(); 
    420         IJ.showStatus("Bio-Formats: " + elapsed + " seconds (" + 
    421           average + " ms per plane)"); 
    422       } 
    423     } 
    424  
    425     if (options.isConcatenate()) { 
    426       ArrayList<Integer> widths = new ArrayList<Integer>(); 
    427       ArrayList<Integer> heights = new ArrayList<Integer>(); 
    428       ArrayList<Integer> types = new ArrayList<Integer>(); 
    429       ArrayList<ImagePlus> newImps = new ArrayList<ImagePlus>(); 
    430  
    431       for (int j=0; j<imps.size(); j++) { 
    432         ImagePlus imp = imps.get(j); 
    433         int wj = imp.getWidth(); 
    434         int hj = imp.getHeight(); 
    435         int tj = imp.getBitDepth(); 
    436         boolean append = false; 
    437         for (int k=0; k<widths.size(); k++) { 
    438           int wk = ((Integer) widths.get(k)).intValue(); 
    439           int hk = ((Integer) heights.get(k)).intValue(); 
    440           int tk = ((Integer) types.get(k)).intValue(); 
    441  
    442           if (wj == wk && hj == hk && tj == tk) { 
    443             ImagePlus oldImp = newImps.get(k); 
    444             ImageStack is = oldImp.getStack(); 
    445             ImageStack newStack = imp.getStack(); 
    446             for (int s=0; s<newStack.getSize(); s++) { 
    447               is.addSlice(newStack.getSliceLabel(s + 1), 
    448                 newStack.getProcessor(s + 1)); 
    449             } 
    450             oldImp.setStack(oldImp.getTitle(), is); 
    451             newImps.set(k, oldImp); 
    452             append = true; 
    453             k = widths.size(); 
    454           } 
    455         } 
    456         if (!append) { 
    457           widths.add(new Integer(wj)); 
    458           heights.add(new Integer(hj)); 
    459           types.add(new Integer(tj)); 
    460           newImps.add(imp); 
    461         } 
    462       } 
    463  
    464       boolean splitC = options.isSplitChannels(); 
    465       boolean splitZ = options.isSplitFocalPlanes(); 
    466       boolean splitT = options.isSplitTimepoints(); 
    467  
    468       for (int j=0; j<newImps.size(); j++) { 
    469         ImagePlus imp = (ImagePlus) newImps.get(j); 
    470         imp.show(); 
    471         if (splitC || splitZ || splitT) { 
    472           IJ.runPlugIn("loci.plugins.Slicer", "slice_z=" + splitZ + 
    473             " slice_c=" + splitC + " slice_t=" + splitT + 
    474             " stack_order=" + stackOrder + " keep_original=false " + 
    475             "hyper_stack=" + options.isViewHyperstack() + " "); 
    476           imp.close(); 
    477         } 
    478         if (options.isMergeChannels() && options.isWindowless()) { 
    479           IJ.runPlugIn("loci.plugins.Colorizer", "stack_order=" + stackOrder + 
    480             " merge=true merge_option=[" + options.getMergeOption() + "] " + 
    481             "series=" + r.getSeries() + " hyper_stack=" + 
    482             options.isViewHyperstack() + " "); 
    483           imp.close(); 
    484         } 
    485         else if (options.isMergeChannels()) { 
    486           IJ.runPlugIn("loci.plugins.Colorizer", "stack_order=" + stackOrder + 
    487             " merge=true series=" + r.getSeries() + " hyper_stack=" + 
    488             options.isViewHyperstack() + " "); 
    489           imp.close(); 
    490         } 
    491       } 
    492     } 
     197    ImagePlusReader ipr = new ImagePlusReader(options); 
     198    ipr.openImagePlus(); 
     199    // TODO - migrate display logic here 
    493200  } 
    494201 
     
    506213    if (!options.isVirtual()) options.getReader().close(); 
    507214    plugin.success = true; 
    508   } 
    509  
    510   // -- Helper methods -- 
    511  
    512   /** 
    513    * Displays the given image stack according to 
    514    * the specified parameters and import options. 
    515    */ 
    516   private void showStack(ImageStack stack, int series, FileInfo fi, 
    517     ImporterOptions options) throws FormatException, IOException 
    518   { 
    519     if (stack == null) return; 
    520  
    521     String seriesName = options.getOMEMetadata().getImageName(series); 
    522     String file = options.getCurrentFile(); 
    523     IMetadata meta = options.getOMEMetadata(); 
    524     int cCount = options.getCCount(series); 
    525     int zCount = options.getZCount(series); 
    526     int tCount = options.getTCount(series); 
    527     IFormatReader r = options.getReader(); 
    528     int sizeZ = r.getSizeZ(); 
    529     int sizeC = r.getEffectiveSizeC(); 
    530     int sizeT = r.getSizeT(); 
    531     boolean windowless = options.isWindowless(); 
    532  
    533     String title = getTitle(r, file, seriesName, options.isGroupFiles()); 
    534     ImagePlus imp = null; 
    535     if (options.isVirtual()) { 
    536       imp = new VirtualImagePlus(title, stack); 
    537       ((VirtualImagePlus) imp).setReader(r); 
    538     } 
    539     else imp = new ImagePlus(title, stack); 
    540  
    541     // place metadata key/value pairs in ImageJ's info field 
    542     String metadata = options.getOriginalMetadata().toString(); 
    543     imp.setProperty("Info", metadata); 
    544  
    545     // retrieve the spatial calibration information, if available 
    546     ImagePlusTools.applyCalibration(meta, imp, r.getSeries()); 
    547     imp.setFileInfo(fi); 
    548     imp.setDimensions(cCount, zCount, tCount); 
    549  
    550     // display the image stack using the appropriate plugin 
    551  
    552     boolean hyper = options.isViewHyperstack() || options.isViewBrowser(); 
    553     imp.setOpenAsHyperStack(hyper); 
    554     int nSlices = imp.getNSlices(); 
    555     int nFrames = imp.getNFrames(); 
    556  
    557     if (options.isAutoscale() && !options.isVirtual()) { 
    558       ImagePlusTools.adjustColorRange(imp, r); 
    559     } 
    560     else if (!(imp.getProcessor() instanceof ColorProcessor)) { 
    561       // ImageJ may autoscale the images anyway, so we need to manually 
    562       // set the display range to the min/max values allowed for 
    563       // this pixel type 
    564       imp.setDisplayRange(0, Math.pow(2, imp.getBitDepth()) - 1); 
    565     } 
    566  
    567     boolean splitC = options.isSplitChannels(); 
    568     boolean splitZ = options.isSplitFocalPlanes(); 
    569     boolean splitT = options.isSplitTimepoints(); 
    570  
    571     int z = r.getSizeZ(); 
    572     int c = r.getSizeC(); 
    573     int t = r.getSizeT(); 
    574  
    575     if (!options.isConcatenate() && options.isMergeChannels()) imp.show(); 
    576  
    577     if (imp.isVisible() && !options.isVirtual()) { 
    578       String arg = "stack_order=" + stackOrder + " merge=true series=" + 
    579         r.getSeries() + " hyper_stack=" + options.isViewHyperstack(); 
    580       if (windowless) arg += " merge_option=[" + options.getMergeOption() + "]"; 
    581       arg += " "; 
    582       IJ.runPlugIn("loci.plugins.Colorizer", arg); 
    583       if (WindowManager.getCurrentImage().getID() != imp.getID()) { 
    584         imp.close(); 
    585       } 
    586     } 
    587  
    588     imp.setDimensions(imp.getStackSize() / (nSlices * nFrames), 
    589       nSlices, nFrames); 
    590  
    591     if (options.isViewVisBio()) { 
    592       // NB: avoid dependency on optional loci.visbio packages 
    593       ReflectedUniverse ru = new ReflectedUniverse(); 
    594       try { 
    595         ru.exec("import loci.visbio.data.Dataset"); 
    596         //ru.setVar("name", name); 
    597         //ru.setVar("pattern", pattern); 
    598         ru.exec("dataset = new Dataset(name, pattern)"); 
    599         // TODO: finish VisBio logic 
    600       } 
    601       catch (ReflectException exc) { 
    602         WindowTools.reportException(exc, options.isQuiet(), 
    603           "Sorry, there was a problem interfacing with VisBio"); 
    604         return; 
    605       } 
    606     } 
    607     else if (options.isViewImage5D()) { 
    608       ReflectedUniverse ru = new ReflectedUniverse(); 
    609       try { 
    610         ru.exec("import i5d.Image5D"); 
    611         ru.setVar("title", imp.getTitle()); 
    612         ru.setVar("stack", imp.getStack()); 
    613         ru.setVar("sizeC", c); 
    614         ru.setVar("sizeZ", z); 
    615         ru.setVar("sizeT", t); 
    616         ru.exec("i5d = new Image5D(title, stack, sizeC, sizeZ, sizeT)"); 
    617         ru.setVar("cal", imp.getCalibration()); 
    618         ru.setVar("fi", imp.getOriginalFileInfo()); 
    619         ru.exec("i5d.setCalibration(cal)"); 
    620         ru.exec("i5d.setFileInfo(fi)"); 
    621         //ru.exec("i5d.setDimensions(sizeC, sizeZ, sizeT)"); 
    622         ru.exec("i5d.show()"); 
    623       } 
    624       catch (ReflectException exc) { 
    625         WindowTools.reportException(exc, options.isQuiet(), 
    626           "Sorry, there was a problem interfacing with Image5D"); 
    627         return; 
    628       } 
    629     } 
    630     else if (options.isViewView5D()) { 
    631       WindowManager.setTempCurrentImage(imp); 
    632       IJ.run("start viewer", ""); 
    633     } 
    634     else { 
    635       // NB: ImageJ 1.39+ is required for hyperstacks 
    636  
    637       if (!options.isConcatenate()) { 
    638         if (options.isViewBrowser()) { 
    639           DataBrowser dataBrowser = new DataBrowser(imp, null, 
    640             r.getChannelDimTypes(), r.getChannelDimLengths()); 
    641           if (options.isShowOMEXML()) dataBrowser.showMetadataWindow(); 
    642         } 
    643         else if (!imp.isVisible()) imp.show(); 
    644  
    645         boolean customColorize = options.isCustomColorize(); 
    646         boolean browser = options.isViewBrowser(); 
    647         boolean virtual = options.isVirtual(); 
    648  
    649         if (options.isColorize() || customColorize) { 
    650           IJ.runPlugIn("loci.plugins.Colorizer", "stack_order=" + stackOrder + 
    651             " merge=false colorize=true ndx=" + (customColorize ? "-1" : "0") + 
    652             " series=" + r.getSeries() + " hyper_stack=" + 
    653             options.isViewHyperstack() + " "); 
    654           imp.close(); 
    655         } 
    656         else if (colorModels != null && !browser && !virtual) { 
    657           Colorizer colorizer = new Colorizer(); 
    658           String arg = "stack_order=" + stackOrder + " merge=false " + 
    659             "colorize=true series=" + r.getSeries() + " hyper_stack=" + 
    660             hyper + " "; 
    661           colorizer.setup(arg, imp); 
    662           for (int channel=0; channel<colorModels.length; channel++) { 
    663             byte[][] lut = new byte[3][256]; 
    664             colorModels[channel].getReds(lut[0]); 
    665             colorModels[channel].getGreens(lut[1]); 
    666             colorModels[channel].getBlues(lut[2]); 
    667             colorizer.setLookupTable(lut, channel); 
    668           } 
    669           new PlugInFilterRunner(colorizer, "", arg); 
    670           imp.close(); 
    671         } 
    672  
    673         if (splitC || splitZ || splitT) { 
    674           IJ.runPlugIn("loci.plugins.Slicer", "slice_z=" + splitZ + 
    675             " slice_c=" + splitC + " slice_t=" + splitT + 
    676             " stack_order=" + stackOrder + " keep_original=false " + 
    677             "hyper_stack=" + hyper + " "); 
    678           imp.close(); 
    679         } 
    680       } 
    681       imps.add(imp); 
    682     } 
    683   } 
    684  
    685   /** Get an appropriate stack title, given the file name. */ 
    686   private String getTitle(IFormatReader r, String file, String seriesName, 
    687     boolean groupFiles) 
    688   { 
    689     String[] used = r.getUsedFiles(); 
    690     String title = file.substring(file.lastIndexOf(File.separator) + 1); 
    691     if (used.length > 1 && groupFiles) { 
    692       FilePattern fp = new FilePattern(new Location(file)); 
    693       if (fp != null) { 
    694         title = fp.getPattern(); 
    695         if (title == null) { 
    696           title = file; 
    697           if (title.indexOf(".") != -1) { 
    698             title = title.substring(0, title.lastIndexOf(".")); 
    699           } 
    700         } 
    701         title = title.substring(title.lastIndexOf(File.separator) + 1); 
    702       } 
    703     } 
    704     if (seriesName != null && !file.endsWith(seriesName) && 
    705       r.getSeriesCount() > 1) 
    706     { 
    707       title += " - " + seriesName; 
    708     } 
    709     if (title.length() > 128) { 
    710       String a = title.substring(0, 62); 
    711       String b = title.substring(title.length() - 62); 
    712       title = a + "..." + b; 
    713     } 
    714     return title; 
    715   } 
    716  
    717   /** Constructs slice label. */ 
    718   private String constructSliceLabel(int ndx, IFormatReader r, 
    719     IMetadata meta, int series, int zCount, int cCount, int tCount) 
    720   { 
    721     r.setSeries(series); 
    722     int[] zct = r.getZCTCoords(ndx); 
    723     int[] subC = r.getChannelDimLengths(); 
    724     String[] subCTypes = r.getChannelDimTypes(); 
    725     StringBuffer sb = new StringBuffer(); 
    726     boolean first = true; 
    727     if (cCount > 1) { 
    728       if (first) first = false; 
    729       else sb.append("; "); 
    730       int[] subCPos = FormatTools.rasterToPosition(subC, zct[1]); 
    731       for (int i=0; i<subC.length; i++) { 
    732         boolean ch = subCTypes[i].equals(FormatTools.CHANNEL); 
    733         sb.append(ch ? "c" : subCTypes[i]); 
    734         sb.append(":"); 
    735         sb.append(subCPos[i] + 1); 
    736         sb.append("/"); 
    737         sb.append(subC[i]); 
    738         if (i < subC.length - 1) sb.append(", "); 
    739       } 
    740     } 
    741     if (zCount > 1) { 
    742       if (first) first = false; 
    743       else sb.append("; "); 
    744       sb.append("z:"); 
    745       sb.append(zct[0] + 1); 
    746       sb.append("/"); 
    747       sb.append(r.getSizeZ()); 
    748     } 
    749     if (tCount > 1) { 
    750       if (first) first = false; 
    751       else sb.append("; "); 
    752       sb.append("t:"); 
    753       sb.append(zct[2] + 1); 
    754       sb.append("/"); 
    755       sb.append(r.getSizeT()); 
    756     } 
    757     // put image name at the end, in case it is long 
    758     String imageName = meta.getImageName(series); 
    759     if (imageName != null && !imageName.trim().equals("")) { 
    760       sb.append(" - "); 
    761       sb.append(imageName); 
    762     } 
    763     return sb.toString(); 
    764215  } 
    765216 
  • trunk/components/loci-plugins/src/loci/plugins/importer/ImporterOptions.java

    r6128 r6130  
    4040import loci.plugins.prefs.StringOption; 
    4141import loci.plugins.util.BF; 
    42 import loci.plugins.util.ImagePlusReader; 
     42import loci.plugins.util.ImageProcessorReader; 
    4343import loci.plugins.util.LibraryChecker; 
    4444 
     
    420420  public Location getIdLocation() { return reader.idLoc; } 
    421421  public String getCurrentFile() { return reader.currentFile; } 
    422   public ImagePlusReader getReader() { return reader.r; } 
     422  public ImageProcessorReader getReader() { return reader.r; } 
    423423  public IMetadata getOMEMetadata() { return reader.meta; } 
    424424  public ImporterMetadata getOriginalMetadata() { return metadata; } 
  • trunk/components/loci-plugins/src/loci/plugins/importer/ImporterReader.java

    r6026 r6130  
    4545import loci.formats.services.OMEXMLService; 
    4646import loci.plugins.util.IJStatusEchoer; 
    47 import loci.plugins.util.ImagePlusReader; 
     47import loci.plugins.util.ImageProcessorReader; 
    4848import loci.plugins.util.LociPrefs; 
    4949import loci.plugins.util.VirtualReader; 
     
    7272  protected String currentFile; 
    7373 
    74   protected ImagePlusReader r; 
     74  protected ImageProcessorReader r; 
    7575  protected VirtualReader virtualReader; 
    7676 
     
    115115    } 
    116116    virtualReader = new VirtualReader(baseReader); 
    117     r = new ImagePlusReader(virtualReader); 
     117    r = new ImageProcessorReader(virtualReader); 
    118118    r.setId(options.getId()); 
    119119  } 
     
    161161    if (options.isLocal() || options.isHTTP()) { 
    162162      if (!options.isQuiet()) IJ.showStatus("Identifying " + idName); 
    163       ImageReader reader = ImagePlusReader.makeImageReader(); 
     163      ImageReader reader = ImageProcessorReader.makeImageReader(); 
    164164      try { baseReader = reader.getReader(options.getId()); } 
    165165      catch (FormatException exc) { 
  • trunk/components/loci-plugins/src/loci/plugins/macro/LociFunctions.java

    r6128 r6130  
    4343import loci.formats.meta.MetadataRetrieve; 
    4444import loci.formats.services.OMEXMLService; 
    45 import loci.plugins.util.ImagePlusReader; 
     45import loci.plugins.util.ImageProcessorReader; 
    4646import loci.plugins.util.ImagePlusTools; 
    4747 
     
    6868  // -- Fields -- 
    6969 
    70   private ImagePlusReader r; 
     70  private ImageProcessorReader r; 
    7171 
    7272  // -- Constructor -- 
    7373 
    7474  public LociFunctions() { 
    75     r = new ImagePlusReader(new ChannelSeparator( 
    76       new FileStitcher(ImagePlusReader.makeImageReader(), true))); 
     75    r = new ImageProcessorReader(new ChannelSeparator( 
     76      new FileStitcher(ImageProcessorReader.makeImageReader(), true))); 
    7777    try { 
    7878      ServiceFactory factory = new ServiceFactory(); 
  • trunk/components/loci-plugins/src/loci/plugins/util/BFVirtualStack.java

    r5144 r6130  
    5555  // -- Fields -- 
    5656 
    57   protected ImagePlusReader reader; 
     57  protected ImageProcessorReader reader; 
    5858  protected String id; 
    5959  protected Cache cache; 
     
    9494  { 
    9595    super(getWidth(r, path), getHeight(r, path), null, path); 
    96     reader = new ImagePlusReader(r); 
     96    reader = new ImageProcessorReader(r); 
    9797    id = path; 
    9898 
     
    124124  public String getPath() { return id; } 
    125125 
    126   public ImagePlusReader getReader() { return reader; } 
     126  public ImageProcessorReader getReader() { return reader; } 
    127127 
    128128  public Cache getCache() { return cache; } 
  • trunk/components/loci-plugins/src/loci/plugins/util/ImageProcessorReader.java

    r6128 r6130  
    11// 
    2 // ImagePlusReader.java 
     2// ImageProcessorReader.java 
    33// 
    44 
     
    5050 
    5151/** 
    52  * Bio-Formats reader for reading ImagePlus objects. 
     52 * A low-level reader for {@link ij.process.ImageProcessor} objects. 
     53 * For a higher-level reader that returns {@link ij.ImagePlus} objects, 
     54 * see {@link loci.plugins.importer.ImagePlusReader} instead. 
    5355 * 
    5456 * <dl><dt><b>Source code:</b></dt> 
    55  * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/loci-plugins/src/loci/plugins/util/ImagePlusReader.java">Trac</a>, 
    56  * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/components/loci-plugins/src/loci/plugins/util/ImagePlusReader.java">SVN</a></dd></dl> 
     57 * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/loci-plugins/src/loci/plugins/util/ImageProcessorReader.java">Trac</a>, 
     58 * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/components/loci-plugins/src/loci/plugins/util/ImageProcessorReader.java">SVN</a></dd></dl> 
    5759 */ 
    58 public class ImagePlusReader extends MinMaxCalculator { 
     60public class ImageProcessorReader extends MinMaxCalculator { 
    5961 
    6062  // -- Utility methods -- 
    6163 
    62   /** Converts the given reader into a ImagePlusReader, wrapping if needed. */ 
    63   public static ImagePlusReader makeImagePlusReader(IFormatReader r) { 
    64     if (r instanceof ImagePlusReader) return (ImagePlusReader) r; 
    65     return new ImagePlusReader(r); 
     64  /** Converts the given reader into a ImageProcessorReader, wrapping if needed. */ 
     65  public static ImageProcessorReader makeImageProcessorReader(IFormatReader r) { 
     66    if (r instanceof ImageProcessorReader) return (ImageProcessorReader) r; 
     67    return new ImageProcessorReader(r); 
    6668  } 
    6769 
     
    7375  public static ImageReader makeImageReader() { 
    7476    // include only enabled classes 
    75     Class[] c = null; 
     77    Class<?>[] c = null; 
    7678    try { 
    7779      ClassList defaultClasses = 
     
    131133  // -- Constructors -- 
    132134 
    133   /** Constructs an ImagePlusReader around a new image reader. */ 
    134   public ImagePlusReader() { super(makeImageReader()); } 
    135  
    136   /** Constructs an ImagePlusReader with the given reader. */ 
    137   public ImagePlusReader(IFormatReader r) { super(r); } 
    138  
    139   // -- ImagePlusReader methods -- 
     135  /** Constructs an ImageProcessorReader around a new image reader. */ 
     136  public ImageProcessorReader() { super(makeImageReader()); } 
     137 
     138  /** Constructs an ImageProcessorReader with the given reader. */ 
     139  public ImageProcessorReader(IFormatReader r) { super(r); } 
     140 
     141  // -- ImageProcessorReader methods -- 
    140142 
    141143  /** 
  • trunk/components/loci-plugins/src/loci/plugins/util/ImageProcessorSource.java

    r5191 r6130  
    4747 
    4848  /** Image reader from which to draw ImageProcessors. */ 
    49   protected ImagePlusReader reader; 
     49  protected ImageProcessorReader reader; 
    5050 
    5151  // -- Constructors -- 
    5252 
    5353  public ImageProcessorSource(IFormatReader reader) throws CacheException { 
    54     if (reader instanceof ImagePlusReader) { 
    55       this.reader = (ImagePlusReader) reader; 
     54    if (reader instanceof ImageProcessorReader) { 
     55      this.reader = (ImageProcessorReader) reader; 
    5656    } 
    5757    else { 
    58       this.reader = new ImagePlusReader(reader); 
     58      this.reader = new ImageProcessorReader(reader); 
    5959    } 
    6060  } 
  • trunk/components/loci-plugins/utils/Read_Image.java

    r5999 r6130  
    1515import loci.formats.FormatException; 
    1616import loci.formats.IFormatReader; 
    17 import loci.plugins.util.ImagePlusReader; 
     17import loci.plugins.util.ImageProcessorReader; 
    1818 
    1919/** A very simple example of using Bio-Formats in an ImageJ plugin. */ 
     
    2424    String name = od.getFileName(); 
    2525    String id = dir + name; 
    26     ImagePlusReader r = new ImagePlusReader( 
    27       new ChannelSeparator(ImagePlusReader.makeImageReader())); 
     26    ImageProcessorReader r = new ImageProcessorReader( 
     27      new ChannelSeparator(ImageProcessorReader.makeImageReader())); 
    2828    try { 
    2929      IJ.showStatus("Examining file " + name); 
Note: See TracChangeset for help on using the changeset viewer.