Changeset 4902


Ignore:
Timestamp:
03/11/09 10:21:50 (11 years ago)
Author:
melissa
Message:

Group DICOM files according to the "Instance Number" tag. Closes #364.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/bio-formats/src/loci/formats/in/DicomReader.java

    r4692 r4902  
    109109  private String pixelSizeX, pixelSizeY; 
    110110 
     111  private Vector fileList; 
     112  private int imagesPerFile; 
     113 
     114  private String originalDate, originalTime, originalInstance; 
     115 
     116  private DicomReader helper; 
     117 
    111118  // -- Constructor -- 
    112119 
     
    162169  } 
    163170 
     171  /* @see loci.formats.IFormatReader#getUsedFiles() */ 
     172  public String[] getUsedFiles() { 
     173    return fileList == null ? null : (String[]) fileList.toArray(new String[0]); 
     174  } 
     175 
     176  /* @see loci.formats.IFormatReader#fileGroupOption(String) */ 
     177  public int fileGroupOption(String id) throws FormatException, IOException { 
     178    return MUST_GROUP; 
     179  } 
     180 
    164181  /** 
    165182   * @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) 
     
    172189    FormatTools.checkBufferSize(this, buf.length, w, h); 
    173190 
     191    if (fileList.size() > 1) { 
     192      int fileNumber = no / imagesPerFile; 
     193      no = no % imagesPerFile; 
     194      initFile((String) fileList.get(fileNumber)); 
     195    } 
     196 
    174197    int ec = isIndexed() ? 1 : getSizeC(); 
    175198    int bpp = FormatTools.getBytesPerPixel(getPixelType()); 
     
    190213          for (int i=0; i<bpp; i++) { 
    191214            tmp[i] = codec.decompress(in, options); 
    192             if (no < getImageCount() - 1 || i < bpp - 1) { 
     215            if (no < imagesPerFile - 1 || i < bpp - 1) { 
    193216              while (in.read() == 0); 
    194217              in.seek(in.getFilePointer() - 1); 
     
    212235            System.arraycopy(tmp, 0, t, 0, tmp.length); 
    213236          } 
    214           if (no < getImageCount() - 1 || c < ec - 1) { 
     237          if (no < imagesPerFile - 1 || c < ec - 1) { 
    215238            while (in.read() == 0); 
    216239            in.seek(in.getFilePointer() - 1); 
     
    323346    rescaleIntercept = 0.0; 
    324347    pixelSizeX = pixelSizeY = null; 
     348    imagesPerFile = 0; 
     349    fileList = null; 
    325350  } 
    326351 
     
    373398        break; 
    374399      } 
    375       int tag = getNextTag(); 
     400      int tag = getNextTag(in); 
    376401 
    377402      if (elementLength == 0) continue; 
     
    400425          addInfo(tag, s); 
    401426          double frames = Double.parseDouble(s); 
    402           if (frames > 1.0) core[0].imageCount = (int) frames; 
     427          if (frames > 1.0) imagesPerFile = (int) frames; 
    403428          break; 
    404429        case SAMPLES_PER_PIXEL: 
     
    487512      } 
    488513    } 
    489     if (getImageCount() == 0) core[0].imageCount = 1; 
     514    if (imagesPerFile == 0) imagesPerFile = 1; 
    490515 
    491516    while (bitsPerPixel % 8 != 0) bitsPerPixel++; 
     
    511536    // calculate the offset to each plane 
    512537 
    513     offsets = new long[getImageCount()]; 
    514     for (int i=0; i<getImageCount(); i++) { 
     538    offsets = new long[imagesPerFile]; 
     539    for (int i=0; i<imagesPerFile; i++) { 
    515540      if (isRLE) { 
    516541        if (i == 0) in.seek(baseOffset); 
     
    563588    } 
    564589 
     590    status("Building file list"); 
     591 
     592    if (fileList == null && originalInstance != null && originalDate != null && 
     593      originalTime != null) 
     594    { 
     595      fileList = new Vector(); 
     596 
     597      int instanceNumber = Integer.parseInt(originalInstance) - 1; 
     598      if (instanceNumber == 0) fileList.add(currentId); 
     599      else { 
     600        while (instanceNumber > fileList.size()) fileList.add(null); 
     601        fileList.add(currentId); 
     602      } 
     603 
     604      Location directory = 
     605        new Location(currentId).getAbsoluteFile().getParentFile(); 
     606      String[] files = directory.list(); 
     607      for (int i=0; i<files.length; i++) { 
     608        String file = new Location(directory, files[i]).getAbsolutePath(); 
     609        if (!files[i].equals(currentId) && !file.equals(currentId) && 
     610          isThisType(files[i])) 
     611        { 
     612          RandomAccessStream stream = new RandomAccessStream(file); 
     613          stream.order(true); 
     614 
     615          stream.seek(128); 
     616          if (!stream.readString(4).equals("DICM")) stream.seek(0); 
     617 
     618          String date = null, time = null, instance = null; 
     619          while (date == null || time == null || instance == null) { 
     620            long fp = stream.getFilePointer(); 
     621            if (fp + 4 >= stream.length() || fp < 0) break; 
     622            int tag = getNextTag(stream); 
     623            String key = (String) TYPES.get(new Integer(tag)); 
     624            if ("Instance Number".equals(key)) { 
     625              instance = stream.readString(elementLength).trim(); 
     626              if (instance.length() == 0) instance = null; 
     627            } 
     628            else if ("Acquisition Time".equals(key)) { 
     629              time = stream.readString(elementLength); 
     630            } 
     631            else if ("Acquisition Date".equals(key)) { 
     632              date = stream.readString(elementLength); 
     633            } 
     634            else stream.skipBytes(elementLength); 
     635          } 
     636          stream.close(); 
     637 
     638          if (date == null || time == null || instance == null) continue; 
     639 
     640          if (date.equals(originalDate) && time.equals(originalTime)) { 
     641            int position = Integer.parseInt(instance) - 1; 
     642            if (position < fileList.size()) { 
     643              fileList.setElementAt(file, position); 
     644            } 
     645            else { 
     646              while (position > fileList.size()) { 
     647                fileList.add(null); 
     648              } 
     649              fileList.add(file); 
     650            } 
     651          } 
     652        } 
     653      } 
     654 
     655      files = (String[]) fileList.toArray(new String[0]); 
     656      fileList.clear(); 
     657      for (int i=0; i<files.length; i++) { 
     658        if (files[i] != null) fileList.add(files[i]); 
     659      } 
     660    } 
     661    else if (fileList == null) { 
     662      fileList = new Vector(); 
     663      fileList.add(currentId); 
     664    } 
     665 
    565666    status("Populating metadata"); 
    566667 
    567     core[0].sizeZ = getImageCount(); 
     668    core[0].sizeZ = imagesPerFile * fileList.size(); 
     669    core[0].imageCount = getSizeZ(); 
    568670    if (getSizeC() == 0) core[0].sizeC = 1; 
    569671    core[0].rgb = getSizeC() > 1; 
     
    640742        else if (info.startsWith("MONOCHROME")) { 
    641743          inverted = info.endsWith("1"); 
     744        } 
     745      } 
     746      else if (key.equals("Acquisition Date")) originalDate = info; 
     747      else if (key.equals("Acquisition Time")) originalTime = info; 
     748      else if (key.equals("Instance Number")) { 
     749        if (info.trim().length() > 0) { 
     750          originalInstance = info; 
    642751        } 
    643752      } 
     
    752861  } 
    753862 
    754   private int getLength(int tag) throws IOException { 
     863  private int getLength(RandomAccessStream stream, int tag) throws IOException { 
    755864    byte[] b = new byte[4]; 
    756     in.read(b); 
     865    stream.read(b); 
    757866 
    758867    // We cannot know whether the VR is implicit or explicit 
     
    772881        // Explicit VR with 32-bit length if other two bytes are zero 
    773882        if ((b[2] == 0) || (b[3] == 0)) { 
    774           return in.readInt(); 
     883          return stream.readInt(); 
    775884        } 
    776885        vr = IMPLICIT_VR; 
     
    814923  } 
    815924 
    816   private int getNextTag() throws IOException { 
    817     int groupWord = in.readShort(); 
     925  private int getNextTag(RandomAccessStream stream) throws IOException { 
     926    int groupWord = stream.readShort(); 
    818927    if (groupWord == 0x0800 && bigEndianTransferSyntax) { 
    819928      core[0].littleEndian = false; 
    820929      groupWord = 0x0008; 
    821       in.order(false); 
    822     } 
    823  
    824     int elementWord = in.readShort(); 
     930      stream.order(false); 
     931    } 
     932 
     933    int elementWord = stream.readShort(); 
    825934    int tag = ((groupWord << 16) & 0xffff0000) | (elementWord & 0xffff); 
    826935 
    827     elementLength = getLength(tag); 
     936    elementLength = getLength(stream, tag); 
    828937 
    829938    if (elementLength == 0 && groupWord == 0x7fe0) { 
    830       elementLength = getLength(tag); 
     939      elementLength = getLength(stream, tag); 
    831940    } 
    832941 
Note: See TracChangeset for help on using the changeset viewer.