Changeset 1320


Ignore:
Timestamp:
08/22/06 10:29:42 (14 years ago)
Author:
callan
Message:

Bug fixes:

  • BaseTiffReader and derivatives have a working openBytes() method for 8-bit and 16-bit data
  • The endian-ness of the byte array returned by openBytes() now matches the file
  • Plane2D properly calculates byte array offsets

New features:

  • Bits class added to centralize byte swapping routines for short, int, etc.
  • BaseTiffReader and derivatives now have the global min and max calculated for each channel on initFile()
Location:
trunk/loci/formats
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/ImageTools.java

    r1306 r1320  
    2929import java.awt.geom.AffineTransform; 
    3030import java.awt.image.*; 
     31import java.nio.ByteBuffer; 
     32import java.nio.ShortBuffer; 
    3133 
    3234/** 
  • trunk/loci/formats/TiffTools.java

    r1294 r1320  
    2828import java.io.*; 
    2929import java.lang.reflect.Field; 
     30import java.nio.ByteBuffer; 
     31import java.nio.ShortBuffer; 
    3032import java.util.*; 
    3133 
     
    3638 * @author Eric Kjellman egkjellman at wisc.edu 
    3739 * @author Melissa Linkert linkert at cs.wisc.edu 
     40 */ 
     41/** 
     42 * @author callan 
     43 * 
    3844 */ 
    3945public abstract class TiffTools { 
     
    779785 
    780786  /** Reads the image defined in the given IFD from the specified file. */ 
    781   public static BufferedImage getImage(Hashtable ifd, RandomAccessStream in, 
     787  public static byte[][] getSamples(Hashtable ifd, RandomAccessStream in, 
    782788    long globalOffset) throws FormatException, IOException 
    783789  { 
     
    789795 
    790796    // get relevant IFD entries 
    791     long imageWidth = getIFDLongValue(ifd, IMAGE_WIDTH, true, 0); 
    792     long imageLength = getIFDLongValue(ifd, IMAGE_LENGTH, true, 0); 
    793     int[] bitsPerSample = getIFDIntArray(ifd, BITS_PER_SAMPLE, false); 
    794     if (bitsPerSample == null) bitsPerSample = new int[] {1}; 
    795     int samplesPerPixel = getIFDIntValue(ifd, SAMPLES_PER_PIXEL, false, 1); 
    796     int compression = getIFDIntValue(ifd, COMPRESSION, false, UNCOMPRESSED); 
    797     int photoInterp = getIFDIntValue(ifd, PHOTOMETRIC_INTERPRETATION, true, 0); 
    798     long[] stripOffsets = getIFDLongArray(ifd, STRIP_OFFSETS, false); 
    799     long[] stripByteCounts = getIFDLongArray(ifd, STRIP_BYTE_COUNTS, false); 
    800     long[] rowsPerStripArray = getIFDLongArray(ifd, ROWS_PER_STRIP, false); 
     797    long imageWidth = getImageWidth(ifd); 
     798    long imageLength = getImageLength(ifd); 
     799    int[] bitsPerSample = getBitsPerSample(ifd); 
     800    int samplesPerPixel = getSamplesPerPixel(ifd); 
     801    int compression = getCompression(ifd); 
     802    int photoInterp = getPhotometricInterpretation(ifd); 
     803    long[] stripOffsets = getStripOffsets(ifd); 
     804    long[] stripByteCounts = getStripByteCounts(ifd); 
     805    long[] rowsPerStripArray = getRowsPerStrip(ifd); 
    801806 
    802807    boolean fakeByteCounts = stripByteCounts == null; 
     
    11331138    byte[] altBytes = new byte[0]; 
    11341139 
    1135     if (bitsPerSample[0] < 8) { 
    1136       samples = new short[samplesPerPixel][numSamples]; 
    1137     } 
    1138  
    1139     byte[][] byteData = new byte[samplesPerPixel][numSamples]; 
    1140     float[][] floatData = new float[samplesPerPixel][numSamples]; 
    1141  
    11421140    if (bitsPerSample[0] == 16) littleEndian = !littleEndian; 
    11431141 
     
    11881186    } 
    11891187 
    1190  
    11911188    // construct field 
    11921189    if (DEBUG) debug("constructing image"); 
    11931190 
     1191    // Since the lowest common denominator for all pixel operations is "byte" 
     1192    // we're going to normalize everything to byte. 
     1193    byte[][] byteData = null; 
     1194    if (bitsPerSample[0] == 16) 
     1195    { 
     1196      byteData = new byte[samplesPerPixel][numSamples * 2]; 
     1197      for (int i = 0; i < samplesPerPixel; i++) 
     1198      { 
     1199        for (int j = 0; j < numSamples; j++) 
     1200        { 
     1201          byteData[i][j * 2]     = (byte) ((samples[i][j] & 0xFF00) >> 8); 
     1202          byteData[i][j * 2 + 1] = (byte) (samples[i][j] & 0x00FF); 
     1203        } 
     1204      } 
     1205    } 
     1206    else if (bitsPerSample[0] == 32) 
     1207    { 
     1208      // FIXME: To be implemented 
     1209      throw new FormatException("Floating point pixel data not yet supported."); 
     1210    } 
     1211    else 
     1212    { 
     1213      byteData = new byte[samplesPerPixel][numSamples]; 
     1214      for (int i=0; i<samplesPerPixel; i++) 
     1215      { 
     1216        for (int j=0; j<numSamples; j++) 
     1217        { 
     1218          byteData[i][j] = (byte) samples[i][j]; 
     1219        } 
     1220      } 
     1221    } 
     1222    return byteData; 
     1223  } 
     1224 
     1225  /** Reads the image defined in the given IFD from the specified file. */ 
     1226  public static BufferedImage getImage(Hashtable ifd, RandomAccessStream in, 
     1227                                       long globalOffset) 
     1228    throws FormatException, IOException 
     1229  { 
     1230    // construct field 
     1231    if (DEBUG) debug("constructing image"); 
     1232 
     1233    byte[][] samples = getSamples(ifd, in, globalOffset); 
     1234    int[] bitsPerSample = getBitsPerSample(ifd); 
     1235    long imageWidth = getImageWidth(ifd); 
     1236    long imageLength = getImageLength(ifd); 
     1237    int samplesPerPixel = getSamplesPerPixel(ifd); 
     1238 
    11941239    if (bitsPerSample[0] == 16) { 
    1195       return ImageTools.makeImage(samples, 
    1196         (int) imageWidth, (int) imageLength); 
    1197     } 
    1198     else if (bitsPerSample[0] == 32) { 
    1199       for (int i=0; i<samplesPerPixel; i++) { 
    1200         for (int j=0; j<numSamples; j++) { 
    1201           floatData[i][j] = (float) samples[i][j]; 
    1202         } 
    1203       } 
    1204       return ImageTools.makeImage(floatData, (int) imageWidth, 
    1205         (int) imageLength); 
    1206     } 
    1207     else { 
    1208       for (int i=0; i<samplesPerPixel; i++) { 
    1209         for (int j=0; j<numSamples; j++) { 
    1210           byteData[i][j] = (byte) samples[i][j]; 
    1211         } 
    1212       } 
    1213       return ImageTools.makeImage(byteData, (int) imageWidth, 
    1214         (int) imageLength); 
    1215     } 
    1216   } 
    1217  
     1240      // First wrap the byte arrays and then use the features of the 
     1241      // ByteBuffer to transform to a ShortBuffer. Finally, use the ShortBuffer 
     1242      // bulk get method to copy the data into a usable form for makeImage(). 
     1243      short[][] sampleData = new short[samplesPerPixel][samples[0].length / 2]; 
     1244      for (int i = 0; i < samplesPerPixel; i++) 
     1245      { 
     1246        ShortBuffer sampleBuf = ByteBuffer.wrap(samples[i]).asShortBuffer(); 
     1247        sampleBuf.get(sampleData[i]); 
     1248      } 
     1249 
     1250      // Now make our image. 
     1251      return ImageTools.makeImage(sampleData, 
     1252          (int) imageWidth, (int) imageLength); 
     1253    } 
     1254    else if (bitsPerSample[0] == 32) 
     1255    { 
     1256      // FIXME: To be implemented. 
     1257      throw new FormatException("Floating point pixel data not yet supported."); 
     1258    } 
     1259    return ImageTools.makeImage(samples, (int) imageWidth, (int) imageLength); 
     1260  } 
     1261   
    12181262  /** 
    12191263   * Extracts pixel information from the given byte array according to the 
     
    20312075    return numBytes; 
    20322076  } 
    2033  
     2077   
     2078  /** 
     2079   * Retrieves the image's width (TIFF tag ImageWidth) from a given TIFF IFD. 
     2080   * @param ifd a TIFF IFD hashtable. 
     2081   * @return the image's width. 
     2082   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2083   */ 
     2084  public static long getImageWidth(Hashtable ifd) throws FormatException 
     2085  { 
     2086          return getIFDLongValue(ifd, IMAGE_WIDTH, true, 0); 
     2087  } 
     2088   
     2089  /** 
     2090   * Retrieves the image's length (TIFF tag ImageLength) from a given TIFF IFD. 
     2091   * @param ifd a TIFF IFD hashtable. 
     2092   * @return the image's length. 
     2093   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2094   */ 
     2095  public static long getImageLength(Hashtable ifd) throws FormatException 
     2096  { 
     2097          return getIFDLongValue(ifd, IMAGE_LENGTH, true, 0); 
     2098  } 
     2099   
     2100  /** 
     2101   * Retrieves the image's bits per sample (TIFF tag BitsPerSample) from a given 
     2102   * TIFF IFD. 
     2103   * @param ifd a TIFF IFD hashtable. 
     2104   * @return the image's bits per sample. The length of the array is equal to 
     2105   * the number of samples per pixel. 
     2106   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2107   * @see #getSamplesPerPixel() 
     2108   */ 
     2109  public static int[] getBitsPerSample(Hashtable ifd) throws FormatException 
     2110  { 
     2111          int[] bitsPerSample = getIFDIntArray(ifd, BITS_PER_SAMPLE, false); 
     2112          if (bitsPerSample == null) 
     2113                  bitsPerSample = new int[] {1}; 
     2114          return bitsPerSample; 
     2115  } 
     2116 
     2117  /** 
     2118   * Retrieves the number of samples per pixel for the image (TIFF tag  
     2119   * SamplesPerPixel) from a given TIFF IFD. 
     2120   * @param ifd a TIFF IFD hashtable. 
     2121   * @return the number of samples per pixel. 
     2122   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2123   */ 
     2124  public static int getSamplesPerPixel(Hashtable ifd) throws FormatException 
     2125  { 
     2126          return getIFDIntValue(ifd, SAMPLES_PER_PIXEL, false, 1); 
     2127  } 
     2128   
     2129  /** 
     2130   * Retrieves the image's compression type (TIFF tag Compression) from a 
     2131   * given TIFF IFD. 
     2132   * @param ifd a TIFF IFD hashtable. 
     2133   * @return the image's compression type. As of TIFF 6.0 this is one of: 
     2134   * <ul> 
     2135   *  <li>Uncompressed (1)</li> 
     2136   *  <li>CCITT 1D (2)</li> 
     2137   *  <li>Group 3 Fax (3)</li> 
     2138   *  <li>Group 4 Fax (4)</li> 
     2139   *  <li>LZW (5)</li> 
     2140   *  <li>JPEG (6)</li> 
     2141   *  <li>PackBits (32773)</li> 
     2142   * <ul> 
     2143   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2144   */ 
     2145  public static int getCompression(Hashtable ifd) throws FormatException 
     2146  { 
     2147          return getIFDIntValue(ifd, COMPRESSION, false, UNCOMPRESSED); 
     2148  } 
     2149   
     2150  /** 
     2151   * Retrieves the image's photometric interpretation (TIFF tag 
     2152   * PhotometricInterpretation) from a given TIFF IFD. 
     2153   * @param ifd a TIFF IFD hashtable. 
     2154   * @return the image's photometric interpretation. As of TIFF 6.0 this is one 
     2155   * of: 
     2156   * <ul> 
     2157   *  <li>WhiteIsZero (0)</li> 
     2158   *  <li>BlackIsZero (1)</li> 
     2159   *  <li>RGB (2)</li> 
     2160   *  <li>RGB Palette (3)</li> 
     2161   *  <li>Transparency mask (4)</li> 
     2162   *  <li>CMYK (5)</li> 
     2163   *  <li>YbCbCr (6)</li> 
     2164   *  <li>CIELab (8)</li> 
     2165   * </ul> 
     2166   * 
     2167   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2168   */ 
     2169  public static int getPhotometricInterpretation(Hashtable ifd) 
     2170        throws FormatException 
     2171  { 
     2172          return getIFDIntValue(ifd, PHOTOMETRIC_INTERPRETATION, true, 0); 
     2173  } 
     2174   
     2175  /** 
     2176   * Retrieves the strip offsets for the image (TIFF tag StripOffsets) from a 
     2177   * given TIFF IFD. 
     2178   * @param ifd a TIFF IFD hashtable. 
     2179   * @return the strip offsets for the image. The lenght of the array is equal 
     2180   * to the number of strips per image. <i>StripsPerImage = floor ((ImageLength  
     2181   * + RowsPerStrip - 1) / RowsPerStrip)</i>. 
     2182   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2183   * @see #getStripByteCounts() 
     2184   * @see #getRowsPerStrip() 
     2185   */ 
     2186  public static long[] getStripOffsets(Hashtable ifd) throws FormatException 
     2187  { 
     2188          return getIFDLongArray(ifd, STRIP_OFFSETS, false); 
     2189  } 
     2190   
     2191  /** 
     2192   * Retrieves strip byte counts for the image (TIFF tag StripByteCounts) from a 
     2193   * given TIFF IFD. 
     2194   * @param ifd a TIFF IFD hashtable. 
     2195   * @return the byte counts for each strip. The length of the array is equal to 
     2196   * the number of strips per image. <i>StripsPerImage = floor ((ImageLength +  
     2197   * RowsPerStrip - 1) / RowsPerStrip)</i>. 
     2198   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2199   * @see #getStripOffsets() 
     2200   */ 
     2201  public static long[] getStripByteCounts(Hashtable ifd) throws FormatException 
     2202  { 
     2203          return getIFDLongArray(ifd, STRIP_BYTE_COUNTS, false); 
     2204  } 
     2205   
     2206  /** 
     2207   * Retrieves the number of rows per strip for image (TIFF tag RowsPerStrip) 
     2208   * from a given TIFF IFD. 
     2209   * @param ifd a TIFF IFD hashtable. 
     2210   * @return the number of rows per strip. 
     2211   * @throws FormatException if there is a problem parsing the IFD metadata. 
     2212   */ 
     2213  public static long[] getRowsPerStrip(Hashtable ifd) throws FormatException 
     2214  { 
     2215          return getIFDLongArray(ifd, ROWS_PER_STRIP, false); 
     2216  } 
    20342217 
    20352218  // -- Compression methods -- 
  • trunk/loci/formats/in/BaseTiffReader.java

    r1302 r1320  
    2828import java.io.IOException; 
    2929import java.nio.ByteBuffer; 
     30import java.nio.ByteOrder; 
     31import java.nio.ShortBuffer; 
    3032import java.util.Hashtable; 
    31 import loci.formats.*; 
     33 
     34import loci.formats.DataTools; 
     35import loci.formats.FormatException; 
     36import loci.formats.FormatReader; 
     37import loci.formats.ImageTools; 
     38import loci.formats.MetadataStore; 
     39import loci.formats.RandomAccessStream; 
     40import loci.formats.TiffRational; 
     41import loci.formats.TiffTools; 
    3242 
    3343/** 
     
    5060  /** Number of images in the current TIFF stack. */ 
    5161  protected int numImages; 
     62   
     63  /** The global min and max for each channel */ 
     64  protected Double[][] channelMinMax;  
    5265 
    5366  // -- Constructors -- 
     
    91104      ByteBuffer.wrap(openBytes(id, no)), 
    92105      Plane2D.typeFromString(getPixelType()), 
    93       isLittleEndian(id)); 
     106      isLittleEndian(id), getSizeX(id), getSizeY(id)); 
    94107  } 
    95108 
     
    433446      for (int i=0; i < getSizeC(currentId); i++) 
    434447      { 
    435           setLogicalChannel(i); 
     448        setLogicalChannel(i); 
     449        setChannelGlobalMinMax(i); 
    436450      } 
    437451 
     452      //Populate the default display options 
     453      store.setDefaultDisplaySettings(null); 
     454       
     455      // Use a default "real" pixel dimension of 1 for each dimensionality. 
     456      Float f = new Float(1); 
     457      store.setDimensions(f, f, f, f, f, null); 
     458       
    438459      // populate Dimensions element 
    439460      int pixelSizeX = TiffTools.getIFDIntValue(ifd, 
     
    528549  } 
    529550 
    530  
    531551  // -- FormatReader API methods -- 
    532552 
     
    614634    throws FormatException, IOException 
    615635  { 
    616     return ImageTools.getBytes(openImage(id, no), isRGB(id) && separated, 
    617       no % 3); 
    618   } 
    619  
    620   /** Obtains the specified image from the given TIFF file. */ 
     636          if (!id.equals(currentId)) initFile(id); 
     637           
     638          byte[][] p = null; 
     639          if (separated && isRGB(id)) 
     640          { 
     641                  p = TiffTools.getSamples(ifds[no / 3], in, 0); 
     642                  // We need to swap back the endian-ness due to the getSamples() 
     643                  // method giving us big-endian (Java) bytes if the image is 
     644                  // little-endian. 
     645                  return swapIfRequired(p[no % p.length]); 
     646          } 
     647          else 
     648          { 
     649                  p = TiffTools.getSamples(ifds[no], in, 0); 
     650                  byte[] rtn = new byte[p.length * p[0].length]; 
     651                  for (int i=0; i<p.length; i++) 
     652                  { 
     653                          swapIfRequired(p[i]); 
     654                          System.arraycopy(p[i], 0, rtn, i * p[0].length, p[0].length); 
     655                  } 
     656                  return rtn; 
     657          } 
     658  } 
     659 
     660  /** 
     661   * Examines a byte array to see if it needs to be byte swapped and modifies 
     662   * the byte array directly. 
     663   * @param byteArray The byte array to check and modify if required. 
     664   * @return the <i>byteArray</i> either swapped or not for convenience. 
     665   * @throws IOException if there is an error read from the file. 
     666   * @throws FormatException if there is an error during metadata parsing. 
     667   */ 
     668  private byte[] swapIfRequired(byte[] byteArray) 
     669        throws FormatException, IOException 
     670  { 
     671          int bitsPerSample = TiffTools.getBitsPerSample(ifds[0])[0]; 
     672           
     673          // We've got nothing to do if the samples are only 8-bits wide or if they 
     674          // are floating point. 
     675          if (bitsPerSample == 8 || bitsPerSample == 32) return byteArray; 
     676           
     677          if (isLittleEndian(currentId)) 
     678          { 
     679                  if (bitsPerSample == 16)  // Short 
     680                  { 
     681                          ShortBuffer buf = ByteBuffer.wrap(byteArray).asShortBuffer(); 
     682                          for (int i = 0; i < (byteArray.length / 2); i++) 
     683                                  buf.put(i, Bits.swap(buf.get(i))); 
     684                  } 
     685                  else 
     686                          throw new FormatException( 
     687                                          "Unsupported sample bit width: '" + bitsPerSample + "'"); 
     688          } 
     689          // We've got a big-endian file with a big-endian byte array. 
     690          return byteArray; 
     691  } 
     692 
     693/** Obtains the specified image from the given TIFF file. */ 
    621694  public BufferedImage openImage(String id, int no) 
    622695    throws FormatException, IOException 
     
    650723  protected void initFile(String id) throws FormatException, IOException { 
    651724    super.initFile(id); 
     725    channelMinMax = null; 
    652726    in = new RandomAccessStream(id); 
    653727    if (in.readShort() == 0x4949) in.order(true); 
     
    709783  } 
    710784 
    711   private void setChannelGlobalMinMax(int i) 
     785  /** 
     786   * Sets the channels global min and max in the metadata store. 
     787   * @param channelIdx the channel to set. 
     788   * @throws FormatException if there is an error parsing metadata. 
     789   * @throws IOException if there is an error reading the file. 
     790   */ 
     791  protected void setChannelGlobalMinMax(int channelIdx) 
    712792    throws FormatException, IOException 
    713793  { 
    714     getMetadataStore(currentId).setChannelGlobalMinMax(i, null, null, null); 
    715   } 
    716  
     794    getChannelGlobalMinMax(); 
     795    getMetadataStore(currentId).setChannelGlobalMinMax(channelIdx, 
     796        channelMinMax[channelIdx][0], channelMinMax[channelIdx][1], null); 
     797  } 
     798   
     799  /** 
     800   * Retrieves the global min and max for each channel. 
     801   * @throws FormatException if there is an error parsing metadata. 
     802   * @throws IOException if there is an error reading the file. 
     803   */ 
     804  public void getChannelGlobalMinMax() throws FormatException, IOException { 
     805    if (channelMinMax == null)  
     806      channelMinMax = new Double[getSizeC(currentId)][2]; 
     807    else return; 
     808 
     809    for (int c = 0; c < getSizeC(currentId); c++) 
     810    { 
     811      double min = Double.MAX_VALUE; 
     812      double max = Double.MIN_VALUE; 
     813      for(int t = 0; t < getSizeT(currentId); t++) 
     814      { 
     815        for(int z = 0; z < getSizeZ(currentId); z++) 
     816        { 
     817          int index = getIndex(currentId, z, c, t); 
     818          Plane2D plane = openPlane2D(currentId, index); 
     819          for (int x = 0; x < getSizeX(currentId); x++) 
     820          { 
     821            for (int y = 0; y < getSizeY(currentId); y++) 
     822            { 
     823              double pixelValue = plane.getPixelValue(x, y); 
     824              if (pixelValue < min) min = pixelValue; 
     825              if (pixelValue > max) max = pixelValue; 
     826            } 
     827          } 
     828        } 
     829      } 
     830      channelMinMax[c][0] = new Double(min); 
     831      channelMinMax[c][1] = new Double(max); 
     832    } 
     833  } 
     834   
     835  /** 
     836   * Sets the logical channel in the metadata store. 
     837   * @param i the logical channel number. 
     838   * @throws FormatException if there is an error parsing metadata. 
     839   * @throws IOException if there is an error reading the file. 
     840   */ 
    717841  private void setLogicalChannel(int i) throws FormatException, IOException { 
    718     getMetadataStore(currentId).setLogicalChannel(i, getChannelName(i), 
    719       getNdFilter(i), getEmWave(i), getExWave(i), 
    720       getPhotometricInterpretation(i), getMode(i), null); 
     842    getMetadataStore(currentId).setLogicalChannel( 
     843        i,  
     844        getChannelName(i),  
     845        getNdFilter(i),  
     846        getEmWave(i),  
     847        getExWave(i),  
     848        getPhotometricInterpretation(i), 
     849        getMode(i), // aquisition mode 
     850        null); 
    721851  } 
    722852 
    723853  private String getChannelName(int i) { return null; } 
    724  
     854   
    725855  private Float getNdFilter(int i) { return null; } 
    726  
     856   
    727857  Integer getEmWave(int i) { return null; } 
    728858 
    729859  private Integer getExWave(int i) { return null; } 
    730  
     860   
    731861  private String getPhotometricInterpretation(int i) 
    732     throws FormatException, IOException 
     862    throws FormatException, IOException  
    733863  { 
    734     return (String) getMetadataValue(currentId, 
    735       "MetaDataPhotometricInterpretation"); 
    736   } 
    737  
     864    return (String) getMetadataValue(currentId,  
     865      "metaDataPhotometricInterpretation"); 
     866  } 
     867   
    738868  private String getMode(int i) { return null; } 
    739869 
  • trunk/loci/formats/in/MetamorphReader.java

    r1302 r1320  
    2828import java.util.Hashtable; 
    2929import java.util.StringTokenizer; 
    30 import loci.formats.*; 
     30 
     31import loci.formats.DataTools; 
     32import loci.formats.FormatException; 
     33import loci.formats.TiffIFDEntry; 
     34import loci.formats.TiffRational; 
     35import loci.formats.TiffTools; 
    3136 
    3237/** 
     
    491496  } 
    492497 
    493   // FIXME: Needs to be implemented. 
    494   protected void initMetadataStore() { 
    495     super.initMetadataStore(); 
    496     for (int i = 0; i < ifds.length; i++) { } 
    497   } 
    498  
    499498  /* 
    500499   * (non-Javadoc) 
     
    515514  } 
    516515 
    517   private void setChannelGlobalMinMax(int i) 
     516  protected void setChannelGlobalMinMax(int i) 
    518517    throws FormatException, IOException 
    519518  { 
    520519    Double globalMin = (Double) metadata.get("grayMin"); 
    521520    Double globalMax = (Double) metadata.get("grayMax"); 
    522     if (globalMin == null | globalMax == null) { 
    523       throw new FormatException("No global min/max"); 
     521    if (globalMin != null | globalMax != null)  
     522    { 
     523      getMetadataStore(currentId).setChannelGlobalMinMax(i,  
     524        globalMin,globalMax, null); 
    524525    } 
    525     getMetadataStore(currentId).setChannelGlobalMinMax(i, 
    526       globalMin, globalMax, null); 
     526    super.setChannelGlobalMinMax(i); 
    527527  } 
    528528 
  • trunk/loci/formats/in/Plane2D.java

    r1302 r1320  
    4343  /** The Java type that we're using for pixel value retrieval */ 
    4444  private int                 type; 
     45   
     46  /** Number of pixels along the <i>X</i>-axis. */ 
     47  private int                 sizeX; 
     48   
     49  /** Number of pixels along the <i>Y</i>-axis. */ 
     50  private int                 sizeY; 
    4551 
    4652  /** Identifies the <i>INT8</i> data type used to store pixel values. */ 
     
    9096   * order. 
    9197   */ 
    92   Plane2D(ByteBuffer data, int type, boolean isLittleEndian) 
     98  Plane2D(ByteBuffer data, int type, boolean isLittleEndian, 
     99          int sizeX, int sizeY) 
    93100  { 
    94101    this.type = type; 
    95102    this.data = data; 
     103    this.sizeX = sizeX; 
     104    this.sizeY = sizeY; 
    96105 
    97106    this.data.order( 
     
    132141  public double getPixelValue(int x, int y) 
    133142  { 
    134     int offset = x * y * bytesPerPixel; 
     143    int offset = ((sizeX * y) + x) * bytesPerPixel; 
    135144 
    136145    switch(type) { 
Note: See TracChangeset for help on using the changeset viewer.