Changeset 6294


Ignore:
Timestamp:
05/12/10 17:02:41 (10 years ago)
Author:
melissa
Message:

Added API for tiled image and multi-file export (see #413 and #486). There are several known issues (see Export), but basic export should work.

Location:
trunk/components
Files:
2 added
32 edited

Legend:

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

    r6266 r6294  
    546546    } 
    547547    throw new IllegalArgumentException("Unknown pixel type: " + pixelType); 
     548  } 
     549 
     550  /** 
     551   * Retrieves the number of bytes per pixel in the current plane. 
     552   * @param pixelType the pixel type, as a String. 
     553   * @return the number of bytes per pixel. 
     554   * @see #pixelTypeFromString(String), #getBytesPerPixel(int) 
     555   */ 
     556  public static int getBytesPerPixel(String pixelType) { 
     557    return getBytesPerPixel(pixelTypeFromString(pixelType)); 
    548558  } 
    549559 
  • trunk/components/bio-formats/src/loci/formats/FormatWriter.java

    r6266 r6294  
    2626import java.awt.image.ColorModel; 
    2727import java.io.IOException; 
    28  
     28import java.util.HashMap; 
     29 
     30import loci.common.DataTools; 
     31import loci.common.RandomAccessOutputStream; 
    2932import loci.formats.meta.DummyMetadata; 
    3033import loci.formats.meta.MetadataRetrieve; 
     
    5558  protected String compression; 
    5659 
    57   /** Whether the current file has been prepped for writing. */ 
    58   protected boolean initialized; 
     60  /** 
     61   * Whether each plane in each series of the current file has been 
     62   * prepped for writing. 
     63   */ 
     64  protected boolean[][] initialized; 
    5965 
    6066  /** Whether the channels in an RGB image are interleaved. */ 
    6167  protected boolean interleaved; 
     68 
     69  /** Current series. */ 
     70  protected int series; 
    6271 
    6372  /** 
     
    6877  protected MetadataRetrieve metadataRetrieve = new DummyMetadata(); 
    6978 
     79  /** 
     80   * Next plane index for each series.  This is only used by deprecated methods. 
     81   */ 
     82  private HashMap<Integer, Integer> planeIndices = 
     83    new HashMap<Integer, Integer>(); 
     84 
     85  /** Current file. */ 
     86  protected RandomAccessOutputStream out; 
     87 
    7088  // -- Constructors -- 
    7189 
     
    8098  // -- IFormatWriter API methods -- 
    8199 
    82   /* @see IFormatWriter#saveBytes(byte[], boolean) */ 
    83   public void saveBytes(byte[] bytes, boolean last) 
     100  /* @see IFormatWriter#changeOutputFile(String) */ 
     101  public void changeOutputFile(String id) throws FormatException, IOException { 
     102    setId(id); 
     103  } 
     104 
     105  /* @see IFormatWriter#saveBytes(int, byte[]) */ 
     106  public void saveBytes(int no, byte[] buf) throws FormatException, IOException 
     107  { 
     108    int width = metadataRetrieve.getPixelsSizeX(0).getValue(); 
     109    int height = metadataRetrieve.getPixelsSizeY(0).getValue(); 
     110    saveBytes(no, buf, 0, 0, width, height); 
     111  } 
     112 
     113  /* @see IFormatWriter#savePlane(int, Object) */ 
     114  public void savePlane(int no, Object plane) 
    84115    throws FormatException, IOException 
    85116  { 
    86     saveBytes(bytes, 0, last, last); 
    87   } 
    88  
    89   /* @see IFormatWriter#savePlane(Object, boolean) */ 
    90   public void savePlane(Object plane, boolean last) 
     117    int width = metadataRetrieve.getPixelsSizeX(0).getValue(); 
     118    int height = metadataRetrieve.getPixelsSizeY(0).getValue(); 
     119    savePlane(no, plane, 0, 0, width, height); 
     120  } 
     121 
     122  /* @see IFormatWriter#savePlane(int, Object, int, int, int, int) */ 
     123  public void savePlane(int no, Object plane, int x, int y, int w, int h) 
    91124    throws FormatException, IOException 
    92   { 
    93     savePlane(plane, 0, last, last); 
    94   } 
    95  
    96   /* @see IFormatWriter#savePlane(Object, int, boolean, boolean) */ 
    97   public void savePlane(Object plane, int series, boolean lastInSeries, 
    98     boolean last) throws FormatException, IOException 
    99125  { 
    100126    // NB: Writers use byte arrays by default as the native type. 
     
    102128      throw new IllegalArgumentException("Object to save must be a byte[]"); 
    103129    } 
    104     saveBytes((byte[]) plane, series, lastInSeries, last); 
     130    saveBytes(no, (byte[]) plane, x, y, w, h); 
     131  } 
     132 
     133  /* @see IFormatWriter#setSeries(int) */ 
     134  public void setSeries(int series) throws FormatException { 
     135    if (series < 0) throw new FormatException("Series must be > 0."); 
     136    if (series >= metadataRetrieve.getImageCount()) { 
     137      throw new FormatException("Series is '" + series + 
     138        "' but MetadataRetrieve only defines " + 
     139        metadataRetrieve.getImageCount() + " series."); 
     140    } 
     141    this.series = series; 
    105142  } 
    106143 
     
    185222  } 
    186223 
     224  // -- Deprecated IFormatWriter API methods -- 
     225 
     226  /** 
     227   * @deprecated 
     228   * @see IFormatWriter#saveBytes(byte[], boolean) 
     229   */ 
     230  public void saveBytes(byte[] bytes, boolean last) 
     231    throws FormatException, IOException 
     232  { 
     233    saveBytes(bytes, 0, last, last); 
     234  } 
     235 
     236  /** 
     237   * @deprecated 
     238   * @see IFormatWriter#saveBytes(byte[], int, boolean, boolean) 
     239   */ 
     240  public void saveBytes(byte[] bytes, int series, boolean lastInSeries, 
     241    boolean last) throws FormatException, IOException 
     242  { 
     243    setSeries(series); 
     244    Integer planeIndex = planeIndices.get(series); 
     245    if (planeIndex == null) planeIndex = 0; 
     246    saveBytes(planeIndex, bytes); 
     247    planeIndex++; 
     248    planeIndices.put(series, planeIndex); 
     249  } 
     250 
     251  /** 
     252   * @deprecated 
     253   * @see IFormatWriter#savePlane(Object, boolean) 
     254   */ 
     255  public void savePlane(Object plane, boolean last) 
     256    throws FormatException, IOException 
     257  { 
     258    savePlane(plane, 0, last, last); 
     259  } 
     260 
     261  /** 
     262   * @deprecated 
     263   * @see IFormatWriter#savePlane(Object, int, boolean, boolean) 
     264   */ 
     265  public void savePlane(Object plane, int series, boolean lastInSeries, 
     266    boolean last) throws FormatException, IOException 
     267  { 
     268    // NB: Writers use byte arrays by default as the native type. 
     269    if (!(plane instanceof byte[])) { 
     270      throw new IllegalArgumentException("Object to save must be a byte[]"); 
     271    } 
     272    saveBytes((byte[]) plane, series, lastInSeries, last); 
     273  } 
     274 
    187275  // -- IFormatHandler API methods -- 
    188276 
     
    192280    close(); 
    193281    currentId = id; 
    194     initialized = false; 
     282    out = new RandomAccessOutputStream(currentId); 
     283 
     284    MetadataRetrieve r = getMetadataRetrieve(); 
     285    initialized = new boolean[r.getImageCount()][]; 
     286    int oldSeries = series; 
     287    for (int i=0; i<r.getImageCount(); i++) { 
     288      setSeries(i); 
     289      initialized[i] = new boolean[getPlaneCount()]; 
     290    } 
     291    setSeries(oldSeries); 
     292  } 
     293 
     294  /* @see IFormatHandler#close() */ 
     295  public void close() throws IOException { 
     296    if (out != null) out.close(); 
     297    out = null; 
     298    currentId = null; 
     299    initialized = null; 
     300  } 
     301 
     302  // -- Helper methods -- 
     303 
     304  /** 
     305   * Ensure that the arguments that are being passed to saveBytes(...) are 
     306   * valid. 
     307   * @throws FormatException if any of the arguments is invalid. 
     308   */ 
     309  protected void checkParams(int no, byte[] buf, int x, int y, int w, int h) 
     310    throws FormatException 
     311  { 
     312    MetadataRetrieve r = getMetadataRetrieve(); 
     313    MetadataTools.verifyMinimumPopulated(r, series); 
     314 
     315    if (buf == null) throw new FormatException("Buffer cannot be null."); 
     316    int z = r.getPixelsSizeZ(series).getValue().intValue(); 
     317    int t = r.getPixelsSizeT(series).getValue().intValue(); 
     318    int c = r.getChannelCount(series); 
     319    int planes = z * c * t; 
     320 
     321    if (no < 0) throw new FormatException("Plane index must be >= 0"); 
     322    if (no >= planes) { 
     323      throw new FormatException("Plane index must be < " + planes); 
     324    } 
     325 
     326    int sizeX = r.getPixelsSizeX(series).getValue().intValue(); 
     327    int sizeY = r.getPixelsSizeY(series).getValue().intValue(); 
     328    if (x < 0) throw new FormatException("X coordinate must be >= 0"); 
     329    if (y < 0) throw new FormatException("Y coordinate must be >= 0"); 
     330    if (x >= sizeX) { 
     331      throw new FormatException("X coordinate must be < " + sizeX); 
     332    } 
     333    if (y >= sizeY) { 
     334      throw new FormatException("Y coordinate must be < " + sizeY); 
     335    } 
     336    if (w <= 0) throw new FormatException("Width must be > 0"); 
     337    if (h <= 0) throw new FormatException("Height must be > 0"); 
     338    if (x + w > sizeX) throw new FormatException("(w + x) must be <= " + sizeX); 
     339    if (y + h > sizeY) throw new FormatException("(h + y) must be <= " + sizeY); 
     340 
     341    int pixelType = 
     342      FormatTools.pixelTypeFromString(r.getPixelsType(series).toString()); 
     343    int bpp = FormatTools.getBytesPerPixel(pixelType); 
     344    Integer samples = r.getChannelSamplesPerPixel(series, 0); 
     345    if (samples == null) samples = 1; 
     346    int minSize = bpp * w * h * samples; 
     347    if (buf.length < minSize) { 
     348      throw new FormatException("Buffer is too small; expected " + minSize + 
     349        " bytes, got " + buf.length + " bytes."); 
     350    } 
     351 
     352    if (!DataTools.containsValue(getPixelTypes(), pixelType)) { 
     353      throw new FormatException("Unsupported image type '" + 
     354        FormatTools.getPixelTypeString(pixelType) + "'."); 
     355    } 
     356  } 
     357 
     358  /** 
     359   * Seek to the given (x, y) coordinate of the image that starts at 
     360   * the given offset. 
     361   */ 
     362  protected void seekToPlaneOffset(long baseOffset, int x, int y) 
     363    throws IOException 
     364  { 
     365    out.seek(baseOffset); 
     366 
     367    MetadataRetrieve r = getMetadataRetrieve(); 
     368    int samples = getSamplesPerPixel(); 
     369    int pixelType = 
     370      FormatTools.pixelTypeFromString(r.getPixelsType(series).toString()); 
     371    int bpp = FormatTools.getBytesPerPixel(pixelType); 
     372 
     373    if (interleaved) bpp *= samples; 
     374 
     375    int sizeX = r.getPixelsSizeX(series).getValue().intValue(); 
     376 
     377    out.skipBytes(bpp * (y * sizeX + x)); 
     378  } 
     379 
     380  /** 
     381   * Returns true if the given rectangle coordinates correspond to a full 
     382   * image in the given series. 
     383   */ 
     384  protected boolean isFullPlane(int x, int y, int w, int h) { 
     385    MetadataRetrieve r = getMetadataRetrieve(); 
     386    int sizeX = r.getPixelsSizeX(series).getValue().intValue(); 
     387    int sizeY = r.getPixelsSizeY(series).getValue().intValue(); 
     388    return x == 0 && y == 0 && w == sizeX && h == sizeY; 
     389  } 
     390 
     391  /** Retrieve the number of samples per pixel for the current series. */ 
     392  protected int getSamplesPerPixel() { 
     393    MetadataRetrieve r = getMetadataRetrieve(); 
     394    Integer samples = r.getChannelSamplesPerPixel(series, 0); 
     395    if (samples == null) { 
     396      LOGGER.warn("SamplesPerPixel #0 is null. It is assumed to be 1."); 
     397    } 
     398    return samples == null ? 1 : samples.intValue(); 
     399  } 
     400 
     401  /** Retrieve the total number of planes in the current series. */ 
     402  protected int getPlaneCount() { 
     403    MetadataRetrieve r = getMetadataRetrieve(); 
     404    int z = r.getPixelsSizeZ(series).getValue().intValue(); 
     405    int t = r.getPixelsSizeT(series).getValue().intValue(); 
     406    int c = r.getChannelCount(series); 
     407    return z * c * t; 
    195408  } 
    196409 
  • trunk/components/bio-formats/src/loci/formats/IFormatWriter.java

    r5590 r6294  
    3939 
    4040  /** 
    41    * Saves the given byte array to the current file. 
    42    * Note that this method will append the byte array to the file; it will not 
    43    * overwrite previously saved byte arrays. 
    44    * If this is the last array to be written, the last flag must be set. 
     41   * Saves the given image to the current series in the current file. 
     42   * 
     43   * @param no the image index, starting from 0. 
     44   * @param buf the byte array that represents the image. 
     45   * @throws FormatException if one of the parameters is invalid. 
     46   * @throws IOException if there was a problem writing to the file. 
    4547   */ 
    46   void saveBytes(byte[] bytes, boolean last) 
     48  void saveBytes(int no, byte[] buf) throws FormatException, IOException; 
     49 
     50  /** 
     51   * Saves the given image tile to the current series in the current file. 
     52   * 
     53   * @param no the image index, starting from 0. 
     54   * @param buf the byte array that represents the image tile. 
     55   * @param x the X coordinate of the upper-left corner of the image tile. 
     56   * @param y the Y coordinate of the upper-left corner of the image tile. 
     57   * @param w the width (in pixels) of the image tile. 
     58   * @param h the height (in pixels) of the image tile. 
     59   * @throws FormatException if one of the parameters is invalid. 
     60   * @throws IOException if there was a problem writing to the file. 
     61   */ 
     62  void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
    4763    throws FormatException, IOException; 
    4864 
    4965  /** 
    50    * Saves the given byte array to the given series in the current file. 
    51    * Note that this method will append the byte array to the file; it will not 
    52    * overwrite previously saved byte arrays. 
    53    * If this is the last array in the series, the lastInSeries flag must be set. 
    54    * If this is the last array to be written, the last flag must be set. 
     66   * Saves the given image plane to the current series in the current file. 
     67   * 
     68   * @param no the image index, starting from 0. 
     69   * @param plane the image plane. 
     70   * @throws FormatException if one of the parameters is invalid. 
     71   * @throws IOException if there was a problem writing to the file. 
    5572   */ 
    56   void saveBytes(byte[] bytes, int series, boolean lastInSeries, boolean last) 
     73  void savePlane(int no, Object plane) throws FormatException, IOException; 
     74 
     75  /** 
     76   * Saves the given image plane to the current series in the current file. 
     77   * 
     78   * @param no the image index, starting from 0. 
     79   * @param plane the image plane. 
     80   * @param x the X coordinate of the upper-left corner of the image tile. 
     81   * @param y the Y coordinate of the upper-left corner of the image tile. 
     82   * @param w the width (in pixels) of the image tile. 
     83   * @param h the height (in pixels) of the image tile. 
     84   * @throws FormatException if one of the parameters is invalid. 
     85   * @throws IOException if there was a problem writing to the file. 
     86   */ 
     87  void savePlane(int no, Object plane, int x, int y, int w, int h) 
    5788    throws FormatException, IOException; 
    5889 
    5990  /** 
    60    * Saves the given image plane to the current file. 
    61    * Note that this method will append the image plane to the file; it will not 
    62    * overwrite previously saved image planes. 
    63    * If this image plane is the last one in the file, the last flag must be set. 
     91   * Sets the current series. 
     92   * 
     93   * @param series the series index, starting from 0. 
     94   * @throws FormatException if the specified series is invalid. 
    6495   */ 
    65   void savePlane(Object plane, boolean last) 
    66     throws FormatException, IOException; 
    67  
    68   /** 
    69    * Saves the given image plane to the given series in the current file. 
    70    * Note that this method will append the image plane to the file; it will not 
    71    * overwrite previously saved image planes. 
    72    * If this image plane is the last one in the series, the lastInSeries flag 
    73    * must be set. 
    74    * If this image plane is the last one in the file, the last flag must be set. 
    75    */ 
    76   void savePlane(Object plane, int series, boolean lastInSeries, boolean last) 
    77     throws FormatException, IOException; 
     96  void setSeries(int series) throws FormatException; 
    7897 
    7998  /** Sets whether or not the channels in an image are interleaved. */ 
     
    130149  String getCompression(); 
    131150 
     151  /** Switch the output file for the current dataset. */ 
     152  void changeOutputFile(String id) throws FormatException, IOException; 
     153 
     154  // -- Deprecated methods -- 
     155 
     156  /** @deprecated Please use saveBytes(int, byte[]) instead. */ 
     157  void saveBytes(byte[] bytes, boolean last) 
     158    throws FormatException, IOException; 
     159 
     160  /** 
     161   * @deprecated Please use saveBytes(int, byte[]) and setSeries(int) instead. 
     162   */ 
     163  void saveBytes(byte[] bytes, int series, boolean lastInSeries, boolean last) 
     164    throws FormatException, IOException; 
     165 
     166  /** @deprecated Please use savePlane(int, Object) instead. */ 
     167  void savePlane(Object plane, boolean last) 
     168    throws FormatException, IOException; 
     169 
     170  /** 
     171   * @deprecated Please use savePlane(int, Object) and setSeries(int) instead. 
     172   */ 
     173  void savePlane(Object plane, int series, boolean lastInSeries, boolean last) 
     174    throws FormatException, IOException; 
     175 
    132176} 
  • trunk/components/bio-formats/src/loci/formats/ImageWriter.java

    r6155 r6294  
    180180  // -- IFormatWriter API methods -- 
    181181 
    182   /* @see IFormatWriter#saveBytes(byte[], boolean) */ 
    183   public void saveBytes(byte[] bytes, boolean last) 
     182  /* @see IFormatWriter#changeOutputFile(String) */ 
     183  public void changeOutputFile(String id) throws FormatException, IOException { 
     184    getWriter().changeOutputFile(id); 
     185  } 
     186 
     187  /* @see IFormatWriter#saveBytes(int, byte[]) */ 
     188  public void saveBytes(int no, byte[] buf) throws FormatException, IOException 
     189  { 
     190    getWriter().saveBytes(no, buf); 
     191  } 
     192 
     193  /* @see IFormatWriter#saveBytes(int, byte[], int, int, int, int) */ 
     194  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
    184195    throws FormatException, IOException 
    185196  { 
    186     getWriter().saveBytes(bytes, last); 
    187   } 
    188  
    189   /* @see IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    190   public void saveBytes(byte[] bytes, int series, boolean lastInSeries, 
    191     boolean last) throws FormatException, IOException 
    192   { 
    193     getWriter().saveBytes(bytes, series, lastInSeries, last); 
    194   } 
    195  
    196   /* @see IFormatWriter#savePlane(Object, boolean) */ 
    197   public void savePlane(Object plane, boolean last) 
     197    getWriter().saveBytes(no, buf, x, y, w, h); 
     198  } 
     199 
     200  /* @see IFormatWriter#savePlane(int, Object) */ 
     201  public void savePlane(int no, Object plane) 
    198202    throws FormatException, IOException 
    199203  { 
    200     getWriter().savePlane(plane, last); 
    201   } 
    202  
    203   /* @see IFormatWriter#savePlane(Object, int, boolean, boolean) */ 
    204   public void savePlane(Object plane, int series, boolean lastInSeries, 
    205     boolean last) throws FormatException, IOException 
    206   { 
    207     getWriter().savePlane(plane, series, lastInSeries, last); 
     204    getWriter().savePlane(no, plane); 
     205  } 
     206 
     207  /* @see IFormatWriter#savePlane(int, Object, int, int, int, int) */ 
     208  public void savePlane(int no, Object plane, int x, int y, int w, int h) 
     209    throws FormatException, IOException 
     210  { 
     211    getWriter().savePlane(no, plane, x, y, w, h); 
     212  } 
     213 
     214  /* @see IFormatWriter#setSeries(int) */ 
     215  public void setSeries(int series) throws FormatException { 
     216    getWriter().setSeries(series); 
    208217  } 
    209218 
     
    310319  } 
    311320 
     321  // -- Deprecated IFormatWriter API methods -- 
     322 
     323  /** 
     324   * @deprecated 
     325   * @see IFormatWriter#saveBytes(byte[], boolean) 
     326   */ 
     327  public void saveBytes(byte[] bytes, boolean last) 
     328    throws FormatException, IOException 
     329  { 
     330    getWriter().saveBytes(bytes, last); 
     331  } 
     332 
     333  /** 
     334   * @deprecated 
     335   * @see IFormatWriter#saveBytes(byte[], int, boolean, boolean) 
     336   */ 
     337  public void saveBytes(byte[] bytes, int series, boolean lastInSeries, 
     338    boolean last) throws FormatException, IOException 
     339  { 
     340    getWriter().saveBytes(bytes, series, lastInSeries, last); 
     341  } 
     342 
     343  /** 
     344   * @deprecated 
     345   * @see IFormatWriter#savePlane(Object, boolean) 
     346   */ 
     347  public void savePlane(Object plane, boolean last) 
     348    throws FormatException, IOException 
     349  { 
     350    getWriter().savePlane(plane, last); 
     351  } 
     352 
     353  /** 
     354   * @deprecated 
     355   * @see IFormatWriter#savePlane(Object, int, boolean, boolean) 
     356   */ 
     357  public void savePlane(Object plane, int series, boolean lastInSeries, 
     358    boolean last) throws FormatException, IOException 
     359  { 
     360    getWriter().savePlane(plane, series, lastInSeries, last); 
     361  } 
     362 
    312363  // -- IFormatHandler API methods -- 
    313364 
  • trunk/components/bio-formats/src/loci/formats/WriterWrapper.java

    r6141 r6294  
    140140  // -- IFormatWriter API methods -- 
    141141 
     142  public void changeOutputFile(String id) throws FormatException, IOException { 
     143    writer.changeOutputFile(id); 
     144  } 
     145 
     146  public void saveBytes(int no, byte[] buf) throws FormatException, IOException 
     147  { 
     148    writer.saveBytes(no, buf); 
     149  } 
     150 
     151  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     152    throws FormatException, IOException 
     153  { 
     154    writer.saveBytes(no, buf, x, y, w, h); 
     155  } 
     156 
     157  public void savePlane(int no, Object plane) 
     158    throws FormatException, IOException 
     159  { 
     160    writer.savePlane(no, plane); 
     161  } 
     162 
     163  public void savePlane(int no, Object plane, int x, int y, int w, int h) 
     164    throws FormatException, IOException 
     165  { 
     166    writer.savePlane(no, plane, x, y, w, h); 
     167  } 
     168 
     169  public void setSeries(int series) throws FormatException { 
     170    writer.setSeries(series); 
     171  } 
     172 
     173  public void setInterleaved(boolean interleaved) { 
     174    writer.setInterleaved(interleaved); 
     175  } 
     176 
     177  public boolean isInterleaved() { 
     178    return writer.isInterleaved(); 
     179  } 
     180 
     181  public boolean canDoStacks() { 
     182    return writer.canDoStacks(); 
     183  } 
     184 
     185  public void setMetadataRetrieve(MetadataRetrieve r) { 
     186    writer.setMetadataRetrieve(r); 
     187  } 
     188 
     189  public MetadataRetrieve getMetadataRetrieve() { 
     190    return writer.getMetadataRetrieve(); 
     191  } 
     192 
     193  public void setColorModel(ColorModel cm) { 
     194    writer.setColorModel(cm); 
     195  } 
     196 
     197  public ColorModel getColorModel() { 
     198    return writer.getColorModel(); 
     199  } 
     200 
     201  public void setFramesPerSecond(int rate) { 
     202    writer.setFramesPerSecond(rate); 
     203  } 
     204 
     205  public int getFramesPerSecond() { 
     206    return writer.getFramesPerSecond(); 
     207  } 
     208 
     209  public String[] getCompressionTypes() { 
     210    return writer.getCompressionTypes(); 
     211  } 
     212 
     213  public int[] getPixelTypes() { 
     214    return writer.getPixelTypes(); 
     215  } 
     216 
     217  public int[] getPixelTypes(String codec) { 
     218    return writer.getPixelTypes(codec); 
     219  } 
     220 
     221  public boolean isSupportedType(int type) { 
     222    return writer.isSupportedType(type); 
     223  } 
     224 
     225  public void setCompression(String compress) throws FormatException { 
     226    writer.setCompression(compress); 
     227  } 
     228 
     229  public String getCompression() { 
     230    return writer.getCompression(); 
     231  } 
     232 
     233  // -- Deprecated IFormatWriter methods -- 
     234 
     235  /** @deprecated */ 
    142236  public void saveBytes(byte[] bytes, boolean last) 
    143237    throws FormatException, IOException 
     
    146240  } 
    147241 
     242  /** @deprecated */ 
    148243  public void saveBytes(byte[] bytes, int series, 
    149244    boolean lastInSeries, boolean last) throws FormatException, IOException 
     
    152247  } 
    153248 
     249  /** @deprecated */ 
    154250  public void savePlane(Object plane, boolean last) 
    155251    throws FormatException, IOException 
     
    158254  } 
    159255 
     256  /** @deprecated */ 
    160257  public void savePlane(Object plane, int series, 
    161258    boolean lastInSeries, boolean last) throws FormatException, IOException 
    162259  { 
    163260    writer.savePlane(plane, series, lastInSeries, last); 
    164   } 
    165  
    166   public void setInterleaved(boolean interleaved) { 
    167     writer.setInterleaved(interleaved); 
    168   } 
    169  
    170   public boolean isInterleaved() { 
    171     return writer.isInterleaved(); 
    172   } 
    173  
    174   public boolean canDoStacks() { 
    175     return writer.canDoStacks(); 
    176   } 
    177  
    178   public void setMetadataRetrieve(MetadataRetrieve r) { 
    179     writer.setMetadataRetrieve(r); 
    180   } 
    181  
    182   public MetadataRetrieve getMetadataRetrieve() { 
    183     return writer.getMetadataRetrieve(); 
    184   } 
    185  
    186   public void setColorModel(ColorModel cm) { 
    187     writer.setColorModel(cm); 
    188   } 
    189  
    190   public ColorModel getColorModel() { 
    191     return writer.getColorModel(); 
    192   } 
    193  
    194   public void setFramesPerSecond(int rate) { 
    195     writer.setFramesPerSecond(rate); 
    196   } 
    197  
    198   public int getFramesPerSecond() { 
    199     return writer.getFramesPerSecond(); 
    200   } 
    201  
    202   public String[] getCompressionTypes() { 
    203     return writer.getCompressionTypes(); 
    204   } 
    205  
    206   public int[] getPixelTypes() { 
    207     return writer.getPixelTypes(); 
    208   } 
    209  
    210   public int[] getPixelTypes(String codec) { 
    211     return writer.getPixelTypes(codec); 
    212   } 
    213  
    214   public boolean isSupportedType(int type) { 
    215     return writer.isSupportedType(type); 
    216   } 
    217  
    218   public void setCompression(String compress) throws FormatException { 
    219     writer.setCompression(compress); 
    220   } 
    221  
    222   public String getCompression() { 
    223     return writer.getCompression(); 
    224261  } 
    225262 
  • trunk/components/bio-formats/src/loci/formats/gui/BufferedImageWriter.java

    r6230 r6294  
    6363 
    6464  /** 
     65   * @deprecated 
    6566   * Saves the given BufferedImage to the current file. 
    6667   * Note that this method will append the image plane to the file; it will not 
     
    7576 
    7677  /** 
     78   * @deprecated 
    7779   * Saves the given BufferedImage to the given series in the current file. 
    7880   * Note that this method will append the image plane to the file; it will not 
  • trunk/components/bio-formats/src/loci/formats/in/EPSReader.java

    r6230 r6294  
    234234      else if (line.startsWith("%%")) { 
    235235        if (line.startsWith("%%BoundingBox:")) { 
    236           line = line.substring(14); 
     236          line = line.substring(14).trim(); 
    237237          String[] t = line.split(" "); 
    238238          int originX = Integer.parseInt(t[0].trim()); 
  • trunk/components/bio-formats/src/loci/formats/out/APNGWriter.java

    r6230 r6294  
    5555  // -- Fields -- 
    5656 
    57   private RandomAccessOutputStream out; 
    5857  private int numFrames = 0; 
    5958  private long numFramesPointer = 0; 
     
    6968  // -- IFormatWriter API methods -- 
    7069 
    71   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    72   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    73     boolean last) throws FormatException, IOException 
     70  /** 
     71   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     72   */ 
     73  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     74    throws FormatException, IOException 
    7475  { 
    75     if (buf == null) { 
    76       throw new FormatException("Byte array is null"); 
    77     } 
     76    checkParams(no, buf, x, y, w, h); 
    7877    MetadataRetrieve meta = getMetadataRetrieve(); 
    79     MetadataTools.verifyMinimumPopulated(meta, series); 
    80     int pixelType = 
    81       FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString()); 
    82     int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType); 
    83     boolean signed = FormatTools.isSigned(pixelType); 
    84     littleEndian = !meta.getPixelsBinDataBigEndian(0, 0); 
    85  
    86     boolean indexed = getColorModel() instanceof IndexColorModel; 
    87     Integer channels = meta.getChannelSamplesPerPixel(series, 0); 
    88     if (channels == null) { 
    89       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    90     } 
    91     int nChannels = channels == null ? 1 : channels.intValue(); 
     78 
    9279    int width = meta.getPixelsSizeX(series).getValue().intValue(); 
    9380    int height = meta.getPixelsSizeY(series).getValue().intValue(); 
    9481 
    95     if (!initialized) { 
    96       out = new RandomAccessOutputStream(currentId); 
     82    if (!initialized[series][no]) { 
     83      writeFCTL(width, height); 
     84      if (no == 0) writePLTE(); 
     85      initialized[series][no] = true; 
     86    } 
     87 
     88    writePixels(no == 0 ? "IDAT" : "fdAT", buf, x, y, w, h); 
     89 
     90    numFrames++; 
     91  } 
     92 
     93  /* @see loci.formats.IFormatWriter#canDoStacks() */ 
     94  public boolean canDoStacks() { return true; } 
     95 
     96  /* @see loci.formats.IFormatWriter#getPixelTypes() */ 
     97  public int[] getPixelTypes() { 
     98    return new int[] {FormatTools.INT8, FormatTools.UINT8, FormatTools.INT16, 
     99      FormatTools.UINT16}; 
     100  } 
     101 
     102  // -- IFormatHandler API methods -- 
     103 
     104  /* @see loci.formats.IFormatHandler#setId(String) */ 
     105  public void setId(String id) throws FormatException, IOException { 
     106    super.setId(id); 
     107 
     108    if (out.length() == 0) { 
     109      MetadataRetrieve r = getMetadataRetrieve(); 
     110      int width = r.getPixelsSizeX(series).getValue().intValue(); 
     111      int height = r.getPixelsSizeY(series).getValue().intValue(); 
     112      int bytesPerPixel = 
     113        FormatTools.getBytesPerPixel(r.getPixelsType(series).toString()); 
     114      int nChannels = getSamplesPerPixel(); 
     115      boolean indexed = 
     116        getColorModel() != null && (getColorModel() instanceof IndexColorModel); 
    97117 
    98118      // write 8-byte PNG signature 
     
    132152      out.writeInt(0); 
    133153      out.writeInt(0); // save a place for the CRC 
    134  
    135       // write fcTL chunk 
    136       writeFCTL(width, height); 
    137  
    138       // write PLTE chunk, if needed 
    139       writePLTE(); 
    140  
    141       // write IDAT chunk 
    142       writePixels("IDAT", buf, width, height, nChannels, signed); 
    143       initialized = true; 
    144     } 
    145     else { 
    146       // write fcTL chunk 
    147       writeFCTL(width, height); 
    148  
    149       // write fdAT chunk 
    150       writePixels("fdAT", buf, width, height, nChannels, signed); 
    151     } 
    152  
    153     numFrames++; 
    154  
    155     if (last) { 
    156       // write IEND chunk 
    157       out.writeInt(0); 
    158       out.writeBytes("IEND"); 
    159       out.writeInt(crc("IEND".getBytes())); 
    160  
    161       // update frame count 
    162       out.seek(numFramesPointer); 
    163       out.writeInt(numFrames); 
    164       out.skipBytes(4); 
    165       byte[] b = new byte[12]; 
    166       b[0] = 'a'; 
    167       b[1] = 'c'; 
    168       b[2] = 'T'; 
    169       b[3] = 'L'; 
    170       DataTools.unpackBytes(numFrames, b, 4, 4, false); 
    171       DataTools.unpackBytes(0, b, 8, 4, false); 
    172       out.writeInt(crc(b)); 
    173     } 
    174   } 
    175  
    176   /* @see loci.formats.IFormatWriter#canDoStacks() */ 
    177   public boolean canDoStacks() { return true; } 
    178  
    179   /* @see loci.formats.IFormatWriter#getPixelTypes() */ 
    180   public int[] getPixelTypes() { 
    181     return new int[] {FormatTools.INT8, FormatTools.UINT8, FormatTools.INT16, 
    182       FormatTools.UINT16}; 
    183   } 
    184  
    185   // -- IFormatHandler API methods -- 
     154    } 
     155  } 
    186156 
    187157  /* @see loci.formats.IFormatHandler#close() */ 
    188158  public void close() throws IOException { 
    189     if (out != null) out.close(); 
    190     out = null; 
    191     currentId = null; 
    192     initialized = false; 
     159    if (out != null) { 
     160      writeFooter(); 
     161    } 
     162    super.close(); 
    193163    numFrames = 0; 
    194164  } 
     
    254224  } 
    255225 
    256   private void writePixels(String chunk, byte[] stream, int width, int height, 
    257     int sizeC, boolean signed) throws IOException 
     226  private void writePixels(String chunk, byte[] stream, int x, int y, 
     227    int width, int height) throws FormatException, IOException 
    258228  { 
     229    MetadataRetrieve r = getMetadataRetrieve(); 
     230    int sizeC = getSamplesPerPixel(); 
     231    String type = r.getPixelsType(series).toString(); 
     232    int pixelType = FormatTools.pixelTypeFromString(type); 
     233    boolean signed = FormatTools.isSigned(pixelType); 
     234 
     235    if (!isFullPlane(x, y, width, height)) { 
     236      throw new FormatException("APNGWriter does not support writing tiles."); 
     237    } 
     238 
    259239    ByteArrayOutputStream s = new ByteArrayOutputStream(); 
    260240    s.write(chunk.getBytes()); 
     
    301281  } 
    302282 
     283  private void writeFooter() throws IOException { 
     284    // write IEND chunk 
     285    out.writeInt(0); 
     286    out.writeBytes("IEND"); 
     287    out.writeInt(crc("IEND".getBytes())); 
     288 
     289    // update frame count 
     290    out.seek(numFramesPointer); 
     291    out.writeInt(numFrames); 
     292    out.skipBytes(4); 
     293    byte[] b = new byte[12]; 
     294    b[0] = 'a'; 
     295    b[1] = 'c'; 
     296    b[2] = 'T'; 
     297    b[3] = 'L'; 
     298    DataTools.unpackBytes(numFrames, b, 4, 4, false); 
     299    DataTools.unpackBytes(0, b, 8, 4, false); 
     300    out.writeInt(crc(b)); 
     301  } 
     302 
    303303} 
  • trunk/components/bio-formats/src/loci/formats/out/AVIWriter.java

    r6230 r6294  
    8080  // -- Fields -- 
    8181 
    82   private RandomAccessOutputStream out; 
    83  
    8482  private int planesWritten = 0; 
    8583 
     
    10098  // -- IFormatWriter API methods -- 
    10199 
    102   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    103   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    104     boolean last) throws FormatException, IOException 
     100  /** 
     101   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     102   */ 
     103  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     104    throws FormatException, IOException 
    105105  { 
    106     if (buf == null) { 
    107       throw new FormatException("Byte array is null"); 
    108     } 
     106    checkParams(no, buf, x, y, w, h); 
    109107    MetadataRetrieve meta = getMetadataRetrieve(); 
    110     MetadataTools.verifyMinimumPopulated(meta, series); 
    111108    int type = 
    112109      FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString()); 
    113     if (!DataTools.containsValue(getPixelTypes(), type)) { 
    114       throw new FormatException("Unsupported image type '" + 
    115         FormatTools.getPixelTypeString(type) + "'."); 
    116     } 
    117  
    118     Integer channels = meta.getChannelSamplesPerPixel(series, 0); 
    119     if (channels == null) { 
    120       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    121     } 
    122     int nChannels = channels == null ? 1 : channels.intValue(); 
     110 
     111    int nChannels = getSamplesPerPixel(); 
    123112 
    124113    byte[][] lut = null; 
     
    133122    } 
    134123 
    135     if (!initialized) { 
    136       initialized = true; 
     124    if (!initialized[series][no]) { 
     125      initialized[series][no] = true; 
    137126      bytesPerPixel = nChannels == 2 ? 3 : nChannels; 
    138127      savedbLength = new Vector<Long>(); 
    139  
    140       out = new RandomAccessOutputStream(currentId); 
    141128 
    142129      if (out.length() > 0) { 
     
    529516    out.seek(FRAME_OFFSET_2); 
    530517    out.writeInt(planesWritten); 
    531  
    532     if (last) { 
    533       out.close(); 
    534     } 
    535518  } 
    536519 
     
    543526  } 
    544527 
    545   // -- IFormatHandler API methods -- 
    546  
    547   /* @see loci.formats.IFormatHandler#close() */ 
    548   public void close() throws IOException { 
    549     if (out != null) out.close(); 
    550     out = null; 
    551     currentId = null; 
    552     initialized = false; 
    553   } 
    554  
    555528} 
  • trunk/components/bio-formats/src/loci/formats/out/EPSWriter.java

    r6230 r6294  
    4545public class EPSWriter extends FormatWriter { 
    4646 
    47   /** Current file. */ 
    48   protected RandomAccessOutputStream out; 
     47  // -- Constants -- 
     48 
     49  private static final String DUMMY_PIXEL = "00"; 
     50 
     51  // -- Fields -- 
     52 
     53  private long planeOffset = 0; 
    4954 
    5055  // -- Constructor -- 
     
    5661  // -- IFormatWriter API methods -- 
    5762 
    58   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    59   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    60     boolean last) throws FormatException, IOException 
     63  /** 
     64   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     65   */ 
     66  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     67    throws FormatException, IOException 
    6168  { 
    62     if (buf == null) { 
    63       throw new FormatException("Byte array is null"); 
     69    checkParams(no, buf, x, y, w, h); 
     70 
     71    MetadataRetrieve meta = getMetadataRetrieve(); 
     72    int sizeX = meta.getPixelsSizeX(series).getValue().intValue(); 
     73    int nChannels = getSamplesPerPixel(); 
     74 
     75    // write pixel data 
     76    // for simplicity, write 80 char lines 
     77 
     78    if (!initialized[series][no]) { 
     79      initialized[series][no] = true; 
     80 
     81      writeHeader(); 
     82 
     83      if (!isFullPlane(x, y, w, h)) { 
     84        // write a dummy plane that will be overwritten in sections 
     85        int planeSize = w * h * nChannels; 
     86        for (int i=0; i<planeSize; i++) { 
     87          out.writeBytes(DUMMY_PIXEL); 
     88        } 
     89      } 
    6490    } 
    6591 
    66     out = new RandomAccessOutputStream(currentId); 
     92    int planeSize = w * h; 
    6793 
    68     MetadataRetrieve meta = getMetadataRetrieve(); 
    69     MetadataTools.verifyMinimumPopulated(meta, series); 
    70     int width = meta.getPixelsSizeX(series).getValue().intValue(); 
    71     int height = meta.getPixelsSizeY(series).getValue().intValue(); 
    72     int type = 
    73       FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString()); 
    74     Integer channels = meta.getChannelSamplesPerPixel(series, 0); 
    75     if (channels == null) { 
    76       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    77     } 
    78     int nChannels = channels == null ? 1 : channels.intValue(); 
     94    StringBuffer buffer = new StringBuffer(); 
    7995 
    80     if (!DataTools.containsValue(getPixelTypes(), type)) { 
    81       throw new FormatException("Unsupported image type '" + 
    82         FormatTools.getPixelTypeString(type) + "'."); 
     96    int offset = y * sizeX * nChannels * 2; 
     97    out.seek(planeOffset + offset); 
     98    for (int row=0; row<h; row++) { 
     99      out.skipBytes(nChannels * x * 2); 
     100      for (int col=0; col<w*nChannels; col++) { 
     101        int i = row * w * nChannels + col; 
     102        int index = interleaved || nChannels == 1 ? i : 
     103          (i % nChannels) * planeSize + (i / nChannels); 
     104        String s = Integer.toHexString(buf[index]); 
     105        // only want last 2 characters of s 
     106        if (s.length() > 1) buffer.append(s.substring(s.length() - 2)); 
     107        else { 
     108          buffer.append("0"); 
     109          buffer.append(s); 
     110        } 
     111      } 
     112      out.writeBytes(buffer.toString()); 
     113      buffer.delete(0, buffer.length()); 
     114      out.skipBytes(nChannels * (sizeX - w - x) * 2); 
    83115    } 
    84116 
    85     // write the header 
     117    // write footer 
     118 
     119    out.seek(out.length()); 
     120    out.writeBytes("\nshowpage\n"); 
     121  } 
     122 
     123  /* @see loci.formats.IFormatWriter#getPixelTypes() */ 
     124  public int[] getPixelTypes() { 
     125    return new int[] {FormatTools.UINT8}; 
     126  } 
     127 
     128  // -- Helper methods -- 
     129 
     130  private void writeHeader() throws IOException { 
     131    MetadataRetrieve r = getMetadataRetrieve(); 
     132    int width = r.getPixelsSizeX(series).getValue().intValue(); 
     133    int height = r.getPixelsSizeY(series).getValue().intValue(); 
     134    int nChannels = getSamplesPerPixel(); 
    86135 
    87136    out.writeBytes("%!PS-Adobe-2.0 EPSF-1.2\n"); 
     
    99148    out.writeBytes(((float) width) + " " + ((float) height) + " scale\n"); 
    100149    out.writeBytes("/picstr 40 string def\n"); 
     150    out.writeBytes(width + " " + height + " 8 [" + width + " 0 0 " + 
     151      (-1 * height) + " 0 " + height + 
     152      "] {currentfile picstr readhexstring pop} "); 
    101153    if (nChannels == 1) { 
    102       out.writeBytes(width + " " + height + " 8 [" + width + " 0 0 " + 
    103         (-1*height) + " 0 " + height + "] {currentfile picstr " + 
    104         "readhexstring pop} image\n"); 
     154      out.writeBytes("image\n"); 
    105155    } 
    106156    else { 
    107       out.writeBytes(width + " " + height + " 8 [" + width + " 0 0 " + 
    108         (-1*height) + " 0 " + height + "] {currentfile picstr " + 
    109         "readhexstring pop} false 3 colorimage\n"); 
     157      out.writeBytes("false 3 colorimage\n"); 
    110158    } 
    111  
    112     // write pixel data 
    113     // for simplicity, write 80 char lines 
    114  
    115     int planeSize = width * height; 
    116     int charCount = 0; 
    117     for (int i=0; i<buf.length; i++) { 
    118       int index = interleaved || nChannels == 1 ? i : 
    119         (i % nChannels) * planeSize + (i / nChannels); 
    120       String s = Integer.toHexString(buf[index]); 
    121       // only want last 2 characters of s 
    122       if (s.length() > 1) s = s.substring(s.length() - 2); 
    123       else s = "0" + s; 
    124       out.writeBytes(s); 
    125       charCount++; 
    126       if (charCount == 40) { 
    127         out.writeBytes("\n"); 
    128         charCount = 0; 
    129       } 
    130     } 
    131  
    132     // write footer 
    133  
    134     out.writeBytes("showpage\n"); 
    135     out.close(); 
    136   } 
    137  
    138   /* @see loci.formats.IFormatWriter#getPixelTypes() */ 
    139   public int[] getPixelTypes() { 
    140     return new int[] {FormatTools.UINT8}; 
    141   } 
    142  
    143   // -- IFormatHandler API methods -- 
    144  
    145   /* @see loci.formats.IFormatHandler#close() */ 
    146   public void close() throws IOException { 
    147     if (out != null) out.close(); 
    148     out = null; 
    149     currentId = null; 
    150     initialized = false; 
     159    planeOffset = out.getFilePointer(); 
    151160  } 
    152161 
  • trunk/components/bio-formats/src/loci/formats/out/ICSWriter.java

    r6230 r6294  
    2525package loci.formats.out; 
    2626 
     27import java.io.ByteArrayOutputStream; 
    2728import java.io.IOException; 
    2829import java.util.StringTokenizer; 
    2930 
     31import loci.common.RandomAccessInputStream; 
    3032import loci.common.RandomAccessOutputStream; 
    3133import loci.formats.FormatException; 
     
    4749  // -- Fields -- 
    4850 
    49   private RandomAccessOutputStream out; 
     51  private long pixelOffset; 
    5052 
    5153  // -- Constructor -- 
     
    5557  // -- IFormatWriter API methods -- 
    5658 
    57   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    58   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    59     boolean last) throws FormatException, IOException 
     59  /** 
     60   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     61   */ 
     62  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     63    throws FormatException, IOException 
    6064  { 
    61     if (buf == null) { 
    62       throw new FormatException("Byte array is null"); 
    63     } 
     65    checkParams(no, buf, x, y, w, h); 
    6466 
    6567    MetadataRetrieve meta = getMetadataRetrieve(); 
    66     MetadataTools.verifyMinimumPopulated(meta, series); 
    67  
     68    int sizeX = meta.getPixelsSizeX(series).getValue().intValue(); 
     69    int sizeY = meta.getPixelsSizeY(series).getValue().intValue(); 
    6870    int pixelType = 
    6971      FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString()); 
    7072    int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType); 
    71     Integer channels = meta.getChannelSamplesPerPixel(series, 0); 
    72     if (channels == null) { 
    73       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    74     } 
    75     int rgbChannels = channels == null ? 1 : channels.intValue(); 
    76  
    77     if (!initialized) { 
    78       initialized = true; 
    79       out = new RandomAccessOutputStream(currentId); 
     73    int rgbChannels = getSamplesPerPixel(); 
     74    int planeSize = sizeX * sizeY * rgbChannels * bytesPerPixel; 
     75 
     76    if (!initialized[series][no]) { 
     77      initialized[series][no] = true; 
     78 
     79      if (!isFullPlane(x, y, w, h)) { 
     80        // write a dummy plane that will be overwritten in sections 
     81        out.seek(pixelOffset + (no + 1) * planeSize); 
     82      } 
     83    } 
     84 
     85    out.seek(pixelOffset + no * planeSize); 
     86    if (isFullPlane(x, y, w, h) && (interleaved || rgbChannels == 1)) { 
     87      out.write(buf); 
     88    } 
     89    else { 
     90      out.skipBytes(bytesPerPixel * rgbChannels * sizeX * y); 
     91      for (int row=0; row<h; row++) { 
     92        ByteArrayOutputStream strip = new ByteArrayOutputStream(); 
     93        for (int col=0; col<w; col++) { 
     94          for (int c=0; c<rgbChannels; c++) { 
     95            int index = interleaved ? rgbChannels * (row * w + col) + c : 
     96              w * (c * h + row) + col; 
     97            strip.write(buf, index * bytesPerPixel, bytesPerPixel); 
     98          } 
     99        } 
     100        out.skipBytes(bytesPerPixel * rgbChannels * x); 
     101        out.write(strip.toByteArray()); 
     102        out.skipBytes(bytesPerPixel * rgbChannels * (sizeX - w - x)); 
     103      } 
     104    } 
     105  } 
     106 
     107  /* @see loci.formats.IFormatWriter#canDoStacks() */ 
     108  public boolean canDoStacks() { return true; } 
     109 
     110  /* @see loci.formats.IFormatWriter#getPixelTypes() */ 
     111  public int[] getPixelTypes() { 
     112    return new int[] {FormatTools.INT8, FormatTools.UINT8, FormatTools.INT16, 
     113      FormatTools.UINT16, FormatTools.INT32, FormatTools.UINT32, 
     114      FormatTools.FLOAT}; 
     115  } 
     116 
     117  /* @see loci.formats.IFormatWriter#setId(String) */ 
     118  public void setId(String id) throws FormatException, IOException { 
     119    super.setId(id); 
     120 
     121    if (out.length() == 0) { 
    80122      out.writeBytes("\t\n"); 
    81123      out.writeBytes("ics_version\t2.0\n"); 
     
    83125      out.writeBytes("layout\tparameters\t6\n"); 
    84126 
     127      MetadataRetrieve meta = getMetadataRetrieve(); 
     128      MetadataTools.verifyMinimumPopulated(meta, series); 
     129 
     130      int pixelType = 
     131        FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString()); 
     132      int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType); 
     133      int rgbChannels = getSamplesPerPixel(); 
     134 
    85135      String order = meta.getPixelsDimensionOrder(series).toString(); 
    86       int x = meta.getPixelsSizeX(series).getValue().intValue(); 
    87       int y = meta.getPixelsSizeY(series).getValue().intValue(); 
     136      int sizeX = meta.getPixelsSizeX(series).getValue().intValue(); 
     137      int sizeY = meta.getPixelsSizeY(series).getValue().intValue(); 
    88138      int z = meta.getPixelsSizeZ(series).getValue().intValue(); 
    89139      int c = meta.getPixelsSizeC(series).getValue().intValue(); 
     
    101151 
    102152      for (int i=0; i<order.length(); i++) { 
    103         if (order.charAt(i) == 'X') sizes[nextSize++] = x; 
    104         else if (order.charAt(i) == 'Y') sizes[nextSize++] = y; 
     153        if (order.charAt(i) == 'X') sizes[nextSize++] = sizeX; 
     154        else if (order.charAt(i) == 'Y') sizes[nextSize++] = sizeY; 
    105155        else if (order.charAt(i) == 'Z') sizes[nextSize++] = z; 
    106156        else if (order.charAt(i) == 'T') sizes[nextSize++] = t; 
     
    168218      out.writeBytes("\nparameter\tunits\tbits\t" + units.toString() + "\n"); 
    169219      out.writeBytes("\nend\n"); 
    170     } 
    171  
    172     out.seek(out.length()); 
    173     if (interleaved || rgbChannels == 1) out.write(buf); 
     220      pixelOffset = out.getFilePointer(); 
     221    } 
    174222    else { 
    175       int planeSize = buf.length / rgbChannels; 
    176       for (int i=0; i<planeSize; i+=bytesPerPixel) { 
    177         for (int ch=0; ch<rgbChannels; ch++) { 
    178           out.write(buf, ch*planeSize + i, bytesPerPixel); 
    179         } 
    180       } 
    181     } 
    182  
    183     if (last) close(); 
     223      RandomAccessInputStream in = new RandomAccessInputStream(currentId); 
     224      in.findString("\nend\n"); 
     225      pixelOffset = in.getFilePointer(); 
     226      in.close(); 
     227    } 
    184228  } 
    185229 
    186   /* @see loci.formats.IFormatWriter#canDoStacks() */ 
    187   public boolean canDoStacks() { return true; } 
    188  
    189   /* @see loci.formats.IFormatWriter#getPixelTypes() */ 
    190   public int[] getPixelTypes() { 
    191     return new int[] {FormatTools.INT8, FormatTools.UINT8, FormatTools.INT16, 
    192       FormatTools.UINT16, FormatTools.INT32, FormatTools.UINT32, 
    193       FormatTools.FLOAT}; 
    194   } 
    195  
    196   // -- IFormatHandler API methods -- 
    197  
    198   /* @see loci.formats.IFormatHandler#close() */ 
    199   public void close() throws IOException { 
    200     if (out != null) out.close(); 
    201     out = null; 
    202     currentId = null; 
    203     initialized = false; 
    204   } 
    205  
    206230} 
  • trunk/components/bio-formats/src/loci/formats/out/ImageIOWriter.java

    r6141 r6294  
    5252 
    5353  protected String kind; 
    54   protected RandomAccessOutputStream out; 
    5554 
    5655  // -- Constructors -- 
     
    7574  // -- IFormatWriter API methods -- 
    7675 
    77   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    78   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    79     boolean last) throws FormatException, IOException 
     76  /** 
     77   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     78   */ 
     79  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     80    throws FormatException, IOException 
    8081  { 
     82    checkParams(no, buf, x, y, w, h); 
    8183    MetadataRetrieve meta = getMetadataRetrieve(); 
    8284    BufferedImage image = AWTImageTools.makeImage(buf, 
    8385      interleaved, meta, series); 
    84     savePlane(image, series, lastInSeries, last); 
     86    savePlane(no, image, x, y, w, h); 
    8587  } 
    8688 
    87   /* @see loci.formats.IFormatWriter#savePlane(Object, int, boolean, boolean) */ 
    88   public void savePlane(Object plane, int series, boolean lastInSeries, 
    89     boolean last) throws FormatException, IOException 
     89  /** 
     90   * @see loci.formats.IFormatWriter#savePlane(int, Object, int, int, int, int) 
     91   */ 
     92  public void savePlane(int no, Object plane, int x, int y, int w, int h) 
     93    throws FormatException, IOException 
    9094  { 
    9195    if (!(plane instanceof Image)) { 
     
    9397        "Object to save must be a java.awt.Image"); 
    9498    } 
     99    if (!isFullPlane(x, y, w, h)) { 
     100      throw new FormatException("ImageIOWriter does not support writing tiles"); 
     101    } 
    95102 
    96103    BufferedImage img = AWTImageTools.makeBuffered((Image) plane, cm); 
    97     int type = AWTImageTools.getPixelType(img); 
    98     int[] types = getPixelTypes(); 
    99     for (int i=0; i<types.length; i++) { 
    100       if (types[i] == type) { 
    101         out = new RandomAccessOutputStream(currentId); 
    102         ImageIO.write(img, kind, out); 
    103         return; 
    104       } 
    105     } 
    106     throw new FormatException("Floating point data not supported."); 
     104    ImageIO.write(img, kind, out); 
    107105  } 
    108106 
     
    119117  } 
    120118 
    121   /* @see loci.formats.IFormatHandler#close() */ 
    122   public void close() throws IOException { 
    123     if (out != null) out.close(); 
    124     out = null; 
    125     currentId = null; 
    126     initialized = false; 
    127   } 
    128  
    129119} 
  • trunk/components/bio-formats/src/loci/formats/out/JPEG2000Writer.java

    r6230 r6294  
    4444public class JPEG2000Writer extends FormatWriter { 
    4545 
    46   // -- Fields -- 
    47  
    48   private RandomAccessOutputStream out; 
    49  
    5046  // -- Constructor -- 
    5147 
     
    5652  // -- IFormatWriter API methods -- 
    5753 
    58   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    59   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    60     boolean last) throws FormatException, IOException 
     54  /** 
     55   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     56   */ 
     57  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     58    throws FormatException, IOException 
    6159  { 
     60    checkParams(no, buf, x, y, w, h); 
    6261    MetadataRetrieve retrieve = getMetadataRetrieve(); 
    63     MetadataTools.verifyMinimumPopulated(retrieve, series); 
    6462    boolean littleEndian = 
    6563      !retrieve.getPixelsBinDataBigEndian(series, 0).booleanValue(); 
     
    6967      FormatTools.pixelTypeFromString( 
    7068      retrieve.getPixelsType(series).toString())); 
    71     Integer channels = retrieve.getChannelSamplesPerPixel(series, 0); 
    72     if (channels == null) { 
    73       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    74     } 
    75     int nChannels = channels == null ? 1 : channels.intValue(); 
    76  
    77     out = new RandomAccessOutputStream(currentId); 
     69    int nChannels = getSamplesPerPixel(); 
    7870 
    7971    CodecOptions options = new CodecOptions(); 
     
    8678 
    8779    out.write(new JPEG2000Codec().compress(buf, options)); 
    88     out.close(); 
    8980  } 
    9081 
     
    9889  } 
    9990 
    100   // -- IFormatHandler API methods -- 
    101  
    102   /* @see loci.formats.IFormatHandler#close() */ 
    103   public void close() throws IOException { 
    104     if (out != null) out.close(); 
    105     out = null; 
    106     currentId = null; 
    107   } 
    108  
    10991} 
  • trunk/components/bio-formats/src/loci/formats/out/JavaWriter.java

    r6230 r6294  
    2626import java.io.File; 
    2727import java.io.IOException; 
    28 import java.io.PrintWriter; 
    2928import java.util.Date; 
    3029 
     
    4746public class JavaWriter extends FormatWriter { 
    4847 
    49   // -- Fields -- 
    50  
    51   protected PrintWriter out; 
    52   protected int no = 0; 
    53  
    5448  // -- Constructor -- 
    5549 
     
    5852  // -- IFormatWriter API methods -- 
    5953 
    60   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    61   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    62     boolean last) throws FormatException, IOException 
    63   { 
    64     if (buf == null) throw new FormatException("Byte array is null"); 
     54  /** 
     55   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     56   */ 
     57  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     58    throws FormatException, IOException 
     59  { 
     60    checkParams(no, buf, x, y, w, h); 
    6561 
    6662    // check pixel type 
    6763    MetadataRetrieve meta = getMetadataRetrieve(); 
    68     MetadataTools.verifyMinimumPopulated(meta, series); 
    6964    String pixelType = meta.getPixelsType(series).toString(); 
    7065    int type = FormatTools.pixelTypeFromString(pixelType); 
     
    7772      Boolean.FALSE.equals(meta.getPixelsBinDataBigEndian(series, 0)); 
    7873 
    79     if (!initialized) { 
    80       writeHeader(); 
    81       initialized = true; 
    82     } 
    83  
    8474    // write array 
    8575    String varName = "series" + series + "Plane" + no; 
    8676    Object array = DataTools.makeDataArray(buf, bpp, fp, little); 
    87     int w = meta.getPixelsSizeX(series).getValue().intValue(); 
    88     int h = meta.getPixelsSizeY(series).getValue().intValue(); 
     77    int sizeX = meta.getPixelsSizeX(series).getValue().intValue(); 
     78    int sizeY = meta.getPixelsSizeY(series).getValue().intValue(); 
     79 
     80    out.seek(out.length()); 
    8981    if (array instanceof byte[]) { 
    9082      writePlane(varName, (byte[]) array, w, h); 
     
    10698    } 
    10799 
    108     no++; 
    109     if (lastInSeries) no = 0; 
    110     if (last) writeFooter(); 
     100    if (no == getPlaneCount() - 1) writeFooter(); 
    111101  } 
    112102 
     
    129119  // -- IFormatHandler API methods -- 
    130120 
    131   /* @see loci.formats.IFormatHandler#close() */ 
    132   public void close() throws IOException { 
    133     if (out != null) out.close(); 
    134     out = null; 
    135     currentId = null; 
    136     initialized = false; 
     121  /* @see loci.formats.IFormatHandler#setId(String) */ 
     122  public void setId(String id) throws FormatException, IOException { 
     123    super.setId(id); 
     124    if (out.length() == 0) writeHeader(); 
    137125  } 
    138126 
     
    140128 
    141129  protected void writeHeader() throws IOException { 
    142     out = new PrintWriter(new RandomAccessOutputStream(currentId)); 
    143  
    144130    String className = currentId.substring(0, currentId.length() - 5); 
    145131    className = className.substring(className.lastIndexOf(File.separator) + 1); 
    146132 
    147     out.println("//"); 
    148     out.println("// " + className + ".java"); 
    149     out.println("//"); 
    150     out.println(); 
    151     out.println("// Generated by Bio-Formats v" + FormatTools.VERSION); 
    152     out.println("// Generated on " + new Date()); 
    153     out.println(); 
    154     out.println("public class " + className + " {"); 
    155     out.println(); 
    156   } 
    157  
    158   protected void writePlane(String varName, byte[] array, int w, int h) { 
    159     int i = 0; 
    160     out.println("  public byte[][] " + varName + " = {"); 
    161     for (int y=0; y<h; y++) { 
    162       out.print("    {"); 
    163       for (int x=0; x<w; x++) { 
    164         out.print(array[i++]); 
    165         if (x < w - 1) out.print(", "); 
    166         else out.print("}"); 
    167       } 
    168       if (y < h - 1) out.println(","); 
    169       else out.println(); 
    170     } 
    171     out.println("  };"); 
    172     out.println(); 
    173   } 
    174  
    175   protected void writePlane(String varName, short[] array, int w, int h) { 
    176     int i = 0; 
    177     out.println("  public short[][] " + varName + " = {"); 
    178     for (int y=0; y<h; y++) { 
    179       out.print("    {"); 
    180       for (int x=0; x<w; x++) { 
    181         out.print(array[i++]); 
    182         if (x < w - 1) out.print(", "); 
    183         else out.print("}"); 
    184       } 
    185       if (y < h - 1) out.println(","); 
    186       else out.println(); 
    187     } 
    188     out.println("  };"); 
    189     out.println(); 
    190   } 
    191  
    192   protected void writePlane(String varName, int[] array, int w, int h) { 
    193     int i = 0; 
    194     out.println("  public int[][] " + varName + " = {"); 
    195     for (int y=0; y<h; y++) { 
    196       out.print("    {"); 
    197       for (int x=0; x<w; x++) { 
    198         out.print(array[i++]); 
    199         if (x < w - 1) out.print(", "); 
    200         else out.print("}"); 
    201       } 
    202       if (y < h - 1) out.println(","); 
    203       else out.println(); 
    204     } 
    205     out.println("  };"); 
    206     out.println(); 
    207   } 
    208  
    209   protected void writePlane(String varName, long[] array, int w, int h) { 
    210     int i = 0; 
    211     out.println("  public long[][] " + varName + " = {"); 
    212     for (int y=0; y<h; y++) { 
    213       out.print("    {"); 
    214       for (int x=0; x<w; x++) { 
    215         out.print(array[i++]); 
    216         if (x < w - 1) out.print(", "); 
    217         else out.print("}"); 
    218       } 
    219       if (y < h - 1) out.println(","); 
    220       else out.println(); 
    221     } 
    222     out.println("  };"); 
    223     out.println(); 
    224   } 
    225  
    226   protected void writePlane(String varName, float[] array, int w, int h) { 
    227     int i = 0; 
    228     out.println("  public float[][] " + varName + " = {"); 
    229     for (int y=0; y<h; y++) { 
    230       out.print("    {"); 
    231       for (int x=0; x<w; x++) { 
    232         out.print(array[i++]); 
    233         if (x < w - 1) out.print(", "); 
    234         else out.print("}"); 
    235       } 
    236       if (y < h - 1) out.println(","); 
    237       else out.println(); 
    238     } 
    239     out.println("  };"); 
    240     out.println(); 
    241   } 
    242  
    243   protected void writePlane(String varName, double[] array, int w, int h) { 
    244     int i = 0; 
    245     out.println("  public double[][] " + varName + " = {"); 
    246     for (int y=0; y<h; y++) { 
    247       out.print("    {"); 
    248       for (int x=0; x<w; x++) { 
    249         out.print(array[i++]); 
    250         if (x < w - 1) out.print(", "); 
    251         else out.print("}"); 
    252       } 
    253       if (y < h - 1) out.println(","); 
    254       else out.println(); 
    255     } 
    256     out.println("  };"); 
    257     out.println(); 
    258   } 
    259  
    260   protected void writeFooter() { 
    261     out.println("}"); 
     133    out.writeLine("//"); 
     134    out.writeLine("// " + className + ".java"); 
     135    out.writeLine("//"); 
     136    out.writeLine(""); 
     137    out.writeLine("// Generated by Bio-Formats v" + FormatTools.VERSION); 
     138    out.writeLine("// Generated on " + new Date()); 
     139    out.writeLine(""); 
     140    out.writeLine("public class " + className + " {"); 
     141    out.writeLine(""); 
     142  } 
     143 
     144  protected void writePlane(String varName, byte[] array, int w, int h) 
     145    throws IOException 
     146  { 
     147    int i = 0; 
     148    out.writeLine("  public byte[][] " + varName + " = {"); 
     149    for (int y=0; y<h; y++) { 
     150      out.writeBytes("    {"); 
     151      for (int x=0; x<w; x++) { 
     152        out.writeBytes(String.valueOf(array[i++])); 
     153        if (x < w - 1) out.writeBytes(", "); 
     154        else out.writeBytes("}"); 
     155      } 
     156      if (y < h - 1) out.writeLine(","); 
     157      else out.writeLine(""); 
     158    } 
     159    out.writeLine("  };"); 
     160    out.writeLine(""); 
     161  } 
     162 
     163  protected void writePlane(String varName, short[] array, int w, int h) 
     164    throws IOException 
     165  { 
     166    int i = 0; 
     167    out.writeLine("  public short[][] " + varName + " = {"); 
     168    for (int y=0; y<h; y++) { 
     169      out.writeBytes("    {"); 
     170      for (int x=0; x<w; x++) { 
     171        out.writeBytes(String.valueOf(array[i++])); 
     172        if (x < w - 1) out.writeBytes(", "); 
     173        else out.writeBytes("}"); 
     174      } 
     175      if (y < h - 1) out.writeLine(","); 
     176      else out.writeLine(""); 
     177    } 
     178    out.writeLine("  };"); 
     179    out.writeLine(""); 
     180  } 
     181 
     182  protected void writePlane(String varName, int[] array, int w, int h) 
     183    throws IOException 
     184  { 
     185    int i = 0; 
     186    out.writeLine("  public int[][] " + varName + " = {"); 
     187    for (int y=0; y<h; y++) { 
     188      out.writeBytes("    {"); 
     189      for (int x=0; x<w; x++) { 
     190        out.writeBytes(String.valueOf(array[i++])); 
     191        if (x < w - 1) out.writeBytes(", "); 
     192        else out.writeBytes("}"); 
     193      } 
     194      if (y < h - 1) out.writeLine(","); 
     195      else out.writeLine(""); 
     196    } 
     197    out.writeLine("  };"); 
     198    out.writeLine(""); 
     199  } 
     200 
     201  protected void writePlane(String varName, long[] array, int w, int h) 
     202    throws IOException 
     203  { 
     204    int i = 0; 
     205    out.writeLine("  public long[][] " + varName + " = {"); 
     206    for (int y=0; y<h; y++) { 
     207      out.writeBytes("    {"); 
     208      for (int x=0; x<w; x++) { 
     209        out.writeBytes(String.valueOf(array[i++])); 
     210        if (x < w - 1) out.writeBytes(", "); 
     211        else out.writeBytes("}"); 
     212      } 
     213      if (y < h - 1) out.writeLine(","); 
     214      else out.writeLine(""); 
     215    } 
     216    out.writeLine("  };"); 
     217    out.writeLine(""); 
     218  } 
     219 
     220  protected void writePlane(String varName, float[] array, int w, int h) 
     221    throws IOException 
     222  { 
     223    int i = 0; 
     224    out.writeLine("  public float[][] " + varName + " = {"); 
     225    for (int y=0; y<h; y++) { 
     226      out.writeBytes("    {"); 
     227      for (int x=0; x<w; x++) { 
     228        out.writeBytes(String.valueOf(array[i++])); 
     229        if (x < w - 1) out.writeBytes(", "); 
     230        else out.writeBytes("}"); 
     231      } 
     232      if (y < h - 1) out.writeLine(","); 
     233      else out.writeLine(""); 
     234    } 
     235    out.writeLine("  };"); 
     236    out.writeLine(""); 
     237  } 
     238 
     239  protected void writePlane(String varName, double[] array, int w, int h) 
     240    throws IOException 
     241  { 
     242    int i = 0; 
     243    out.writeLine("  public double[][] " + varName + " = {"); 
     244    for (int y=0; y<h; y++) { 
     245      out.writeBytes("    {"); 
     246      for (int x=0; x<w; x++) { 
     247        out.writeBytes(String.valueOf(array[i++])); 
     248        if (x < w - 1) out.writeBytes(", "); 
     249        else out.writeBytes("}"); 
     250      } 
     251      if (y < h - 1) out.writeLine(","); 
     252      else out.writeLine(""); 
     253    } 
     254    out.writeLine("  };"); 
     255    out.writeLine(""); 
     256  } 
     257 
     258  protected void writeFooter() throws IOException { 
     259    out.writeLine("}"); 
    262260  } 
    263261 
  • trunk/components/bio-formats/src/loci/formats/out/LegacyQTWriter.java

    r6141 r6294  
    116116  // -- IFormatWriter API methods -- 
    117117 
    118   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    119   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    120     boolean last) throws FormatException, IOException 
     118  /** 
     119   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     120   */ 
     121  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     122    throws FormatException, IOException 
    121123  { 
     124    checkParams(no, buf, x, y, w, h); 
    122125    MetadataRetrieve meta = getMetadataRetrieve(); 
    123126    BufferedImage image = AWTImageTools.makeImage(buf, 
    124127      interleaved, meta, series); 
    125     savePlane(image, series, lastInSeries, last); 
    126   } 
    127  
    128   /* @see loci.formats.IFormatWriter#savePlane(Image, int, boolean, boolean) */ 
    129   public void savePlane(Object plane, int series, boolean lastInSeries, 
    130     boolean last) throws FormatException, IOException 
     128    savePlane(no, image, x, y, w, h); 
     129  } 
     130 
     131  /** 
     132   * @see loci.formats.IFormatWriter#savePlane(int, Image, int, int, int, int) 
     133   */ 
     134  public void savePlane(int no, Object plane, int x, int y, int w, int h) 
     135    throws FormatException, IOException 
    131136  { 
    132137    if (!(plane instanceof Image)) { 
     
    143148    BufferedImage img = AWTImageTools.makeBuffered((Image) plane); 
    144149 
    145     if (!initialized) { 
    146       initialized = true; 
     150    if (!initialized[series][no]) { 
     151      initialized[series][no] = true; 
    147152 
    148153      try { 
     
    227232      if (nativeLittle) { 
    228233        int offset1, offset2; 
    229         for (int y=0; y<height; y++) { 
    230           offset1 = y * width; 
    231           offset2 = y * intsPerRow; 
    232           for (int x=0; x<width; x++) { 
     234        for (int row=0; row<height; row++) { 
     235          offset1 = row * width; 
     236          offset2 = row * intsPerRow; 
     237          for (int col=0; col<width; col++) { 
    233238            r.setVar("thisByte", pixels[offset1++]); 
    234239            r.exec("b = EndianOrder.flipBigEndianToNative32(thisByte)"); 
     
    271276      throw new FormatException("Legacy QuickTime writer failed", e); 
    272277    } 
    273     if (last) { 
     278 
     279    if (no == getPlaneCount() - 1) { 
    274280      try { 
    275281        r.exec("videoMedia.endEdits()"); 
     
    303309  /* @see loci.formats.IFormatHandler#close() */ 
    304310  public void close() throws IOException { 
     311    super.close(); 
    305312    r = null; 
    306313    numWritten = 0; 
     
    308315    height = 0; 
    309316    pixels2 = null; 
    310     currentId = null; 
    311     initialized = false; 
    312317  } 
    313318 
  • trunk/components/bio-formats/src/loci/formats/out/OMETiffWriter.java

    r6230 r6294  
    211211    seriesMap = null; 
    212212    wroteLast = false; 
    213     if (out != null) out.close(); 
    214     out = null; 
    215213  } 
    216214 
    217215  // -- IFormatWriter API methods -- 
    218216 
    219   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    220   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    221     boolean last) throws FormatException, IOException 
     217  /** 
     218   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     219   */ 
     220  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     221    throws FormatException, IOException 
    222222  { 
    223223    if (seriesMap == null) seriesMap = new ArrayList<Integer>(); 
    224224    seriesMap.add(new Integer(series)); 
    225     if (last) wroteLast = true; 
    226     super.saveBytes(buf, series, lastInSeries, last); 
     225 
     226    MetadataRetrieve r = getMetadataRetrieve(); 
     227 
     228    wroteLast = series == r.getImageCount() - 1 && no == getPlaneCount() - 1; 
     229    super.saveBytes(no, buf, x, y, w, h); 
    227230  } 
    228231 
  • trunk/components/bio-formats/src/loci/formats/out/OMEXMLWriter.java

    r6230 r6294  
    6262 
    6363  private Vector<String> xmlFragments; 
    64   private RandomAccessOutputStream out; 
    6564  private String currentFragment; 
    6665 
     
    7675  // -- IFormatHandler API methods -- 
    7776 
     77  /* @see loci.formats.IFormatHandler#setId(String) */ 
     78  public void setId(String id) throws FormatException, IOException { 
     79    super.setId(id); 
     80 
     81    MetadataRetrieve retrieve = getMetadataRetrieve(); 
     82    String xml; 
     83    try { 
     84      ServiceFactory factory = new ServiceFactory(); 
     85      OMEXMLService service = factory.getInstance(OMEXMLService.class); 
     86      xml = service.getOMEXML(retrieve); 
     87    } 
     88    catch (DependencyException de) { 
     89      throw new MissingLibraryException(OMETiffReader.NO_OME_XML_MSG, de); 
     90    } 
     91    catch (ServiceException se) { 
     92      throw new FormatException(se); 
     93    } 
     94 
     95    xmlFragments = new Vector<String>(); 
     96    currentFragment = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
     97    XMLTools.parseXML(xml, new OMEHandler()); 
     98 
     99    xmlFragments.add(currentFragment); 
     100    if (out.length() == 0) { 
     101      out.writeBytes(xmlFragments.get(0)); 
     102    } 
     103  } 
     104 
    78105  /* @see loci.formats.IFormatHandler#close() */ 
    79106  public void close() throws IOException { 
    80     if (out != null) out.close(); 
    81     out = null; 
     107    super.close(); 
    82108    xmlFragments = null; 
    83     initialized = false; 
    84109  } 
    85110 
    86111  // -- IFormatWriter API methods -- 
    87112 
    88   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    89   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    90     boolean last) throws FormatException, IOException 
     113  /** 
     114   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     115   */ 
     116  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     117    throws FormatException, IOException 
    91118  { 
     119    checkParams(no, buf, x, y, w, h); 
    92120    MetadataRetrieve retrieve = getMetadataRetrieve(); 
    93     MetadataTools.verifyMinimumPopulated(retrieve, series); 
    94     if (!initialized) { 
    95       out = new RandomAccessOutputStream(currentId); 
    96  
    97       String xml; 
    98       try { 
    99         ServiceFactory factory = new ServiceFactory(); 
    100         OMEXMLService service = factory.getInstance(OMEXMLService.class); 
    101         xml = service.getOMEXML(retrieve); 
    102       } 
    103       catch (DependencyException de) { 
    104         throw new MissingLibraryException(OMETiffReader.NO_OME_XML_MSG, de); 
    105       } 
    106       catch (ServiceException se) { 
    107         throw new FormatException(se); 
    108       } 
    109  
    110       xmlFragments = new Vector<String>(); 
    111       currentFragment = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
    112       XMLTools.parseXML(xml, new OMEHandler()); 
    113  
    114       xmlFragments.add(currentFragment); 
    115  
    116       out.writeBytes(xmlFragments.get(0)); 
    117       initialized = true; 
    118     } 
    119     boolean littleEndian = 
    120       !retrieve.getPixelsBinDataBigEndian(series, 0).booleanValue(); 
    121121 
    122122    String type = retrieve.getPixelsType(series).toString(); 
    123123    int pixelType = FormatTools.pixelTypeFromString(type); 
    124  
    125     CodecOptions options = new CodecOptions(); 
    126     options.width = retrieve.getPixelsSizeX(series).getValue().intValue(); 
    127     options.height = retrieve.getPixelsSizeY(series).getValue().intValue(); 
    128     options.channels = 1; 
    129     options.interleaved = false; 
    130     options.littleEndian = littleEndian; 
    131     options.signed = FormatTools.isSigned(pixelType); 
    132  
    133     // TODO: Create a method compress to handle all compression methods 
    134124    int bytes = FormatTools.getBytesPerPixel(pixelType); 
    135     options.bitsPerSample = bytes * 8; 
    136  
    137     Integer channels = retrieve.getChannelSamplesPerPixel(series, 0); 
    138     if (channels == null) { 
    139       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    140     } 
    141     int nChannels = channels == null ? 1 : channels.intValue(); 
     125    int nChannels = getSamplesPerPixel(); 
     126    int sizeX = retrieve.getPixelsSizeX(series).getValue().intValue(); 
     127    int sizeY = retrieve.getPixelsSizeY(series).getValue().intValue(); 
     128    int planeSize = sizeX * sizeY * bytes; 
     129    boolean bigEndian = retrieve.getPixelsBinDataBigEndian(series, 0); 
    142130 
    143131    for (int i=0; i<nChannels; i++) { 
    144132      byte[] b = ImageTools.splitChannels(buf, i, nChannels, bytes, false, 
    145133        interleaved); 
    146       if (compression.equals("J2K")) { 
    147         b = new JPEG2000Codec().compress(b, options); 
    148       } 
    149       else if (compression.equals("JPEG")) { 
    150         b = new JPEGCodec().compress(b, options); 
    151       } 
    152       else if (compression.equals("zlib")) { 
    153         b = new ZlibCodec().compress(b, options); 
    154       } 
    155       byte[] encodedPix = new Base64Codec().compress(b, options); 
    156  
    157       StringBuffer plane = new StringBuffer("\n<Bin:BinData Length=\""); 
    158       plane.append(encodedPix.length); 
     134      byte[] encodedPix = compress(b); 
     135 
     136      StringBuffer plane = new StringBuffer("\n<BinData Length=\""); 
     137      plane.append(planeSize); 
     138      plane.append("\""); 
     139      plane.append(" BigEndian=\""); 
     140      plane.append(bigEndian); 
    159141      plane.append("\""); 
    160142      if (compression != null && !compression.equals("Uncompressed")) { 
     
    165147      plane.append(">"); 
    166148      plane.append(new String(encodedPix)); 
    167       plane.append("</Bin:BinData>"); 
     149      plane.append("</BinData>"); 
    168150      out.writeBytes(plane.toString()); 
    169151    } 
    170152 
    171     if (lastInSeries) { 
    172       out.writeBytes((String) xmlFragments.get(series + 1)); 
    173     } 
    174     if (last) close(); 
     153    if (no == getPlaneCount() - 1) { 
     154      out.writeBytes(xmlFragments.get(series + 1)); 
     155    } 
    175156  } 
    176157 
     
    184165    } 
    185166    return getPixelTypes(); 
     167  } 
     168 
     169  // -- Helper methods -- 
     170 
     171  /** 
     172   * Compress the given byte array using the current codec. 
     173   * The compressed data is then base64-encoded. 
     174   */ 
     175  private byte[] compress(byte[] b) throws FormatException, IOException { 
     176    MetadataRetrieve r = getMetadataRetrieve(); 
     177    String type = r.getPixelsType(series).toString(); 
     178    int pixelType = FormatTools.pixelTypeFromString(type); 
     179    int bytes = FormatTools.getBytesPerPixel(pixelType); 
     180 
     181    CodecOptions options = new CodecOptions(); 
     182    options.width = r.getPixelsSizeX(series).getValue().intValue(); 
     183    options.height = r.getPixelsSizeY(series).getValue().intValue(); 
     184    options.channels = 1; 
     185    options.interleaved = false; 
     186    options.signed = FormatTools.isSigned(pixelType); 
     187    options.littleEndian = 
     188      !r.getPixelsBinDataBigEndian(series, 0).booleanValue(); 
     189    options.bitsPerSample = bytes * 8; 
     190 
     191    if (compression.equals("J2K")) { 
     192      b = new JPEG2000Codec().compress(b, options); 
     193    } 
     194    else if (compression.equals("JPEG")) { 
     195      b = new JPEGCodec().compress(b, options); 
     196    } 
     197    else if (compression.equals("zlib")) { 
     198      b = new ZlibCodec().compress(b, options); 
     199    } 
     200    return new Base64Codec().compress(b, options); 
    186201  } 
    187202 
  • trunk/components/bio-formats/src/loci/formats/out/QTWriter.java

    r6230 r6294  
    8787  public static final int QUALITY_MAXIMUM = 1023; 
    8888 
     89  /** Seek to this offset to update the total number of pixel bytes. */ 
     90  private static final long BYTE_COUNT_OFFSET = 8; 
     91 
    8992  // -- Fields -- 
    90  
    91   /** Current file. */ 
    92   protected RandomAccessOutputStream out; 
    9393 
    9494  /** The codec to use. */ 
     
    9898  protected int quality = QUALITY_NORMAL; 
    9999 
    100   /** Number of planes written. */ 
    101   protected int numWritten; 
    102  
    103   /** Seek to this offset to update the total number of pixel bytes. */ 
    104   protected long byteCountOffset; 
    105  
    106100  /** Total number of pixel bytes. */ 
    107101  protected int numBytes; 
     
    112106  /** Time the file was created. */ 
    113107  protected int created; 
     108 
     109  /** Number of padding bytes in each row. */ 
     110  protected int pad; 
    114111 
    115112  /** Whether we need the legacy writer. */ 
     
    164161  // -- IFormatWriter API methods -- 
    165162 
    166   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    167   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    168     boolean last) throws FormatException, IOException 
     163  /** 
     164   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     165   */ 
     166  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     167    throws FormatException, IOException 
    169168  { 
    170     if (legacy == null) legacy = new LegacyQTWriter(); 
    171  
     169    checkParams(no, buf, x, y, w, h); 
    172170    if (needLegacy) { 
    173       legacy.saveBytes(buf, last); 
     171      legacy.saveBytes(no, buf, x, y, w, h); 
    174172      return; 
    175173    } 
    176174 
    177175    MetadataRetrieve r = getMetadataRetrieve(); 
    178     MetadataTools.verifyMinimumPopulated(r, series); 
    179176 
    180177    // get the width and height of the image 
     
    186183    // bytes to make the width a multiple of 8 
    187184 
    188     int bytesPerPixel = 
    189       FormatTools.pixelTypeFromString(r.getPixelsType(series).toString()); 
    190     Integer samples = r.getChannelSamplesPerPixel(series, 0); 
    191     if (samples == null) { 
    192       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    193     } 
    194     int nChannels = samples == null ? 1 : samples.intValue(); 
    195     int pad = nChannels > 1 ? 0 : (4 - (width % 4)) % 4; 
    196  
    197     if (!initialized) { 
    198       initialized = true; 
     185    int nChannels = getSamplesPerPixel(); 
     186    int planeSize = width * height * nChannels; 
     187 
     188    if (!initialized[series][no]) { 
     189      initialized[series][no] = true; 
    199190      setCodec(); 
    200191      if (codec != CODEC_RAW) { 
    201192        needLegacy = true; 
    202         legacy.setCodec(codec); 
    203         legacy.setMetadataRetrieve(getMetadataRetrieve()); 
    204193        legacy.setId(currentId); 
    205         legacy.saveBytes(buf, series, lastInSeries, last); 
     194        legacy.saveBytes(no, buf, x, y, w, h); 
    206195        return; 
    207196      } 
    208197 
    209       // -- write the header -- 
    210  
    211       offsets = new Vector<Integer>(); 
    212       out = new RandomAccessOutputStream(currentId); 
    213       created = (int) System.currentTimeMillis(); 
    214       numWritten = 0; 
    215       numBytes = buf.length + pad * height; 
    216       byteCountOffset = 8; 
    217  
    218       if (out.length() == 0) { 
    219         // -- write the first header -- 
    220  
    221         out.writeInt(8); 
    222         out.writeBytes("wide"); 
    223  
    224         out.writeInt(numBytes + 8); 
    225         out.writeBytes("mdat"); 
    226       } 
    227       else { 
    228         out.seek(byteCountOffset); 
    229  
    230         RandomAccessInputStream in = new RandomAccessInputStream(currentId); 
    231         in.seek(byteCountOffset); 
    232         numBytes = (int) (in.readInt() & 0xffffffff) - 8; 
    233         in.close(); 
    234  
    235         numWritten = numBytes / (buf.length + pad * height); 
    236         numBytes += (buf.length + pad * height); 
    237  
    238         out.seek(byteCountOffset); 
    239         out.write(numBytes + 8); 
    240  
    241         for (int i=0; i<numWritten; i++) { 
    242           offsets.add(16 + i * (buf.length + pad * height)); 
    243         } 
    244  
    245         out.seek(out.length()); 
    246       } 
    247  
    248       // -- write the first plane of pixel data (mdat) -- 
    249  
    250       offsets.add((int) out.length()); 
    251     } 
    252     else { 
    253198      // update the number of pixel bytes written 
    254199      int planeOffset = numBytes; 
    255       numBytes += (buf.length + pad * height); 
    256       out.seek(byteCountOffset); 
     200      numBytes += (planeSize + pad * height); 
     201      out.seek(BYTE_COUNT_OFFSET); 
    257202      out.writeInt(numBytes + 8); 
    258203 
    259       // write this plane's pixel data 
    260       out.seek(out.length()); 
    261  
    262       offsets.add(planeOffset + 16); 
    263     } 
     204      out.seek(offsets.get(no)); 
     205 
     206      if (!isFullPlane(x, y, w, h)) { 
     207        out.skipBytes(planeSize + pad * height); 
     208      } 
     209    } 
     210 
     211    out.seek(offsets.get(no) + y * (nChannels * width + pad)); 
    264212 
    265213    // invert each pixel 
     
    267215    // but needs to be reversed in QTReader 
    268216 
    269     if (nChannels == 1 && bytesPerPixel == 1 && !needLegacy) { 
     217    if (nChannels == 1 && !needLegacy) { 
    270218      for (int i=0; i<buf.length; i++) { 
    271219        buf[i] = (byte) (255 - buf[i]); 
     
    278226      System.arraycopy(buf, 0, tmp, 0, buf.length); 
    279227      for (int i=0; i<buf.length; i++) { 
    280         int c = i / (width * height); 
    281         int index = i % (width * height); 
     228        int c = i / (w * h); 
     229        int index = i % (w * h); 
    282230        buf[index * nChannels + c] = tmp[i]; 
    283231      } 
    284232    } 
    285233 
    286     int rowLen = buf.length / height; 
    287     for (int row=0; row<height; row++) { 
     234    int rowLen = buf.length / h; 
     235    for (int row=0; row<h; row++) { 
     236      out.skipBytes(nChannels * x); 
    288237      out.write(buf, row * rowLen, rowLen); 
    289238      for (int i=0; i<pad; i++) { 
    290239        out.writeByte(0); 
    291240      } 
    292     } 
    293  
    294     numWritten++; 
    295  
    296     if (last) { 
    297       int timeScale = 100; 
    298       int duration = numWritten * (timeScale / fps); 
    299       int bitsPerPixel = (nChannels > 1) ? bytesPerPixel * 24 : 
    300         bytesPerPixel * 8 + 32; 
    301       if (bytesPerPixel == 2) { 
    302         bitsPerPixel = nChannels > 1 ? 16 : 40; 
     241      if (row < h - 1) { 
     242        out.skipBytes(nChannels * (width - w - x)); 
    303243      } 
    304       int channels = (bitsPerPixel >= 40) ? 1 : 3; 
    305  
    306       // -- write moov atom -- 
    307  
    308       int atomLength = 685 + 8*numWritten; 
    309       out.writeInt(atomLength); 
    310       out.writeBytes("moov"); 
    311  
    312       // -- write mvhd atom -- 
    313  
    314       out.writeInt(108); 
    315       out.writeBytes("mvhd"); 
    316       out.writeShort(0); // version 
    317       out.writeShort(0); // flags 
    318       out.writeInt(created); // creation time 
    319       out.writeInt((int) System.currentTimeMillis()); 
    320       out.writeInt(timeScale); // time scale 
    321       out.writeInt(duration); // duration 
    322       out.write(new byte[] {0, 1, 0, 0});  // preferred rate & volume 
    323       out.write(new byte[] {0, -1, 0, 0, 0, 0, 0, 0, 0, 0}); // reserved 
    324  
    325       // 3x3 matrix - tells reader how to rotate image 
    326  
    327       out.writeInt(1); 
    328       out.writeInt(0); 
    329       out.writeInt(0); 
    330       out.writeInt(0); 
    331       out.writeInt(1); 
    332       out.writeInt(0); 
    333       out.writeInt(0); 
    334       out.writeInt(0); 
    335       out.writeInt(16384); 
    336  
    337       out.writeShort(0); // not sure what this is 
    338       out.writeInt(0); // preview duration 
    339       out.writeInt(0); // preview time 
    340       out.writeInt(0); // poster time 
    341       out.writeInt(0); // selection time 
    342       out.writeInt(0); // selection duration 
    343       out.writeInt(0); // current time 
    344       out.writeInt(2); // next track's id 
    345  
    346       // -- write trak atom -- 
    347  
    348       atomLength -= 116; 
    349       out.writeInt(atomLength); 
    350       out.writeBytes("trak"); 
    351  
    352       // -- write tkhd atom -- 
    353  
    354       out.writeInt(92); 
    355       out.writeBytes("tkhd"); 
    356       out.writeShort(0); // version 
    357       out.writeShort(15); // flags 
    358  
    359       out.writeInt(created); // creation time 
    360       out.writeInt((int) System.currentTimeMillis()); 
    361       out.writeInt(1); // track id 
    362       out.writeInt(0); // reserved 
    363  
    364       out.writeInt(duration); // duration 
    365       out.writeInt(0); // reserved 
    366       out.writeInt(0); // reserved 
    367       out.writeShort(0); // reserved 
    368  
    369       out.writeInt(0); // unknown 
    370  
    371       // 3x3 matrix - tells reader how to rotate the image 
    372  
    373       out.writeInt(1); 
    374       out.writeInt(0); 
    375       out.writeInt(0); 
    376       out.writeInt(0); 
    377       out.writeInt(1); 
    378       out.writeInt(0); 
    379       out.writeInt(0); 
    380       out.writeInt(0); 
    381       out.writeInt(16384); 
    382  
    383       out.writeInt(width); // image width 
    384       out.writeInt(height); // image height 
    385       out.writeShort(0); // reserved 
    386  
    387       // -- write edts atom -- 
    388  
    389       out.writeInt(36); 
    390       out.writeBytes("edts"); 
    391  
    392       // -- write elst atom -- 
    393  
    394       out.writeInt(28); 
    395       out.writeBytes("elst"); 
    396  
    397       out.writeShort(0); // version 
    398       out.writeShort(0); // flags 
    399       out.writeInt(1); // number of entries in the table 
    400       out.writeInt(duration); // duration 
    401       out.writeShort(0); // time 
    402       out.writeInt(1); // rate 
    403       out.writeShort(0); // unknown 
    404  
    405       // -- write mdia atom -- 
    406  
    407       atomLength -= 136; 
    408       out.writeInt(atomLength); 
    409       out.writeBytes("mdia"); 
    410  
    411       // -- write mdhd atom -- 
    412  
    413       out.writeInt(32); 
    414       out.writeBytes("mdhd"); 
    415  
    416       out.writeShort(0); // version 
    417       out.writeShort(0); // flags 
    418       out.writeInt(created); // creation time 
    419       out.writeInt((int) System.currentTimeMillis()); 
    420       out.writeInt(timeScale); // time scale 
    421       out.writeInt(duration); // duration 
    422       out.writeShort(0); // language 
    423       out.writeShort(0); // quality 
    424  
    425       // -- write hdlr atom -- 
    426  
    427       out.writeInt(58); 
    428       out.writeBytes("hdlr"); 
    429  
    430       out.writeShort(0); // version 
    431       out.writeShort(0); // flags 
    432       out.writeBytes("mhlr"); 
    433       out.writeBytes("vide"); 
    434       out.writeBytes("appl"); 
    435       out.write(new byte[] {16, 0, 0, 0, 0, 1, 1, 11, 25}); 
    436       out.writeBytes("Apple Video Media Handler"); 
    437  
    438       // -- write minf atom -- 
    439  
    440       atomLength -= 98; 
    441       out.writeInt(atomLength); 
    442       out.writeBytes("minf"); 
    443  
    444       // -- write vmhd atom -- 
    445  
    446       out.writeInt(20); 
    447       out.writeBytes("vmhd"); 
    448  
    449       out.writeShort(0); // version 
    450       out.writeShort(1); // flags 
    451       out.writeShort(64); // graphics mode 
    452       out.writeShort(32768);  // opcolor 1 
    453       out.writeShort(32768);  // opcolor 2 
    454       out.writeShort(32768);  // opcolor 3 
    455  
    456       // -- write hdlr atom -- 
    457  
    458       out.writeInt(57); 
    459       out.writeBytes("hdlr"); 
    460  
    461       out.writeShort(0); // version 
    462       out.writeShort(0); // flags 
    463       out.writeBytes("dhlr"); 
    464       out.writeBytes("alis"); 
    465       out.writeBytes("appl"); 
    466       out.write(new byte[] {16, 0, 0, 1, 0, 1, 1, 31, 24}); 
    467       out.writeBytes("Apple Alias Data Handler"); 
    468  
    469       // -- write dinf atom -- 
    470  
    471       out.writeInt(36); 
    472       out.writeBytes("dinf"); 
    473  
    474       // -- write dref atom -- 
    475  
    476       out.writeInt(28); 
    477       out.writeBytes("dref"); 
    478  
    479       out.writeShort(0); // version 
    480       out.writeShort(0); // flags 
    481       out.writeShort(0); // version 2 
    482       out.writeShort(1); // flags 2 
    483       out.write(new byte[] {0, 0, 0, 12}); 
    484       out.writeBytes("alis"); 
    485       out.writeShort(0); // version 3 
    486       out.writeShort(1); // flags 3 
    487  
    488       // -- write stbl atom -- 
    489  
    490       atomLength -= 121; 
    491       out.writeInt(atomLength); 
    492       out.writeBytes("stbl"); 
    493  
    494       // -- write stsd atom -- 
    495  
    496       out.writeInt(118); 
    497       out.writeBytes("stsd"); 
    498  
    499       out.writeShort(0); // version 
    500       out.writeShort(0); // flags 
    501       out.writeInt(1); // number of entries in the table 
    502       out.write(new byte[] {0, 0, 0, 102}); 
    503       out.writeBytes("raw "); // codec 
    504       out.write(new byte[] {0, 0, 0, 0, 0, 0});  // reserved 
    505       out.writeShort(1); // data reference 
    506       out.writeShort(1); // version 
    507       out.writeShort(1); // revision 
    508       out.writeBytes("appl"); 
    509       out.writeInt(0); // temporal quality 
    510       out.writeInt(768); // spatial quality 
    511       out.writeShort(width); // image width 
    512       out.writeShort(height); // image height 
    513       out.write(new byte[] {0, 72, 0, 0}); // horizontal dpi 
    514       out.write(new byte[] {0, 72, 0, 0}); // vertical dpi 
    515       out.writeInt(0); // data size 
    516       out.writeShort(1); // frames per sample 
    517       out.writeShort(12); // length of compressor name 
    518       out.writeBytes("Uncompressed"); // compressor name 
    519       out.writeInt(bitsPerPixel); // unknown 
    520       out.writeInt(bitsPerPixel); // unknown 
    521       out.writeInt(bitsPerPixel); // unknown 
    522       out.writeInt(bitsPerPixel); // unknown 
    523       out.writeInt(bitsPerPixel); // unknown 
    524       out.writeShort(bitsPerPixel); // bits per pixel 
    525       out.writeInt(65535); // ctab ID 
    526       out.write(new byte[] {12, 103, 97, 108}); // gamma 
    527       out.write(new byte[] {97, 1, -52, -52, 0, 0, 0, 0}); // unknown 
    528  
    529       // -- write stts atom -- 
    530  
    531       out.writeInt(24); 
    532       out.writeBytes("stts"); 
    533  
    534       out.writeShort(0); // version 
    535       out.writeShort(0); // flags 
    536       out.writeInt(1); // number of entries in the table 
    537       out.writeInt(numWritten); // number of planes 
    538       out.writeInt(fps); // frames per second 
    539  
    540       // -- write stsc atom -- 
    541  
    542       out.writeInt(28); 
    543       out.writeBytes("stsc"); 
    544  
    545       out.writeShort(0); // version 
    546       out.writeShort(0); // flags 
    547       out.writeInt(1); // number of entries in the table 
    548       out.writeInt(1); // chunk 
    549       out.writeInt(1); // samples 
    550       out.writeInt(1); // id 
    551  
    552       // -- write stsz atom -- 
    553  
    554       out.writeInt(20 + 4*numWritten); 
    555       out.writeBytes("stsz"); 
    556  
    557       out.writeShort(0); // version 
    558       out.writeShort(0); // flags 
    559       out.writeInt(0); // sample size 
    560       out.writeInt(numWritten); // number of planes 
    561       for (int i=0; i<numWritten; i++) { 
    562         // sample size 
    563         out.writeInt(channels * height * (width + pad) * bytesPerPixel); 
    564       } 
    565  
    566       // -- write stco atom -- 
    567  
    568       out.writeInt(16 + 4*numWritten); 
    569       out.writeBytes("stco"); 
    570  
    571       out.writeShort(0); // version 
    572       out.writeShort(0); // flags 
    573       out.writeInt(numWritten); // number of planes 
    574       for (int i=0; i<numWritten; i++) { 
    575         // write the plane offset 
    576         out.writeInt(offsets.get(i)); 
    577       } 
    578  
    579       out.close(); 
    580244    } 
    581245  } 
     
    591255  // -- IFormatHandler API methods -- 
    592256 
     257  /* @see loci.formats.IFormatHandler#setId(String) */ 
     258  public void setId(String id) throws FormatException, IOException { 
     259    super.setId(id); 
     260    MetadataRetrieve r = getMetadataRetrieve(); 
     261    MetadataTools.verifyMinimumPopulated(r, series); 
     262 
     263    int width = r.getPixelsSizeX(series).getValue().intValue(); 
     264    int height = r.getPixelsSizeY(series).getValue().intValue(); 
     265    int nChannels = getSamplesPerPixel(); 
     266    int planeSize = width * height * nChannels; 
     267 
     268    pad = nChannels > 1 ? 0 : (4 - (width % 4)) % 4; 
     269 
     270    if (legacy == null) { 
     271      legacy = new LegacyQTWriter(); 
     272      legacy.setCodec(codec); 
     273      legacy.setMetadataRetrieve(r); 
     274    } 
     275    offsets = new Vector<Integer>(); 
     276    created = (int) System.currentTimeMillis(); 
     277    numBytes = 0; 
     278 
     279    if (out.length() == 0) { 
     280      // -- write the first header -- 
     281 
     282      writeAtom(8, "wide"); 
     283      writeAtom(numBytes + 8, "mdat"); 
     284    } 
     285    else { 
     286      out.seek(BYTE_COUNT_OFFSET); 
     287 
     288      RandomAccessInputStream in = new RandomAccessInputStream(currentId); 
     289      in.seek(BYTE_COUNT_OFFSET); 
     290      numBytes = (int) (in.readInt() & 0xffffffff) - 8; 
     291      in.close(); 
     292    } 
     293 
     294    for (int i=0; i<getPlaneCount(); i++) { 
     295      offsets.add(16 + i * (planeSize + pad * height)); 
     296    } 
     297  } 
     298 
    593299  /* @see loci.formats.IFormatHandler#close() */ 
    594300  public void close() throws IOException { 
    595     if (out != null) out.close(); 
    596     out = null; 
    597     numWritten = 0; 
    598     byteCountOffset = 0; 
     301    if (out != null) writeFooter(); 
     302    super.close(); 
    599303    numBytes = 0; 
    600304    created = 0; 
    601305    offsets = null; 
    602     currentId = null; 
    603     initialized = false; 
     306    pad = 0; 
    604307  } 
    605308 
     
    619322  } 
    620323 
     324  private void writeFooter() throws IOException { 
     325    out.seek(out.length()); 
     326    int numWritten = getPlaneCount(); 
     327    MetadataRetrieve r = getMetadataRetrieve(); 
     328    int width = r.getPixelsSizeX(series).getValue().intValue(); 
     329    int height = r.getPixelsSizeY(series).getValue().intValue(); 
     330    int nChannels = getSamplesPerPixel(); 
     331 
     332    int timeScale = 100; 
     333    int duration = numWritten * (timeScale / fps); 
     334    int bitsPerPixel = (nChannels > 1) ? 24 : 40; 
     335    int channels = (bitsPerPixel >= 40) ? 1 : 3; 
     336 
     337    // -- write moov atom -- 
     338 
     339    int atomLength = 685 + 8*numWritten; 
     340    writeAtom(atomLength, "moov"); 
     341 
     342    // -- write mvhd atom -- 
     343 
     344    writeAtom(108, "mvhd"); 
     345    out.writeShort(0); // version 
     346    out.writeShort(0); // flags 
     347    out.writeInt(created); // creation time 
     348    out.writeInt((int) System.currentTimeMillis()); 
     349    out.writeInt(timeScale); // time scale 
     350    out.writeInt(duration); // duration 
     351    out.write(new byte[] {0, 1, 0, 0});  // preferred rate & volume 
     352    out.write(new byte[] {0, -1, 0, 0, 0, 0, 0, 0, 0, 0}); // reserved 
     353 
     354    writeRotationMatrix(); 
     355 
     356    out.writeShort(0); // not sure what this is 
     357    out.writeInt(0); // preview duration 
     358    out.writeInt(0); // preview time 
     359    out.writeInt(0); // poster time 
     360    out.writeInt(0); // selection time 
     361    out.writeInt(0); // selection duration 
     362    out.writeInt(0); // current time 
     363    out.writeInt(2); // next track's id 
     364 
     365    // -- write trak atom -- 
     366 
     367    atomLength -= 116; 
     368    writeAtom(atomLength, "trak"); 
     369 
     370    // -- write tkhd atom -- 
     371 
     372    writeAtom(92, "tkhd"); 
     373    out.writeShort(0); // version 
     374    out.writeShort(15); // flags 
     375 
     376    out.writeInt(created); // creation time 
     377    out.writeInt((int) System.currentTimeMillis()); 
     378    out.writeInt(1); // track id 
     379    out.writeInt(0); // reserved 
     380 
     381    out.writeInt(duration); // duration 
     382    out.writeInt(0); // reserved 
     383    out.writeInt(0); // reserved 
     384    out.writeShort(0); // reserved 
     385    out.writeInt(0); // unknown 
     386 
     387    writeRotationMatrix(); 
     388 
     389    out.writeInt(width); // image width 
     390    out.writeInt(height); // image height 
     391    out.writeShort(0); // reserved 
     392 
     393    // -- write edts atom -- 
     394 
     395    writeAtom(36, "edts"); 
     396 
     397    // -- write elst atom -- 
     398 
     399    writeAtom(28, "elst"); 
     400 
     401    out.writeShort(0); // version 
     402    out.writeShort(0); // flags 
     403    out.writeInt(1); // number of entries in the table 
     404    out.writeInt(duration); // duration 
     405    out.writeShort(0); // time 
     406    out.writeInt(1); // rate 
     407    out.writeShort(0); // unknown 
     408 
     409    // -- write mdia atom -- 
     410 
     411    atomLength -= 136; 
     412    writeAtom(atomLength, "mdia"); 
     413 
     414    // -- write mdhd atom -- 
     415 
     416    writeAtom(32, "mdhd"); 
     417 
     418    out.writeShort(0); // version 
     419    out.writeShort(0); // flags 
     420    out.writeInt(created); // creation time 
     421    out.writeInt((int) System.currentTimeMillis()); 
     422    out.writeInt(timeScale); // time scale 
     423    out.writeInt(duration); // duration 
     424    out.writeShort(0); // language 
     425    out.writeShort(0); // quality 
     426 
     427    // -- write hdlr atom -- 
     428 
     429    writeAtom(58, "hdlr"); 
     430 
     431    out.writeShort(0); // version 
     432    out.writeShort(0); // flags 
     433    out.writeBytes("mhlr"); 
     434    out.writeBytes("vide"); 
     435    out.writeBytes("appl"); 
     436    out.write(new byte[] {16, 0, 0, 0, 0, 1, 1, 11, 25}); 
     437    out.writeBytes("Apple Video Media Handler"); 
     438 
     439    // -- write minf atom -- 
     440 
     441    atomLength -= 98; 
     442    writeAtom(atomLength, "minf"); 
     443 
     444    // -- write vmhd atom -- 
     445 
     446    writeAtom(20, "vmhd"); 
     447 
     448    out.writeShort(0); // version 
     449    out.writeShort(1); // flags 
     450    out.writeShort(64); // graphics mode 
     451    out.writeShort(32768);  // opcolor 1 
     452    out.writeShort(32768);  // opcolor 2 
     453    out.writeShort(32768);  // opcolor 3 
     454 
     455    // -- write hdlr atom -- 
     456 
     457    writeAtom(57, "hdlr"); 
     458 
     459    out.writeShort(0); // version 
     460    out.writeShort(0); // flags 
     461    out.writeBytes("dhlr"); 
     462    out.writeBytes("alis"); 
     463    out.writeBytes("appl"); 
     464    out.write(new byte[] {16, 0, 0, 1, 0, 1, 1, 31, 24}); 
     465    out.writeBytes("Apple Alias Data Handler"); 
     466 
     467    // -- write dinf atom -- 
     468 
     469    writeAtom(36, "dinf"); 
     470 
     471    // -- write dref atom -- 
     472 
     473    writeAtom(28, "dref"); 
     474 
     475    out.writeShort(0); // version 
     476    out.writeShort(0); // flags 
     477    out.writeShort(0); // version 2 
     478    out.writeShort(1); // flags 2 
     479    out.write(new byte[] {0, 0, 0, 12}); 
     480    out.writeBytes("alis"); 
     481    out.writeShort(0); // version 3 
     482    out.writeShort(1); // flags 3 
     483 
     484    // -- write stbl atom -- 
     485 
     486    atomLength -= 121; 
     487    writeAtom(atomLength, "stbl"); 
     488 
     489    // -- write stsd atom -- 
     490 
     491    writeAtom(118, "stsd"); 
     492 
     493    out.writeShort(0); // version 
     494    out.writeShort(0); // flags 
     495    out.writeInt(1); // number of entries in the table 
     496    out.write(new byte[] {0, 0, 0, 102}); 
     497    out.writeBytes("raw "); // codec 
     498    out.write(new byte[] {0, 0, 0, 0, 0, 0});  // reserved 
     499    out.writeShort(1); // data reference 
     500    out.writeShort(1); // version 
     501    out.writeShort(1); // revision 
     502    out.writeBytes("appl"); 
     503    out.writeInt(0); // temporal quality 
     504    out.writeInt(768); // spatial quality 
     505    out.writeShort(width); // image width 
     506    out.writeShort(height); // image height 
     507    byte[] dpi = new byte[] {0, 72, 0, 0}; 
     508    out.write(dpi); // horizontal dpi 
     509    out.write(dpi); // vertical dpi 
     510    out.writeInt(0); // data size 
     511    out.writeShort(1); // frames per sample 
     512    out.writeShort(12); // length of compressor name 
     513    out.writeBytes("Uncompressed"); // compressor name 
     514    out.writeInt(bitsPerPixel); // unknown 
     515    out.writeInt(bitsPerPixel); // unknown 
     516    out.writeInt(bitsPerPixel); // unknown 
     517    out.writeInt(bitsPerPixel); // unknown 
     518    out.writeInt(bitsPerPixel); // unknown 
     519    out.writeShort(bitsPerPixel); // bits per pixel 
     520    out.writeInt(65535); // ctab ID 
     521    out.write(new byte[] {12, 103, 97, 108}); // gamma 
     522    out.write(new byte[] {97, 1, -52, -52, 0, 0, 0, 0}); // unknown 
     523 
     524    // -- write stts atom -- 
     525 
     526    writeAtom(24, "stts"); 
     527 
     528    out.writeShort(0); // version 
     529    out.writeShort(0); // flags 
     530    out.writeInt(1); // number of entries in the table 
     531    out.writeInt(numWritten); // number of planes 
     532    out.writeInt(fps); // frames per second 
     533 
     534    // -- write stsc atom -- 
     535 
     536    writeAtom(28, "stsc"); 
     537 
     538    out.writeShort(0); // version 
     539    out.writeShort(0); // flags 
     540    out.writeInt(1); // number of entries in the table 
     541    out.writeInt(1); // chunk 
     542    out.writeInt(1); // samples 
     543    out.writeInt(1); // id 
     544 
     545    // -- write stsz atom -- 
     546 
     547    writeAtom(20 + 4 * numWritten, "stsz"); 
     548 
     549    out.writeShort(0); // version 
     550    out.writeShort(0); // flags 
     551    out.writeInt(0); // sample size 
     552    out.writeInt(numWritten); // number of planes 
     553    for (int i=0; i<numWritten; i++) { 
     554      // sample size 
     555      out.writeInt(channels * height * (width + pad)); 
     556    } 
     557 
     558    // -- write stco atom -- 
     559 
     560    writeAtom(16 + 4 * numWritten, "stco"); 
     561 
     562    out.writeShort(0); // version 
     563    out.writeShort(0); // flags 
     564    out.writeInt(numWritten); // number of planes 
     565    for (int i=0; i<numWritten; i++) { 
     566      // write the plane offset 
     567      out.writeInt(offsets.get(i)); 
     568    } 
     569  } 
     570 
     571  /** Write the 3x3 matrix that describes how to rotate the image. */ 
     572  private void writeRotationMatrix() throws IOException { 
     573    out.writeInt(1); 
     574    out.writeInt(0); 
     575    out.writeInt(0); 
     576    out.writeInt(0); 
     577    out.writeInt(1); 
     578    out.writeInt(0); 
     579    out.writeInt(0); 
     580    out.writeInt(0); 
     581    out.writeInt(16384); 
     582  } 
     583 
     584  /** Write the atom length and type. */ 
     585  private void writeAtom(int length, String type) throws IOException { 
     586    out.writeInt(length); 
     587    out.writeBytes(type); 
     588  } 
     589 
    621590} 
  • trunk/components/bio-formats/src/loci/formats/out/TiffWriter.java

    r6230 r6294  
    5858  // -- Fields -- 
    5959 
    60   /** Current output stream. */ 
    61   protected RandomAccessOutputStream out; 
    62  
    6360  /** Whether or not the output file is a BigTIFF file. */ 
    6461  protected boolean isBigTiff; 
     
    9390   * the last flag must be set. 
    9491   */ 
    95   public void saveBytes(byte[] buf, IFD ifd, boolean last) 
     92  public void saveBytes(int no, byte[] buf, IFD ifd) 
    9693    throws IOException, FormatException 
    9794  { 
    98     saveBytes(buf, ifd, 0, last, last); 
     95    MetadataRetrieve r = getMetadataRetrieve(); 
     96    int w = r.getPixelsSizeX(series).getValue().intValue(); 
     97    int h = r.getPixelsSizeY(series).getValue().intValue(); 
     98    saveBytes(no, buf, ifd, 0, 0, w, h); 
    9999  } 
    100100 
     
    106106   * file, the last flag must be set. 
    107107   */ 
    108   public void saveBytes(byte[] buf, IFD ifd, int series, 
    109     boolean lastInSeries, boolean last) throws IOException, FormatException 
     108  public void saveBytes(int no, byte[] buf, IFD ifd, int x, int y, int w, int h) 
     109    throws IOException, FormatException 
    110110  { 
     111    checkParams(no, buf, x, y, w, h); 
    111112    MetadataRetrieve retrieve = getMetadataRetrieve(); 
    112     MetadataTools.verifyMinimumPopulated(retrieve, series); 
    113113    Boolean bigEndian = retrieve.getPixelsBinDataBigEndian(series, 0); 
    114114    boolean littleEndian = bigEndian == null ? 
    115115      false : !bigEndian.booleanValue(); 
    116116 
    117     if (initialized) { 
    118       tiffSaver = new TiffSaver(out); 
    119       tiffSaver.setLittleEndian(littleEndian); 
    120       tiffSaver.setBigTiff(isBigTiff); 
    121     } 
    122  
    123     if (!initialized) { 
    124       initialized = true; 
    125       out = new RandomAccessOutputStream(currentId); 
    126       tiffSaver = new TiffSaver(out); 
    127       tiffSaver.setLittleEndian(littleEndian); 
    128       tiffSaver.setBigTiff(isBigTiff); 
     117    tiffSaver = new TiffSaver(out); 
     118    tiffSaver.setLittleEndian(littleEndian); 
     119    tiffSaver.setBigTiff(isBigTiff); 
     120 
     121    if (!initialized[series][no]) { 
     122      initialized[series][no] = true; 
    129123 
    130124      RandomAccessInputStream tmp = new RandomAccessInputStream(currentId); 
     
    137131    int width = retrieve.getPixelsSizeX(series).getValue().intValue(); 
    138132    int height = retrieve.getPixelsSizeY(series).getValue().intValue(); 
    139     Integer channels = retrieve.getChannelSamplesPerPixel(series, 0); 
    140     if (channels == null) { 
    141       LOGGER.warn("SamplesPerPixel #0 is null.  It is assumed to be 1."); 
    142     } 
    143     int c = channels == null ? 1 : channels.intValue(); 
     133    int c = getSamplesPerPixel(); 
    144134    int type = FormatTools.pixelTypeFromString( 
    145135      retrieve.getPixelsType(series).toString()); 
     
    158148          false, interleaved); 
    159149 
    160         saveBytes(b, ifd, series, lastInSeries && i == c - 1, 
    161           last && i == c - 1); 
     150        saveBytes(no, b, ifd, x, y, w, h); 
    162151      } 
    163152      return; 
     
    189178    out.seek(out.length()); 
    190179    ifd.putIFDValue(IFD.PLANAR_CONFIGURATION, interleaved ? 1 : 2); 
    191     tiffSaver.writeImage(buf, ifd, last, type); 
    192     if (last) close(); 
     180    tiffSaver.writeImage(buf, ifd, no, type, x, y, w, h, 
     181      no == getPlaneCount() - 1); 
    193182  } 
    194183 
    195184  // -- IFormatWriter API methods -- 
    196185 
    197   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    198   public void saveBytes(byte[] buf, int series, boolean lastInSeries, 
    199     boolean last) throws FormatException, IOException 
     186  /** 
     187   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     188   */ 
     189  public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) 
     190    throws FormatException, IOException 
    200191  { 
    201     IFD h = new IFD(); 
     192    IFD ifd = new IFD(); 
    202193    if (compression == null) compression = ""; 
    203194    TiffCompression compressType = TiffCompression.UNCOMPRESSED; 
     
    214205      compressType = TiffCompression.JPEG; 
    215206    } 
    216     h.put(new Integer(IFD.COMPRESSION), compressType.getCode()); 
    217     saveBytes(buf, h, series, lastInSeries, last); 
     207    ifd.put(new Integer(IFD.COMPRESSION), compressType.getCode()); 
     208    saveBytes(no, buf, ifd, x, y, w, h); 
    218209  } 
    219210 
     
    229220  } 
    230221 
    231   // -- IFormatHandler API methods -- 
    232  
    233   /* @see loci.formats.IFormatHandler#close() */ 
    234   public void close() throws IOException { 
    235     if (out != null) out.close(); 
    236     out = null; 
    237     currentId = null; 
    238     initialized = false; 
    239   } 
    240  
    241222  // -- TiffWriter API methods -- 
    242223 
  • trunk/components/bio-formats/src/loci/formats/tiff/TiffSaver.java

    r6128 r6294  
    141141    for (int i=0; i<ifds.size(); i++) { 
    142142      if (i < buf.length) { 
    143         writeImage(buf[i], ifds.get(i), i == ifds.size() - 1, pixelType); 
     143        writeImage(buf[i], ifds.get(i), i, pixelType, i == ifds.size() - 1); 
    144144      } 
    145145    } 
     
    148148  /** 
    149149   */ 
    150   public void writeImage(byte[] buf, IFD ifd, boolean last, int pixelType) 
     150  public void writeImage(byte[] buf, IFD ifd, int no, int pixelType, 
     151    boolean last) 
     152    throws FormatException, IOException 
     153  { 
     154    int w = (int) ifd.getImageWidth(); 
     155    int h = (int) ifd.getImageLength(); 
     156    writeImage(buf, ifd, no, pixelType, 0, 0, w, h, last); 
     157  } 
     158 
     159  /** 
     160   */ 
     161  public void writeImage(byte[] buf, IFD ifd, int no, int pixelType, int x, 
     162    int y, int w, int h, boolean last) 
    151163    throws FormatException, IOException 
    152164  { 
     
    197209 
    198210    // write pixel strips to output buffers 
    199     for (int y=0; y<height; y++) { 
    200       int strip = y / rowsPerStrip; 
    201       for (int x=0; x<width; x++) { 
    202         int ndx = y * width * bytesPerPixel + x * bytesPerPixel; 
     211    for (int row=0; row<height; row++) { 
     212      int strip = row / rowsPerStrip; 
     213      for (int col=0; col<width; col++) { 
     214        int ndx = row * width * bytesPerPixel + col * bytesPerPixel; 
    203215        for (int c=0; c<nChannels; c++) { 
    204216          for (int n=0; n<bps[c]/8; n++) { 
     
    246258    } 
    247259    long endFP = out.getFilePointer(); 
    248     if (last) endFP = 0; 
    249  
    250260    out.seek(fp); 
    251     writeIFD(ifd, endFP); 
     261    writeIFD(ifd, last ? 0 : endFP); 
    252262  } 
    253263 
  • trunk/components/bio-formats/src/loci/formats/tools/ImageConverter.java

    r6182 r6294  
    230230    for (int q=first; q<last; q++) { 
    231231      reader.setSeries(q); 
     232      writer.setSeries(q); 
    232233      writer.setInterleaved(reader.isInterleaved()); 
    233234      int numImages = writer.canDoStacks() ? reader.getImageCount() : 1; 
     
    246247        } 
    247248        long m = System.currentTimeMillis(); 
    248         boolean lastInSeries = i == numImages - 1; 
    249         writer.saveBytes(buf, q, lastInSeries, q == last - 1 && lastInSeries); 
     249        writer.saveBytes(i, buf); 
    250250        long e = System.currentTimeMillis(); 
    251251        read += m - s; 
  • trunk/components/bio-formats/utils/ConvertToOmeTiff.java

    r6038 r6294  
    4747      for (int s=0; s<seriesCount; s++) { 
    4848        reader.setSeries(s); 
     49        writer.setSeries(s); 
    4950        int planeCount = reader.getImageCount(); 
    5051        for (int p=0; p<planeCount; p++) { 
    5152          byte[] plane = reader.openBytes(p); 
    5253          // write plane to output file 
    53           writer.saveBytes(plane, s, p == planeCount - 1, 
    54             (p == planeCount - 1) && (s == seriesCount - 1)); 
     54          writer.saveBytes(p, plane); 
    5555          System.out.print("."); 
    5656        } 
  • trunk/components/bio-formats/utils/MakeLZW.java

    r6038 r6294  
    3939        System.out.print("."); 
    4040        byte[] plane = reader.openBytes(p); 
    41         writer.saveBytes(plane, p == planeCount - 1); 
     41        writer.saveBytes(p, plane); 
    4242      } 
    4343      System.out.println(" [done]"); 
  • trunk/components/bio-formats/utils/MinimumWriter.java

    r6241 r6294  
    6363    writer.setMetadataRetrieve(meta); 
    6464    writer.setId(id); 
    65     writer.saveBytes(img, true); 
     65    writer.saveBytes(0, img); 
    6666    writer.close(); 
    6767 
  • trunk/components/bio-formats/utils/ReadWriteInMemory.java

    r6038 r6294  
    100100        reader.openBytes(i, plane); 
    101101      } 
    102       writer.saveBytes(plane, i == imageCount - 1); 
     102      writer.saveBytes(i, plane); 
    103103      System.out.print("."); 
    104104    } 
  • trunk/components/bio-formats/utils/SewTiffs.java

    r6038 r6294  
    7777          ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, desc); 
    7878          comment = true; 
    79           out.saveBytes(image, ifd, t == num - 1); 
     79          out.saveBytes(t, image, ifd); 
    8080          System.out.print("."); 
    8181          continue; 
     
    8484 
    8585      // write image plane 
    86       out.saveBytes(image, t == num - 1); 
     86      out.saveBytes(t, image); 
    8787 
    8888      // update status 
  • trunk/components/bio-formats/utils/WriteRGBMovie.java

    r6241 r6294  
    7070    for (int t=0; t<numFrames; t++) { 
    7171      System.out.print("."); 
    72       writer.saveBytes(img[t], t == numFrames - 1); 
     72      writer.saveBytes(t, img[t]); 
    7373    } 
    7474    writer.close(); 
  • trunk/components/common/src/loci/common/RandomAccessOutputStream.java

    r6050 r6294  
    9696  } 
    9797 
     98  /** Writes the given string followed by a newline character. */ 
     99  public void writeLine(String s) throws IOException { 
     100    writeBytes(s); 
     101    writeBytes("\n"); 
     102  } 
     103 
    98104  // -- DataOutput API methods -- 
    99105 
  • trunk/components/legacy/ome-editor/src/loci/ome/editor/MetadataPane.java

    r6234 r6294  
    519519        // write plane to output file 
    520520        try { 
    521           writer.saveBytes(plane, ifd, i == imageCount - 1); 
     521          writer.saveBytes(i, plane, ifd); 
    522522        } 
    523523        catch (Exception exc) { 
     
    576576      try { 
    577577        writer.setId(outId); 
    578         writer.saveBytes(plane, ifd, i == imageCount - 1); 
     578        writer.saveBytes(i, plane, ifd); 
    579579      } 
    580580      catch (Exception exc) { 
  • trunk/components/ome-io/src/loci/ome/io/OMEWriter.java

    r6234 r6294  
    114114  // -- IFormatWriter API methods -- 
    115115 
    116   /* @see loci.formats.IFormatWriter#saveBytes(byte[], int, boolean, boolean) */ 
    117   public void saveBytes(byte[] bytes, int series, boolean lastInSeries, 
    118     boolean last) 
     116  /** 
     117   * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, int) 
     118   */ 
     119  public void saveBytes(int no, byte[] bytes, int x, int y, int w, int h) 
    119120    throws FormatException, IOException 
    120121  { 
     
    187188    } 
    188189 
    189     int x = metadataRetrieve.getPixelsSizeX(series).getValue().intValue(); 
    190     int y = metadataRetrieve.getPixelsSizeY(series).getValue().intValue(); 
     190    int sizeX = metadataRetrieve.getPixelsSizeX(series).getValue().intValue(); 
     191    int sizeY = metadataRetrieve.getPixelsSizeY(series).getValue().intValue(); 
    191192    int z = metadataRetrieve.getPixelsSizeZ(series).getValue().intValue(); 
    192193    int c = metadataRetrieve.getPixelsSizeC(series).getValue().intValue(); 
     
    203204      r.exec("is = ImageServer.getHTTPImageServer(omeis, sessionKey)"); 
    204205      if (credentials.imageID == -1) { 
    205         r.setVar("x", x); 
    206         r.setVar("y", y); 
     206        r.setVar("x", sizeX); 
     207        r.setVar("y", sizeY); 
    207208        r.setVar("z", z); 
    208209        r.setVar("c", c); 
     
    221222 
    222223    try { 
    223       int planeLength = x * y * bpp; 
     224      int planeLength = sizeX * sizeY * bpp; 
    224225      int nChannels = bytes.length / planeLength; 
    225226 
     
    246247    } 
    247248 
    248     if (lastInSeries) { 
     249    if (series == metadataRetrieve.getImageCount() - 1) { 
    249250      try { 
    250251        r.exec("pixelsId = is.finishPixels(pixelsId)"); 
     
    373374      credentials.imageID = -1; 
    374375    } 
    375  
    376     if (last) close(); 
    377376  } 
    378377 
     
    542541    for (int s=start; s<end; s++) { 
    543542      reader.setSeries(s); 
     543      uploader.setSeries(s); 
    544544      for (int i=0; i<reader.getImageCount(); i++) { 
    545         boolean last = i == reader.getImageCount() - 1; 
    546         uploader.saveBytes(reader.openBytes(i), s, last, 
    547           last && s == end - 1); 
     545        uploader.saveBytes(i, reader.openBytes(i)); 
    548546      } 
    549547    } 
  • trunk/components/ome-plugins/src/loci/plugins/ome/LociUploader.java

    r6234 r6294  
    253253        } 
    254254 
    255         ul.saveBytes(toUpload, i == is.getSize() - 1); 
     255        ul.saveBytes(i, toUpload); 
    256256      } 
    257257 
  • trunk/components/test-suite/src/loci/tests/testng/FormatWriterTest.java

    r6026 r6294  
    197197      for (int series=0; series<seriesCount; series++) { 
    198198        reader.setSeries(series); 
    199         boolean lastSeries = series == seriesCount - 1; 
     199        writer.setSeries(series); 
    200200        int imageCount = writer.canDoStacks() ? reader.getImageCount() : 1; 
    201201        for (int image=0; image<imageCount; image++) { 
    202           boolean lastImage = image == imageCount - 1; 
    203           writer.saveBytes(reader.openBytes(image), series, 
    204             lastImage, lastImage && lastSeries); 
     202          writer.saveBytes(image, reader.openBytes(image)); 
    205203        } 
    206204      } 
Note: See TracChangeset for help on using the changeset viewer.