gt:                 store.setPixelsSizeT(new PositiveInteger(1), 0);
context: /*
   * #%L
   * Bio-Formats Plugins for ImageJ: a collection of ImageJ plugins including the
   * Bio-Formats Importer, Bio-Formats Exporter, Bio-Formats Macro Extensions,
   * Data Browser and Stack Slicer.
   * %%
   * Copyright (C) 2006 - 2017 Open Microscopy Environment:
   *   - Board of Regents of the University of Wisconsin-Madison
   *   - Glencoe Software, Inc.
   *   - University of Dundee
   * %%
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as
   * published by the Free Software Foundation, either version 2 of the 
   * License, or (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public 
   * License along with this program.  If not, see
   * <http://www.gnu.org/licenses/gpl-2.0.html>.
   * #L%
   */
  
  package loci.plugins.out;
  
  import ij.CompositeImage;
  import ij.IJ;
  import ij.ImagePlus;
  import ij.ImageStack;
  import ij.Macro;
  import ij.Prefs;
  import ij.WindowManager;
  import ij.gui.GenericDialog;
  import ij.io.FileInfo;
  import ij.io.OpenDialog;
  import ij.measure.Calibration;
  import ij.plugin.frame.Recorder;
  import ij.process.ByteProcessor;
  import ij.process.ColorProcessor;
  import ij.process.FloatProcessor;
  import ij.process.ImageProcessor;
  import ij.process.LUT;
  import ij.process.ShortProcessor;
  
  import java.awt.Image;
  import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.swing.JFileChooser;
  import javax.swing.JOptionPane;
  import javax.swing.filechooser.FileFilter;
  
  import loci.common.DataTools;
  import loci.common.services.DependencyException;
  import loci.common.services.ServiceException;
  import loci.common.services.ServiceFactory;
  import loci.formats.FormatException;
  import loci.formats.FormatTools;
  import loci.formats.IFormatWriter;
  import loci.formats.ImageWriter;
  import loci.formats.MetadataTools;
  import loci.formats.gui.AWTImageTools;
  import loci.formats.gui.ExtensionFileFilter;
  import loci.formats.gui.GUITools;
  import loci.formats.gui.Index16ColorModel;
  import loci.formats.meta.IMetadata;
  import loci.formats.services.OMEXMLService;
  import loci.plugins.BF;
  import loci.plugins.LociExporter;
  import loci.plugins.util.ROIHandler;
  import loci.plugins.util.RecordedImageProcessor;
  import loci.plugins.util.WindowTools;
  import ome.units.UNITS;
  import ome.units.quantity.Time;
  import ome.xml.meta.OMEXMLMetadataRoot;
  import ome.xml.model.ROI;
  import ome.xml.model.enums.DimensionOrder;
  import ome.xml.model.enums.EnumerationException;
  import ome.xml.model.enums.PixelType;
  import ome.xml.model.primitives.PositiveInteger;
  
  /**
   * Core logic for the Bio-Formats Exporter ImageJ plugin.
   *
   * @author Melissa Linkert melissa at glencoesoftware.com
   */
  public class Exporter {
  
      // -- Constants --
  
      private static final String ORDER = "XYCZT";
  
      // -- Fields --
  
      /** Current stack. */
      private ImagePlus imp;
  
      private LociExporter plugin;
  
      /**
       * Removes the extension of the specified name.
       *
       * @param name The name to handle.
       * @return See above.
       */
      private String removeExtension(String name)
      {
          int index = name.lastIndexOf(".");
          //check if separator
          int unixPos = name.lastIndexOf('/');
          int windowsPos = name.lastIndexOf('\\');
          int max = Math.max(unixPos, windowsPos);
          if (max < index) {
              return name.substring(0, index);
          }
          return name;
      }
      // -- Constructor --
  
      public Exporter(LociExporter plugin, ImagePlus imp) {
          this.plugin = plugin;
          this.imp = imp;
      }
  
      // -- Exporter API methods --
  
      /** Executes the plugin. */
      public void run() {
          String outfile = null;
          Boolean splitZ = null;
          Boolean splitC = null;
          Boolean splitT = null;
          Boolean padded = null;
          Boolean saveRoi = null;
          String compression = null;
  
          Boolean windowless = Boolean.FALSE;
          if (plugin.arg != null) {
              outfile = Macro.getValue(plugin.arg, "outfile", null);
  
              String z = Macro.getValue(plugin.arg, "splitZ", null);
              String c = Macro.getValue(plugin.arg, "splitC", null);
              String t = Macro.getValue(plugin.arg, "splitT", null);
              String zeroPad = Macro.getValue(plugin.arg, "padded", null);
              String sr = Macro.getValue(plugin.arg, "saveRoi", null);
              compression = Macro.getValue(plugin.arg, "compression", null);
              String id = Macro.getValue(plugin.arg, "imageid", null);
              splitZ = z == null ? null : Boolean.valueOf(z);
              splitC = c == null ? null : Boolean.valueOf(c);
              splitT = t == null ? null : Boolean.valueOf(t);
              padded = zeroPad == null ? null : Boolean.valueOf(zeroPad);
              saveRoi = sr == null ? null : Boolean.valueOf(sr);
              if (id != null) {
                  try {
                      int imageID = Integer.parseInt(id);
                      ImagePlus plus = WindowManager.getImage(imageID);
                      if (plus != null) imp = plus;
                  } catch (Exception e) {
                      //nothing to do, we use the current imagePlus
                  }
              }
              String w =  Macro.getValue(plugin.arg, "windowless", null);
              if (w != null) {
                  windowless = Boolean.valueOf(w);
              }
              plugin.arg = null;
          }
          if (outfile == null) {
              String options = Macro.getOptions();
              if (options != null) {
                  String save = Macro.getValue(options, "save", null);
                  if (save != null) outfile = save;
              }
          }
          //create a temporary file if window less
          if (windowless && (outfile == null || outfile.length() == 0)) {
              File tmp = null;
              try {
                  String name = removeExtension(imp.getTitle());
                  String n = name+ ".ome.tif";
                  tmp = File.createTempFile(name, ".ome.tif");
                  File p = tmp.getParentFile();
                  File[] list = p.listFiles();
                  //make sure we delete a previous tmp file with same name if any
                  if (list != null) {
                      File toDelete = null;
                      for (int i = 0; i < list.length; i++) {
                          if (list[i].getName().equals(n)) {
                              toDelete = list[i];
                              break;
                          }
                      }
                      if (toDelete != null) {
                          toDelete.delete();
                      }
                  }
                  outfile = new File(p, n).getAbsolutePath();
                  if (Recorder.record) Recorder.recordPath("outputfile", outfile);
                  IJ.log("exporter outputfile "+outfile);
              } catch (Exception e) {
                  //fall back to window mode.
              } finally {
                  if (tmp != null) tmp.delete();
              }
          }
          File f = null;
          if (outfile == null || outfile.length() == 0) {
              // open a dialog prompting for the filename to save
              // NB: Copied and adapted from ij.io.SaveDIalog.jSaveDispatchThread,
              // so that the save dialog has a file filter for choosing output format.
  
              String dir = null, name = null;
              JFileChooser fc = GUITools.buildFileChooser(new ImageWriter(), false);
              fc.setDialogTitle("Bio-Formats Exporter");
              String defaultDir = OpenDialog.getDefaultDirectory();
              if (defaultDir != null) fc.setCurrentDirectory(new File(defaultDir));
  
              // set OME-TIFF as the default output format
              FileFilter[] ff = fc.getChoosableFileFilters();
              FileFilter defaultFilter = null;
              for (int i=0; i<ff.length; i++) {
                  if (ff[i] instanceof ExtensionFileFilter) {
                      ExtensionFileFilter eff = (ExtensionFileFilter) ff[i];
                      if (i == 0 || eff.getExtension().equals("ome.tif")) {
                          defaultFilter = eff;
                          break;
                      }
                  }
              }
              if (defaultFilter != null) fc.setFileFilter(defaultFilter);
  
              int returnVal = fc.showSaveDialog(IJ.getInstance());
              if (returnVal != JFileChooser.APPROVE_OPTION) {
                  Macro.abort();
                  return;
              }
              f = fc.getSelectedFile();
              dir = fc.getCurrentDirectory().getPath() + File.separator;
              name = fc.getName(f);
              if (f.exists()) {
                  int ret = JOptionPane.showConfirmDialog(fc,
                          "The file " + f.getName() + " already exists. \n" +
                                  "Would you like to replace it?", "Replace?",
                                  JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
                  if (ret != JOptionPane.OK_OPTION) f = null;
              } else {
                  // ensure filename matches selected filter
                  FileFilter filter = fc.getFileFilter();
                  if (filter instanceof ExtensionFileFilter) {
                      ExtensionFileFilter eff = (ExtensionFileFilter) filter;
                      String[] ext = eff.getExtensions();
                      String lName = name.toLowerCase();
                      boolean hasExtension = false;
                      for (int i=0; i<ext.length; i++) {
                          if (lName.endsWith("." + ext[i])) {
                              hasExtension = true;
                              break;
                          }
                      }
                      if (!hasExtension && ext.length > 0) {
                          // append chosen extension
                          name = name + "." + ext[0];
                      }
  
                      f = fc.getSelectedFile();
                      String filePath = f.getAbsolutePath();
                      if(!filePath.endsWith("." + ext[0])) {
                          f = new File(filePath + '.' + ext[0]);
                      }
                      if (f.exists()) {
                          int ret1 = JOptionPane.showConfirmDialog(fc,
                                  "The file " + f.getName() + " already exists. \n" +
                                          "Would you like to replace it?", "Replace?",
                                          JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
                          if (ret1 != JOptionPane.OK_OPTION) f = null;
                      }
  
                  }
              }
              if (f == null) Macro.abort();
              else {
                  // do some ImageJ bookkeeping
                  OpenDialog.setDefaultDirectory(dir);
                  if (Recorder.record) Recorder.recordPath("save", dir+name);
              }
  
              if (dir == null || name == null) return;
              outfile = new File(dir, name).getAbsolutePath();
              if (outfile == null) return;
          }
  
          if (windowless) {
              if (splitZ == null) splitZ = Boolean.FALSE;
              if (splitC == null) splitC = Boolean.FALSE;
              if (splitT == null) splitT = Boolean.FALSE;
              if (padded == null) padded = Boolean.FALSE;
          }
          if (splitZ == null || splitC == null || splitT == null) {
              // ask if we want to export multiple files
  
              GenericDialog multiFile =
                      new GenericDialog("Bio-Formats Exporter - Multiple Files");
              multiFile.addCheckbox("Write_each_Z_section to a separate file", false);
              multiFile.addCheckbox("Write_each_timepoint to a separate file", false);
              multiFile.addCheckbox("Write_each_channel to a separate file", false);
              multiFile.addCheckbox("Use zero padding for filename indexes", false);
              multiFile.showDialog();
  
              splitZ = multiFile.getNextBoolean();
              splitT = multiFile.getNextBoolean();
              splitC = multiFile.getNextBoolean();
              padded = multiFile.getNextBoolean();
              if (multiFile.wasCanceled()) return;
          }
  
          try (IFormatWriter w = new ImageWriter().getWriter(outfile)) {
              int ptype = 0;
              int channels = 1;
              switch (imp.getType()) {
                  case ImagePlus.GRAY8:
                  case ImagePlus.COLOR_256:
                      ptype = FormatTools.UINT8;
                      break;
                  case ImagePlus.COLOR_RGB:
                      channels = 3;
                      ptype = FormatTools.UINT8;
                      break;
                  case ImagePlus.GRAY16:
                      ptype = FormatTools.UINT16;
                      break;
                  case ImagePlus.GRAY32:
                      ptype = FormatTools.FLOAT;
                      break;
              }
              String title = imp.getTitle();
  
              w.setWriteSequentially(true);
              FileInfo fi = imp.getOriginalFileInfo();
              String xml = fi == null ? null : fi.description == null ? null :
                  fi.description.indexOf("xml") == -1 ? null : fi.description;
  
              OMEXMLService service = null;
              IMetadata store = null;
  
              try {
                  ServiceFactory factory = new ServiceFactory();
                  service = factory.getInstance(OMEXMLService.class);
                  store = service.createOMEXMLMetadata(xml);
              }
              catch (DependencyException de) { }
              catch (ServiceException se) { }
  
  
  
              if (store == null) IJ.error("OME-XML Java library not found.");
  
              OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) store.getRoot();
              if (root.sizeOfROIList()>0){
                  while (root.sizeOfROIList() > 0) {
                      ROI roi = root.getROI(0);
                      root.removeROI(roi);
                  }
                  store.setRoot(root);
              }
              if (xml == null) {
                  store.createRoot();
              }
              else if (store.getImageCount() > 1) {
                  // the original dataset had multiple series
                  // we need to modify the IMetadata to represent the correct series
                  ArrayList<Integer> matchingSeries = new ArrayList<Integer>();
                  for (int series=0; series<store.getImageCount(); series++) {
                      String type = store.getPixelsType(series).toString();
                      int pixelType = FormatTools.pixelTypeFromString(type);
                      if (pixelType == ptype) {
                          String imageName = store.getImageName(series);
                          if (title.indexOf(imageName) >= 0) {
                              matchingSeries.add(series);
                          }
                      }
                  }
  
                  int series = 0;
                  if (matchingSeries.size() > 1) {
                      for (int i=0; i<matchingSeries.size(); i++) {
                          int index = matchingSeries.get(i);
                          String name = store.getImageName(index);
                          boolean valid = true;
                          for (int j=0; j<matchingSeries.size(); j++) {
                              if (i != j) {
                                  String compName = store.getImageName(matchingSeries.get(j));
                                  if (compName.indexOf(name) >= 0) {
                                      valid = false;
                                      break;
                                  }
                              }
                          }
                          if (valid) {
                              series = index;
                              break;
                          }
                      }
                  }
                  else if (matchingSeries.size() == 1) series = matchingSeries.get(0);
  
                  ome.xml.model.Image exportImage = root.getImage(series);
                  List<ome.xml.model.Image> allImages = root.copyImageList();
                  for (ome.xml.model.Image img : allImages) {
                      if (!img.equals(exportImage)) {
                          root.removeImage(img);
                      }
                  }
                  store.setRoot(root);
              }
  
              store.setPixelsSizeX(new PositiveInteger(imp.getWidth()), 0);
              store.setPixelsSizeY(new PositiveInteger(imp.getHeight()), 0);
              store.setPixelsSizeZ(new PositiveInteger(imp.getNSlices()), 0);
              store.setPixelsSizeC(new PositiveInteger(channels*imp.getNChannels()), 0);
              store.setPixelsSizeT(new PositiveInteger(imp.getNFrames()), 0);
  
              if (store.getImageID(0) == null) {
                  store.setImageID(MetadataTools.createLSID("Image", 0), 0);
              }
              if (store.getPixelsID(0) == null) {
                  store.setPixelsID(MetadataTools.createLSID("Pixels", 0), 0);
              }
  
              // reset the pixel type, unless the only change is signedness
              // this prevents problems if the user changed the bit depth of the image
              boolean applyCalibrationFunction = false;
              try {
                  int originalType = -1;
                  if (store.getPixelsType(0) != null) {
                    originalType = FormatTools.pixelTypeFromString(
                    store.getPixelsType(0).toString());
                  }
                  if (ptype != originalType &&
                    (store.getPixelsType(0) == null ||
                    !FormatTools.isSigned(originalType) ||
                    FormatTools.getBytesPerPixel(originalType) !=
                    FormatTools.getBytesPerPixel(ptype)))
                  {
                    store.setPixelsType(PixelType.fromString(
                      FormatTools.getPixelTypeString(ptype)), 0);
                  }
                  else if (FormatTools.isSigned(originalType)) {
                    applyCalibrationFunction = true;
                  }
              }
              catch (EnumerationException e) { }
  
              if (store.getPixelsBinDataCount(0) == 0 ||
                      store.getPixelsBinDataBigEndian(0, 0) == null)
              {
                  store.setPixelsBinDataBigEndian(Boolean.FALSE, 0, 0);
              }
              if (store.getPixelsDimensionOrder(0) == null) {
                  try {
                      store.setPixelsDimensionOrder(DimensionOrder.fromString(ORDER), 0);
                  }
                  catch (EnumerationException e) { }
              }
  
              LUT[] luts = new LUT[imp.getNChannels()];
  
              for (int c=0; c<imp.getNChannels(); c++) {
                  if (c >= store.getChannelCount(0) || store.getChannelID(0, c) == null) {
                      String lsid = MetadataTools.createLSID("Channel", 0, c);
                      store.setChannelID(lsid, 0, c);
                  }
                  store.setChannelSamplesPerPixel(new PositiveInteger(channels), 0, 0);
  
                  if (imp instanceof CompositeImage) {
                      luts[c] = ((CompositeImage) imp).getChannelLut(c + 1);
                  }
              }
  
              Calibration cal = imp.getCalibration();
  
              store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(cal.pixelWidth), 0);
              store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(cal.pixelHeight), 0);
              store.setPixelsPhysicalSizeZ(FormatTools.getPhysicalSizeZ(cal.pixelDepth), 0);
              store.setPixelsTimeIncrement(new Time(new Double(cal.frameInterval), UNITS.SECOND), 0);
  
              if (imp.getImageStackSize() !=
                      imp.getNChannels() * imp.getNSlices() * imp.getNFrames())
              {
                  if (!windowless) {
                      IJ.showMessageWithCancel("Bio-Formats Exporter Warning",
                              "The number of planes in the stack (" + imp.getImageStackSize() +
                              ") does not match the number of expected planes (" +
                              (imp.getNChannels() * imp.getNSlices() * imp.getNFrames()) + ")." +
                              "\nIf you select 'OK', only " + imp.getImageStackSize() +
                              " planes will be exported. If you wish to export all of the " +
                              "planes,\nselect 'Cancel' and convert the Image5D window " +
                              "to a stack.");
                  }
                  store.setPixelsSizeZ(new PositiveInteger(imp.getImageStackSize()), 0);
                  store.setPixelsSizeC(new PositiveInteger(1), 0);
  