Changeset 2603


Ignore:
Timestamp:
04/12/07 11:03:57 (13 years ago)
Author:
melissa
Message:

Improved Metamorph metadata parsing, courtesy of Sebastien Huart.

Location:
trunk/loci/formats/in
Files:
2 edited

Legend:

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

    r2601 r2603  
    544544      } 
    545545      catch (Exception e) { 
    546         if (debug) e.printStackTrace(); 
    547         creationDate = null; 
     546        try { 
     547          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 
     548          SimpleDateFormat parse =  
     549            new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS"); 
     550          Date date = parse.parse(creationDate, new ParsePosition(0)); 
     551          creationDate = sdf.format(date); 
     552        } 
     553        catch (Exception ex) { 
     554          if (debug) ex.printStackTrace(); 
     555          creationDate = null; 
     556        }  
    548557      } 
    549558 
  • trunk/loci/formats/in/MetamorphReader.java

    r2601 r2603  
    2828import java.util.Hashtable; 
    2929import java.util.StringTokenizer; 
    30  
     30import java.text.DecimalFormat; 
    3131import loci.formats.DataTools; 
    3232import loci.formats.FormatException; 
     
    4141 * @author Melissa Linkert linkert at wisc.edu 
    4242 * @author Curtis Rueden ctrueden at wisc.edu 
     43 * @author Sebastien Huart Sebastien dot Huart at curie.fr  
    4344 */ 
    4445public class MetamorphReader extends BaseTiffReader { 
     
    4849  // IFD tag numbers of important fields 
    4950  private static final int METAMORPH_ID = 33628; 
     51  private static final int UIC1TAG = METAMORPH_ID; 
    5052  private static final int UIC2TAG = 33629; 
    5153  private static final int UIC3TAG = 33630; 
     
    6365  private long[] emWavelength; 
    6466 
     67  private int mmPlanes; //number of metamorph planes 
    6568  // -- Constructor -- 
    6669 
     
    7073  // -- FormatReader API methods -- 
    7174 
    72   /* @see loci.formats.IFormatReader#isThisType(byte[]) */ 
     75  /* @see loci.formats.IFormatReader#isThisType(byte[]) */  
    7376  public boolean isThisType(byte[] block) { 
    7477    // If the file is a Metamorph STK file, it should have a specific IFD tag. 
     
    107110  // -- Internal BaseTiffReader API methods -- 
    108111 
    109   /* @see BaseTiffReader#initStandardMetadata() */ 
     112  /* @see BaseTiffReader#initStandardMetadata() */  
    110113  protected void initStandardMetadata() throws FormatException, IOException { 
    111114    super.initStandardMetadata(); 
     
    114117      // Now that the base TIFF standard metadata has been parsed, we need to 
    115118      // parse out the STK metadata from the UIC4TAG. 
    116       TiffIFDEntry uic4tagEntry = TiffTools.getFirstIFDEntry(in, UIC4TAG); 
     119        TiffIFDEntry uic1tagEntry= TiffTools.getFirstIFDEntry(in, UIC1TAG); 
     120        TiffIFDEntry uic2tagEntry=TiffTools.getFirstIFDEntry(in, UIC2TAG); 
     121        TiffIFDEntry uic3tagEntry=TiffTools.getFirstIFDEntry(in, UIC3TAG); 
     122        TiffIFDEntry uic4tagEntry = TiffTools.getFirstIFDEntry(in, UIC4TAG); 
     123        int planes = uic4tagEntry.getValueCount(); 
     124      mmPlanes = planes; 
     125        parseUIC2Tags(uic2tagEntry.getValueOffset()); 
     126        parseUIC4Tags(uic4tagEntry.getValueOffset()); 
     127        parseUIC1Tags(uic1tagEntry.getValueOffset(), 
     128        uic1tagEntry.getValueCount()); 
    117129      in.seek(uic4tagEntry.getValueOffset()); 
    118       int planes = uic4tagEntry.getValueCount(); 
    119  
    120       parseTags(planes); 
    121  
    122       // no idea how this tag is organized - this is just a guess 
    123       long[] uic1 = TiffTools.getIFDLongArray(ifds[0], METAMORPH_ID, true); 
    124       try { 
    125         for (int i=1; i<uic1.length; i+=2) { 
    126           if (uic1[i] >= in.length() / 2) { 
    127             in.seek(uic1[i] + 12); 
    128  
    129             // read a null-terminated string (key), followed by an int value 
    130  
    131             byte[] b = new byte[(int) (in.length() - in.getFilePointer())]; 
    132             in.read(b); 
    133  
    134             StringBuffer sb = new StringBuffer(new String(b)); 
    135  
    136             int pt = 0; 
    137             while (pt < sb.length()) { 
    138               if (!Character.isDefined(sb.charAt(i))) { 
    139                 sb = sb.deleteCharAt(i); 
    140               } 
    141               else pt++; 
    142             } 
    143  
    144             addMeta("Extra data", sb.toString().trim()); 
    145           } 
    146         } 
    147       } 
    148       catch (Exception e) { 
    149         // CTR TODO - eliminate catch-all exception handling 
    150         if (debug) e.printStackTrace(); 
    151       } 
    152  
     130       
    153131      // copy ifds into a new array of Hashtables that will accomodate the 
    154132      // additional image planes 
     
    159137      for (int i=0; i<uic3.length; i++) { 
    160138        in.seek(uic3[i]); 
    161         put("Wavelength [" + i + "]", in.readLong() / in.readLong()); 
     139        put("Wavelength [" + intFormatMax(i,mmPlanes) + "]",  
     140          in.readLong() / in.readLong()); 
    162141      } 
    163142 
     
    303282  } 
    304283 
    305   /*@see BaseTiffReader#getImageName() */ 
     284  /* @see BaseTiffReader#getImageName() */ 
    306285  protected String getImageName() { 
    307286    if (imageName == null) return super.getImageName(); 
     
    321300 
    322301  // -- Utility methods -- 
    323  
    324   /** Parse (tag, value) pairs. */ 
    325   private void parseTags(int planes) throws IOException { 
    326     // Loop through and parse out each field. A field whose 
    327     // code is "0" represents the end of the fields so we'll stop 
    328     // when we reach that; much like a NULL terminated C string. 
    329     int currentcode = in.readShort(); 
    330     byte[] toread; 
    331     while (currentcode != 0) { 
    332       // variable declarations, because switch is dumb 
    333       int num, denom; 
    334       int xnum, xdenom, ynum, ydenom; 
    335       double xpos, ypos; 
    336       String thedate, thetime; 
    337       switch (currentcode) { 
    338         case 1: 
    339           put("MinScale", in.readInt()); 
    340           break; 
    341         case 2: 
    342           put("MaxScale", in.readInt()); 
    343           break; 
    344         case 3: 
    345           int calib = in.readInt(); 
    346           String calibration = calib == 0 ? "on" : "off"; 
    347           put("Spatial Calibration", calibration); 
    348           break; 
    349         case 4: 
    350           num = in.readInt(); 
    351           denom = in.readInt(); 
    352           put("XCalibration", new TiffRational(num, denom)); 
    353           break; 
    354         case 5: 
    355           num = in.readInt(); 
    356           denom = in.readInt(); 
    357           put("YCalibration", new TiffRational(num, denom)); 
    358           break; 
    359         case 6: 
    360           num = in.readInt(); 
    361           toread = new byte[num]; 
    362           in.read(toread); 
    363           put("CalibrationUnits", new String(toread)); 
    364           break; 
    365         case 7: 
    366           num = in.readInt(); 
    367           toread = new byte[num]; 
    368           in.read(toread); 
    369           String name = new String(toread); 
    370           put("Name", name); 
    371           imageName = name; 
    372           break; 
    373         case 8: 
    374           int thresh = in.readInt(); 
    375           String threshState = "off"; 
    376           if (thresh == 1) threshState = "inside"; 
    377           else if (thresh == 2) threshState = "outside"; 
    378           put("ThreshState", threshState); 
    379           break; 
    380         case 9: 
    381           put("ThreshStateRed", in.readInt()); 
    382           break; 
    383         // there is no 10 
    384         case 11: 
    385           put("ThreshStateGreen", in.readInt()); 
    386           break; 
    387         case 12: 
    388           put("ThreshStateBlue", in.readInt()); 
    389           break; 
    390         case 13: 
    391           put("ThreshStateLo", in.readInt()); 
    392           break; 
    393         case 14: 
    394           put("ThreshStateHi", in.readInt()); 
    395           break; 
    396         case 15: 
    397           int zoom = in.readInt(); 
    398           put("Zoom", zoom); 
    399 //            OMETools.setAttribute(ome, "DisplayOptions", "Zoom", "" + zoom); 
    400           break; 
    401         case 16: // oh how we hate you Julian format... 
    402           thedate = decodeDate(in.readInt()); 
    403           thetime = decodeTime(in.readInt()); 
    404           put("DateTime", thedate + " " + thetime); 
    405           imageCreationDate = thedate + " " + thetime; 
    406           break; 
    407         case 17: 
    408           thedate = decodeDate(in.readInt()); 
    409           thetime = decodeTime(in.readInt()); 
    410           put("LastSavedTime", thedate + " " + thetime); 
    411           break; 
    412         case 18: 
    413           put("currentBuffer", in.readInt()); 
    414           break; 
    415         case 19: 
    416           put("grayFit", in.readInt()); 
    417           break; 
    418         case 20: 
    419           put("grayPointCount", in.readInt()); 
    420           break; 
    421         case 21: 
    422           num = in.readInt(); 
    423           denom = in.readInt(); 
    424           put("grayX", new TiffRational(num, denom)); 
    425           break; 
    426         case 22: 
    427           num = in.readInt(); 
    428           denom = in.readInt(); 
    429           put("gray", new TiffRational(num, denom)); 
    430           break; 
    431         case 23: 
    432           num = in.readInt(); 
    433           denom = in.readInt(); 
    434           put("grayMin", new TiffRational(num, denom)); 
    435           break; 
    436         case 24: 
    437           num = in.readInt(); 
    438           denom = in.readInt(); 
    439           put("grayMax", new TiffRational(num, denom)); 
    440           break; 
    441         case 25: 
    442           num = in.readInt(); 
    443           toread = new byte[num]; 
    444           in.read(toread); 
    445           put("grayUnitName", new String(toread)); 
    446           break; 
    447         case 26: 
    448           int standardLUT = in.readInt(); 
    449           String standLUT; 
    450           switch (standardLUT) { 
    451             case 0: 
    452               standLUT = "monochrome"; 
    453               break; 
    454             case 1: 
    455               standLUT = "pseudocolor"; 
    456               break; 
    457             case 2: 
    458               standLUT = "Red"; 
    459               break; 
    460             case 3: 
    461               standLUT = "Green"; 
    462               break; 
    463             case 4: 
    464               standLUT = "Blue"; 
    465               break; 
    466             case 5: 
    467               standLUT = "user-defined"; 
    468               break; 
    469             default: 
    470               standLUT = "monochrome"; break; 
    471           } 
    472           put("StandardLUT", standLUT); 
    473           break; 
    474         case 27: 
    475           put("Wavelength", in.readInt()); 
    476           break; 
    477         case 28: 
    478           for (int i = 0; i < planes; i++) { 
    479             xnum = in.readInt(); 
    480             xdenom = in.readInt(); 
    481             ynum = in.readInt(); 
    482             ydenom = in.readInt(); 
    483             xpos = xnum / xdenom; 
    484             ypos = ynum / ydenom; 
    485             put("Stage Position Plane " + i, 
    486               "(" + xpos + ", " + ypos + ")"); 
    487           } 
    488           break; 
    489         case 29: 
    490           for (int i = 0; i < planes; i++) { 
    491             xnum = in.readInt(); 
    492             xdenom = in.readInt(); 
    493             ynum = in.readInt(); 
    494             ydenom = in.readInt(); 
    495             xpos = xnum / xdenom; 
    496             ypos = ynum / ydenom; 
    497             put("Camera Offset Plane " + i, 
    498               "(" + xpos + ", " + ypos + ")"); 
    499           } 
    500           break; 
    501         case 30: 
    502           put("OverlayMask", in.readInt()); 
    503           break; 
    504         case 31: 
    505           put("OverlayCompress", in.readInt()); 
    506           break; 
    507         case 32: 
    508           put("Overlay", in.readInt()); 
    509           break; 
    510         case 33: 
    511           put("SpecialOverlayMask", in.readInt()); 
    512           break; 
    513         case 34: 
    514           put("SpecialOverlayCompress", in.readInt()); 
    515           break; 
    516         case 35: 
    517           put("SpecialOverlay", in.readInt()); 
    518           break; 
    519         case 36: 
    520           put("ImageProperty", in.readInt()); 
    521           break; 
    522         case 37: 
    523           for (int i = 0; i<planes; i++) { 
    524             num = in.readInt(); 
    525             toread = new byte[num]; 
    526             in.read(toread); 
    527             String s = new String(toread); 
    528             put("StageLabel Plane " + i, s); 
    529           } 
    530           break; 
    531         case 38: 
    532           num = in.readInt(); 
    533           denom = in.readInt(); 
    534           put("AutoScaleLoInfo", new TiffRational(num, denom)); 
    535           break; 
    536         case 39: 
    537           num = in.readInt(); 
    538           denom = in.readInt(); 
    539           put("AutoScaleHiInfo", new TiffRational(num, denom)); 
    540           break; 
    541         case 40: 
    542           for (int i=0; i<planes; i++) { 
    543             num = in.readInt(); 
    544             denom = in.readInt(); 
    545             put("AbsoluteZ Plane " + i, new TiffRational(num, denom)); 
    546           } 
    547           break; 
    548         case 41: 
    549           for (int i=0; i<planes; i++) { 
    550             put("AbsoluteZValid Plane " + i, in.readInt()); 
    551           } 
    552           break; 
    553         case 42: 
    554           put("Gamma", in.readInt()); 
    555           break; 
    556         case 43: 
    557           put("GammaRed", in.readInt()); 
    558           break; 
    559         case 44: 
    560           put("GammaGreen", in.readInt()); 
    561           break; 
    562         case 45: 
    563           put("GammaBlue", in.readInt()); 
    564           break; 
    565       } 
    566       currentcode = in.readShort(); 
    567     } 
     302                 
     303  /** Populates metadata fields with some contained in MetaMorph UIC2 Tag  
     304   * (for each plane:6 integers: 
     305   * zdistance numerator, zdistance denominator,  
     306   * creation date, creation time, modif date, modif time) 
     307   * @param long uic2offset: offset to UIC2 (33629) tag entries  
     308   *  
     309   * not a regular tiff tag (6*N entries, N being the tagCount) 
     310   * @throws IOException  
     311   */ 
     312        void parseUIC2Tags(long uic2offset) throws IOException { 
     313 
     314                int saveLoc = in.getFilePointer(); 
     315                in.seek(uic2offset); 
     316 
     317                /*number of days since the 1st of January 4713 B.C*/ 
     318                int cDate; 
     319                /*milliseconds since 0:00*/ 
     320                int cTime; 
     321 
     322                /*z step, distance separating previous slice from  current one*/ 
     323                double zDistance; 
     324                String iAsString; 
     325 
     326                for (int i=0; i<mmPlanes; i++) { 
     327                        iAsString = intFormatMax(i, mmPlanes); 
     328                        int num = in.readInt(); 
     329                        int den = in.readInt(); 
     330                        zDistance = (double) num / den; 
     331                        put("zDistance[" + iAsString + "]", zDistance); 
     332                        cDate = in.readInt(); 
     333                        put("creationDate[" + iAsString + "]", decodeDate(cDate)); 
     334 
     335                        cTime = in.readInt(); 
     336                        put("creationTime[" + iAsString + "]", decodeTime(cTime)); 
     337                        /* modification date and time are skipped  
     338                                as they all seem equal to 0...??? 
     339                         */ 
     340                        in.skip(8);  
     341                } 
     342                in.seek(saveLoc); 
     343        } 
     344 
     345        /** UIC4 metadata parser 
     346         *  
     347         * UIC4 Table contains per-plane blocks of metadata 
     348         * stage X/Y positions, 
     349         * camera chip offsets, 
     350         * stage labels... 
     351         * @param long uic4offset: offset of UIC4 table (not tiff-compliant) 
     352         * @throws IOException 
     353         *  
     354         */ 
     355        private void parseUIC4Tags(long uic4offset) throws IOException { 
     356                long saveLoc = in.getFilePointer(); 
     357                in.seek(uic4offset); 
     358                boolean end=false; 
     359                short id; 
     360                while (!end) { 
     361                        id = in.readShort(); 
     362 
     363                        switch (id) { 
     364                        case 0: 
     365                                end=true; 
     366                                break; 
     367                        case 28: 
     368                                readStagePositions(); 
     369                                break; 
     370                        case 29: 
     371                                readCameraChipOffsets(); 
     372                                break; 
     373                        case 37: 
     374                                readStageLabels(); 
     375                                break; 
     376                        case 40: 
     377                                readAbsoluteZ(); 
     378                                break; 
     379                        case 41: 
     380                                readAbsoluteZValid(); 
     381                                break; 
     382                        default: 
     383                                //unknown tags: do nothing 
     384                                break; 
     385 
     386                        //28->stagePositions 
     387                        //29->cameraChipOffsets 
     388                        //30->stageLabel 
     389                        //40->AbsoluteZ 
     390                        //41AbsoluteZValid 
     391                        //0->end 
     392                        } 
     393 
     394                } 
     395                in.seek(saveLoc); 
     396        } 
     397         
     398  void readStagePositions() throws IOException { 
     399                int nx, dx, ny, dy; 
     400                /* for each plane:  
     401           2 ints (rational:numerator,denominator) for stage X,  
     402           2 ints (idem) for stage Y position 
     403                 */ 
     404                double xPosition, yPosition; 
     405                String iAsString; 
     406                for(int i=0; i<mmPlanes; i++) { 
     407                        nx = in.readInt(); 
     408                        dx = in.readInt(); 
     409                        ny = in.readInt(); 
     410                        dy = in.readInt(); 
     411                        xPosition = (dx == 0) ? Double.NaN : (double) nx / dx; 
     412                        yPosition = (dy == 0) ? Double.NaN : (double) ny / dy; 
     413                        iAsString = intFormatMax(i, mmPlanes); 
     414                        put("stageX[" + iAsString + "]", xPosition); 
     415                        put("stageY[" + iAsString + "]", yPosition); 
     416                } 
     417 
     418        } 
     419 
     420        void readCameraChipOffsets() throws IOException { 
     421                int nx, dx, ny, dy; 
     422                double cameraXChipOffset, cameraYChipOffset; 
     423                String iAsString; 
     424                for(int i=0; i<mmPlanes; i++) { 
     425                        iAsString = intFormatMax(i, mmPlanes); 
     426                        nx = in.readInt(); 
     427                        dx = in.readInt(); 
     428                        ny = in.readInt(); 
     429                        dy = in.readInt(); 
     430                        cameraXChipOffset = (dx == 0) ? Double.NaN: (double) nx / dx; 
     431                        cameraYChipOffset = (dy == 0) ? Double.NaN: (double) ny/ dy; 
     432                        put("cameraXChipOffset[" + iAsString + "]", cameraXChipOffset); 
     433                        put("cameraYChipOffset[" + iAsString + "]", cameraYChipOffset); 
     434                } 
     435        } 
     436 
     437        void readStageLabels() throws IOException { 
     438                int strlen; 
     439                byte[] curlabel; 
     440                String iAsString; 
     441                for (int i=0; i<mmPlanes; i++) { 
     442                        iAsString = intFormatMax(i, mmPlanes); 
     443                        strlen = in.readInt(); 
     444                        curlabel = new byte[strlen]; 
     445                        in.read(curlabel); 
     446                        put("stageLabel[" + iAsString + "]", new String(curlabel)); 
     447                } 
     448        } 
     449 
     450        void readAbsoluteZ() throws IOException { 
     451                int nz, dz; 
     452                double absoluteZ; 
     453                for(int i=0; i<mmPlanes; i++) { 
     454                        nz = in.readInt(); 
     455                        dz = in.readInt(); 
     456                        absoluteZ = (dz == 0) ? Double.NaN : (double) nz / dz; 
     457                        put("absoluteZ[" + intFormatMax(i, mmPlanes) + "]", absoluteZ); 
     458                } 
     459        } 
     460 
     461        void readAbsoluteZValid() throws IOException { 
     462                for (int i=0; i<mmPlanes; i++) { 
     463                        put("absoluteZValid[" + intFormatMax(i, mmPlanes) + "]", in.readInt()); 
     464    }    
    568465  } 
    569466 
     467        /** UIC1 entry parser  
     468         * @throws IOException 
     469         * @param long uic1offset : offset as found in the tiff tag 33628 (UIC1Tag) 
     470         * @param int uic1count : number of entries in UIC1 table (not tiff-compliant) 
     471         * */ 
     472        private void parseUIC1Tags(long uic1offset, int uic1count) throws IOException 
     473  { 
     474                // Loop through and parse out each field. A field whose 
     475                // code is "0" represents the end of the fields so we'll stop 
     476                // when we reach that; much like a NULL terminated C string. 
     477                long saveLoc = in.getFilePointer(); 
     478                in.seek(uic1offset); 
     479                int currentID, valOrOffset; 
     480                // variable declarations, because switch is dumb 
     481                int num, denom; 
     482                String thedate, thetime; 
     483                long lastOffset; 
     484                byte[] toread; 
     485                for(int i=0; i<uic1count; i++) { 
     486                        currentID = in.readInt(); 
     487                        valOrOffset = in.readInt(); 
     488                                         
     489                        switch (currentID) { 
     490                        case 1: 
     491                                put("MinScale", valOrOffset); 
     492                                break; 
     493                        case 2: 
     494                                put("MaxScale", valOrOffset); 
     495                                break; 
     496                        case 3: 
     497                                int calib = valOrOffset; 
     498                                String calibration = calib != 0 ? "on" : "off"; 
     499                                put("Spatial Calibration", calibration); 
     500                                break; 
     501                        case 4: 
     502                                lastOffset = in.getFilePointer(); 
     503                                in.seek(valOrOffset); 
     504                                num = in.readInt(); 
     505                                denom = in.readInt(); 
     506                                put("XCalibration", new TiffRational(num, denom)); 
     507                                in.seek(lastOffset); 
     508                                break; 
     509                        case 5: 
     510                                lastOffset = in.getFilePointer(); 
     511                                in.seek(valOrOffset); 
     512                                num = in.readInt(); 
     513                                denom = in.readInt(); 
     514                                put("YCalibration", new TiffRational(num, denom)); 
     515                                in.seek(lastOffset); 
     516                                break; 
     517                        case 6: 
     518                                lastOffset = in.getFilePointer(); 
     519                                in.seek(valOrOffset); 
     520                                num = in.readInt(); 
     521                                toread = new byte[num]; 
     522                                in.read(toread); 
     523                                put("CalibrationUnits", new String(toread)); 
     524                                in.seek(lastOffset); 
     525                                break; 
     526                        case 7: 
     527                                lastOffset = in.getFilePointer(); 
     528                                in.seek(valOrOffset); 
     529                                num = in.readInt(); 
     530                                toread = new byte[num]; 
     531                                in.read(toread); 
     532                                String name = new String(toread); 
     533                                put("Name", name); 
     534                                imageName = name; 
     535                                in.seek(lastOffset); 
     536                                break; 
     537                                 
     538                        case 8: 
     539                                int thresh = valOrOffset; 
     540                                String threshState = "off"; 
     541                                if (thresh == 1) threshState = "inside"; 
     542                                else if (thresh == 2) threshState = "outside"; 
     543                                put("ThreshState", threshState); 
     544                                break; 
     545                        case 9: 
     546                                put("ThreshStateRed", valOrOffset); 
     547                                break; 
     548                                // there is no 10 
     549                        case 11: 
     550                                put("ThreshStateGreen", valOrOffset); 
     551                                break; 
     552                        case 12: 
     553                                put("ThreshStateBlue", valOrOffset); 
     554                                break; 
     555                        case 13: 
     556                                put("ThreshStateLo", valOrOffset); 
     557                                break; 
     558                        case 14: 
     559                                put("ThreshStateHi", valOrOffset); 
     560                                break; 
     561                        case 15: 
     562                                int zoom = valOrOffset; 
     563                                put("Zoom", zoom); 
     564//                              OMETools.setAttribute(ome, "DisplayOptions", "Zoom", "" + zoom); 
     565                                break; 
     566                        case 16: // oh how we hate you Julian format... 
     567                                lastOffset = in.getFilePointer(); 
     568                                in.seek(valOrOffset); 
     569                                thedate = decodeDate(in.readInt()); 
     570                                thetime = decodeTime(in.readInt()); 
     571                                put("DateTime", thedate + " " + thetime); 
     572                                imageCreationDate = thedate + " " + thetime; 
     573                                in.seek(lastOffset); 
     574                                break; 
     575                        case 17: 
     576                                lastOffset = in.getFilePointer(); 
     577                                in.seek(valOrOffset); 
     578                                thedate = decodeDate(in.readInt()); 
     579                                thetime = decodeTime(in.readInt()); 
     580                                put("LastSavedTime", thedate + " " + thetime); 
     581                                in.seek(lastOffset); 
     582                                break; 
     583                        case 18: 
     584                                put("currentBuffer", valOrOffset); 
     585                                break; 
     586                        case 19: 
     587                                put("grayFit", valOrOffset); 
     588                                break; 
     589                        case 20: 
     590                                put("grayPointCount", valOrOffset); 
     591                                break; 
     592                        case 21: 
     593                                lastOffset = in.getFilePointer(); 
     594                                in.seek(valOrOffset); 
     595                                num = in.readInt(); 
     596                                denom = in.readInt(); 
     597                                put("grayX", new TiffRational(num, denom)); 
     598                                in.seek(lastOffset); 
     599                                break; 
     600                        case 22: 
     601                                lastOffset = in.getFilePointer(); 
     602                                in.seek(valOrOffset); 
     603                                num = in.readInt(); 
     604                                denom = in.readInt(); 
     605                                put("gray", new TiffRational(num, denom)); 
     606                                in.seek(lastOffset); 
     607                                break; 
     608                        case 23: 
     609                                lastOffset = in.getFilePointer(); 
     610                                in.seek(valOrOffset); 
     611                                num = in.readInt(); 
     612                                denom = in.readInt(); 
     613                                put("grayMin", new TiffRational(num, denom)); 
     614                                in.seek(lastOffset); 
     615                                break; 
     616                        case 24: 
     617                                lastOffset = in.getFilePointer(); 
     618                                in.seek(valOrOffset); 
     619                                num = in.readInt(); 
     620                                denom = in.readInt(); 
     621                                put("grayMax", new TiffRational(num, denom)); 
     622                                in.seek(lastOffset); 
     623                                break; 
     624                                 
     625                        case 25: 
     626                                lastOffset = in.getFilePointer(); 
     627                                in.seek(valOrOffset); 
     628                                num = in.readInt(); 
     629                                toread = new byte[num]; 
     630                                in.read(toread); 
     631                                put("grayUnitName", new String(toread)); 
     632                                in.seek(lastOffset); 
     633                                break; 
     634                                 
     635                        case 26: 
     636                                lastOffset = in.getFilePointer(); 
     637                                in.seek(valOrOffset); 
     638                                int standardLUT = in.readInt(); 
     639                                in.seek(lastOffset); 
     640                                String standLUT; 
     641                                switch (standardLUT) { 
     642                                case 0: 
     643                                        standLUT = "monochrome"; 
     644                                        break; 
     645                                case 1: 
     646                                        standLUT = "pseudocolor"; 
     647                                        break; 
     648                                case 2: 
     649                                        standLUT = "Red"; 
     650                                        break; 
     651                                case 3: 
     652                                        standLUT = "Green"; 
     653                                        break; 
     654                                case 4: 
     655                                        standLUT = "Blue"; 
     656                                        break; 
     657                                case 5: 
     658                                        standLUT = "user-defined"; 
     659                                        break; 
     660                                default: 
     661                                        standLUT = "monochrome"; break; 
     662                                } 
     663                                put("StandardLUT", standLUT); 
     664                                break; 
     665                        case 27: 
     666                                put("Wavelength", valOrOffset); 
     667                                break; 
     668                        case 30: 
     669                                put("OverlayMask", valOrOffset); 
     670                                break; 
     671                        case 31: 
     672                                put("OverlayCompress", valOrOffset); 
     673                                break; 
     674                        case 32: 
     675                                put("Overlay", valOrOffset); 
     676                                break; 
     677                        case 33: 
     678                                put("SpecialOverlayMask", valOrOffset); 
     679                                break; 
     680                        case 34: 
     681                                put("SpecialOverlayCompress", in.readInt()); 
     682                                break; 
     683                        case 35: 
     684                                put("SpecialOverlay", valOrOffset); 
     685                                break; 
     686                        case 36: 
     687                                put("ImageProperty", valOrOffset); 
     688                                break; 
     689                        case 38: 
     690                                lastOffset = in.getFilePointer(); 
     691                                in.seek(valOrOffset); 
     692                                num = in.readInt(); 
     693                                denom = in.readInt(); 
     694                                put("AutoScaleLoInfo", new TiffRational(num, denom)); 
     695                                in.seek(lastOffset); 
     696                                break; 
     697                        case 39: 
     698                                lastOffset = in.getFilePointer(); 
     699                                in.seek(valOrOffset); 
     700                                num = in.readInt(); 
     701                                denom = in.readInt(); 
     702                                put("AutoScaleHiInfo", new TiffRational(num, denom)); 
     703                                in.seek(lastOffset); 
     704                                break; 
     705                        case 42: 
     706                                put("Gamma", valOrOffset); 
     707                                break; 
     708                        case 43: 
     709                                put("GammaRed", valOrOffset); 
     710                                break; 
     711                        case 44: 
     712                                put("GammaGreen", valOrOffset); 
     713                                break; 
     714                        case 45: 
     715                                put("GammaBlue", valOrOffset); 
     716                                break; 
     717                        case 46: 
     718                                lastOffset = in.getFilePointer(); 
     719                                in.seek(valOrOffset); 
     720                                int xBin, yBin; 
     721                                xBin = in.readInt(); 
     722                                yBin = in.readInt(); 
     723                                put("CameraBin", new String("(" + xBin + "," + yBin + ")")); 
     724                                in.seek(lastOffset); 
     725                    break;       
     726      default: 
     727                                break; 
     728                        } 
     729                } 
     730                in.seek(saveLoc); 
     731        } 
     732         
    570733  /** Converts a Julian date value into a human-readable string. */ 
    571734  public static String decodeDate(int julian) { 
     
    608771    millis /= 60; 
    609772    hours = millis; 
    610  
    611     return hours + ":" + minutes + ":" + seconds + "." + ms; 
     773    return intFormat(hours, 2) + ":" + intFormat(minutes, 2) + ":" +  
     774      intFormat(seconds, 2) + "." + intFormat(ms, 3); 
    612775  } 
     776   
     777  /** Formats an integer value with leading 0s if needed. */ 
     778        public static String intFormat(int myint, int digits) { 
     779                String formatstring = "0"; 
     780                while (formatstring.length() < digits) { 
     781                        formatstring += "0"; 
     782    } 
     783                DecimalFormat df = new DecimalFormat(formatstring); 
     784                return df.format(myint); 
     785        } 
     786   
     787  /** 
     788   * Formats an integer with leading 0 using maximum sequence number 
     789         *  
     790         * @param myint : integer to format 
     791         * @param maxint : max of "myint" 
     792         * @return String 
     793         */ 
     794        public static String intFormatMax(int myint, int maxint) { 
     795                return intFormat(myint, new Integer(maxint).toString().length()); 
     796        } 
    613797 
    614798} 
Note: See TracChangeset for help on using the changeset viewer.