Changeset 3320


Ignore:
Timestamp:
10/26/07 13:31:35 (12 years ago)
Author:
melissa
Message:

Multiple series are now correctly detected; replaced evil axis size/dimension order calculation logic with much nicer stuff.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/in/ND2Reader.java

    r3303 r3320  
    133133 
    134134  /** Array of image offsets. */ 
    135   private long[] offsets; 
     135  private long[][] offsets; 
    136136 
    137137  /** Whether or not the pixel data is compressed using JPEG 2000. */ 
     
    145145  private Vector zs = new Vector(); 
    146146  private Vector ts = new Vector(); 
     147 
     148  private int numSeries; 
    147149 
    148150  // -- Constructor -- 
     
    168170    FormatTools.checkBufferSize(this, buf.length); 
    169171 
    170     in.seek(offsets[no]); 
     172    in.seek(offsets[series][no]); 
    171173 
    172174    if (isJPEG) { 
    173175      BufferedImage b = openImage(no); 
    174176      byte[][] pixels = ImageTools.getPixelBytes(b, false); 
    175       if (pixels.length == 1 && core.sizeC[0] > 1) { 
    176         pixels = ImageTools.splitChannels(pixels[0], core.sizeC[0], 
    177           FormatTools.getBytesPerPixel(core.pixelType[0]), false, 
    178           !core.interleaved[0]); 
    179       } 
    180       for (int i=0; i<core.sizeC[0]; i++) { 
     177      if (pixels.length == 1 && core.sizeC[series] > 1) { 
     178        pixels = ImageTools.splitChannels(pixels[series], core.sizeC[series], 
     179          FormatTools.getBytesPerPixel(core.pixelType[series]), false, 
     180          !core.interleaved[series]); 
     181      } 
     182      for (int i=0; i<core.sizeC[series]; i++) { 
    181183        System.arraycopy(pixels[i], 0, buf, i*pixels[i].length, 
    182184          pixels[i].length); 
     
    188190      in.read(b); 
    189191 
    190       if ((core.sizeX[0] % 2) != 0) { 
    191         buf = new byte[(core.sizeX[0] + 1) * core.sizeY[0] * 
     192      if ((core.sizeX[series] % 2) != 0) { 
     193        buf = new byte[(core.sizeX[series] + 1) * core.sizeY[series] * 
    192194          getRGBChannelCount() * 
    193           FormatTools.getBytesPerPixel(core.pixelType[0])]; 
     195          FormatTools.getBytesPerPixel(core.pixelType[series])]; 
    194196      } 
    195197 
     
    200202      decompresser.end(); 
    201203 
    202       if ((core.sizeX[0] % 2) != 0) { 
     204      if ((core.sizeX[series] % 2) != 0) { 
    203205        byte[] tmp = buf; 
    204         buf = new byte[core.sizeX[0] * core.sizeY[0] * getRGBChannelCount() * 
    205           FormatTools.getBytesPerPixel(core.pixelType[0])]; 
    206         int row = core.sizeX[0] * getRGBChannelCount() * 
    207           FormatTools.getBytesPerPixel(core.pixelType[0]); 
    208         int padRow = (core.sizeX[0] + 1) * getRGBChannelCount() * 
    209           FormatTools.getBytesPerPixel(core.pixelType[0]); 
    210         for (int i=0; i<core.sizeY[0]; i++) { 
     206        buf = new byte[core.sizeX[series] * core.sizeY[series] * 
     207          getRGBChannelCount() * 
     208          FormatTools.getBytesPerPixel(core.pixelType[series])]; 
     209        int row = core.sizeX[series] * getRGBChannelCount() * 
     210          FormatTools.getBytesPerPixel(core.pixelType[series]); 
     211        int padRow = (core.sizeX[series] + 1) * getRGBChannelCount() * 
     212          FormatTools.getBytesPerPixel(core.pixelType[series]); 
     213        for (int i=0; i<core.sizeY[series]; i++) { 
    211214          System.arraycopy(tmp, padRow * i, buf, row * i, row); 
    212215        } 
     
    220223  public BufferedImage openImage(int no) throws FormatException, IOException { 
    221224    if (!isJPEG) { 
    222       return ImageTools.makeImage(openBytes(no), core.sizeX[0], core.sizeY[0], 
    223         core.sizeC[0], core.interleaved[0], 
    224         FormatTools.getBytesPerPixel(core.pixelType[0]), core.littleEndian[0]); 
     225      return ImageTools.makeImage(openBytes(no), core.sizeX[series], 
     226        core.sizeY[series], core.sizeC[series], core.interleaved[series], 
     227        FormatTools.getBytesPerPixel(core.pixelType[series]), 
     228        core.littleEndian[series]); 
    225229    } 
    226230 
     
    228232    FormatTools.checkPlaneNumber(this, no); 
    229233 
    230     in.seek(offsets[no]); 
    231  
    232     long len = no < core.imageCount[0] - 1 ? offsets[no + 1] - offsets[no] : 
    233       in.length() - offsets[no]; 
     234    in.seek(offsets[series][no]); 
     235 
     236    long len = no < core.imageCount[series] - 1 ? offsets[series][no + 1] - 
     237      offsets[series][no] : in.length() - offsets[series][no]; 
    234238 
    235239    byte[] b = new byte[(int) len]; 
     
    328332                FormatTools.getBytesPerPixel(core.pixelType[0])); 
    329333            } 
    330             offsets[ndx] = in.getFilePointer() - len + sb.length() + 21; 
    331             while (offsets[ndx] - in.getFilePointer() + 
     334            offsets[0][ndx] = in.getFilePointer() - len + sb.length() + 21; 
     335            while (offsets[0][ndx] - in.getFilePointer() + 
    332336              len - 14 - sb.length() < 8) 
    333337            { 
    334               offsets[ndx]++; 
     338              offsets[0][ndx]++; 
    335339            } 
    336340          } 
     
    374378 
    375379          if (core.imageCount[0] > 0 && offsets == null) { 
    376             offsets = new long[core.imageCount[0]]; 
     380            offsets = new long[1][core.imageCount[0]]; 
    377381          } 
    378382 
     
    389393      if (core.sizeC[0] > 1 && adjustImageCount) { 
    390394        core.imageCount[0] /= 3; 
    391         core.sizeZ[0] /= 3; 
     395        core.sizeT[0] /= 3; 
    392396      } 
    393397      core.littleEndian[0] = true; 
     
    435439    } 
    436440 
    437     offsets = new long[vs.size()]; 
    438     for (int i=0; i<offsets.length; i++) { 
    439       offsets[i] = ((Long) vs.get(i)).longValue(); 
    440     } 
    441     vs.clear(); 
    442     vs = null; 
    443  
    444441    status("Finding XML metadata"); 
    445442 
    446     core.imageCount[0] = offsets.length; 
    447  
    448     core.pixelType[0] = FormatTools.UINT8; 
    449     core.indexed[0] = false; 
    450     core.falseColor[0] = false; 
    451  
    452443    // read XML metadata from the end of the file 
    453444 
    454     in.seek(offsets[offsets.length - 1]); 
     445    in.seek(((Long) vs.get(vs.size() - 1)).longValue()); 
    455446 
    456447    boolean found = false; 
     
    459450    while (!found && in.getFilePointer() < in.length()) { 
    460451      int read = 0; 
    461       if (in.getFilePointer() == offsets[offsets.length - 1]) { 
     452      if (in.getFilePointer() == ((Long) vs.get(vs.size() - 1)).longValue()) { 
    462453        read = in.read(buf); 
    463454      } 
     
    532523                    addMeta(effectiveKey, value); 
    533524 
    534                     if (effectiveKey.equals( 
    535                       "MetadataSeq _SEQUENCE_INDEX=\"0\" uiCompCount value")) 
    536                     { 
    537                       if (value != null) { 
    538                         core.sizeC[0] = Integer.parseInt(value); 
    539                       } 
    540                     } 
    541                     else if (effectiveKey.endsWith("dTimeAbsolute value")) { 
     525                    if (effectiveKey.endsWith("dTimeMSec value")) { 
    542526                      long v = (long) Double.parseDouble(value); 
    543527                      if (!ts.contains(new Long(v))) { 
    544                         core.sizeT[0]++; 
    545528                        ts.add(new Long(v)); 
    546529                      } 
     
    549532                      long v = (long) Double.parseDouble(value); 
    550533                      if (!zs.contains(new Long(v))) { 
    551                         core.sizeZ[0]++; 
    552534                        zs.add(new Long(v)); 
     535                      } 
     536                    } 
     537                    else if (effectiveKey.endsWith("uiComp value")) { 
     538                      if (core.sizeC[0] == 0) { 
     539                        core.sizeC[0] = Integer.parseInt(value); 
     540                      } 
     541                    } 
     542                    else if (effectiveKey.endsWith("uiCount value")) { 
     543                      if (core.sizeT[0] == 0) { 
     544                        core.sizeT[0] = Integer.parseInt(value); 
     545                      } 
     546                    } 
     547                    else if (effectiveKey.endsWith("TextInfoItem Text")) { 
     548                      value = value.replaceAll("&#x000d;&#x000a;", "\n"); 
     549                      StringTokenizer tokens = new StringTokenizer(value, "\n"); 
     550                      while (tokens.hasMoreTokens()) { 
     551                        String t = tokens.nextToken().trim(); 
     552                        if (t.startsWith("Dimensions:")) { 
     553                          t = t.substring(11); 
     554                          StringTokenizer dims = new StringTokenizer(t, " x "); 
     555                          while (dims.hasMoreTokens()) { 
     556                            String dim = dims.nextToken().trim(); 
     557                            int idx = dim.indexOf("("); 
     558                            int v = Integer.parseInt(dim.substring(idx + 1, 
     559                              dim.indexOf(")", idx))); 
     560                            if (dim.startsWith("XY")) { 
     561                              numSeries = v; 
     562                              if (numSeries > 1) { 
     563                                int x = core.sizeX[0]; 
     564                                int y = core.sizeY[0]; 
     565                                int z = core.sizeZ[0]; 
     566                                int ts = core.sizeT[0]; 
     567                                int c = core.sizeC[0]; 
     568                                core = new CoreMetadata(numSeries); 
     569                                Arrays.fill(core.sizeX, x); 
     570                                Arrays.fill(core.sizeY, y); 
     571                                Arrays.fill(core.sizeZ, z); 
     572                                Arrays.fill(core.sizeC, c); 
     573                                Arrays.fill(core.sizeT, ts); 
     574                              } 
     575                              int cs = core.sizeC[0]; 
     576                              int ts = core.sizeT[0]; 
     577                              int zs = core.sizeZ[0]; 
     578                              if (cs == 0) cs = 1; 
     579                              if (ts == 0) ts = 1; 
     580                              if (zs == 0) zs = 1; 
     581                            } 
     582                            else if (dim.startsWith("T")) { 
     583                              Arrays.fill(core.sizeT, v); 
     584                            } 
     585                            else if (dim.startsWith("Z")) { 
     586                              Arrays.fill(core.sizeZ, v); 
     587                            } 
     588                            else { 
     589                              Arrays.fill(core.sizeC, v); 
     590                            } 
     591                          } 
     592 
     593                          if (core.sizeZ[0] == 0) Arrays.fill(core.sizeZ, 1); 
     594                          if (core.sizeC[0] == 0) Arrays.fill(core.sizeC, 1); 
     595                          if (core.sizeT[0] == 0) Arrays.fill(core.sizeT, 1); 
     596 
     597                          int count = 
     598                            core.sizeZ[0] * core.sizeC[0] * core.sizeT[0]; 
     599                          Arrays.fill(core.imageCount, count); 
     600 
     601                          Arrays.fill(core.currentOrder, "XYCZT"); 
     602                        } 
    553603                      } 
    554604                    } 
     
    584634 
    585635    status("Populating metadata"); 
    586  
     636    if (core.imageCount[0] == 0) { 
     637      core.sizeZ[0] = zs.size() == 0 ? 1 : zs.size(); 
     638      core.sizeT[0] = ts.size() == 0 ? 1 : ts.size(); 
     639      core.sizeC[0] = (vs.size() + 1) / (core.sizeT[0] * core.sizeZ[0]); 
     640      core.imageCount[0] = vs.size(); 
     641      while (core.imageCount[0] % core.sizeC[0] != 0) core.imageCount[0]--; 
     642      while (core.sizeC[0] * core.sizeZ[0] * core.sizeT[0] > core.imageCount[0]) 
     643      { 
     644        if (core.sizeZ[0] < core.sizeT[0]) core.sizeT[0]--; 
     645        else core.sizeZ[0]--; 
     646      } 
     647    } 
     648 
     649    if (core.sizeC[0] * core.sizeZ[0] * core.sizeT[0] != core.imageCount[0]) { 
     650      core.sizeZ[0] = zs.size(); 
     651      core.sizeT[0] = ts.size(); 
     652      core.imageCount[0] = core.sizeC[0] * core.sizeZ[0] * core.sizeT[0]; 
     653    } 
     654 
     655    core.pixelType[0] = FormatTools.UINT8; 
     656    offsets = new long[1][2]; 
     657    offsets[0][0] = ((Long) vs.get(0)).longValue(); 
     658    offsets[0][1] = ((Long) vs.get(1)).longValue(); 
    587659    BufferedImage img = openImage(0); 
    588     core.sizeX[0] = img.getWidth(); 
    589     core.sizeY[0] = img.getHeight(); 
    590     core.sizeC[0] = img.getRaster().getNumBands(); 
    591     core.rgb[0] = core.sizeC[0] > 1; 
    592     core.pixelType[0] = ImageTools.getPixelType(img); 
    593  
    594     int numInvalid = 0; 
    595  
    596     for (int i=1; i<offsets.length; i++) { 
    597       if (offsets[i] - offsets[i - 1] < (core.sizeX[0] * core.sizeY[0] / 4)) { 
    598         offsets[i - 1] = 0; 
    599         numInvalid++; 
    600       } 
    601     } 
    602  
    603     long[] tempOffsets = new long[core.imageCount[0] - numInvalid]; 
    604     int pt = 0; 
    605     for (int i=0; i<offsets.length; i++) { 
    606       if (offsets[i] != 0) { 
    607         tempOffsets[pt] = offsets[i]; 
    608         pt++; 
    609       } 
    610     } 
    611     offsets = tempOffsets; 
    612     core.imageCount[0] = offsets.length; 
    613  
    614     String sigBits = 
    615       (String) getMeta("AdvancedImageAttributes SignificantBits value"); 
    616     int bits = 0; 
    617     if (sigBits != null && sigBits.length() > 0) { 
    618       bits = Integer.parseInt(sigBits.trim()); 
     660    Arrays.fill(core.sizeX, img.getWidth()); 
     661    Arrays.fill(core.sizeY, img.getHeight()); 
     662    if (core.sizeC[0] == 0) core.sizeC[0] = 1; 
     663    int c = img.getRaster().getNumBands() * core.sizeC[0]; 
     664    Arrays.fill(core.sizeC, c); 
     665    Arrays.fill(core.rgb, img.getRaster().getNumBands() > 1); 
     666    Arrays.fill(core.pixelType, ImageTools.getPixelType(img)); 
     667 
     668    if (vs.size() < core.imageCount[0]) { 
     669      Arrays.fill(core.imageCount, vs.size()); 
     670    } 
     671 
     672    if (numSeries == 0) numSeries = 1; 
     673    offsets = new long[numSeries][core.imageCount[0]]; 
     674 
     675    for (int i=0; i<core.sizeZ[0]*core.sizeT[0]; i++) { 
     676      for (int j=0; j<numSeries; j++) { 
     677        for (int k=0; k<core.sizeC[0]; k++) { 
     678          offsets[j][i*core.sizeC[0] + k] = ((Long) vs.remove(0)).longValue(); 
     679        } 
     680      } 
    619681    } 
    620682 
     
    635697    } 
    636698 
    637     core.currentOrder[0] = "XY"; 
    638     long deltaT = ts.size() > 1 ? 
    639       ((Long) ts.get(1)).longValue() - ((Long) ts.get(0)).longValue() : 1; 
    640     long deltaZ = zs.size() > 1 ? 
    641       ((Long) zs.get(1)).longValue() - ((Long) zs.get(0)).longValue() : 1; 
    642  
    643     if (deltaT < deltaZ || deltaZ == 0) core.currentOrder[0] += "CTZ"; 
    644     else core.currentOrder[0] += "CZT"; 
    645  
    646     // we calculate this directly (instead of calling getEffectiveSizeC) because 
    647     // sizeZ and sizeT have not been accurately set yet 
    648     int effectiveC = ((core.sizeC[0] - 1) / 3) + 1; 
    649  
    650     if (core.imageCount[0] < core.sizeZ[0] * core.sizeT[0]) { 
    651       if (core.sizeT[0] == core.imageCount[0]) { 
    652         core.sizeT[0] /= core.sizeZ[0] * effectiveC; 
    653         while (core.imageCount[0] > core.sizeZ[0] * core.sizeT[0] * effectiveC) 
    654         { 
    655           core.sizeT[0]++; 
    656         } 
    657       } 
    658       else if (core.sizeZ[0] == core.imageCount[0]) { 
    659         core.sizeZ[0] /= core.sizeT[0] * effectiveC; 
    660         while (core.imageCount[0] > core.sizeZ[0] * core.sizeT[0] * effectiveC) 
    661         { 
    662           core.sizeZ[0]++; 
    663         } 
    664       } 
    665  
    666       if (core.imageCount[0] < core.sizeZ[0] * core.sizeT[0] * effectiveC) { 
    667         if (core.sizeZ[0] < core.sizeT[0]) { 
    668           core.sizeZ[0]--; 
    669           while (core.imageCount[0] > 
    670             core.sizeZ[0] * core.sizeT[0] * effectiveC) 
    671           { 
    672             core.sizeT[0]++; 
    673           } 
    674           while (core.imageCount[0] < 
    675             core.sizeZ[0] * core.sizeT[0] * effectiveC) 
    676           { 
    677             core.sizeT[0]--; 
    678           } 
    679         } 
    680         else { 
    681           core.sizeT[0]--; 
    682           while (core.imageCount[0] > 
    683             core.sizeZ[0] * core.sizeT[0] * effectiveC) 
    684           { 
    685             core.sizeZ[0]++; 
    686           } 
    687           if (core.imageCount[0] < core.sizeZ[0] * core.sizeT[0] * effectiveC) { 
    688             core.sizeZ[0]--; 
    689           } 
    690         } 
    691         while (core.imageCount[0] > core.sizeZ[0] * core.sizeT[0] * effectiveC) 
    692         { 
    693           core.imageCount[0]--; 
    694         } 
    695       } 
    696     } 
    697  
    698     if (bits != 0) { 
    699       int bpp = bits; 
    700       while (bpp % 8 != 0) bpp++; 
    701       switch (bpp) { 
    702         case 8: 
    703           core.pixelType[0] = FormatTools.UINT8; 
    704           break; 
    705         case 16: 
    706           core.pixelType[0] = FormatTools.UINT16; 
    707           break; 
    708         case 32: 
    709           core.pixelType[0] = FormatTools.UINT8; 
    710           core.sizeC[0] = 4; 
    711           break; 
    712         default: 
    713           throw new FormatException("Unsupported bits per pixel: " + bpp); 
    714       } 
    715  
    716     } 
    717  
    718     if (core.sizeZ[0] == 0) core.sizeZ[0] = 1; 
    719     if (core.sizeT[0] == 0) core.sizeT[0] = 1; 
    720  
    721     if (core.imageCount[0] < core.sizeZ[0] * core.sizeT[0] * core.sizeC[0]) { 
    722       core.sizeT[0] = core.imageCount[0]; 
    723       core.sizeZ[0] = 1; 
    724     } 
    725  
    726     if (core.sizeZ[0] * core.sizeT[0] * core.sizeC[0] < core.imageCount[0]) { 
    727       core.sizeT[0] = 1; 
    728       core.sizeZ[0] = core.imageCount[0]; 
    729     } 
    730  
    731     core.rgb[0] = core.sizeC[0] >= 3; 
    732     core.interleaved[0] = false; 
    733     core.littleEndian[0] = true; 
    734     core.metadataComplete[0] = true; 
     699    Arrays.fill(core.interleaved, false); 
     700    Arrays.fill(core.littleEndian, true); 
     701    Arrays.fill(core.metadataComplete, true); 
    735702 
    736703    MetadataStore store = getMetadataStore(); 
    737     store.setImage(currentId, null, null, null); 
    738704    FormatTools.populatePixels(store, this); 
    739  
    740     store.setDimensions(new Float(pixSizeX), new Float(pixSizeX), 
    741       new Float(pixSizeZ), null, null, null); 
    742     for (int i=0; i<core.sizeC[0]; i++) { 
    743       store.setLogicalChannel(i, null, null, null, null, null, null, null, null, 
    744         null, null, null, null, null, null, null, null, null, null, null, null, 
    745         null, null, null, null); 
     705    for (int i=0; i<numSeries; i++) { 
     706      Integer ii = new Integer(i); 
     707      store.setImage(currentId, null, null, ii); 
     708 
     709      store.setDimensions(new Float(pixSizeX), new Float(pixSizeX), 
     710        new Float(pixSizeZ), null, null, ii); 
     711      for (int j=0; j<core.sizeC[0]; j++) { 
     712        store.setLogicalChannel(j, null, null, null, null, null, null, null, 
     713          null, null, null, null, null, null, null, null, null, null, null, 
     714          null, null, null, null, null, ii); 
     715      } 
    746716    } 
    747717 
     
    798768            break; 
    799769          case 2: 
    800                 core.pixelType[0] = FormatTools.UINT16; 
    801                 break; 
     770                core.pixelType[0] = FormatTools.UINT16; 
     771                break; 
    802772          case 4: 
    803                 core.pixelType[0] = FormatTools.UINT32; 
    804                 break; 
     773                core.pixelType[0] = FormatTools.UINT32; 
     774                break; 
    805775          default: core.pixelType[0] = FormatTools.UINT8; 
    806776        } 
     
    814784        if (core.imageCount[0] == 0) { 
    815785          core.imageCount[0] = n; 
    816           core.sizeZ[0] = n; 
     786          core.sizeT[0] = n; 
    817787        } 
    818         core.sizeT[0] = 1; 
     788        core.sizeZ[0] = 1; 
    819789      } 
    820790      else if (qName.equals("dCompressionParam")) { 
Note: See TracChangeset for help on using the changeset viewer.