Changeset 2001


Ignore:
Timestamp:
01/03/07 12:01:19 (13 years ago)
Author:
melissa
Message:

Added close method to IFormatWriter API; tweaked most readers to either
explicitly support > 1 bytes per pixel, or throw an exception.

Location:
trunk/loci/formats
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/IFormatWriter.java

    r1630 r2001  
    3939    throws FormatException, IOException; 
    4040 
     41  /** Closes open files */ 
     42  void close() throws FormatException, IOException; 
     43 
    4144  /** Reports whether the writer can save multiple images to a single file. */ 
    4245  boolean canDoStacks(String id) throws FormatException; 
  • trunk/loci/formats/ImageWriter.java

    r1967 r2001  
    188188  } 
    189189 
     190  /* @see IFormatWriter#close() */ 
     191  public void close() throws FormatException, IOException { 
     192    getWriter(currentId).close(); 
     193  } 
     194 
    190195  /* @see IFormatWriter#canDoStacks(String) */ 
    191196  public boolean canDoStacks(String id) throws FormatException { 
  • trunk/loci/formats/TiffTools.java

    r1989 r2001  
    2626 
    2727import java.awt.image.BufferedImage; 
     28import java.awt.image.DataBuffer; 
    2829import java.io.*; 
    2930import java.lang.reflect.Array; 
     
    20752076    if (DEBUG) debug("writeImage (offset=" + offset + "; last=" + last + ")"); 
    20762077 
    2077     // get pixels 
    2078  
    2079     //Object data = ImageTools.getPixels(img); 
    2080  
    2081     /* 
    2082     int[][] values = new int[0][0]; 
    2083  
    2084     if (data instanceof byte[][]) { 
    2085       byte[][] pix = (byte[][]) data; 
    2086       values = new int[pix.length][pix[0].length]; 
    2087       for (int i=0; i<pix.length; i++) { 
    2088         for (int j=0; j<pix[i].length; j++) { 
    2089           values[i][j] = (int) pix[i][j]; 
    2090         } 
    2091       } 
    2092     } 
    2093     else if (data instanceof short[][]) { 
    2094       short[][] pix = (short[][]) data; 
    2095       values = new int[pix.length][pix[0].length]; 
    2096       for (int i=0; i<pix.length; i++) { 
    2097         for (int j=0; j<pix[i].length; j++) { 
    2098           values[i][j] = (int) pix[i][j]; 
    2099         } 
    2100       } 
    2101     } 
    2102     else if (data instanceof int[][]) { 
    2103       values = (int[][]) data; 
    2104     } 
    2105     else { 
    2106       // should add cases for float/double data...later 
    2107       throw new FormatException("data type not supported"); 
    2108     } 
    2109     */ 
    2110  
    2111     byte[][] values = ImageTools.getBytes(img); 
     2078    byte[][] values = ImageTools.getPixelBytes(img, false); 
    21122079 
    21132080    int width = img.getWidth(); 
     
    21242091      }; 
    21252092    } 
     2093   
     2094    int bytesPerPixel = values[0].length / (width * height); 
    21262095 
    21272096    // populate required IFD directory entries (except strip information) 
     
    21302099    putIFDValue(ifd, IMAGE_LENGTH, height); 
    21312100    if (getIFDValue(ifd, BITS_PER_SAMPLE) == null) { 
    2132       int max = 0; 
    2133       for (int c=0; c<values.length; c++) { 
    2134         for (int ndx=0; ndx<values[c].length; ndx++) { 
    2135           int v = values[c][ndx]; 
    2136           int iv = v; 
    2137           if (v != iv) { 
    2138             throw new FormatException("Sample #" + ndx + 
    2139               " of range component #" + c + " is not an integer (" + v + ")"); 
    2140           } 
    2141           if (iv > max) max = iv; 
    2142         } 
    2143       } 
    2144       int bps = max < 256 ? 8 : (max < 65536 ? 16 : 32); 
     2101      int bps = 8 * bytesPerPixel; 
    21452102      int[] bpsArray = new int[values.length]; 
    21462103      Arrays.fill(bpsArray, bps); 
    21472104      putIFDValue(ifd, BITS_PER_SAMPLE, bpsArray); 
    21482105    } 
     2106    if (img.getRaster().getTransferType() == DataBuffer.TYPE_FLOAT) { 
     2107      putIFDValue(ifd, SAMPLE_FORMAT, 3); 
     2108    } 
    21492109    if (getIFDValue(ifd, COMPRESSION) == null) { 
    21502110      putIFDValue(ifd, COMPRESSION, UNCOMPRESSED); 
     
    21712131    // create pixel output buffers 
    21722132    int stripSize = 8192; 
    2173     int rowsPerStrip = stripSize / width; 
     2133    int rowsPerStrip = stripSize / (width * bytesPerPixel); 
    21742134    int stripsPerImage = (height + rowsPerStrip - 1) / rowsPerStrip; 
    21752135    int[] bps = (int[]) getIFDValue(ifd, BITS_PER_SAMPLE, true, int[].class); 
     
    21862146      int strip = y / rowsPerStrip; 
    21872147      for (int x=0; x<width; x++) { 
    2188         int ndx = y * width + x; 
     2148        int ndx = y * width * bytesPerPixel + x * bytesPerPixel; 
    21892149        for (int c=0; c<values.length; c++) { 
    21902150          int q = values[c][ndx]; 
    21912151          if (bps[c] == 8) stripOut[strip].writeByte(q); 
    2192           else if (bps[c] == 16) stripOut[strip].writeShort(q); 
    2193           else if (bps[c] == 32) stripOut[strip].writeInt(q); 
     2152          else if (bps[c] == 16) { 
     2153            stripOut[strip].writeByte(q); 
     2154            stripOut[strip].writeByte(values[c][ndx+1]); 
     2155          } 
     2156          else if (bps[c] == 32) { 
     2157            for (int i=0; i<4; i++) { 
     2158              stripOut[strip].writeByte(values[c][ndx + i]); 
     2159            } 
     2160          } 
    21942161          else { 
    21952162            throw new FormatException("Unsupported bits per sample value (" + 
  • trunk/loci/formats/out/AVIWriter.java

    r1629 r2001  
    512512  } 
    513513 
     514  /* @see IFormatWriter#close() */ 
     515  public void close() throws FormatException, IOException { 
     516    if (raFile != null) raFile.close(); 
     517    raFile = null; 
     518    currentId = null; 
     519  } 
     520 
    514521  /** Reports whether the writer can save multiple images to a single file. */ 
    515522  public boolean canDoStacks(String id) { return true; } 
  • trunk/loci/formats/out/EPSWriter.java

    r1629 r2001  
    144144  } 
    145145 
     146  /* @see IFormatWriter#close() */ 
     147  public void close() throws FormatException, IOException { 
     148    if (out != null) out.close(); 
     149    out = null; 
     150    currentId = null; 
     151  } 
     152 
    146153  /** Reports whether the writer can save multiple images to a single file. */ 
    147154  public boolean canDoStacks(String id) { return false; } 
  • trunk/loci/formats/out/ImageIOWriter.java

    r1629 r2001  
    4545 
    4646  protected String kind; 
     47  protected DataOutputStream out; 
    4748 
    4849  // -- Constructors -- 
     
    7677    BufferedImage img = (cm == null) ? 
    7778      ImageTools.makeBuffered(image) : ImageTools.makeBuffered(image, cm); 
    78     ImageIO.write(img, kind, new DataOutputStream( 
    79       new BufferedOutputStream(new FileOutputStream(id), 4096))); 
     79    if (ImageTools.getPixelType(img) == FormatReader.FLOAT) { 
     80      throw new FormatException("Floating point data not supported."); 
     81    } 
     82    out = new DataOutputStream(new BufferedOutputStream( 
     83      new FileOutputStream(id), 4096)); 
     84    ImageIO.write(img, kind, out);  
     85  } 
     86 
     87  /* @see IFormatWriter#close() */ 
     88  public void close() throws FormatException, IOException { 
     89    if (out != null) out.close(); 
     90    out = null; 
     91    currentId = null; 
    8092  } 
    8193 
  • trunk/loci/formats/out/JPEGWriter.java

    r1629 r2001  
    2525package loci.formats.out; 
    2626 
     27import java.awt.Image; 
     28import java.awt.image.BufferedImage; 
    2729import java.io.IOException; 
    28 import loci.formats.FormatException; 
     30import loci.formats.*; 
    2931 
    3032/** JPEGWriter is the file format writer for JPEG files. */ 
     
    3840  } 
    3941 
     42  // -- FormatWriter API methods -- 
     43 
     44  /* @see ImageIOWriter#save(String, Image, boolean) */ 
     45  public void save(String id, Image image, boolean last) 
     46    throws FormatException, IOException 
     47  { 
     48    BufferedImage img = (cm == null) ? 
     49      ImageTools.makeBuffered(image) : ImageTools.makeBuffered(image, cm); 
     50    int type = ImageTools.getPixelType(img); 
     51    if (type == FormatReader.UINT16 || type == FormatReader.INT16) { 
     52      throw new FormatException("16-bit data not supported."); 
     53    } 
     54    super.save(id, image, last); 
     55  } 
     56 
    4057  // -- Main method -- 
    4158 
  • trunk/loci/formats/out/LegacyQTWriter.java

    r1264 r2001  
    276276  } 
    277277 
     278  /* @see IFormatWriter#close() */ 
     279  public void close() throws FormatException, IOException { 
     280    r = null; 
     281    numWritten = 0; 
     282    width = 0; 
     283    height = 0; 
     284    pixels2 = null; 
     285  } 
     286 
    278287  /** Reports whether the writer can save multiple images to a single file. */ 
    279288  public boolean canDoStacks(String id) { return true; } 
  • trunk/loci/formats/out/QTWriter.java

    r1629 r2001  
    178178 
    179179    // retrieve pixel data for this plane 
    180     byte[][] byteData = ImageTools.getBytes(img); 
     180    byte[][] byteData = ImageTools.getPixelBytes(img, false); 
    181181 
    182182    // need to check if the width is a multiple of 8 
     
    187187    pad = (4 - pad) % 4; 
    188188 
     189    int bytesPerPixel = byteData[0].length / (width * height); 
     190     
     191    if (bytesPerPixel > 1) { 
     192      throw new FormatException("Unsupported bits per pixel : " +  
     193        (8 * bytesPerPixel) + "."); 
     194    } 
     195     
     196    pad *= bytesPerPixel; 
     197 
    189198    byte[][] temp = byteData; 
    190199    byteData = new byte[temp.length][temp[0].length + height*pad]; 
    191200 
     201    int rowLength = width * bytesPerPixel; 
    192202    for (int oldScanline=0; oldScanline<height; oldScanline++) { 
    193203      for (int k=0; k<temp.length; k++) { 
    194         System.arraycopy(temp[k], oldScanline*width, byteData[k], 
    195           oldScanline*(width+pad), width); 
    196  
    197         // add padding bytes 
    198  
    199         for (int i=0; i<pad; i++) { 
    200           byteData[k][oldScanline*(width+pad) + width + i] = 0; 
    201         } 
     204        System.arraycopy(temp[k], oldScanline*rowLength, byteData[k], 
     205          oldScanline*(rowLength + pad), rowLength); 
    202206      } 
    203207    } 
     
    207211    // but needs to be reversed in QTReader 
    208212 
    209     if (byteData.length == 1) { 
     213    if (byteData.length == 1 && bytesPerPixel == 1) { 
    210214      for (int i=0; i<byteData.length; i++) { 
    211215        for (int k=0; k<byteData[0].length; k++) { 
     
    216220 
    217221    if (!id.equals(currentId)) { 
     222      close(); 
    218223      setCodec(); 
    219224      if (codec != 0) { 
     
    245250      DataTools.writeString(out, "mdat"); 
    246251 
    247       for (int i=0; i<byteData[0].length; i++) { 
    248         for (int j=0; j<byteData.length; j++) { 
    249           out.write(byteData[j][i]); 
    250         } 
     252      for (int i=0; i<byteData.length; i++) { 
     253        out.write(byteData[i]); 
    251254      } 
    252255 
     
    262265      // write this plane's pixel data 
    263266      out.seek(out.length()); 
    264  
    265       for (int i=0; i<byteData[0].length; i++) { 
    266         for (int j=0; j<byteData.length; j++) { 
    267           out.write(byteData[j][i]); 
    268         } 
     267     
     268      for (int i=0; i<byteData.length; i++) { 
     269        out.write(byteData[i]); 
    269270      } 
    270271 
     
    276277      int timeScale = 100; 
    277278      int duration = numWritten * (timeScale / fps); 
    278       int bitsPerPixel = (byteData.length > 1) ? 24 : 40; 
    279       int channels = (bitsPerPixel == 40) ? 1 : 3; 
     279      int bitsPerPixel = (byteData.length > 1) ? bytesPerPixel * 24 :  
     280        bytesPerPixel * 8 + 32; 
     281      int channels = (bitsPerPixel >= 40) ? 1 : 3; 
    280282 
    281283      // -- write moov atom -- 
     
    298300      out.write(new byte[] {0, -1, 0, 0, 0, 0, 0, 0, 0, 0}); // reserved 
    299301 
    300       // 3x3 matrix - unsure of significance 
     302      // 3x3 matrix - tells reader how to rotate image   
    301303 
    302304      DataTools.writeInt(out, 1, false); 
     
    343345 
    344346      DataTools.writeInt(out, 0, false); // unknown 
    345       // 3x3 matrix - unsure of significance 
     347 
     348      // 3x3 matrix - tells reader how to rotate the image  
    346349 
    347350      DataTools.writeInt(out, 1, false); 
     
    535538      for (int i=0; i<numWritten; i++) { 
    536539        // sample size 
    537         DataTools.writeInt(out, channels*height*(width+pad), false); 
     540        DataTools.writeInt(out, channels*height*(width+pad)*bytesPerPixel,  
     541          false); 
    538542      } 
    539543 
     
    553557      out.close(); 
    554558    } 
     559  } 
     560 
     561  /* @see IFormatWriter#close() */ 
     562  public void close() throws FormatException, IOException { 
     563    if (out != null) out.close(); 
     564    out = null; 
     565    numWritten = 0; 
     566    byteCountOffset = 0; 
     567    numBytes = 0; 
     568    created = 0; 
     569    offsets = null; 
    555570  } 
    556571 
  • trunk/loci/formats/out/TiffWriter.java

    r1629 r2001  
    6262  { 
    6363    if (!id.equals(currentId)) { 
    64       if (out != null) { 
    65         System.err.println("Warning: abandoning previous TIFF file (" + 
    66           currentId + ")"); 
    67         out.close(); 
    68       } 
     64      close(); 
    6965      currentId = id; 
    70       out = new BufferedOutputStream(new FileOutputStream(currentId), 4096); 
     66      out =  
     67        new BufferedOutputStream(new FileOutputStream(currentId, true), 4096); 
    7168      DataOutputStream dataOut = new DataOutputStream(out); 
    7269      dataOut.writeByte(TiffTools.BIG); 
     
    8279    lastOffset += TiffTools.writeImage(img, ifd, out, lastOffset, last); 
    8380    if (last) { 
    84       out.close(); 
    85       out = null; 
    86       currentId = null; 
     81      close(); 
    8782    } 
    8883  } 
     
    10499  } 
    105100 
     101  /* @see IFormatWriter#close() */ 
     102  public void close() throws FormatException, IOException { 
     103    if (out != null) out.close(); 
     104    out = null; 
     105    currentId = null; 
     106    lastOffset = 0; 
     107  } 
     108 
    106109  /** Reports whether the writer can save multiple images to a single file. */ 
    107110  public boolean canDoStacks(String id) { return true; } 
Note: See TracChangeset for help on using the changeset viewer.