Changeset 6872


Ignore:
Timestamp:
09/02/10 10:43:35 (9 years ago)
Author:
melissa
Message:

Fixed OMETiffWriter.close() so that it releases resources even if an exception is thrown, and in the process made it a bit easier to read. Closes #543.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/bio-formats/src/loci/formats/out/OMETiffWriter.java

    r6743 r6872  
    7979  private String[][] imageLocations; 
    8080  private int totalPlanes = 0; 
     81  private OMEXMLMetadata omeMeta; 
     82  private OMEXMLService service; 
    8183 
    8284  // -- Constructor -- 
     
    9092  /* @see loci.formats.IFormatHandler#close() */ 
    9193  public void close() throws IOException { 
    92     if (currentId != null) { 
    93       if (!wroteLast) { 
    94         super.close(); 
    95         return; 
    96       } 
    97  
    98       // extract OME-XML string from metadata object 
    99       MetadataRetrieve retrieve = getMetadataRetrieve(); 
    100  
    101       OMEXMLMetadata omeMeta; 
    102       OMEXMLService service; 
    103       try { 
    104         ServiceFactory factory = new ServiceFactory(); 
    105         service = factory.getInstance(OMEXMLService.class); 
    106         omeMeta = service.getOMEMetadata(retrieve); 
    107         if (omeMeta instanceof OMEXMLMetadataImpl) { 
    108           ((OMEXMLMetadataImpl) omeMeta).resolveReferences(); 
     94    try { 
     95      if (currentId != null && wroteLast) { 
     96        setupServiceAndMetadata(); 
     97 
     98        // remove any BinData elements from the OME-XML 
     99        removeBinData(omeMeta); 
     100 
     101        for (int series=0; series<omeMeta.getImageCount(); series++) { 
     102          populateImage(omeMeta, series); 
    109103        } 
    110       } 
    111       catch (DependencyException de) { 
    112         // TODO : Modify close() signature to include FormatException? 
    113         // throw new MissingLibraryException(OMETiffReader.NO_OME_XML_JAR, de); 
    114         throw new RuntimeException(de); 
    115       } 
    116       catch (ServiceException se) { 
    117         // TODO : Modify close() signature to include FormatException? 
    118         // throw new FormatException(se); 
    119         throw new RuntimeException(se); 
    120       } 
    121  
    122       // remove any BinData elements from the OME-XML 
    123  
    124       OME root = (OME) omeMeta.getRoot(); 
    125       List<Image> images = root.copyImageList(); 
    126       for (Image img : images) { 
    127         Pixels pix = img.getPixels(); 
    128         List<BinData> binData = pix.copyBinDataList(); 
    129         for (BinData bin : binData) { 
    130           pix.removeBinData(bin); 
     104 
     105        ArrayList<String> files = new ArrayList<String>(); 
     106        for (String[] s : imageLocations) { 
     107          for (String f : s) { 
     108            if (!files.contains(f)) { 
     109              files.add(f); 
     110 
     111              String xml = getOMEXML(f); 
     112 
     113              // write OME-XML to the first IFD's comment 
     114              saveComment(f, xml); 
     115            } 
     116          } 
    131117        } 
    132118      } 
    133       omeMeta.setRoot(root); 
    134  
    135       for (int series=0; series<omeMeta.getImageCount(); series++) { 
    136         String dimensionOrder = 
    137           omeMeta.getPixelsDimensionOrder(series).toString(); 
    138         int sizeZ = omeMeta.getPixelsSizeZ(series).getValue().intValue(); 
    139         int sizeC = omeMeta.getPixelsSizeC(series).getValue().intValue(); 
    140         int sizeT = omeMeta.getPixelsSizeT(series).getValue().intValue(); 
    141  
    142         int imageCount = getPlaneCount(); 
    143         int ifdCount = seriesMap.size(); 
    144  
    145         if (imageCount == 0) { 
    146           omeMeta.setTiffDataPlaneCount(new NonNegativeInteger(0), series, 0); 
    147           continue; 
    148         } 
    149  
    150         PositiveInteger samplesPerPixel = 
    151           new PositiveInteger((sizeZ * sizeC * sizeT) / imageCount); 
    152         for (int c=0; c<omeMeta.getChannelCount(series); c++) { 
    153           omeMeta.setChannelSamplesPerPixel(samplesPerPixel, series, c); 
    154         } 
    155         sizeC /= samplesPerPixel.getValue(); 
    156  
    157         HashMap<String, Integer> ifdCounts = new HashMap<String, Integer>(); 
    158  
    159         for (int plane=0; plane<imageCount; plane++) { 
    160           int[] zct = FormatTools.getZCTCoords(dimensionOrder, 
    161             sizeZ, sizeC, sizeT, imageCount, plane); 
    162           String filename = 
    163             new Location(imageLocations[series][plane]).getName(); 
    164  
    165           Integer ifdIndex = ifdCounts.get(filename); 
    166           int ifd = ifdIndex == null ? 0 : ifdIndex.intValue(); 
    167  
    168           omeMeta.setUUIDFileName(filename, series, plane); 
    169           String uuid = "urn:uuid:" + getUUID(filename); 
    170           omeMeta.setUUIDValue(uuid, series, plane); 
    171           // fill in any non-default TiffData attributes 
    172           omeMeta.setTiffDataFirstZ( 
    173               new NonNegativeInteger(zct[0]), series, plane); 
    174           omeMeta.setTiffDataFirstC( 
    175               new NonNegativeInteger(zct[1]), series, plane); 
    176           omeMeta.setTiffDataFirstT( 
    177               new NonNegativeInteger(zct[2]), series, plane); 
    178           omeMeta.setTiffDataIFD(new NonNegativeInteger(ifd), series, plane); 
    179           omeMeta.setTiffDataPlaneCount( 
    180               new NonNegativeInteger(1), series, plane); 
    181  
    182           ifdCounts.put(filename, ifd + 1); 
    183         } 
    184       } 
    185  
    186       ArrayList<String> files = new ArrayList<String>(); 
    187       for (String[] s : imageLocations) { 
    188         for (String f : s) { 
    189           if (!files.contains(f)) files.add(f); 
    190         } 
    191       } 
    192  
    193       for (String file : files) { 
    194         // generate UUID and add to OME element 
    195         String uuid = "urn:uuid:" + getUUID(new Location(file).getName()); 
    196         omeMeta.setUUID(uuid); 
    197  
    198         String xml; 
    199         try { 
    200           xml = service.getOMEXML(omeMeta); 
    201         } 
    202         catch (ServiceException se) { 
    203           // FIXME: Modify close() signature to include FormatException? 
    204           // throw new FormatException(se); 
    205           throw new RuntimeException(se); 
    206         } 
    207  
    208         // insert warning comment 
    209         String prefix = xml.substring(0, xml.indexOf(">") + 1); 
    210         String suffix = xml.substring(xml.indexOf(">") + 1); 
    211         xml = prefix + WARNING_COMMENT + suffix; 
    212  
    213         if (out != null) out.close(); 
    214         out = new RandomAccessOutputStream(file); 
    215  
    216         // write OME-XML to the first IFD's comment 
    217         try { 
    218           TiffSaver saver = new TiffSaver(out); 
    219           RandomAccessInputStream in = new RandomAccessInputStream(file); 
    220           saver.overwriteLastIFDOffset(in); 
    221           saver.overwriteComment(in, xml); 
    222           in.close(); 
    223         } 
    224         catch (FormatException exc) { 
    225           IOException io = new IOException("Unable to append OME-XML comment"); 
    226           io.initCause(exc); 
    227           throw io; 
    228         } 
    229       } 
    230     } 
    231     super.close(); 
    232     seriesMap = null; 
    233     imageLocations = null; 
    234     wroteLast = false; 
    235     totalPlanes = 0; 
     119    } 
     120    catch (DependencyException de) { 
     121      throw new RuntimeException(de); 
     122    } 
     123    catch (ServiceException se) { 
     124      throw new RuntimeException(se); 
     125    } 
     126    catch (FormatException fe) { 
     127      throw new RuntimeException(fe); 
     128    } 
     129    catch (IllegalArgumentException iae) { 
     130      throw new RuntimeException(iae); 
     131    } 
     132    finally { 
     133      super.close(); 
     134      if (wroteLast) { 
     135        seriesMap = null; 
     136        imageLocations = null; 
     137        wroteLast = false; 
     138        totalPlanes = 0; 
     139        omeMeta = null; 
     140        service = null; 
     141      } 
     142    } 
    236143  } 
    237144 
     
    297204  } 
    298205 
     206  private void setupServiceAndMetadata() 
     207    throws DependencyException, ServiceException 
     208  { 
     209    // extract OME-XML string from metadata object 
     210    MetadataRetrieve retrieve = getMetadataRetrieve(); 
     211 
     212    ServiceFactory factory = new ServiceFactory(); 
     213    service = factory.getInstance(OMEXMLService.class); 
     214    omeMeta = service.getOMEMetadata(retrieve); 
     215    if (omeMeta instanceof OMEXMLMetadataImpl) { 
     216      ((OMEXMLMetadataImpl) omeMeta).resolveReferences(); 
     217    } 
     218  } 
     219 
     220  private String getOMEXML(String file) throws FormatException, IOException { 
     221    // generate UUID and add to OME element 
     222    String uuid = "urn:uuid:" + getUUID(new Location(file).getName()); 
     223    omeMeta.setUUID(uuid); 
     224 
     225    String xml; 
     226    try { 
     227      xml = service.getOMEXML(omeMeta); 
     228    } 
     229    catch (ServiceException se) { 
     230      throw new FormatException(se); 
     231    } 
     232 
     233    // insert warning comment 
     234    String prefix = xml.substring(0, xml.indexOf(">") + 1); 
     235    String suffix = xml.substring(xml.indexOf(">") + 1); 
     236    return prefix + WARNING_COMMENT + suffix; 
     237  } 
     238 
     239  private void saveComment(String file, String xml) throws IOException { 
     240    if (out != null) out.close(); 
     241    out = new RandomAccessOutputStream(file); 
     242    RandomAccessInputStream in = null; 
     243    try { 
     244      TiffSaver saver = new TiffSaver(out); 
     245      in = new RandomAccessInputStream(file); 
     246      saver.overwriteLastIFDOffset(in); 
     247      saver.overwriteComment(in, xml); 
     248      in.close(); 
     249    } 
     250    catch (FormatException exc) { 
     251      IOException io = new IOException("Unable to append OME-XML comment"); 
     252      io.initCause(exc); 
     253      throw io; 
     254    } 
     255    finally { 
     256      if (out != null) out.close(); 
     257      if (in != null) in.close(); 
     258    } 
     259  } 
     260 
     261  private void removeBinData(OMEXMLMetadata omeMeta) { 
     262    OME root = (OME) omeMeta.getRoot(); 
     263    List<Image> images = root.copyImageList(); 
     264    for (Image img : images) { 
     265      Pixels pix = img.getPixels(); 
     266      List<BinData> binData = pix.copyBinDataList(); 
     267      for (BinData bin : binData) { 
     268        pix.removeBinData(bin); 
     269      } 
     270    } 
     271    omeMeta.setRoot(root); 
     272  } 
     273 
     274  private void populateTiffData(OMEXMLMetadata omeMeta, int[] zct, 
     275    int ifd, int series, int plane) 
     276  { 
     277    omeMeta.setTiffDataFirstZ(new NonNegativeInteger(zct[0]), series, plane); 
     278    omeMeta.setTiffDataFirstC(new NonNegativeInteger(zct[1]), series, plane); 
     279    omeMeta.setTiffDataFirstT(new NonNegativeInteger(zct[2]), series, plane); 
     280    omeMeta.setTiffDataIFD(new NonNegativeInteger(ifd), series, plane); 
     281    omeMeta.setTiffDataPlaneCount(new NonNegativeInteger(1), series, plane); 
     282  } 
     283 
     284  private void populateImage(OMEXMLMetadata omeMeta, int series) { 
     285    String dimensionOrder = omeMeta.getPixelsDimensionOrder(series).toString(); 
     286    int sizeZ = omeMeta.getPixelsSizeZ(series).getValue().intValue(); 
     287    int sizeC = omeMeta.getPixelsSizeC(series).getValue().intValue(); 
     288    int sizeT = omeMeta.getPixelsSizeT(series).getValue().intValue(); 
     289 
     290    int imageCount = getPlaneCount(); 
     291    int ifdCount = seriesMap.size(); 
     292 
     293    if (imageCount == 0) { 
     294      omeMeta.setTiffDataPlaneCount(new NonNegativeInteger(0), series, 0); 
     295      return; 
     296    } 
     297 
     298    PositiveInteger samplesPerPixel = 
     299      new PositiveInteger((sizeZ * sizeC * sizeT) / imageCount); 
     300    for (int c=0; c<omeMeta.getChannelCount(series); c++) { 
     301      omeMeta.setChannelSamplesPerPixel(samplesPerPixel, series, c); 
     302    } 
     303    sizeC /= samplesPerPixel.getValue(); 
     304 
     305    HashMap<String, Integer> ifdCounts = new HashMap<String, Integer>(); 
     306 
     307    for (int plane=0; plane<imageCount; plane++) { 
     308      int[] zct = FormatTools.getZCTCoords(dimensionOrder, 
     309        sizeZ, sizeC, sizeT, imageCount, plane); 
     310      String filename = new Location(imageLocations[series][plane]).getName(); 
     311 
     312      Integer ifdIndex = ifdCounts.get(filename); 
     313      int ifd = ifdIndex == null ? 0 : ifdIndex.intValue(); 
     314 
     315      omeMeta.setUUIDFileName(filename, series, plane); 
     316      String uuid = "urn:uuid:" + getUUID(filename); 
     317      omeMeta.setUUIDValue(uuid, series, plane); 
     318 
     319      // fill in any non-default TiffData attributes 
     320      populateTiffData(omeMeta, zct, ifd, series, plane); 
     321      ifdCounts.put(filename, ifd + 1); 
     322    } 
     323  } 
     324 
    299325} 
Note: See TracChangeset for help on using the changeset viewer.