Ignore:
Timestamp:
06/11/10 10:43:11 (10 years ago)
Author:
melissa
Message:

Merged r6521 and a bunch of ImageJ plugin changes to 4.2.

Location:
branches/4.2/components/loci-plugins
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • branches/4.2/components/loci-plugins

  • branches/4.2/components/loci-plugins/build.properties

    r6517 r6524  
    1515                           ${lib.dir}/forms-1.3.0.jar:\ 
    1616                           ${lib.dir}/ij.jar:\ 
    17                            ${lib.dir}/junit.jar:\ 
     17                           ${lib.dir}/junit-4.8.2.jar:\ 
    1818                           ${lib.dir}/log4j-1.2.15.jar 
    1919component.java-version   = 1.5 
  • branches/4.2/components/loci-plugins/build.xml

    r6016 r6524  
    1212  <import file="${root.dir}/ant/java.xml"/> 
    1313  <property file="build.properties"/> 
     14 
     15  <target name="test" depends="jar, compile-tests" 
     16    description="run tests" if="doTests"> 
     17    <!-- overrides default 'test' target in java.xml --> 
     18 
     19    <junit> 
     20      <classpath> 
     21        <pathelement path="${component.classpath}"/> 
     22        <pathelement location="${test-classes.dir}"/> 
     23      </classpath> 
     24      <formatter type="plain" usefile="true"/> 
     25      <test name="loci.plugins.in.ImporterTest"/> 
     26    </junit> 
     27  </target> 
    1428</project> 
  • branches/4.2/components/loci-plugins/src

    • Property svn:mergeinfo deleted
  • branches/4.2/components/loci-plugins/src/loci/plugins/Slicer.java

    • Property svn:mergeinfo deleted
  • branches/4.2/components/loci-plugins/src/loci/plugins/in/ImagePlusReader.java

    r6500 r6524  
    310310  private List<ImagePlus> applyColors(List<ImagePlus> imps) { 
    311311    final ImporterOptions options = process.getOptions(); 
    312  
    313     // CTR FIXME - problems with default color mode 
    314     int mode = -1; 
    315     boolean indexed = process.getReader().isIndexed(); 
    316     int sizeC = process.getReader().getSizeC(); 
    317     if (sizeC == 1) { 
    318       // NB: Cannot use CompositeImage for single-channel images. 
    319       // CTR FIXME finish sizeC==1 case 
    320       loci.plugins.BF.warn(options.isQuiet(), "sizeC = 1");//TEMP 
    321     } 
    322     else if (sizeC > 7) { 
    323       // NB: Cannot use CompositeImage when there are more than seven channels. 
    324       // CTR FIXME finish sizeC>7 case 
    325       loci.plugins.BF.warn(options.isQuiet(), "sizeC > 7");//TEMP 
    326     } 
    327     else if (options.isColorModeComposite()) mode = CompositeImage.COMPOSITE; 
    328     else if (options.isColorModeColorized()) mode = CompositeImage.COLOR; 
    329     else if (options.isColorModeGrayscale()) mode = CompositeImage.GRAYSCALE; 
    330     else if (options.isColorModeCustom()) mode = CompositeImage.COLOR; 
    331     else if (indexed && sizeC > 1) mode = CompositeImage.COLOR; 
    332  
    333     if (mode != -1) { 
    334       List<ImagePlus> compositeImps = new ArrayList<ImagePlus>(); 
    335       for (ImagePlus imp : imps) { 
     312    final ImageProcessorReader reader = process.getReader(); 
     313 
     314    for (int image=0; image<imps.size(); image++) { 
     315      ImagePlus imp = imps.get(image); 
     316      int series = (Integer) imp.getProperty("Series"); 
     317      reader.setSeries(series); 
     318 
     319      // CTR FIXME - problems with default color mode 
     320      int mode = -1; 
     321      boolean indexed = reader.isIndexed(); 
     322      int sizeC = reader.getEffectiveSizeC(); 
     323      if (sizeC == 1 && 
     324        (options.isColorModeColorized() || options.isColorModeCustom())) 
     325      { 
     326        LUT lut = makeLUT(options.getDefaultCustomColor(0)); 
     327        if (options.isColorModeCustom()) { 
     328          lut = makeLUT(series, 0); 
     329        } 
     330        imp.getProcessor().setColorModel(lut); 
     331      } 
     332      else if (sizeC > 7) { 
     333        // NB: Cannot use CompositeImage when there are more than 
     334        // seven channels. 
     335        // CTR FIXME finish sizeC>7 case 
     336        loci.plugins.BF.warn(options.isQuiet(), "sizeC > 7");//TEMP 
     337      } 
     338      else if (options.isColorModeComposite()) mode = CompositeImage.COMPOSITE; 
     339      else if (options.isColorModeColorized()) mode = CompositeImage.COLOR; 
     340      else if (options.isColorModeGrayscale()) mode = CompositeImage.GRAYSCALE; 
     341      else if (options.isColorModeCustom()) mode = CompositeImage.COLOR; 
     342      else if (indexed && sizeC > 1) mode = CompositeImage.COLOR; 
     343 
     344      if (mode != -1) { 
    336345        CompositeImage compImage = new CompositeImage(imp, mode); 
    337346        LUT[] luts = null; 
    338         int series = (Integer) imp.getProperty("Series"); 
    339347        if (options.isColorModeCustom()) luts = makeLUTs(series); 
    340348        else if (indexed) { 
     
    343351            byte[][] lut = null; 
    344352            try { 
    345               int index = process.getReader().getIndex(0, i, 0); 
    346               process.getReader().openBytes(index, 0, 0, 1, 1); 
    347               lut = process.getReader().get8BitLookupTable(); 
     353              int index = reader.getIndex(0, i, 0); 
     354              reader.openBytes(index, 0, 0, 1, 1); 
     355              lut = reader.get8BitLookupTable(); 
    348356            } 
    349357            catch (FormatException e) { } 
     
    359367        } 
    360368        if (luts != null) compImage.setLuts(luts); 
    361         compositeImps.add(compImage); 
    362       } 
    363       imps = compositeImps; 
     369        imps.set(image, compImage); 
     370      } 
    364371    } 
    365372    return imps; 
  • branches/4.2/components/loci-plugins/src/loci/plugins/in/ImporterOptions.java

    • Property svn:mergeinfo deleted
  • branches/4.2/components/loci-plugins/src/loci/plugins/util/ImagePlusTools.java

    r6477 r6524  
    184184    MinMaxCalculator minMaxCalc) 
    185185  { 
    186     double min = Double.MAX_VALUE; 
    187     double max = Double.MIN_VALUE; 
     186    double min = Double.POSITIVE_INFINITY; 
     187    double max = Double.NEGATIVE_INFINITY; 
    188188 
    189189    // try to grab min and max values from the MinMaxCalculator 
     
    207207 
    208208    // couldn't find min and max values; determine manually 
    209     if (min == Double.MAX_VALUE && max == Double.MIN_VALUE) { 
     209    if (min == Double.POSITIVE_INFINITY && max == Double.NEGATIVE_INFINITY) { 
    210210      ImageStack stack = imp.getStack(); 
    211211      for (int i=0; i<stack.getSize(); i++) { 
  • branches/4.2/components/loci-plugins/src/loci/plugins/util/ImageProcessorReader.java

    r6477 r6524  
    3131import ij.process.ShortProcessor; 
    3232 
     33import java.awt.image.ColorModel; 
    3334import java.awt.image.IndexColorModel; 
    3435import java.io.IOException; 
     
    128129    } 
    129130 
     131    // create a color model for this plane (null means default) 
     132    final ColorModel cm = createColorModel(); 
     133 
    130134    // convert byte array to appropriate primitive array type 
    131135    boolean isFloat = FormatTools.isFloatingPoint(type); 
    132136    boolean isLittle = isLittleEndian(); 
    133137    boolean isSigned = FormatTools.isSigned(type); 
    134  
    135     IndexColorModel cm = null; 
    136     if (isIndexed()) cm = createIndexColorModel(); 
    137138 
    138139    // construct image processors 
     
    214215  // -- Helper methods -- 
    215216 
    216   private IndexColorModel createIndexColorModel() 
    217     throws FormatException, IOException 
    218   { 
     217  private ColorModel createColorModel() throws FormatException, IOException { 
     218    // NB: If a color table is present, we might as well use it, 
     219    // regardless of the value of isIndexed. 
     220    //if (!isIndexed()) return null; 
     221 
    219222    byte[][] byteTable = get8BitLookupTable(); 
    220223    if (byteTable == null) byteTable = convertTo8Bit(get16BitLookupTable()); 
  • branches/4.2/components/loci-plugins/test/loci/plugins/in/ImporterTest.java

    r6341 r6524  
    55package loci.plugins.in; 
    66 
     7import org.junit.Test; 
     8 
    79import static org.junit.Assert.assertEquals; 
    8 import static org.junit.Assert.assertArrayEquals; 
    910import static org.junit.Assert.assertNotNull; 
    1011import static org.junit.Assert.assertTrue; 
     
    1314 
    1415import ij.CompositeImage; 
     16import ij.IJ; 
    1517import ij.ImagePlus; 
    1618import ij.ImageStack; 
     19import ij.WindowManager; 
     20import ij.measure.Calibration; 
    1721import ij.process.ImageProcessor; 
     22import ij.process.LUT; 
    1823 
    1924import java.awt.Color; 
     25import java.awt.image.IndexColorModel; 
    2026import java.io.IOException; 
    2127import java.lang.reflect.Field; 
     
    2632import loci.formats.FormatTools; 
    2733import loci.plugins.BF; 
    28  
    29 import org.junit.Test; 
     34import loci.plugins.in.ImporterOptions; 
    3035 
    3136// TODO 
    32 //    waiting on BF implementations for 
    33 //      range step by 0 
    34 //      BF/imageJ returning wrong max num pixels for UINT32 - off by one 
    35 //      memoryRecord failure needs BF code fix? 
    36 //      mergeOptions BF api for finishing merge tests 
    37 //      custom color BF api for doing that test 
    38 //      coboCropAutoscale() - autoscale of a cropped image returning min of whole image 
    39 //  - flesh out existing tests 
    40 //      write tests for the color options : 4 cases - some mention was made that indexcolor is an issue in testing 
    41 //        merge - basic test in place but not passing. need to flesh out mergeOptions when BF code in place. 
    42 //        rgb colorize - need to do actual tests. see BF gui to get idea of how it works 
    43 //        custom colorize - waiting for creation of API for setting r,g,b info 
    44 //        autoscale - working 
    45 //      open individual files: try to come up with a way to test without a disk file as source 
    46 //      swapped dims test needs to test cases other than from default swapping Z & T 
    47 //      output stack order - testing of iIndex? 
    48 //      range - more combos of ztc? uncomment the by 0 tests 
     37 
     38// seem broken but don't know status from Curtis 
     39//   colorized: 1/1/indexed (all indices 0 for all images), 3/1/indexed (iIndex,cIndex) (although w/ falseColor its okay), 
     40//     6/3/nonindexed (iIndex,cIndex), 12/3/nonindexed (iIndex,cIndex), 3/3/indexed (iIndex,cIndex) 
     41//   concat and split (returns wrong number of images per imp) 
     42//   record does not work 
     43 
     44// broken 
     45//   comboCropAndAutoscale for INT32. I think its a limitation of Fake. The values of the cropped image are outside 
     46//   the minimum represntable value of an int as a float. So when we make a FloatProcessor on the int[] data the 
     47//   huge negative values get clamped to the lowest representable point and thus max and min are not set correctly 
     48//   by IJ. I have verified that the pixel data that is sent to FloatProcessor() is correct. Limitation we'll live 
     49//   with I guess. 
     50 
     51// testable code according to my notes 
     52//   composite, gray, custom: working for 2 <= sizeC <= 7 and nonindexed (not yet tested) 
     53 
     54// unwritten 
     55//   color grayscale and color custom : hoping to adapt a working color colorized method for these. 
     56//   color composite: I don't remember Curtis telling me how this should work 
     57//   color default : Curtis never explained how this should work and code probably not in place 
     58 
     59// note 
     60//   I changed MemoryRecord from "Flip Horizontally" (which could not be found at runtime) to "Invert". Verified 
     61//     "Invert" is recordable and record("invert") getting called but doRecording is false for some reason. Also Curtis 
     62//     thought flip would be easier to use for predicting actual values rather than special case code with invert. As 
     63//     I'm only doing UINT8 for now this is not a problem. 
     64 
     65// waiting on BF implementations for 
     66//   - indexed color support 
     67//   - changes to concat 
     68 
     69// must address before release 
     70 
     71//  - macros should still work like before 
     72//  - write tests for the color options : some mention was made that indexcolor is an issue in testing 
     73//     default - waiting on BF to know how it should behave 
     74//     composite 
     75//     colorized 
     76//     grayscale 
     77//     custom 
    4978//  - add some tests for combination of options 
    50 //  - improve, comment, and generalize code for increased coverage 
     79//      comboConcatSplit() - done but not passing 
     80//      comboManyOptions - done and passing 
     81//      other combo tests - rely on color code working. Waiting for BF. 
     82 
     83// would be nice to address before release 
     84 
     85//    - BF/imageJ returning wrong values of max num pixels (UINT32 off by one - IJ bug, float weird too, etc.) 
     86//    - memoryRecord failure (needs BF code fix) 
     87//    - open individual files: try to come up with a way to test without a disk file as source 
     88//    - output stack order - testing of iIndex? should match imagestack number? i.e. 5th plane == 4 - doesn't look so 
     89//    - improve, comment, and generalize code for increased coverage 
    5190 
    5291public class ImporterTest { 
     
    5493  private enum Axis {Z,C,T}; 
    5594   
    56   private enum ChannelOrder {XYZTC, XYZCT, XYTZC, XYTCZ, XYCTZ, XYCZT}; 
     95  private enum ChannelOrder {ZCT, ZTC, CZT, CTZ, TZC, TCZ}; 
    5796   
    5897  private static final boolean[] BooleanStates = new boolean[] {false, true}; 
    5998   
    6099  private static final int[] PixelTypes = new int[] { 
     100      FormatTools.FLOAT, FormatTools.DOUBLE, 
    61101      FormatTools.UINT8, FormatTools.UINT16, FormatTools.UINT32, 
    62       FormatTools.INT8,  FormatTools.INT16,  FormatTools.INT32, 
    63       FormatTools.FLOAT, FormatTools.DOUBLE 
     102      FormatTools.INT8,  FormatTools.INT16,  FormatTools.INT32 
    64103      }; 
    65104   
     105  private static Color[] DefaultColorOrder = 
     106    new Color[] {Color.RED, Color.GREEN, Color.BLUE, Color.WHITE, Color.CYAN, Color.MAGENTA, Color.YELLOW}; 
     107   
     108  private static Color[] CustomColorOrder = 
     109    new Color[] {Color.BLUE, Color.RED, Color.GREEN, Color.MAGENTA, Color.YELLOW, Color.CYAN, Color.WHITE}; 
     110 
    66111  private static final String[] FAKE_FILES; 
    67112  private static final String FAKE_PATTERN; 
    68   
     113 
     114  private static final int FakePlaneCount = 7; 
     115   
    69116  static { 
    70117 
    71118    //String template = "test_C%s_TP%s&sizeX=50&sizeY=20&sizeZ=7.fake"; 
    72     String template = constructFakeFilename("test_C%s_TP%s", FormatTools.INT32, 50, 20, 7, 1, 1, -1); 
     119    String template = constructFakeFilename("test_C%s_TP%s", FormatTools.INT32, 50, 20, FakePlaneCount, 1, 1, -1, false, -1, false, -1); 
    73120                                                                        // BDZ - INT32 is desirable for the color tests 
    74121     
     
    88135      String.format(template, "1", "5"), 
    89136      String.format(template, "2", "5"), 
    90       String.format(template, "3", "5"), 
    91       "outlier.txt" // optional 
     137      String.format(template, "3", "5") 
    92138    }; 
    93139    FAKE_PATTERN = String.format(template, "<1-3>", "<1-5>"); 
     
    101147 
    102148  private static String constructFakeFilename(String title, 
    103       int pixelType, int sizeX, int sizeY, int sizeZ, int sizeC, int sizeT, int numSeries) 
     149      int pixelType, int sizeX, int sizeY, int sizeZ, int sizeC, int sizeT, int numSeries, 
     150      boolean indexed, int rgb, boolean falseColor, int lutLength) 
    104151  { 
    105152    // some tests rely on each image being large enough to get the s,i,z,t,c index pixels of a 
     
    119166    fileName += "&sizeT=" + sizeT; 
    120167    if (numSeries > 0) fileName += "&series=" + numSeries; 
     168    if (indexed) fileName += "&indexed=true"; 
     169    if (rgb != -1) fileName += "&rgb=" + rgb; 
     170    if (falseColor) fileName += "&falseColor=true"; 
     171    if (lutLength > 0) fileName += "&lutLength=" + lutLength; 
    121172    fileName += ".fake"; 
    122173     
     
    150201  } 
    151202 
     203  /** returns the character at the given index within a string that is a permutation of ZCT */ 
    152204  private char axisChar(String order, int d) 
    153205  { 
     
    155207      throw new IllegalArgumentException("axisChar() - index out of bounds [0..2]: "+d); 
    156208     
    157     return order.charAt(2+d); 
    158   } 
    159    
     209    return order.charAt(d); 
     210  } 
     211   
     212  /** returns Axis given an order string and an index */ 
    160213  private Axis axis(String order, int d) 
    161214  { 
     
    169222  } 
    170223 
     224  /** returns z, c, or t value given an Axis selector */ 
    171225  private int value(Axis axis, int z, int c, int t) 
    172226  { 
     
    178232  } 
    179233   
     234  /** returns z, c, or t index value given an ImageProcessor and an Axis selector */ 
    180235  private int index(Axis axis, ImageProcessor proc) 
    181236  { 
     
    187242  } 
    188243 
     244  /** get full order (XYTCZ) from ChannelOrder (TCZ) as string */ 
     245  private String bfChanOrd(ChannelOrder order) 
     246  { 
     247    return "XY" + order.toString(); 
     248  } 
     249   
     250  /** returns the number of of elements in a series given from, to, and by values */ 
    189251  private int numInSeries(int from, int to, int by) 
    190252  { 
     253    if (by < 1) 
     254      throw new IllegalArgumentException("numInSeries passed a stepBy value < 1"); 
     255     
    191256    // could calc this but simple loop suffices for our purposes 
    192257    int count = 0; 
     
    285350        throw new IllegalArgumentException("maxPixelValue() - unknown pixel type passed in: " + pixType); 
    286351    } 
    287     /* 
    288      
    289     long maxUnsigned = (1L << FormatTools.getBytesPerPixel(pixType)*8) - 1; 
    290      
    291     // signed data type 
    292     if (FormatTools.isSigned(pixType)) 
    293        
    294       return maxUnsigned / 2; 
    295      
    296     else  // unsigned data type 
    297        
    298       return maxUnsigned; 
    299     */ 
    300  
    301352  } 
    302353   
     
    304355  { 
    305356    if (FormatTools.isFloatingPoint(pixType)) 
    306       //return -4294967296L; // expected -Float.MAX_VALUE or maybe -Double.MAX_VALUE rather than -2^32 (and also its not 2^32-1 !!!) 
    307       return 0;  // TODO this allows autoscale testing to work for floating types _ makes sense cuz FakeReader only does unsigned float data  
     357      //return -4294967296L; // -2^32 (and also its not 2^32-1 !!!) 
     358      return 0;  // TODO this allows autoscale testing to work for floating types - makes sense cuz FakeReader only does unsigned float data  
    308359  
    309360    switch (pixType) 
     
    319370        throw new IllegalArgumentException("minPixelValue() - unknown pixel type passed in: " + pixType); 
    320371    } 
    321     /* 
    322     if (FormatTools.isFloatingPoint(pixType)) 
    323       return (long)-Float.MAX_VALUE; 
    324   
    325     // signed data type 
    326     if (FormatTools.isSigned(pixType)) 
    327  
    328       return - (1L << ((FormatTools.getBytesPerPixel(pixType)*8)-1));  // -1 accounts for use of sign bit 
    329        
    330     else  // unsigned data type 
    331        
    332       return 0; 
    333     */ 
    334   } 
    335  
     372  } 
     373 
     374  // note - this code relies on setPosition(c,z,t) being called previously. Otherwise regular ImagePlus case won't work. 
     375  //   In general this method not designed for general use but actually just for use by getPixelValue(). 
     376   
     377  private LUT getColorTable(ImagePlus imp, int channel) 
     378  { 
     379    if (imp instanceof CompositeImage) 
     380      return ((CompositeImage)imp).getChannelLut(channel+1); 
     381     
     382    // else a regular ImagePlus 
     383     
     384    System.out.println("  getting color table from a regular ImagePlus."); 
     385     
     386    IndexColorModel icm = (IndexColorModel)imp.getProcessor().getColorModel(); 
     387     
     388    byte[] reds = new byte[256], greens = new byte[256], blues = new byte[256]; 
     389     
     390    icm.getReds(reds); 
     391    icm.getGreens(greens); 
     392    icm.getBlues(blues); 
     393     
     394    return new LUT(reds,greens,blues); 
     395  } 
     396   
     397  /** get the actual pixel value (lookup when data is indexed) of the index of a fake image at a given z,c,t */ 
     398  private int getPixelValue(int x,int y, ImagePlus imp, int z, int c, int t, boolean indexed) 
     399  { 
     400    // our indices are 0-based while IJ's are 1-based 
     401    imp.setPosition(c+1, z+1, t+1); 
     402     
     403    int rawValue = (int) (imp.getProcessor().getPixelValue(x, y)); 
     404     
     405    if (!indexed) 
     406      return rawValue; 
     407 
     408    // otherwise indexed - lookup pixel value in LUT 
     409     
     410    LUT lut = getColorTable(imp,c); 
     411    int value = lut.getRed(rawValue);  // since r g and b vals should be the same choose one arbitrarily. 
     412      // OR Use red in case lut len < 3 and zero fills other channels 
     413     
     414    System.out.println("  getPixelValue("+z+","+c+","+t+") = "+value+" (rawValue = "+rawValue+")"); 
     415     
     416    return value; 
     417  } 
     418   
     419  /** gets the value of the index of a fake file doing LUT lookup if needed */  
     420  private int getIndexValue(ImagePlus imp, int z, int c, int t, boolean indexed) 
     421  { 
     422    return getPixelValue(10,0,imp,z,c,t,indexed); 
     423  } 
     424   
     425  /** calculate the effective size C of an image given various params */ 
     426  private int effectiveC(int sizeC, int rgb, int lutLen, boolean indexed, boolean falseColor) 
     427  { 
     428    int effC = sizeC; 
     429     
     430    if (indexed) 
     431    { 
     432      if (falseColor) 
     433        effC /= rgb; 
     434      else // not falseColor 
     435        effC *= lutLen; 
     436    } 
     437     
     438    return effC; 
     439  } 
     440   
     441  // ****** helper tests **************************************************************************************** 
     442   
     443  /** tests that the correct number of ImagePluses exist */ 
     444  private void impsCountTest(ImagePlus[] imps, int numExpected) 
     445  { 
     446    assertNotNull(imps); 
     447    assertEquals(numExpected,imps.length); 
     448  } 
     449   
     450  /** tests that the dimensions of an ImagePlus match passed in x,y,z,c,t values */ 
    336451  private void xyzctTest(ImagePlus imp, int x, int y, int z, int c, int t) 
    337452  { 
     
    344459  } 
    345460   
    346   // ****** helper tests **************************************************************************************** 
    347    
     461  /** tests that the first and last entries of a lut match expected values */ 
     462  private void lutTest(CompositeImage ci, int channel, int minR, int minG, int minB, int maxR, int maxG, int maxB) 
     463  { 
     464    // channel is 0-based 
     465    LUT lut = ci.getChannelLut(channel+1);  // IJ is 1-based 
     466     
     467    byte[] reds = new byte[256]; 
     468    byte[] blues = new byte[256]; 
     469    byte[] greens = new byte[256]; 
     470     
     471    lut.getReds(reds); 
     472    lut.getGreens(greens); 
     473    lut.getBlues(blues); 
     474     
     475    /* TODO - helper for testing falseColor problems 
     476    System.out.println("  expected min rgb : "+minR+" "+minG+" "+minB); 
     477    System.out.println("  expected max rgb : "+maxR+" "+maxG+" "+maxB); 
     478    System.out.println("  actual min rgb : "+reds[0]+" "+greens[0]+" "+blues[0]); 
     479    System.out.println("  actual max rgb : "+(reds[255]&0xff)+" "+(greens[255]&0xff)+" "+(blues[255]&0xff)); 
     480    */ 
     481     
     482    assertEquals((byte)minR,reds[0]); 
     483    assertEquals((byte)maxR,reds[255]); 
     484    assertEquals((byte)minG,greens[0]); 
     485    assertEquals((byte)maxG,greens[255]); 
     486    assertEquals((byte)minB,blues[0]); 
     487    assertEquals((byte)maxB,blues[255]); 
     488  } 
     489 
     490  /** tests that each channel lut in a CompositeImage matches the passed in expected colors */ 
     491  private void colorTests(CompositeImage ci, int numChannels, Color[] expectedColors) 
     492  { 
     493    for (int i = 0; i < numChannels; i++) 
     494    { 
     495      Color color = expectedColors[i]; 
     496      lutTest(ci,i,0,0,0,color.getRed(),color.getGreen(),color.getBlue()); 
     497    } 
     498  } 
     499   
     500  /** tests that input to the crop tests is valid */ 
     501  private void verifyCropInput(int sizeX, int sizeY, int originCropX, int originCropY, int sizeCrop) 
     502  { 
     503    assertTrue((sizeX > 50) || (sizeY > 10)); 
     504    assertTrue(sizeX < 256); 
     505    assertTrue(sizeY < 256); 
     506    assertTrue(sizeCrop > 0); 
     507    assertTrue(originCropX >= 0); 
     508    assertTrue(originCropY >= 0); 
     509    assertTrue((originCropX > 50) || (originCropY > 10)); 
     510    assertTrue(originCropX + sizeCrop <= sizeX); 
     511    assertTrue(originCropY + sizeCrop <= sizeY); 
     512  } 
     513   
     514  /** tests BioFormats when directly calling BF.openImagePlus(path) (no options set) */ 
    348515  private void defaultBehaviorTest(int pixType, int x, int y, int z, int c, int t) 
    349516  { 
    350     String path = constructFakeFilename("default", pixType, x, y, z, c, t, -1); 
     517    String path = constructFakeFilename("default", pixType, x, y, z, c, t, -1, false, -1, false, -1); 
    351518    ImagePlus[] imps = null; 
    352519     
     
    361528    } 
    362529     
    363     assertNotNull(imps); 
    364     assertEquals(1,imps.length); 
     530    impsCountTest(imps,1); 
     531 
    365532    ImagePlus imp = imps[0]; 
    366533     
     
    368535  } 
    369536   
    370   private void outputStackOrderTest(int pixType, String order, int x, int y, int z, int c, int t) 
    371   { 
    372     String path = constructFakeFilename(order, pixType, x, y, z, c, t, -1); 
    373      
    374     ImagePlus[] imps = null; 
    375     try { 
    376       ImporterOptions options = new ImporterOptions(); 
    377       options.setId(path); 
    378       options.setStackOrder(order); 
    379       imps = BF.openImagePlus(options); 
    380     } 
    381     catch (IOException e) { 
    382       fail(e.getMessage()); 
    383     } 
    384     catch (FormatException e) { 
    385       fail(e.getMessage()); 
    386     } 
    387  
    388     assertNotNull(imps); 
    389     assertEquals(1,imps.length); 
     537  private void outputStackOrderTest(int pixType, ChannelOrder order, int x, int y, int z, int c, int t) 
     538  { 
     539    String bfChOrder = bfChanOrd(order); 
     540    String chOrder = order.toString(); 
     541     
     542    String path = constructFakeFilename("stack", pixType, x, y, z, c, t, -1, false, -1, false, -1); 
     543     
     544    ImagePlus[] imps = null; 
     545    try { 
     546      ImporterOptions options = new ImporterOptions(); 
     547      options.setId(path); 
     548      options.setStackOrder(bfChOrder); 
     549      imps = BF.openImagePlus(options); 
     550    } 
     551    catch (IOException e) { 
     552      fail(e.getMessage()); 
     553    } 
     554    catch (FormatException e) { 
     555      fail(e.getMessage()); 
     556    } 
     557 
     558    impsCountTest(imps,1); 
    390559     
    391560    ImagePlus imp = imps[0]; 
     
    398567    assertEquals(z*c*t,numSlices); 
    399568 
    400     int count = 0; 
     569    int procNum = 1; 
    401570    //System.out.println(order); 
    402     Axis fastest = axis(order,0); 
    403     Axis middle = axis(order,1); 
    404     Axis slowest = axis(order,2); 
     571    Axis fastest = axis(chOrder,0); 
     572    Axis middle = axis(chOrder,1); 
     573    Axis slowest = axis(chOrder,2); 
    405574    int maxI = value(slowest,z,c,t); 
    406575    int maxJ = value(middle,z,c,t); 
     
    410579        for (int k = 0; k < maxK; k++) 
    411580        { 
    412           ImageProcessor proc = st.getProcessor(count+1); 
     581          ImageProcessor proc = st.getProcessor(procNum++); 
    413582          //printVals(proc); 
    414583          assertNotNull(proc); 
     
    419588          assertEquals(j,index(middle,proc)); 
    420589          assertEquals(k,index(fastest,proc)); 
    421           count++; 
    422590        } 
    423591  } 
     
    425593  private void datasetSwapDimsTest(int pixType, int x, int y, int z, int t) 
    426594  { 
    427     int c = 3; String origOrder = "XYZCT", swappedOrder = "XYTCZ"; 
    428     String path = constructFakeFilename("swapDims", pixType, x, y, z, c, t, -1); 
     595    int c = 3; 
     596    ChannelOrder swappedOrder = ChannelOrder.TCZ; // original order is ZCT 
     597    String path = constructFakeFilename("swapDims", pixType, x, y, z, c, t, -1, false, -1, false, -1); 
    429598    ImagePlus[] imps = null; 
    430599    try { 
     
    432601      options.setId(path); 
    433602      options.setSwapDimensions(true); 
    434       options.setInputOrder(0, swappedOrder); 
    435       imps = BF.openImagePlus(options); 
    436     } 
    437     catch (IOException e) { 
    438       fail(e.getMessage()); 
    439     } 
    440     catch (FormatException e) { 
    441       fail(e.getMessage()); 
    442     } 
    443  
    444     assertNotNull(imps); 
    445     assertEquals(1,imps.length); 
     603      options.setInputOrder(0, bfChanOrd(swappedOrder)); 
     604      imps = BF.openImagePlus(options); 
     605    } 
     606    catch (IOException e) { 
     607      fail(e.getMessage()); 
     608    } 
     609    catch (FormatException e) { 
     610      fail(e.getMessage()); 
     611    } 
     612 
     613    impsCountTest(imps,1); 
    446614 
    447615    ImagePlus imp = imps[0]; 
     
    453621    assertEquals(z*c*t,numSlices); 
    454622 
    455     // make sure the dimensions were swapped correctly 
     623    // verify that the dimensional extents were swapped 
     624    final int actualSizeZ = imp.getNSlices(); 
     625    final int actualSizeC = imp.getNChannels(); 
     626    final int actualSizeT = imp.getNFrames(); 
     627    assertEquals(t, actualSizeZ); // Z<->T swapped 
     628    assertEquals(c, actualSizeC); 
     629    assertEquals(z, actualSizeT); // Z<->T swapped 
     630 
     631    // verify that every plane appears in the swapped order 
    456632    int p = 1; 
    457     for (int zIndex = 0; zIndex < z; zIndex++) 
    458       for (int cIndex = 0; cIndex < c; cIndex++) 
    459         for (int tIndex = 0; tIndex < t; tIndex++) 
     633    for (int tIndex = 0; tIndex < actualSizeT; tIndex++) 
     634      for (int cIndex = 0; cIndex < actualSizeC; cIndex++) 
     635        for (int zIndex = 0; zIndex < actualSizeZ; zIndex++) 
    460636        { 
    461637          ImageProcessor proc = st.getProcessor(p++); 
    462           assertEquals(tIndex,zIndex(proc)); // Z<->T swapped 
    463           assertEquals(cIndex,cIndex(proc)); 
    464           assertEquals(zIndex,tIndex(proc)); // Z<->T swapped 
     638          final int actualZ = tIndex(proc); // Z<->T swapped 
     639          final int actualC = cIndex(proc); 
     640          final int actualT = zIndex(proc); // Z<->T swapped 
     641          assertEquals(zIndex, actualZ); 
     642          assertEquals(cIndex, actualC); 
     643          assertEquals(tIndex, actualT); 
    465644        } 
    466645  } 
     
    468647  private void datasetOpenAllSeriesTest(int x, int y, int z, int c, int t, int s) 
    469648  { 
    470     String path = constructFakeFilename("XYZCT", FormatTools.UINT32, x, y, z, c, t, s); 
     649    String path = constructFakeFilename("openAllSeries", FormatTools.UINT32, x, y, z, c, t, s, false, -1, false, -1); 
    471650     
    472651    // try it when false 
     
    488667    // test results 
    489668     
    490     assertEquals(1,imps.length); 
     669    impsCountTest(imps,1); 
    491670    xyzctTest(imps[0],x,y,z,c,t); 
    492671    assertEquals(z*c*t, imps[0].getStack().getSize()); 
     
    518697  } 
    519698   
    520   private void datasetConcatenateTest(int pixType, String order, 
    521       int x, int y, int z, int c, int t, int s) 
     699  private void datasetConcatenateTest(int pixType, int x, int y, int z, int c, int t, int s) 
    522700  { 
    523701    assertTrue(s >= 1);  // necessary for this test 
     
    525703    // open all series as one 
    526704     
    527     String path = constructFakeFilename(order, pixType, x, y, z, c, t, s); 
     705    String path = constructFakeFilename("concat", pixType, x, y, z, c, t, s, false, -1, false, -1); 
    528706    ImagePlus[] imps = null; 
    529707    try { 
     
    543721    // test results 
    544722     
    545     assertNotNull(imps); 
    546     assertEquals(1,imps.length); 
     723    impsCountTest(imps,1); 
    547724    ImageStack st = imps[0].getStack(); 
    548725 
     
    550727    assertEquals(z*c*t*s, st.getSize()); 
    551728     
    552     int index = 0; 
     729    int index = 1; 
    553730    for (int sIndex = 0; sIndex < s; sIndex++) { 
    554731      for (int tIndex = 0; tIndex < t; tIndex++) { 
    555732        for (int cIndex = 0; cIndex < c; cIndex++) { 
    556733          for (int zIndex = 0; zIndex < z; zIndex++) { 
    557             ImageProcessor proc = st.getProcessor(++index);  
     734            ImageProcessor proc = st.getProcessor(index++);  
    558735            assertEquals(sIndex, sIndex(proc)); 
    559736            assertEquals(zIndex, zIndex(proc)); 
     
    569746  { 
    570747    final int sizeZ = 2, sizeC = 3, sizeT = 4, sizeX = 51, sizeY = 16; 
    571     final String path = constructFakeFilename("autoscale",pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, -1); 
     748    final String path = constructFakeFilename("autoscale",pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
    572749     
    573750    ImagePlus[] imps = null; 
     
    587764    } 
    588765     
    589     assertEquals(1,imps.length); 
     766    impsCountTest(imps,1); 
    590767     
    591768    imp = imps[0]; 
     
    598775    long expectedMax,expectedMin; 
    599776     
    600     if (wantAutoscale) 
     777    if (wantAutoscale || (FormatTools.isFloatingPoint(pixType))) 
    601778    { 
    602779      expectedMax = Math.max( minPixelValue(pixType)+sizeX-1, sizeZ*sizeC*sizeT - 1 );  // series size always 1 so ignore 
     
    609786    } 
    610787 
     788    // if signed make sure Calibration is setup correctly 
     789    if (FormatTools.isSigned(pixType) && !FormatTools.isFloatingPoint(pixType)) 
     790    { 
     791      Calibration cal = imp.getCalibration(); 
     792      assertEquals(Calibration.STRAIGHT_LINE,cal.getFunction()); 
     793      double[] coeffs = cal.getCoefficients(); 
     794      int bitsPerPix = FormatTools.getBytesPerPixel(pixType) * 8; 
     795      assertEquals(-(Math.pow(2, (bitsPerPix-1))),coeffs[0],0); 
     796      assertEquals(1,coeffs[1],0); 
     797       
     798      // note - IJ clamps min and max to a range for ShortProcessor (unlike all other processors) 
     799      if (pixType == FormatTools.INT16)  // hack : clamp like IJ does 
     800      { 
     801        if (expectedMin < 0) 
     802          expectedMin = 0; 
     803        if (expectedMax > 65535) 
     804          expectedMax = 65535; 
     805      } 
     806    } 
     807     
    611808    for (int i = 0; i < numSlices; i++) 
    612809    { 
     
    617814  } 
    618815   
    619   // note - this test needs to rely on crop() to get predictable nonzero minimums 
    620    
    621   private void cropAndAutoscaleTest(int pixType, int sizeX, int sizeY, int sizeZ, int sizeC, int sizeT, int numSeries, 
    622       int originCropX, int originCropY, int sizeCrop) 
    623   { 
    624     final String path = constructFakeFilename("cropAutoscale",pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries); 
    625      
    626     // needed for this test 
    627     assertTrue(originCropX >= 50); 
    628     assertTrue(originCropY >= 10);  
    629     assertTrue(sizeCrop > 0); 
    630     assertTrue(originCropX + sizeCrop < sizeX); 
    631     assertTrue(originCropY + sizeCrop < sizeY); 
    632     assertTrue(originCropX + sizeCrop < 255); 
     816  private void colorCompositeTest(int pixType, boolean indexed, int rgb, boolean falseColor, int sizeC, int numSeries) 
     817  { 
     818    int sizeX = 55, sizeY = 71, sizeZ = 3, sizeT = 4; 
     819     
     820    // reportedly works in BF for 2<=sizeC<=7 and also numSeries*sizeC*3 <= 25 
     821     
     822    assertTrue(sizeC >= 2); 
     823    assertTrue(sizeC <= 7); 
     824    assertTrue(numSeries*sizeC*3 <= 25);  // slider limit in IJ 
     825     
     826    String path = constructFakeFilename("colorComposite", pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries, 
     827        indexed, rgb, falseColor, -1); 
    633828     
    634829    ImagePlus[] imps = null; 
    635830    ImagePlus imp = null; 
    636      
    637     try { 
    638       ImporterOptions options = new ImporterOptions(); 
    639       options.setAutoscale(true); 
    640       options.setCrop(true); 
    641       options.setCropRegion(0,new Region(originCropX,originCropY,sizeCrop,sizeCrop)); 
    642       options.setId(path); 
    643       imps = BF.openImagePlus(options); 
    644     } 
    645     catch (IOException e) { 
    646       fail(e.getMessage()); 
    647     } 
    648     catch (FormatException e) { 
    649       fail(e.getMessage()); 
    650     } 
    651      
    652     assertEquals(1,imps.length); 
     831    CompositeImage ci = null; 
     832     
     833    try { 
     834      ImporterOptions options = new ImporterOptions(); 
     835      options.setColorMode(ImporterOptions.COLOR_MODE_COMPOSITE); 
     836      options.setId(path); 
     837      imps = BF.openImagePlus(options); 
     838    } 
     839    catch (IOException e) { 
     840      fail(e.getMessage()); 
     841    } 
     842    catch (FormatException e) { 
     843      fail(e.getMessage()); 
     844    } 
     845 
     846    // TODO - notice I pass in numSeries but don't test it below : no for loop for it. 
     847     
     848    impsCountTest(imps,1); 
     849     
    653850    imp = imps[0]; 
    654     xyzctTest(imps[0],sizeCrop,sizeCrop,sizeZ,sizeC,sizeT); 
    655  
    656     ImageStack st = imp.getStack(); 
    657     int numSlices = st.getSize(); 
    658  
    659     long expectedMax = originCropX+sizeCrop-1; 
    660     long expectedMin = originCropX; 
    661  
    662     for (int i = 0; i < numSlices; i++) 
    663     { 
    664       ImageProcessor proc = st.getProcessor(i+1); 
    665       assertEquals(expectedMax,proc.getMax(),0.1); 
    666       assertEquals(expectedMin,proc.getMin(),0.1); 
    667     } 
     851 
     852    int lutLen = 3; 
     853     
     854    int expectedSizeC = effectiveC(sizeC, rgb, lutLen, indexed, falseColor); 
     855    
     856    xyzctTest(imp,sizeX,sizeY,sizeZ,expectedSizeC,sizeT); 
     857     
     858    assertTrue(imp.isComposite()); 
     859     
     860    ci = (CompositeImage)imp; 
     861     
     862    assertFalse(ci.hasCustomLuts()); 
     863 
     864    assertEquals(CompositeImage.COMPOSITE, ci.getMode()); 
     865     
     866    colorTests(ci,expectedSizeC,DefaultColorOrder); 
     867 
     868    ci.reset();  // force the channel processors to get initialized, otherwise nullptr  - TODO : does this point out a IJ bug? 
     869     
     870    int maxZ = ci.getNSlices(); 
     871    int maxC = ci.getNChannels(); 
     872    int maxT = ci.getNFrames(); 
     873     
     874    //System.out.println("Checking index vals"); 
     875    //System.out.println("maxes z c t = "+maxZ+" "+maxC+" "+maxT); 
     876     
     877    // check that each image in the overall series has the correct iIndex value 
     878    int index = 0; 
     879    for (int t = 0; t < maxT; t++) 
     880      for (int z = 0; z < maxZ; z++) 
     881        for (int c = 0; c < maxC; c++) 
     882          assertEquals(index++, getIndexValue(ci,z,c,t,indexed));  // expected value from CZT order 
     883  } 
     884   
     885  private void colorColorizedTest() 
     886  { 
     887    // TODO: temp first attempt: sizeC == 1 and rgb matches 
     888     
     889    int sizeX = 100, sizeY = 120, sizeZ = 1, sizeC = 1, sizeT = 1, rgb = 1; 
     890    boolean indexed = true, falseColor = false; 
     891     
     892    String path = constructFakeFilename("colorColorized", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, indexed, rgb, false, -1); 
     893     
     894    ImagePlus[] imps = null; 
     895    ImagePlus imp = null; 
     896    CompositeImage ci = null; 
     897     
     898    try { 
     899      ImporterOptions options = new ImporterOptions(); 
     900      options.setColorMode(ImporterOptions.COLOR_MODE_COLORIZED); 
     901      options.setId(path); 
     902      imps = BF.openImagePlus(options); 
     903    } 
     904    catch (IOException e) { 
     905      fail(e.getMessage()); 
     906    } 
     907    catch (FormatException e) { 
     908      fail(e.getMessage()); 
     909    } 
     910 
     911    impsCountTest(imps,1); 
     912     
     913    imp = imps[0]; 
     914     
     915    int lutLen = 3; 
     916     
     917    int expectedSizeC = effectiveC(sizeC, rgb, lutLen, indexed, falseColor); 
     918 
     919    xyzctTest(imp,sizeX,sizeY,sizeZ,expectedSizeC,sizeT); 
     920     
     921    assertTrue(imp.isComposite()); 
     922     
     923    ci = (CompositeImage)imp; 
     924     
     925    assertFalse(ci.hasCustomLuts()); 
     926 
     927    assertEquals(CompositeImage.COLOR, ci.getMode()); 
     928     
     929    colorTests(ci,expectedSizeC,DefaultColorOrder); 
     930 
     931    fail("unfinished"); 
     932  } 
     933   
     934  private void colorGrayscaleTest() 
     935  { 
     936    int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4; 
     937     
     938    String path = constructFakeFilename("colorGrayscale", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
     939     
     940    ImagePlus[] imps = null; 
     941    ImagePlus imp = null; 
     942    CompositeImage ci = null; 
     943     
     944    try { 
     945      ImporterOptions options = new ImporterOptions(); 
     946      options.setColorMode(ImporterOptions.COLOR_MODE_GRAYSCALE); 
     947      options.setId(path); 
     948      imps = BF.openImagePlus(options); 
     949    } 
     950    catch (IOException e) { 
     951      fail(e.getMessage()); 
     952    } 
     953    catch (FormatException e) { 
     954      fail(e.getMessage()); 
     955    } 
     956 
     957    impsCountTest(imps,1); 
     958     
     959    imp = imps[0]; 
     960     
     961    xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,sizeT); 
     962     
     963    assertTrue(imp.isComposite()); 
     964     
     965    ci = (CompositeImage)imp; 
     966     
     967    assertFalse(ci.hasCustomLuts()); 
     968 
     969    assertEquals(CompositeImage.GRAYSCALE, ci.getMode()); 
     970 
     971    colorTests(ci,sizeC,DefaultColorOrder); 
     972 
     973    fail("unfinished"); 
     974  } 
     975 
     976  private void colorCustomTest(int pixType, int sizeX, int sizeY, int sizeZ, int sizeC, int sizeT, int numSeries) 
     977  { 
     978    // reportedly works in BF for 2<=sizeC<=7 and also numSeries*sizeC*3 <= 25 
     979     
     980    assertTrue(sizeC >= 2); 
     981    assertTrue(sizeC <= 7); 
     982    assertTrue(numSeries*sizeC*3 <= 25);  // slider limit in IJ 
     983     
     984    String path = constructFakeFilename("colorCustom", pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries, false, -1, false, -1); 
     985    ImagePlus[] imps = null; 
     986    ImagePlus imp = null; 
     987    CompositeImage ci = null; 
     988     
     989    try { 
     990      ImporterOptions options = new ImporterOptions(); 
     991      options.setColorMode(ImporterOptions.COLOR_MODE_CUSTOM); 
     992      for (int s = 0; s < numSeries; s++) 
     993        for (int c = 0; c < sizeC; c++) 
     994          options.setCustomColor(s, c, CustomColorOrder[c]); 
     995      options.setId(path); 
     996      imps = BF.openImagePlus(options); 
     997    } 
     998    catch (IOException e) { 
     999      fail(e.getMessage()); 
     1000    } 
     1001    catch (FormatException e) { 
     1002      fail(e.getMessage()); 
     1003    } 
     1004 
     1005    // TODO - notice numSeries passed in but never tested against 
     1006     
     1007    impsCountTest(imps,1); 
     1008     
     1009    imp = imps[0]; 
     1010     
     1011    xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,sizeT); 
     1012     
     1013    assertTrue(imp.isComposite()); 
     1014     
     1015    ci = (CompositeImage)imp; 
     1016     
     1017    assertFalse(ci.hasCustomLuts()); 
     1018 
     1019    assertEquals(CompositeImage.COLOR, ci.getMode()); 
     1020 
     1021    colorTests(ci,sizeC,CustomColorOrder); 
    6681022  } 
    6691023   
     
    6721026      int x = 604, y = 531, z = 7, c = 1, t = 1; 
    6731027       
    674       String path = constructFakeFilename("vstack", FormatTools.UINT16, x, y, z, c, t, -1); 
     1028      String path = constructFakeFilename("vstack", FormatTools.UINT16, x, y, z, c, t, -1, false, -1, false, -1); 
    6751029       
    6761030      // open stack 
     
    6901044   
    6911045      // test results 
    692       assertNotNull(imps); 
    693       assertEquals(1,imps.length); 
     1046      impsCountTest(imps,1); 
    6941047      ImagePlus imp = imps[0]; 
    695       assertNotNull(imp); 
    6961048      xyzctTest(imp,x,y,z,c,t); 
    6971049   
     
    7011053  private void memoryRecordModificationsTest(boolean wantToRemember) 
    7021054  { 
    703     int x = 444, y = 387, z = 7, c = 1, t = 1; 
    704     String path = constructFakeFilename("memRec", FormatTools.UINT8, x, y, z, c, t, -1); 
     1055    int x = 50, y = 15, z = 3, c = 1, t = 1; 
     1056    String path = constructFakeFilename("memRec", FormatTools.UINT8, x, y, z, c, t, -1, false, -1, false, -1); 
    7051057    ImagePlus[] imps = null; 
    7061058    ImagePlus imp = null; 
    7071059     
    7081060    assertTrue(y > 10);  // needed for this test 
     1061    assertTrue(z > 1); 
    7091062     
    7101063    // open file 
     
    7241077 
    7251078    // basic tests 
    726     assertNotNull(imps); 
    727     assertEquals(1,imps.length); 
     1079    impsCountTest(imps,1); 
    7281080    imp = imps[0]; 
    729     assertNotNull(imp); 
    7301081    xyzctTest(imp,x,y,z,c,t); 
    7311082 
    7321083    // change data in slice 1, swap to slice 2, swap back, see whether data reverts 
    7331084 
    734     // original way - looks correct 
    7351085    imp.setSlice(1); 
    736     assertEquals(0,(int)imp.getProcessor().getPixelValue(0,10)); 
    737     imp.getProcessor().invert(); 
    738     //IJ.runPlugIn(imp, "Invert", "");  // this makes no difference 
    739     assertEquals(255,(int)imp.getProcessor().getPixelValue(0,10)); 
     1086    assertEquals(1,(int)imp.getProcessor().getPixelValue(1,10)); 
     1087 
     1088    // run a plugin whose changes are recorded 
     1089    WindowManager.setTempCurrentImage(imp); 
     1090    IJ.run("Invert","slice"); 
     1091    assertEquals(254,(int)imp.getProcessor().getPixelValue(1,10)); 
     1092     
    7401093    imp.setSlice(2); 
    741     assertEquals(0,(int)imp.getProcessor().getPixelValue(0,10)); 
     1094    assertEquals(1,(int)imp.getProcessor().getPixelValue(1,10)); 
     1095     
    7421096    imp.setSlice(1); 
    743     int expectedVal = wantToRemember ? 255 : 0; 
    744     assertEquals(expectedVal,(int)imp.getProcessor().getPixelValue(0,10)); 
    745      
    746     /* 
    747     // alternative way - should be equivalent but testing to be sure 
    748     imp.setSlice(1); 
    749     assertEquals(0,(int)imp.getStack().getProcessor(1).getPixelValue(0,10)); 
    750     imp.getStack().getProcessor(1).invert(); 
    751     assertEquals(255,(int)imp.getStack().getProcessor(1).getPixelValue(0,10)); 
    752     imp.setSlice(2); 
    753     assertEquals(0,(int)imp.getStack().getProcessor(2).getPixelValue(0,10)); 
    754     imp.setSlice(1); 
    755     int expectedVal = wantToRemember ? 255 : 0; 
    756     assertEquals(expectedVal,(int)imp.getStack().getProcessor(1).getPixelValue(0,10)); 
    757     */ 
     1097    int expectedVal = wantToRemember ? 254 : 1; 
     1098    assertEquals(expectedVal,(int)imp.getProcessor().getPixelValue(1,10)); 
    7581099  } 
    7591100   
     
    7631104      int tFrom, int tTo, int tBy) 
    7641105  {  
    765     int pixType = FormatTools.UINT8, x=50, y=5, s=-1; 
    766     String path = constructFakeFilename("range", pixType, x, y, z, c, t, s); 
     1106    int pixType = FormatTools.UINT8, x=50, y=5; 
     1107    String path = constructFakeFilename("range", pixType, x, y, z, c, t, -1, false, -1, false, -1); 
    7671108    ImagePlus[] imps = null; 
    7681109    try { 
     
    8061147     
    8071148    // should have the data in one series 
    808     assertNotNull(imps); 
    809     assertEquals(1,imps.length); 
     1149    impsCountTest(imps,1); 
    8101150    ImagePlus imp = imps[0]; 
    8111151    xyzctTest(imp,x,y,numInSeries(zFrom,zTo,zBy),numInSeries(cFrom,cTo,cBy),numInSeries(tFrom,tTo,tBy)); 
     
    8161156  } 
    8171157   
    818   private void memoryCropTest(int pixType, int x, int y, int cx, int cy) 
    819   { 
    820     String path = constructFakeFilename("crop", pixType, x, y, 1, 1, 1, 1); 
     1158  private void memoryCropTest(int x, int y, int ox, int oy, int cropSize) 
     1159  { 
     1160    verifyCropInput(x, y, ox, oy, cropSize);  // needed for this test 
     1161 
     1162    String path = constructFakeFilename("crop", FormatTools.UINT8, x, y, 1, 1, 1, -1, false, -1, false, -1); 
    8211163     
    8221164    // open image 
     
    8261168      options.setId(path); 
    8271169      options.setCrop(true); 
    828       options.setCropRegion(0, new Region(0, 0, cx, cy)); 
     1170      options.setCropRegion(0, new Region(ox, oy, cropSize, cropSize)); 
    8291171      imps = BF.openImagePlus(options); 
    8301172    } 
     
    8371179 
    8381180    // test results 
    839     assertNotNull(imps); 
    840     assertEquals(1,imps.length); 
    841     xyzctTest(imps[0],cx,cy,1,1,1); 
    842   } 
    843    
    844  
     1181    impsCountTest(imps,1); 
     1182    xyzctTest(imps[0],cropSize,cropSize,1,1,1); 
     1183     
     1184    // test we got the right pixels 
     1185    ImageProcessor proc = imps[0].getProcessor(); 
     1186     
     1187    for (int ix = 0; ix < cropSize; ix++) 
     1188      for (int iy = 0; iy < cropSize; iy++) 
     1189        assertEquals(ox+ix,proc.getPixelValue(ix, iy),0); 
     1190  } 
     1191 
     1192  // note - this test needs to rely on crop() to get predictable nonzero minimums 
     1193   
     1194  private void comboCropAndAutoscaleTest(int pixType, int sizeX, int sizeY, int sizeZ, int sizeC, int sizeT, 
     1195      int originCropX, int originCropY, int sizeCrop) 
     1196  { 
     1197    final String path = constructFakeFilename("cropAutoscale",pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
     1198     
     1199    // needed for this test 
     1200    verifyCropInput(sizeX,sizeY,originCropX,originCropY,sizeCrop); 
     1201     
     1202    ImagePlus[] imps = null; 
     1203    ImagePlus imp = null; 
     1204     
     1205    try { 
     1206      ImporterOptions options = new ImporterOptions(); 
     1207      options.setAutoscale(true); 
     1208      options.setCrop(true); 
     1209      options.setCropRegion(0,new Region(originCropX,originCropY,sizeCrop,sizeCrop)); 
     1210      options.setId(path); 
     1211      imps = BF.openImagePlus(options); 
     1212    } 
     1213    catch (IOException e) { 
     1214      fail(e.getMessage()); 
     1215    } 
     1216    catch (FormatException e) { 
     1217      fail(e.getMessage()); 
     1218    } 
     1219     
     1220    impsCountTest(imps,1); 
     1221    imp = imps[0]; 
     1222    xyzctTest(imps[0],sizeCrop,sizeCrop,sizeZ,sizeC,sizeT); 
     1223 
     1224    ImageStack st = imp.getStack(); 
     1225    int numSlices = st.getSize(); 
     1226     
     1227    assertEquals(sizeZ*sizeC*sizeT,numSlices); 
     1228 
     1229    long expectedMax = minPixelValue(pixType) + originCropX + sizeCrop - 1; 
     1230    long expectedMin = minPixelValue(pixType) + originCropX; 
     1231 
     1232    // make sure Calibration is set correctly 
     1233    if (FormatTools.isSigned(pixType) && !FormatTools.isFloatingPoint(pixType)) 
     1234    { 
     1235      Calibration cal = imp.getCalibration(); 
     1236      assertEquals(Calibration.STRAIGHT_LINE,cal.getFunction()); 
     1237      double[] coeffs = cal.getCoefficients(); 
     1238      int bitsPerPix = FormatTools.getBytesPerPixel(pixType) * 8; 
     1239      assertEquals(-(Math.pow(2, (bitsPerPix-1))),coeffs[0],0); 
     1240      assertEquals(1,coeffs[1],0); 
     1241       
     1242      // note - IJ clamps min and max to a range for ShortProcessor (unlike all other processors) 
     1243      if (pixType == FormatTools.INT16)  // hack : clamp like IJ does 
     1244      { 
     1245        if (expectedMin < 0) 
     1246          expectedMin = 0; 
     1247        if (expectedMax > 65535) 
     1248          expectedMax = 65535; 
     1249      } 
     1250    } 
     1251 
     1252    /* 
     1253    System.out.println("comboCropAutoScale :: PixType("+FormatTools.getPixelTypeString(pixType)+")"); 
     1254    System.out.println("  imp max min "+(long)imp.getProcessor().getMax()+" "+(long)imp.getProcessor().getMin()); 
     1255    System.out.println("  exp max min "+expectedMax+" "+expectedMin); 
     1256    */ 
     1257     
     1258    for (int i = 0; i < numSlices; i++) 
     1259    { 
     1260      ImageProcessor proc = st.getProcessor(i+1); 
     1261      assertEquals(expectedMin,proc.getMin(),0.1); 
     1262      assertEquals(expectedMax,proc.getMax(),0.1); 
     1263    } 
     1264  } 
     1265   
     1266  private void comboConcatSplitFocalPlanesTest() 
     1267  { 
     1268    // take a nontrivial zct set of series 
     1269    // run split and concat at same time 
     1270 
     1271    final int sizeX = 50, sizeY = 20, sizeZ = 5, sizeC = 3, sizeT = 7, series = 4; 
     1272    final String path = constructFakeFilename("concatSplitZ", 
     1273      FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, series, false, -1, false, -1); 
     1274 
     1275    // open image 
     1276    ImagePlus[] imps = null; 
     1277    try { 
     1278      ImporterOptions options = new ImporterOptions(); 
     1279      options.setConcatenate(true); 
     1280      options.setSplitFocalPlanes(true); 
     1281      options.setId(path); 
     1282      imps = BF.openImagePlus(options); 
     1283    } 
     1284    catch (IOException e) { 
     1285      fail(e.getMessage()); 
     1286    } 
     1287    catch (FormatException e) { 
     1288      fail(e.getMessage()); 
     1289      } 
     1290     
     1291    // one image per focal plane 
     1292    impsCountTest(imps,sizeZ); 
     1293 
     1294    // from ZCT order: Z pulled out, CT in order 
     1295    for (int z = 0; z < sizeZ; z++) 
     1296    { 
     1297      ImagePlus imp = imps[z]; 
     1298      xyzctTest(imp,sizeX,sizeY,1,sizeC,sizeT); 
     1299      ImageStack st = imp.getStack(); 
     1300      assertEquals(series*sizeC*sizeT,st.getSize()); 
     1301      for (int s = 0; s < series; s++) { 
     1302        int index = s*sizeC*sizeT; 
     1303        for (int t = 0; t < sizeT; t++) { 
     1304          for (int c = 0; c < sizeC; c++) { 
     1305            //System.out.println("index "+index); 
     1306            ImageProcessor proc = st.getProcessor(++index); 
     1307            //System.out.println("s z c t "+s+" "+z+" "+c+" "+t); 
     1308            //System.out.println("z c t "+z+" "+c+" "+t); 
     1309            //System.out.println("is iz ic it "+sIndex(proc)+" "+zIndex(proc)+" "+cIndex(proc)+" "+tIndex(proc)); 
     1310            // test the values 
     1311            assertEquals(z,zIndex(proc)); 
     1312            assertEquals(c,cIndex(proc)); 
     1313            assertEquals(t,tIndex(proc)); 
     1314            assertEquals(s,sIndex(proc)); 
     1315          } 
     1316        } 
     1317      } 
     1318    } 
     1319  } 
     1320   
     1321  private void comboConcatSplitChannelsTest() 
     1322  { 
     1323    // take a nontrivial zct set of series 
     1324    // run split and concat at same time 
     1325 
     1326    final int sizeX = 50, sizeY = 20, sizeZ = 5, sizeC = 3, sizeT = 7, series = 4; 
     1327    final String path = constructFakeFilename("concatSplitC", 
     1328      FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, series, false, -1, false, -1); 
     1329 
     1330    // open image 
     1331    ImagePlus[] imps = null; 
     1332    try { 
     1333      ImporterOptions options = new ImporterOptions(); 
     1334      options.setConcatenate(true); 
     1335      options.setSplitChannels(true); 
     1336      options.setId(path); 
     1337      imps = BF.openImagePlus(options); 
     1338    } 
     1339    catch (IOException e) { 
     1340      fail(e.getMessage()); 
     1341    } 
     1342    catch (FormatException e) { 
     1343      fail(e.getMessage()); 
     1344      } 
     1345     
     1346    // one image per channel 
     1347    impsCountTest(imps,sizeC); 
     1348     
     1349    // from ZCT order: C pulled out, ZT in order 
     1350    for (int c = 0; c < sizeC; c++) 
     1351    { 
     1352      ImagePlus imp = imps[c]; 
     1353      xyzctTest(imp,sizeX,sizeY,sizeZ,1,sizeT); 
     1354      ImageStack st = imp.getStack(); 
     1355      assertEquals(series*sizeZ*sizeT,st.getSize()); 
     1356      for (int s = 0; s < series; s++) { 
     1357        int index = s*sizeZ*sizeT; 
     1358        for (int t = 0; t < sizeT; t++) { 
     1359          for (int z = 0; z < sizeZ; z++) { 
     1360            ImageProcessor proc = st.getProcessor(++index); 
     1361            //System.out.println("index "+index); 
     1362            //System.out.println("s z c t "+s+" "+z+" "+c+" "+t); 
     1363            //System.out.println("iz ic it "+zIndex(proc)+" "+cIndex(proc)+" "+tIndex(proc)); 
     1364            // test the values 
     1365            assertEquals(z,zIndex(proc)); 
     1366            assertEquals(c,cIndex(proc)); 
     1367            assertEquals(t,tIndex(proc)); 
     1368            assertEquals(s,sIndex(proc)); 
     1369          } 
     1370        } 
     1371      } 
     1372    } 
     1373  } 
     1374   
     1375  private void comboConcatSplitTimepointsTest() 
     1376  { 
     1377    // take a nontrivial zct set of series 
     1378    // run split and concat at same time 
     1379 
     1380    final int sizeX = 50, sizeY = 20, sizeZ = 5, sizeC = 3, sizeT = 7, series = 4; 
     1381    final String path = constructFakeFilename("concatSplitT", 
     1382      FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, series, false, -1, false, -1); 
     1383 
     1384    // open image 
     1385    ImagePlus[] imps = null; 
     1386    try { 
     1387      ImporterOptions options = new ImporterOptions(); 
     1388      options.setConcatenate(true); 
     1389      options.setSplitTimepoints(true); 
     1390      options.setId(path); 
     1391      imps = BF.openImagePlus(options); 
     1392    } 
     1393    catch (IOException e) { 
     1394      fail(e.getMessage()); 
     1395    } 
     1396    catch (FormatException e) { 
     1397      fail(e.getMessage()); 
     1398      } 
     1399     
     1400    // one image per time point 
     1401    impsCountTest(imps,sizeT); 
     1402     
     1403    // from ZCT order: T pulled out, ZC in order 
     1404    for (int t = 0; t < sizeT; t++) 
     1405    { 
     1406      ImagePlus imp = imps[t]; 
     1407      xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,1); 
     1408      ImageStack st = imp.getStack(); 
     1409      assertEquals(series*sizeZ*sizeC,st.getSize()); 
     1410      for (int s = 0; s < series; s++) { 
     1411        int index = s*sizeZ*sizeC; 
     1412        for (int c = 0; c < sizeC; c++) { 
     1413          for (int z = 0; z < sizeZ; z++) { 
     1414            ImageProcessor proc = st.getProcessor(++index); 
     1415            //System.out.println("index "+index); 
     1416            //System.out.println("s z c t "+s+" "+z+" "+c+" "+t); 
     1417            //System.out.println("iz ic it "+zIndex(proc)+" "+cIndex(proc)+" "+tIndex(proc)); 
     1418            // test the values 
     1419            assertEquals(z,zIndex(proc)); 
     1420            assertEquals(c,cIndex(proc)); 
     1421            assertEquals(t,tIndex(proc)); 
     1422            assertEquals(s,sIndex(proc)); 
     1423          } 
     1424        } 
     1425      } 
     1426    } 
     1427  } 
     1428   
    8451429// ** ImporterTest methods ************************************************************** 
    8461430 
     
    8541438    defaultBehaviorTest(FormatTools.INT32, 158, 99, 2, 3, 4); 
    8551439    defaultBehaviorTest(FormatTools.INT8, 232, 153, 3, 7, 5); 
     1440    defaultBehaviorTest(FormatTools.FLOAT, 73, 99, 3, 4, 5); 
     1441    defaultBehaviorTest(FormatTools.DOUBLE, 106, 44, 5, 5, 4); 
    8561442  } 
    8571443 
     
    8601446  { 
    8611447    for (ChannelOrder order : ChannelOrder.values()) 
    862       outputStackOrderTest(FormatTools.UINT8, order.toString(),  82, 47, 2, 3, 4); 
     1448      outputStackOrderTest(FormatTools.UINT8, order,  82, 47, 2, 3, 4); 
    8631449  } 
    8641450     
     
    8831469      } 
    8841470     
    885     assertEquals(1,imps.length); 
    886     assertEquals(105,imps[0].getStack().getSize()); 
     1471    impsCountTest(imps,1); 
     1472     
     1473    ImageStack st = imps[0].getStack(); 
     1474     
     1475    assertEquals(FAKE_FILES.length*FakePlaneCount,st.getSize()); 
     1476     
     1477    int slice = 1; 
     1478    for (int fnum = 0; fnum < FAKE_FILES.length; fnum++) 
     1479    { 
     1480      for (int plane = 0; plane < FakePlaneCount; plane++) 
     1481      { 
     1482        ImageProcessor proc = st.getProcessor(slice++); 
     1483        //printVals(proc); 
     1484        assertEquals(0,sIndex(proc)); 
     1485        assertEquals(plane,iIndex(proc)); 
     1486        assertEquals(plane,zIndex(proc)); 
     1487        assertEquals(0,cIndex(proc)); 
     1488        assertEquals(0,tIndex(proc)); 
     1489      } 
     1490    } 
    8871491  } 
    8881492 
     
    9151519    // test results 
    9161520     
    917     assertEquals(1,imps.length); 
     1521    impsCountTest(imps,1); 
    9181522    assertEquals(16,imps[0].getStack().getSize());  // one loaded as one set with 16 slices 
    9191523     
     
    9351539    // test results 
    9361540     
    937     assertEquals(1,imps.length); 
     1541    impsCountTest(imps,1); 
    9381542    assertEquals(32,imps[0].getStack().getSize());  // both loaded as one set of 32 slices 
    9391543  } 
     
    9421546  public void testDatasetSwapDims() 
    9431547  { 
    944     // TODO: testing only swapping Z&T of XYZTC. Add more option testing 
     1548    // TODO: testing only swapping Z&T of XYZTC. Add more option testing. 
     1549    //   Note that testComboManyOptions() tests another swap order 
    9451550 
    9461551    datasetSwapDimsTest(FormatTools.UINT8, 82, 47, 1, 3); 
     
    9481553    datasetSwapDimsTest(FormatTools.UINT16, 82, 47, 5, 2); 
    9491554    datasetSwapDimsTest(FormatTools.UINT32, 82, 47, 5, 2); 
    950     datasetSwapDimsTest(FormatTools.INT8, 44, 109, 1, 4); 
    951     datasetSwapDimsTest(FormatTools.INT16, 44, 109, 2, 1); 
    952     datasetSwapDimsTest(FormatTools.INT32, 44, 109, 4, 3); 
    953     datasetSwapDimsTest(FormatTools.UINT8, 82, 47, 3, 2); 
     1555    datasetSwapDimsTest(FormatTools.INT8, 44, 108, 1, 4); 
     1556    datasetSwapDimsTest(FormatTools.INT16, 44, 108, 2, 1); 
     1557    datasetSwapDimsTest(FormatTools.INT32, 44, 108, 4, 3); 
     1558    datasetSwapDimsTest(FormatTools.FLOAT, 67, 109, 4, 3); 
     1559    datasetSwapDimsTest(FormatTools.DOUBLE, 67, 100, 3, 2); 
    9541560  } 
    9551561 
     
    9661572  { 
    9671573    // open a dataset that has multiple series and should get back a single series 
    968     datasetConcatenateTest(FormatTools.UINT8, "XYZCT", 82, 47, 1, 1, 1, 1); 
    969     datasetConcatenateTest(FormatTools.UINT8, "XYZCT", 82, 47, 1, 1, 1, 17); 
    970     datasetConcatenateTest(FormatTools.UINT8, "XYZCT", 82, 47, 4, 5, 2, 9); 
     1574    datasetConcatenateTest(FormatTools.UINT8, 82, 47, 1, 1, 1, 1); 
     1575    datasetConcatenateTest(FormatTools.UINT8, 82, 47, 1, 1, 1, 17); 
     1576    datasetConcatenateTest(FormatTools.UINT8, 82, 47, 4, 5, 2, 9); 
    9711577  } 
    9721578 
     
    9741580  public void testColorDefault() 
    9751581  { 
    976     int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4, numSeries = 3; 
    977      
    978     String path = constructFakeFilename("colorized", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries); 
     1582    int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4; 
     1583     
     1584    String path = constructFakeFilename("colorDefault", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
    9791585     
    9801586    ImagePlus[] imps = null; 
     
    9941600    } 
    9951601 
    996     assertEquals(1,imps.length); 
     1602    impsCountTest(imps,1); 
    9971603     
    9981604    imp = imps[0]; 
     
    10011607     
    10021608    assertFalse(imp.isComposite()); 
     1609 
     1610    // TODO - not a composite - need to determine what to test 
    10031611     
    10041612    fail("unfinished"); 
     
    10081616  public void testColorComposite() 
    10091617  { 
    1010     int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4, numSeries = 3; 
    1011      
    1012     String path = constructFakeFilename("colorized", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries); 
    1013      
    1014     ImagePlus[] imps = null; 
    1015     ImagePlus imp = null; 
    1016     CompositeImage ci = null; 
    1017      
    1018     try { 
    1019       ImporterOptions options = new ImporterOptions(); 
    1020       options.setColorMode(ImporterOptions.COLOR_MODE_COMPOSITE); 
    1021       options.setId(path); 
    1022       imps = BF.openImagePlus(options); 
    1023     } 
    1024     catch (IOException e) { 
    1025       fail(e.getMessage()); 
    1026     } 
    1027     catch (FormatException e) { 
    1028       fail(e.getMessage()); 
    1029     } 
    1030  
    1031     assertEquals(1,imps.length); 
    1032      
    1033     imp = imps[0]; 
    1034      
    1035     xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,sizeT); 
    1036      
    1037     assertTrue(imp.isComposite()); 
    1038      
    1039     ci = (CompositeImage)imp; 
    1040      
    1041     assertFalse(ci.hasCustomLuts()); 
    1042     assertArrayEquals(new int[]{0,0,0,0}, ci.getPixel(55,22)); 
    1043     fail("unfinished"); 
     1618    // BF only supporting C from 2 to 7 and due to IJ's slider limitation (C*numSeries*3) <= 25 
     1619 
     1620    // these here to simplify debugging 
     1621    colorCompositeTest(FormatTools.UINT8,false,1,false,3,1); 
     1622    colorCompositeTest(FormatTools.UINT8,true,1,false,3,1); 
     1623 
     1624    int[] pixTypes = new int[] {FormatTools.UINT8}; 
     1625    int[] cs = new int[] {2,3,4,5,6,7};  // all that BF/IJ supports right now 
     1626    int[] ts = new int[] {1,2}; 
     1627    int[] series = new int[] {1,2,3,4}; 
     1628    int[] rgbs = new int[]{1,2,3}; 
     1629     
     1630    for (int pixFormat : pixTypes) 
     1631      for (int c : cs) 
     1632        for (int t : ts) 
     1633          for (int s : series) 
     1634            if ((c*s*3) <= 25)  // IJ slider limitation 
     1635              for (int rgb : rgbs) 
     1636                for (boolean indexed : BooleanStates) 
     1637                  for (boolean falseColor : BooleanStates) 
     1638                  { 
     1639                    //System.out.println(" format "+pixFormat+"indexed "+indexed+" rgb "+rgb+" fasleColor "+falseColor+" c "+c+" s "+s); 
     1640                    colorCompositeTest(pixFormat,indexed,rgb,falseColor,c,s); 
     1641                  } 
    10441642  } 
    10451643   
     
    10471645  public void testColorColorized() 
    10481646  { 
    1049     int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4, numSeries = 3; 
    1050      
    1051     String path = constructFakeFilename("colorized", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries); 
    1052      
    1053     ImagePlus[] imps = null; 
    1054     ImagePlus imp = null; 
    1055     CompositeImage ci = null; 
    1056      
    1057     try { 
    1058       ImporterOptions options = new ImporterOptions(); 
    1059       options.setColorMode(ImporterOptions.COLOR_MODE_COLORIZED); 
    1060       options.setId(path); 
    1061       imps = BF.openImagePlus(options); 
    1062     } 
    1063     catch (IOException e) { 
    1064       fail(e.getMessage()); 
    1065     } 
    1066     catch (FormatException e) { 
    1067       fail(e.getMessage()); 
    1068     } 
    1069  
    1070     assertEquals(1,imps.length); 
    1071      
    1072     imp = imps[0]; 
    1073      
    1074     xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,sizeT); 
    1075      
    1076     assertTrue(imp.isComposite()); 
    1077      
    1078     ci = (CompositeImage)imp; 
    1079      
    1080     assertFalse(ci.hasCustomLuts()); 
    1081     assertArrayEquals(new int[]{0,0,0,0}, ci.getPixel(55,22)); 
    1082     fail("unfinished"); 
     1647    colorColorizedTest(); 
    10831648  } 
    10841649   
     
    10861651  public void testColorGrayscale() 
    10871652  { 
    1088     int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4, numSeries = 3; 
    1089      
    1090     String path = constructFakeFilename("colorized", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries); 
    1091      
    1092     ImagePlus[] imps = null; 
    1093     ImagePlus imp = null; 
    1094     CompositeImage ci = null; 
    1095      
    1096     try { 
    1097       ImporterOptions options = new ImporterOptions(); 
    1098       options.setColorMode(ImporterOptions.COLOR_MODE_GRAYSCALE); 
    1099       options.setId(path); 
    1100       imps = BF.openImagePlus(options); 
    1101     } 
    1102     catch (IOException e) { 
    1103       fail(e.getMessage()); 
    1104     } 
    1105     catch (FormatException e) { 
    1106       fail(e.getMessage()); 
    1107     } 
    1108  
    1109     assertEquals(1,imps.length); 
    1110      
    1111     imp = imps[0]; 
    1112      
    1113     xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,sizeT); 
    1114      
    1115     assertTrue(imp.isComposite()); 
    1116      
    1117     ci = (CompositeImage)imp; 
    1118      
    1119     assertFalse(ci.hasCustomLuts()); 
    1120     assertArrayEquals(new int[]{0,0,0,0}, ci.getPixel(55,22)); 
    1121     fail("unfinished"); 
     1653    colorGrayscaleTest(); 
    11221654  } 
    11231655   
     
    11251657  public void testColorCustom() 
    11261658  { 
    1127     int sizeX = 100, sizeY = 120, sizeZ = 2, sizeC = 7, sizeT = 4, numSeries = 3; 
    1128      
    1129     String path = constructFakeFilename("colorized", FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries); 
    1130      
    1131     ImagePlus[] imps = null; 
    1132     ImagePlus imp = null; 
    1133     CompositeImage ci = null; 
    1134      
    1135     try { 
    1136       ImporterOptions options = new ImporterOptions(); 
    1137       options.setColorMode(ImporterOptions.COLOR_MODE_CUSTOM); 
    1138       int series = 0; int channel = 0; 
    1139       options.setCustomColor(series, channel, Color.BLUE); 
    1140       options.setId(path); 
    1141       imps = BF.openImagePlus(options); 
    1142     } 
    1143     catch (IOException e) { 
    1144       fail(e.getMessage()); 
    1145     } 
    1146     catch (FormatException e) { 
    1147       fail(e.getMessage()); 
    1148     } 
    1149  
    1150     assertEquals(1,imps.length); 
    1151      
    1152     imp = imps[0]; 
    1153      
    1154     xyzctTest(imp,sizeX,sizeY,sizeZ,sizeC,sizeT); 
    1155      
    1156     assertTrue(imp.isComposite()); 
    1157      
    1158     ci = (CompositeImage)imp; 
    1159      
    1160     assertFalse(ci.hasCustomLuts()); 
    1161     assertArrayEquals(new int[]{0,0,0,0}, ci.getPixel(55,22)); 
    1162     fail("unfinished"); 
    1163   } 
    1164    
    1165   /* 
    1166   @Test 
    1167   public void testColorMerge() 
    1168   { 
    1169      
    1170     String path = FAKE_FILES[0]; 
    1171      
    1172     ImagePlus[] imps = null; 
    1173     ImagePlus imp = null; 
    1174      
    1175     // test when color merge false 
    1176  
    1177     // open file 
    1178     try { 
    1179       ImporterOptions options = new ImporterOptions(); 
    1180       options.setMergeChannels(false); 
    1181       options.setId(path); 
    1182       imps = BF.openImagePlus(options); 
    1183     } 
    1184     catch (IOException e) { 
    1185       fail(e.getMessage()); 
    1186     } 
    1187     catch (FormatException e) { 
    1188       fail(e.getMessage()); 
    1189     } 
    1190      
    1191     // test results 
    1192     assertEquals(1,imps.length); 
    1193     imp = imps[0]; 
    1194     assertEquals(3,getEffectiveSizeC(imp));  // unmerged 
    1195     assertEquals(7,getSizeZ(imp)); 
    1196     assertEquals(5,getSizeT(imp)); 
    1197      
    1198     // test when color merge true 
    1199      
    1200     // open file 
    1201     try { 
    1202       ImporterOptions options = new ImporterOptions(); 
    1203       options.setMergeChannels(true); 
    1204       options.setId(path); 
    1205       imps = BF.openImagePlus(options); 
    1206     } 
    1207     catch (IOException e) { 
    1208       fail(e.getMessage()); 
    1209     } 
    1210     catch (FormatException e) { 
    1211       fail(e.getMessage()); 
    1212     } 
    1213      
    1214     // test results 
    1215     assertEquals(1,imps.length); 
    1216     imp = imps[0]; 
    1217     assertTrue(imp.getHeight() > 10);  // required for this test to work 
    1218     assertEquals(1, getEffectiveSizeC(imp));  // merged 
    1219     assertEquals(7, getSizeZ(imp)); 
    1220     assertEquals(5, getSizeT(imp)); 
    1221     for (int i = 0; i < 10; i++) 
    1222       assertEquals(mergedPixel(i),imp.getProcessor().get(i,10)); 
    1223      
    1224     // TODO - also test mergeOptions when chans > 3. it will be an int == chans per plane. extra blank images are 
    1225     //   added as needed to make multiple images each with same number of channels 
    1226     //   i.e. 6 channels can -> 123/456 or 12/34/56 or 1/2/3/4/5/6 (last one not merged ???) 
    1227     //        5 channels can -> 123/45b or 12/34/5b or 1/2/3/4/5 (last one not merged ???) 
    1228      
    1229     fail("unfinished implementation"); 
    1230   } 
    1231    
    1232   @Test 
    1233   public void testColorRgbColorize() 
    1234   { 
    1235     // From BF: RGB colorize channels - Each channel is assigned an appropriate pseudocolor table rather than the normal 
    1236     // grayscale.  The first channel is colorized red, the second channel is green, and the third channel is blue. This 
    1237     // option is not available when Merge channels to RGB or Custom colorize channels are set. 
    1238      
    1239     String path = FAKE_FILES[0]; 
    1240      
    1241     ImagePlus[] imps = null; 
    1242     ImagePlus imp = null; 
    1243  
    1244     // TODO - should not allow mergeChannels with rgb colorize 
    1245     try { 
    1246       ImporterOptions options = new ImporterOptions(); 
    1247       options.setColorize(true); 
    1248       options.setMergeChannels(true); 
    1249       options.setId(path); 
    1250       imps = BF.openImagePlus(options); 
    1251       // TODO - eventually fail() here but need BF support first I think 
    1252     } 
    1253     catch (IOException e) { 
    1254       fail(e.getMessage()); 
    1255     } 
    1256     catch (FormatException e) { 
    1257       fail(e.getMessage()); 
    1258     } 
    1259      
    1260     // TODO - should not allow mergeChannels with custom colorize 
    1261     try { 
    1262       ImporterOptions options = new ImporterOptions(); 
    1263       options.setColorize(true); 
    1264       options.setCustomColorize(true); 
    1265       options.setId(path); 
    1266       imps = BF.openImagePlus(options); 
    1267       // TODO - eventually fail() here but need BF support first I think 
    1268     } 
    1269     catch (IOException e) { 
    1270       fail(e.getMessage()); 
    1271     } 
    1272     catch (FormatException e) { 
    1273       fail(e.getMessage()); 
    1274     } 
    1275  
    1276     // TODO - legitimate testing 
    1277     // open file 
    1278     try { 
    1279       ImporterOptions options = new ImporterOptions(); 
    1280       options.setColorize(true); 
    1281       options.setId(path); 
    1282       imps = BF.openImagePlus(options); 
    1283     } 
    1284     catch (IOException e) { 
    1285       fail(e.getMessage()); 
    1286     } 
    1287     catch (FormatException e) { 
    1288       fail(e.getMessage()); 
    1289     } 
    1290      
    1291     assertEquals(1,imps.length); 
    1292     imp = imps[0]; 
    1293     assertEquals(7,getSizeZ(imp)); 
    1294     assertEquals(1,getEffectiveSizeC(imp));  // TODO : correct? 
    1295     assertEquals(1,getSizeT(imp));  // TODO : huh? 
    1296      
    1297     // TODO - actual tests of data 
    1298      
    1299     fail("unfinished implementation"); 
    1300   } 
    1301  
    1302   @Test 
    1303   public void testColorCustomColorize() 
    1304   { 
    1305     // From BF: Custom colorize channels - Each channel is assigned a pseudocolor table rather than the normal grayscale. 
    1306     //   The color for each channel is chosen by the user. This option is not available when Merge channels to RGB or RGB 
    1307     //   colorize channels are set. 
    1308      
    1309     // TODO 
    1310     fail("to be implemented"); 
    1311   } 
    1312   */ 
     1659    // BF only supporting C from 2 to 7 and due to IJ's slider limitation (C*numSeries*3) <= 25 
     1660     
     1661    int[] pixTypes = new int[]{FormatTools.UINT8, FormatTools.UINT16, FormatTools.FLOAT}; 
     1662    int[] xs = new int[] {45}; 
     1663    int[] ys = new int[] {14}; 
     1664    int[] zs = new int[] {1,2}; 
     1665    int[] cs = new int[] {2,3,4,5,6,7};  // all that BF/IJ supports right now 
     1666    int[] ts = new int[] {1,2}; 
     1667    int[] series = new int[] {1,2,3,4}; 
     1668     
     1669    for (int pixFormat : pixTypes) 
     1670      for (int x : xs) 
     1671        for (int y : ys) 
     1672          for (int z : zs) 
     1673            for (int c : cs) 
     1674              for (int t : ts) 
     1675                for (int s : series) 
     1676                  if ((c*s*3) <= 25)  // IJ slider limitation 
     1677                  { 
     1678                    //System.out.println("format "+pixFormat+" x "+x+" y "+y+" z "+z+" c "+c+" t "+t+" s "+s); 
     1679                    colorCustomTest(pixFormat,x,y,z,c,t,s); 
     1680                  } 
     1681  } 
    13131682   
    13141683  @Test 
    13151684  public void testColorAutoscale() 
    13161685  { 
    1317      
    13181686    // From BF: 
    13191687    // Autoscale - Stretches the histogram of the image planes to fit the data range. Does not alter underlying values in 
     
    13211689    // throughout the stack. 
    13221690 
    1323     autoscaleTest(FormatTools.UINT8,false); 
    1324     autoscaleTest(FormatTools.UINT16,false); 
    1325     autoscaleTest(FormatTools.UINT32,false); 
    1326     autoscaleTest(FormatTools.INT8,false); 
    1327     autoscaleTest(FormatTools.INT16,false); 
    1328     autoscaleTest(FormatTools.INT32,false); 
    1329     autoscaleTest(FormatTools.DOUBLE,false); 
    1330     autoscaleTest(FormatTools.FLOAT,false); 
    1331      
    1332     autoscaleTest(FormatTools.UINT8,true); 
    1333     autoscaleTest(FormatTools.UINT16,true); 
    1334     autoscaleTest(FormatTools.UINT32,true); 
    1335     autoscaleTest(FormatTools.INT8,true); 
    1336     //autoscaleTest(FormatTools.INT16,true);  // TODO in this case IJ via ShortProcessor::setMinAndMax() clamps the min value to 0 : bug due to obliviousness to sign? 
    1337     autoscaleTest(FormatTools.INT32,true); 
    1338     autoscaleTest(FormatTools.DOUBLE,true); 
    1339     autoscaleTest(FormatTools.FLOAT,true); 
    1340  
    1341     /* 
    1342     // TODO - delete above code when tests are passing 
    13431691    for (int pixType : PixelTypes) 
    13441692    { 
     
    13491697      } 
    13501698    } 
    1351     */ 
    13521699  } 
    13531700 
     
    14541801    try { 
    14551802      z=7; c=7; t=7; zFrom=0; zTo=z-1; zBy=0; cFrom=0; cTo=c-1; cBy=1; tFrom=0; tTo=t-1; tBy=1; 
    1456       // TODO - enable post fix 
    1457       //memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
    1458       //fail(); 
     1803      memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
     1804      fail(); 
    14591805    } catch (IllegalArgumentException e) { 
    14601806      assertTrue(true); 
     
    14821828    try { 
    14831829      z=7; c=7; t=7; zFrom=0; zTo=z-1; zBy=1; cFrom=0; cTo=c-1; cBy=0; tFrom=0; tTo=t-1; tBy=1; 
    1484       // TODO - enable post fix 
    1485       //memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
    1486       //fail(); 
     1830      memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
     1831      fail(); 
    14871832    } catch (IllegalArgumentException e) { 
    14881833      assertTrue(true); 
     
    15101855    try { 
    15111856      z=7; c=7; t=7; zFrom=0; zTo=z-1; zBy=1; cFrom=0; cTo=c-1; cBy=1; tFrom=0; tTo=t-1; tBy=0; 
    1512       // TODO - enable post fix 
    1513       //memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
    1514       //fail(); 
     1857      memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
     1858      fail(); 
    15151859    } catch (IllegalArgumentException e) { 
    15161860      assertTrue(true); 
    15171861    } 
    15181862     
    1519     /* TODO - enable when step by 0 code fixed and remove extra tests above 
    1520     // uber combo test 
     1863    /* TODO - could replace above code with this uber combo test 
     1864    // comprehensive but probably WAY too much computation to finish in reasonable time 
    15211865    z = 6; c = 5; t = 4; 
    15221866    for (int zStart = -1; zStart < z+2; zStart++) 
     
    15291873                  for (int tEnd = -1; tEnd < t+2; tEnd++) 
    15301874                    for (int tInc = -1; tInc < t+2; tInc++) 
     1875                      // if an invalid index of some kind 
    15311876                      if ((zStart < 0) || (zStart >= z) || 
    1532                           (zEnd < 0) || (zEnd >= z) || (zEnd < zStart) || 
     1877                          (zEnd < 0) || (zEnd >= z) || // ignored by BF (zEnd < zStart) || 
    15331878                          (zInc < 1) || 
    15341879                          (cStart < 0) || (cStart >= c) || 
    1535                           (cEnd < 0) || (cEnd >= c) || (cEnd < cStart) || 
     1880                          (cEnd < 0) || (cEnd >= c) || // ignored by BF (cEnd < cStart) || 
    15361881                          (cInc < 1) || 
    15371882                          (tStart < 0) || (tStart >= t) || 
    1538                           (tEnd < 0) || (tEnd >= z) || (tEnd < tStart) || 
     1883                          (tEnd < 0) || (tEnd >= t) || // ignored by BF (tEnd < tStart) || 
    15391884                          (tInc < 1)) 
    15401885                      { 
     1886                        // expect failure 
    15411887                        try { 
    15421888                          memorySpecifyRangeTest(z,c,t,zFrom,zTo,zBy,cFrom,cTo,cBy,tFrom,tTo,tBy); 
     
    15511897                      } 
    15521898                      else 
     1899                        // expect success 
    15531900                        memorySpecifyRangeTest(z,c,t,zStart,zEnd,zInc,cStart,cEnd,cInc,tStart,tEnd,tInc); 
    15541901    */ 
     
    15591906  public void testMemoryCrop() 
    15601907  { 
    1561     memoryCropTest(FormatTools.UINT8, 203, 409, 185, 104); 
    1562     memoryCropTest(FormatTools.UINT8, 203, 409, 203, 409); 
    1563     memoryCropTest(FormatTools.UINT8, 100, 30, 3, 3); 
    1564     memoryCropTest(FormatTools.INT32, 100, 30, 3, 3); 
     1908    memoryCropTest(203, 255, 55, 20, 3); 
     1909    memoryCropTest(203, 184, 55, 40, 2); 
     1910    memoryCropTest(101, 76, 0, 25, 4); 
     1911    memoryCropTest(100, 122, 0, 15, 3); 
    15651912  } 
    15661913   
     
    15701917    final int sizeX = 50, sizeY = 20, sizeZ = 5, sizeC = 3, sizeT = 7; 
    15711918    final String path = constructFakeFilename("splitC", 
    1572       FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1); 
     1919      FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
    15731920 
    15741921    // open image 
     
    15871934    } 
    15881935 
    1589     // one channel per image 
    1590     assertEquals(sizeC,imps.length); 
     1936    // one image per channel 
     1937    impsCountTest(imps,sizeC); 
    15911938     
    15921939    // unwind ZCT loop : C pulled outside, ZT in order 
     
    16141961    final int sizeX = 50, sizeY = 20, sizeZ = 5, sizeC = 3, sizeT = 7; 
    16151962    final String path = constructFakeFilename("splitZ", 
    1616       FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1); 
     1963      FormatTools.UINT8, sizeX, sizeY, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
    16171964 
    16181965    // open image 
     
    16311978      } 
    16321979     
    1633     // one focal plane per image 
    1634     assertEquals(sizeZ,imps.length); 
     1980    // one image per focal plane 
     1981    impsCountTest(imps,sizeZ); 
    16351982 
    16361983    // unwind ZCT loop : Z pulled outside, CT in order 
     
    16582005    final int sizeX = 50, sizeY = 20, sizeZ = 5, sizeC = 3, sizeT = 7; 
    16592006    final String path = constructFakeFilename("splitT", 
    1660       FormatTools.UINT8, 50, 20, sizeZ, sizeC, sizeT, -1); 
     2007      FormatTools.UINT8, 50, 20, sizeZ, sizeC, sizeT, -1, false, -1, false, -1); 
    16612008 
    16622009    // open image 
     
    16752022      } 
    16762023     
    1677     // one time point per image 
    1678     assertEquals(sizeT,imps.length); 
     2024    // one image per time point 
     2025    impsCountTest(imps,sizeT); 
    16792026     
    16802027    // unwind ZTC loop : T pulled outside, ZC in order 
     
    16982045 
    16992046  @Test 
     2047  public void testMacros() 
     2048  { 
     2049    //IJ.runMacro("Bio-Formats Importer", "open=int8&pixelType=int8&sizeZ=3&sizeC=5&sizeT=7&sizeY=50.fake merge_channels stack_order=Default"); 
     2050    fail("unimplemented"); 
     2051  } 
     2052   
     2053  @Test 
    17002054  public void testComboCropAutoscale() 
    17012055  { 
    17022056    // try a simple test: single small byte type image  
    1703     cropAndAutoscaleTest(FormatTools.UINT8,100,80,1,1,1,1,70,40,25); 
     2057    comboCropAndAutoscaleTest(FormatTools.UINT8,240,240,1,1,1,70,40,25); 
    17042058     
    17052059    // try multiple dimensions 
    1706     cropAndAutoscaleTest(FormatTools.UINT8,84,63,4,3,2,5,51,8,13); 
     2060    comboCropAndAutoscaleTest(FormatTools.UINT8,240,240,4,3,2,51,15,13); 
    17072061     
    17082062    // try various pixTypes 
    17092063    for (int pixType : PixelTypes) 
    1710       cropAndAutoscaleTest(pixType,96,96,2,2,2,2,70,60,10); 
     2064      comboCropAndAutoscaleTest(pixType,240,240,2,2,2,225,225,10); 
     2065  } 
     2066   
     2067  @Test 
     2068  public void testComboConcatColorize() 
     2069  { 
     2070    fail("unimplemented"); 
     2071  } 
     2072 
     2073  @Test 
     2074  public void testComboConcatSplitZ() 
     2075  { 
     2076    comboConcatSplitFocalPlanesTest(); 
     2077  } 
     2078 
     2079  @Test 
     2080  public void testComboConcatSplitC() 
     2081  { 
     2082    comboConcatSplitChannelsTest(); 
     2083  } 
     2084 
     2085  @Test 
     2086  public void testComboConcatSplitT() 
     2087  { 
     2088    comboConcatSplitTimepointsTest(); 
     2089  } 
     2090 
     2091  @Test 
     2092  public void testComboColorizeSplit() 
     2093  { 
     2094    fail("unimplemented"); 
     2095  } 
     2096   
     2097  @Test 
     2098  public void testComboConcatColorizeSplit() 
     2099  { 
     2100    fail("unimplemented"); 
     2101  } 
     2102   
     2103  @Test 
     2104  public void testComboManyOptions() 
     2105  { 
     2106    int pixType = FormatTools.UINT16, sizeX = 106, sizeY = 33, sizeZ = 3, sizeC = 5, sizeT = 7; 
     2107    int cropOriginX = 0, cropOriginY = 0, cropSizeX = 55, cropSizeY = 16, start = 1, stepBy = 2; 
     2108    ChannelOrder swappedOrder = ChannelOrder.CTZ;  // orig is ZCT : this is a deadly swap of all dims 
     2109 
     2110    // note - to reuse existing code it is necessary that the crop origin is (0,0) 
     2111     
     2112    String path = constructFakeFilename("superCombo", pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, 1, false, -1, false, -1); 
     2113   
     2114    ImagePlus[] imps = null; 
     2115    try { 
     2116      ImporterOptions options = new ImporterOptions(); 
     2117      options.setId(path); 
     2118      options.setSwapDimensions(true); 
     2119      options.setInputOrder(0, bfChanOrd(swappedOrder)); 
     2120      options.setCrop(true); 
     2121      options.setCropRegion(0, new Region(cropOriginX,cropOriginY,cropSizeX,cropSizeY)); 
     2122      options.setTStep(0, stepBy); 
     2123      options.setTBegin(0, start); 
     2124      options.setSplitFocalPlanes(true); 
     2125      imps = BF.openImagePlus(options); 
     2126    } 
     2127    catch (IOException e) { 
     2128      fail(e.getMessage()); 
     2129    } 
     2130    catch (FormatException e) { 
     2131      fail(e.getMessage()); 
     2132    } 
     2133 
     2134    impsCountTest(imps,sizeT);  // we split on Z but that dim was swapped with T 
     2135 
     2136    for (int zIndex = 0; zIndex < sizeT; zIndex++)  // sizeT = Z 
     2137    { 
     2138      ImagePlus imp = imps[zIndex]; 
     2139       
     2140      int numC = numInSeries(start,sizeC-1,stepBy); 
     2141 
     2142      xyzctTest(imp,cropSizeX,cropSizeY,1,sizeZ,numC); // all dims changed 
     2143   
     2144      ImageStack st = imp.getStack(); 
     2145      assertEquals(sizeZ*numC,st.getSize());  // sizeZ = C, numC = T 
     2146       
     2147      int p = 1; 
     2148      for (int tIndex = start; tIndex < sizeC; tIndex += stepBy) 
     2149        for (int cIndex = 0; cIndex < sizeZ; cIndex++) 
     2150        { 
     2151          ImageProcessor proc = st.getProcessor(p++); 
     2152           
     2153          assertEquals(cropSizeX,proc.getWidth()); 
     2154          assertEquals(cropSizeY,proc.getHeight()); 
     2155 
     2156          final int actualZ = tIndex(proc); 
     2157          final int actualC = zIndex(proc); 
     2158          final int actualT = cIndex(proc); 
     2159           
     2160          assertEquals(zIndex, actualZ); 
     2161          assertEquals(cIndex, actualC); 
     2162          assertEquals(tIndex, actualT); 
     2163        } 
     2164    } 
     2165  } 
     2166 
     2167  private void colorColorizedTester(int pixType, int sizeC, int rgb, boolean indexed, boolean falseColor, int lutLen) 
     2168  { 
     2169    if ((pixType != FormatTools.UINT8) && (pixType != FormatTools.UINT16)) 
     2170      throw new IllegalArgumentException("colorColorizedTester(): passed an invalid pixelType: not UINT8 or UINT16 ("+pixType+")"); 
     2171 
     2172    if (sizeC % rgb != 0) 
     2173      throw new IllegalArgumentException("colorColorizedTester() passed a bad combo of sizeC and rgb: "+sizeC+" "+rgb); 
     2174 
     2175    int totalChannels = sizeC; 
     2176    int channelsPerPlane = rgb; 
     2177    int totalPlanes = totalChannels / channelsPerPlane; 
     2178 
     2179    if (channelsPerPlane > 7) 
     2180      throw new IllegalArgumentException("colorColorizedTester() passed bad sizeC - channelsPerPlane > 7 : "+channelsPerPlane); 
     2181     
     2182    int sizeX = 60, sizeY = 30, sizeZ = 1, sizeT = 1, numSeries = 1; 
     2183     
     2184    String path = constructFakeFilename("colorColorized", pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, numSeries, indexed, rgb, falseColor, lutLen); 
     2185 
     2186    ImagePlus[] imps = null; 
     2187    ImagePlus imp = null; 
     2188    CompositeImage ci = null; 
     2189     
     2190    try { 
     2191      ImporterOptions options = new ImporterOptions(); 
     2192      options.setColorMode(ImporterOptions.COLOR_MODE_COLORIZED); 
     2193      options.setId(path); 
     2194      imps = BF.openImagePlus(options); 
     2195    } 
     2196    catch (IOException e) { 
     2197      fail(e.getMessage()); 
     2198    } 
     2199    catch (FormatException e) { 
     2200      fail(e.getMessage()); 
     2201    } 
     2202 
     2203    impsCountTest(imps,1); 
     2204     
     2205    imp = imps[0]; 
     2206    
     2207    System.out.println("  Returned imp: Z = " +imp.getNSlices()+ " C = " +imp.getNChannels()+" T = "+imp.getNFrames()); 
     2208    for (int cIndex = 0; cIndex < imp.getNChannels(); cIndex++) 
     2209      for (int zIndex = 0; zIndex < imp.getNSlices(); zIndex++) 
     2210        for (int tIndex = 0; tIndex < imp.getNFrames(); tIndex++) 
     2211        { 
     2212          imp.setPosition(cIndex+1,zIndex+1,tIndex+1); 
     2213          ImageProcessor proc = imp.getProcessor(); 
     2214          printVals(proc); 
     2215        } 
     2216     
     2217    if (lutLen == -1) 
     2218      lutLen = 3; 
     2219 
     2220    int expectedSizeC = effectiveC(sizeC, rgb, lutLen, indexed, falseColor); 
     2221       
     2222    //System.out.println("  chans channsPerPlane planes expectedSizeC "+totalChannels+" "+channelsPerPlane+" "+totalPlanes+" "+expectedSizeC); 
     2223 
     2224    xyzctTest(imp,sizeX,sizeY,sizeZ,expectedSizeC,sizeT); 
     2225 
     2226    // TODO: the following code conditional as BF sometimes does not return a CompositeImage. Handle better after BF 
     2227    //   changed and after I've handled all special cases. 
     2228   
     2229    if (imp.isComposite()) 
     2230    { 
     2231      ci = (CompositeImage)imp; 
     2232     
     2233      assertFalse(ci.hasCustomLuts()); 
     2234 
     2235      assertEquals(CompositeImage.COLOR, ci.getMode()); 
     2236     
     2237      // TODO - falseColor stuff needs to be impl 
     2238      if (!falseColor) 
     2239        colorTests(ci,expectedSizeC,DefaultColorOrder); 
     2240       
     2241    } 
     2242    else 
     2243      System.out.println("  Not a composite image"); 
     2244 
     2245    int iIndex = 0; 
     2246    for (int cIndex = 0; cIndex < expectedSizeC; cIndex++) 
     2247      for (int tIndex = 0; tIndex < sizeT; tIndex++) 
     2248        for (int zIndex = 0; zIndex < sizeZ; zIndex++) 
     2249          getIndexValue(imp, zIndex, cIndex, tIndex, indexed); 
     2250          //assertEquals(iIndex++,getIndexValue(imp, zIndex, cIndex, tIndex, indexed)); 
     2251  } 
     2252 
     2253  @Test 
     2254  public void testColorizeSubcases() 
     2255  { 
     2256    System.out.println("testColorizeSubcases() - begin special cases"); 
     2257     
     2258    // INDEXED and sizeC == 1,2,3,anything bigger than 3 
     2259     
     2260    // sizeC == 1, rgb == 1, indexed, 8 bit, implicit lut length of 3 - KEY test to do, also note can vary lut len 
     2261    System.out.println("1/1 indexed"); 
     2262    colorColorizedTester(FormatTools.UINT8,1,1,true,false,-1); 
     2263    System.out.println("1/1 indexed falseColor"); 
     2264    colorColorizedTester(FormatTools.UINT8,1,1,true,true,-1); 
     2265    System.out.println("1/1/indexed lutLen==2"); 
     2266    colorColorizedTester(FormatTools.UINT8,1,1,true,false,2); 
     2267     
     2268    // sizeC = 3 and rgb = 1 
     2269    System.out.println("3/1 indexed"); 
     2270    colorColorizedTester(FormatTools.UINT8,3,1,true,false,-1); 
     2271    System.out.println("3/1 indexed falseColor"); 
     2272    colorColorizedTester(FormatTools.UINT8,3,1,true,true,-1); 
     2273 
     2274    // sizeC = 3 and rgb = 3 : interleaved 
     2275    System.out.println("3/3 indexed"); 
     2276    colorColorizedTester(FormatTools.UINT8,3,3,true,false,-1); 
     2277    System.out.println("3/3 indexed falseColor"); 
     2278    colorColorizedTester(FormatTools.UINT8,3,3,true,true,-1); 
     2279 
     2280    // NOT INDEXED 
     2281     
     2282    // sizeC == 1 : don't test yet 
     2283     
     2284    // sizeC = 4 and rgb = 4 : interleaved including alpha 
     2285    // if indexed == true this combo throws exception in CompositeImage constructor 
     2286    System.out.println("4/4 nonindexed"); 
     2287    colorColorizedTester(FormatTools.UINT8,4,4,false,false,-1); 
     2288 
     2289    // sizeC = 6, rgb = 3, indexed = false 
     2290    // if indexed == true this combo throws exception in CompositeImage constructor 
     2291    System.out.println("6/3 nonindexed"); 
     2292    colorColorizedTester(FormatTools.UINT8,6,3,false,false,-1); 
     2293    
     2294    // sizeC = 12, rgb = 3, indexed = false 
     2295    System.out.println("12/3 nonindexed"); 
     2296    colorColorizedTester(FormatTools.UINT8,12,3,false,false,-1); 
     2297 
     2298    System.out.println("testColorizeSubcases() - past special cases"); 
     2299 
     2300    /* 
     2301    for (int sizeC : new int[] {1,2,3,4,6,12}) 
     2302      for (int rgb : new int[] {1,2,3,4}) 
     2303        if (sizeC % rgb == 0) 
     2304          for (int pixType : new int[] {FormatTools.UINT8}) // TODO - add later FormatTools.UINT16 
     2305            for (boolean indexed : BooleanStates) 
     2306              for (boolean falseColor : BooleanStates) 
     2307              { 
     2308                if (!indexed && falseColor)  // if !indexed make sure falseColor is false to avoid illegal combo 
     2309                  continue; 
     2310                System.out.println("Colorized: pixType("+FormatTools.getPixelTypeString(pixType)+") sizeC("+sizeC+") rgb("+rgb+") indexed("+indexed+") falseColor("+falseColor+")"); 
     2311                colorColorizedTester(pixType,sizeC,rgb,indexed,falseColor,-1); 
     2312              } 
     2313    System.out.println("testColorizeSubcases() - past all cases"); 
     2314    */ 
     2315     
     2316    fail("Numerous failures : actual tests commented out to see all print statements."); 
    17112317  } 
    17122318   
Note: See TracChangeset for help on using the changeset viewer.