Save This Page
Home » openjdk-7 » javax » imageio » [javadoc | source]
    1   /*
    2    * Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.imageio;
   27   
   28   import java.awt.Dimension;
   29   import java.awt.image.BufferedImage;
   30   
   31   /**
   32    * A class describing how a stream is to be decoded.  Instances of
   33    * this class or its subclasses are used to supply prescriptive
   34    * "how-to" information to instances of <code>ImageReader</code>.
   35    *
   36    * <p> An image encoded as part of a file or stream may be thought of
   37    * extending out in multiple dimensions: the spatial dimensions of
   38    * width and height, a number of bands, and a number of progressive
   39    * decoding passes.  This class allows a contiguous (hyper)rectangular
   40    * subarea of the image in all of these dimensions to be selected for
   41    * decoding.  Additionally, the spatial dimensions may be subsampled
   42    * discontinuously.  Finally, color and format conversions may be
   43    * specified by controlling the <code>ColorModel</code> and
   44    * <code>SampleModel</code> of the destination image, either by
   45    * providing a <code>BufferedImage</code> or by using an
   46    * <code>ImageTypeSpecifier</code>.
   47    *
   48    * <p> An <code>ImageReadParam</code> object is used to specify how an
   49    * image, or a set of images, will be converted on input from
   50    * a stream in the context of the Java Image I/O framework.  A plug-in for a
   51    * specific image format will return instances of
   52    * <code>ImageReadParam</code> from the
   53    * <code>getDefaultReadParam</code> method of its
   54    * <code>ImageReader</code> implementation.
   55    *
   56    * <p> The state maintained by an instance of
   57    * <code>ImageReadParam</code> is independent of any particular image
   58    * being decoded.  When actual decoding takes place, the values set in
   59    * the read param are combined with the actual properties of the image
   60    * being decoded from the stream and the destination
   61    * <code>BufferedImage</code> that will receive the decoded pixel
   62    * data.  For example, the source region set using
   63    * <code>setSourceRegion</code> will first be intersected with the
   64    * actual valid source area.  The result will be translated by the
   65    * value returned by <code>getDestinationOffset</code>, and the
   66    * resulting rectangle intersected with the actual valid destination
   67    * area to yield the destination area that will be written.
   68    *
   69    * <p> The parameters specified by an <code>ImageReadParam</code> are
   70    * applied to an image as follows.  First, if a rendering size has
   71    * been set by <code>setSourceRenderSize</code>, the entire decoded
   72    * image is rendered at the size given by
   73    * <code>getSourceRenderSize</code>.  Otherwise, the image has its
   74    * natural size given by <code>ImageReader.getWidth</code> and
   75    * <code>ImageReader.getHeight</code>.
   76    *
   77    * <p> Next, the image is clipped against the source region
   78    * specified by <code>getSourceXOffset</code>, <code>getSourceYOffset</code>,
   79    * <code>getSourceWidth</code>, and <code>getSourceHeight</code>.
   80    *
   81    * <p> The resulting region is then subsampled according to the
   82    * factors given in {@link IIOParam#setSourceSubsampling
   83    * <code>IIOParam.setSourceSubsampling</code>}.  The first pixel,
   84    * the number of pixels per row, and the number of rows all depend
   85    * on the subsampling settings.
   86    * Call the minimum X and Y coordinates of the resulting rectangle
   87    * (<code>minX</code>, <code>minY</code>), its width <code>w</code>
   88    * and its height <code>h</code>.
   89    *
   90    * <p> This rectangle is offset by
   91    * (<code>getDestinationOffset().x</code>,
   92    * <code>getDestinationOffset().y</code>) and clipped against the
   93    * destination bounds.  If no destination image has been set, the
   94    * destination is defined to have a width of
   95    * <code>getDestinationOffset().x</code> + <code>w</code>, and a
   96    * height of <code>getDestinationOffset().y</code> + <code>h</code> so
   97    * that all pixels of the source region may be written to the
   98    * destination.
   99    *
  100    * <p> Pixels that land, after subsampling, within the destination
  101    * image, and that are written in one of the progressive passes
  102    * specified by <code>getSourceMinProgressivePass</code> and
  103    * <code>getSourceNumProgressivePasses</code> are passed along to the
  104    * next step.
  105    *
  106    * <p> Finally, the source samples of each pixel are mapped into
  107    * destination bands according to the algorithm described in the
  108    * comment for <code>setDestinationBands</code>.
  109    *
  110    * <p> Plug-in writers may extend the functionality of
  111    * <code>ImageReadParam</code> by providing a subclass that implements
  112    * additional, plug-in specific interfaces.  It is up to the plug-in
  113    * to document what interfaces are available and how they are to be
  114    * used.  Readers will silently ignore any extended features of an
  115    * <code>ImageReadParam</code> subclass of which they are not aware.
  116    * Also, they may ignore any optional features that they normally
  117    * disable when creating their own <code>ImageReadParam</code>
  118    * instances via <code>getDefaultReadParam</code>.
  119    *
  120    * <p> Note that unless a query method exists for a capability, it must
  121    * be supported by all <code>ImageReader</code> implementations
  122    * (<i>e.g.</i> source render size is optional, but subsampling must be
  123    * supported).
  124    *
  125    *
  126    * @see ImageReader
  127    * @see ImageWriter
  128    * @see ImageWriteParam
  129    */
  130   public class ImageReadParam extends IIOParam {
  131   
  132       /**
  133        * <code>true</code> if this <code>ImageReadParam</code> allows
  134        * the source rendering dimensions to be set.  By default, the
  135        * value is <code>false</code>.  Subclasses must set this value
  136        * manually.
  137        *
  138        * <p> <code>ImageReader</code>s that do not support setting of
  139        * the source render size should set this value to
  140        * <code>false</code>.
  141        */
  142       protected boolean canSetSourceRenderSize = false;
  143   
  144       /**
  145        * The desired rendering width and height of the source, if
  146        * <code>canSetSourceRenderSize</code> is <code>true</code>, or
  147        * <code>null</code>.
  148        *
  149        * <p> <code>ImageReader</code>s that do not support setting of
  150        * the source render size may ignore this value.
  151        */
  152       protected Dimension sourceRenderSize = null;
  153   
  154       /**
  155        * The current destination <code>BufferedImage</code>, or
  156        * <code>null</code> if none has been set.  By default, the value
  157        * is <code>null</code>.
  158        */
  159       protected BufferedImage destination = null;
  160   
  161       /**
  162        * The set of destination bands to be used, as an array of
  163        * <code>int</code>s.  By default, the value is <code>null</code>,
  164        * indicating all destination bands should be written in order.
  165        */
  166       protected int[] destinationBands = null;
  167   
  168       /**
  169        * The minimum index of a progressive pass to read from the
  170        * source.  By default, the value is set to 0, which indicates
  171        * that passes starting with the first available pass should be
  172        * decoded.
  173        *
  174        * <p> Subclasses should ensure that this value is
  175        * non-negative.
  176        */
  177       protected int minProgressivePass = 0;
  178   
  179       /**
  180        * The maximum number of progressive passes to read from the
  181        * source.  By default, the value is set to
  182        * <code>Integer.MAX_VALUE</code>, which indicates that passes up
  183        * to and including the last available pass should be decoded.
  184        *
  185        * <p> Subclasses should ensure that this value is positive.
  186        * Additionally, if the value is not
  187        * <code>Integer.MAX_VALUE</code>, then <code>minProgressivePass +
  188        * numProgressivePasses - 1</code> should not exceed
  189        * <code>Integer.MAX_VALUE</code>.
  190        */
  191       protected int numProgressivePasses = Integer.MAX_VALUE;
  192   
  193       /**
  194        * Constructs an <code>ImageReadParam</code>.
  195        */
  196       public ImageReadParam() {}
  197   
  198       // Comment inherited
  199       public void setDestinationType(ImageTypeSpecifier destinationType) {
  200           super.setDestinationType(destinationType);
  201           setDestination(null);
  202       }
  203   
  204       /**
  205        * Supplies a <code>BufferedImage</code> to be used as the
  206        * destination for decoded pixel data.  The currently set image
  207        * will be written to by the <code>read</code>,
  208        * <code>readAll</code>, and <code>readRaster</code> methods, and
  209        * a reference to it will be returned by those methods.
  210        *
  211        * <p> Pixel data from the aforementioned methods will be written
  212        * starting at the offset specified by
  213        * <code>getDestinationOffset</code>.
  214        *
  215        * <p> If <code>destination</code> is <code>null</code>, a
  216        * newly-created <code>BufferedImage</code> will be returned by
  217        * those methods.
  218        *
  219        * <p> At the time of reading, the image is checked to verify that
  220        * its <code>ColorModel</code> and <code>SampleModel</code>
  221        * correspond to one of the <code>ImageTypeSpecifier</code>s
  222        * returned from the <code>ImageReader</code>'s
  223        * <code>getImageTypes</code> method.  If it does not, the reader
  224        * will throw an <code>IIOException</code>.
  225        *
  226        * @param destination the BufferedImage to be written to, or
  227        * <code>null</code>.
  228        *
  229        * @see #getDestination
  230        */
  231       public void setDestination(BufferedImage destination) {
  232           this.destination = destination;
  233       }
  234   
  235       /**
  236        * Returns the <code>BufferedImage</code> currently set by the
  237        * <code>setDestination</code> method, or <code>null</code>
  238        * if none is set.
  239        *
  240        * @return the BufferedImage to be written to.
  241        *
  242        * @see #setDestination
  243        */
  244       public BufferedImage getDestination() {
  245           return destination;
  246       }
  247   
  248       /**
  249        * Sets the indices of the destination bands where data
  250        * will be placed.  Duplicate indices are not allowed.
  251        *
  252        * <p> A <code>null</code> value indicates that all destination
  253        * bands will be used.
  254        *
  255        * <p> Choosing a destination band subset will not affect the
  256        * number of bands in the output image of a read if no destination
  257        * image is specified; the created destination image will still
  258        * have the same number of bands as if this method had never been
  259        * called.  If a different number of bands in the destination
  260        * image is desired, an image must be supplied using the
  261        * <code>ImageReadParam.setDestination</code> method.
  262        *
  263        * <p> At the time of reading or writing, an
  264        * <code>IllegalArgumentException</code> will be thrown by the
  265        * reader or writer if a value larger than the largest destination
  266        * band index has been specified, or if the number of source bands
  267        * and destination bands to be used differ.  The
  268        * <code>ImageReader.checkReadParamBandSettings</code> method may
  269        * be used to automate this test.
  270        *
  271        * @param destinationBands an array of integer band indices to be
  272        * used.
  273        *
  274        * @exception IllegalArgumentException if <code>destinationBands</code>
  275        * contains a negative or duplicate value.
  276        *
  277        * @see #getDestinationBands
  278        * @see #getSourceBands
  279        * @see ImageReader#checkReadParamBandSettings
  280        */
  281       public void setDestinationBands(int[] destinationBands) {
  282           if (destinationBands == null) {
  283               this.destinationBands = null;
  284           } else {
  285               int numBands = destinationBands.length;
  286               for (int i = 0; i < numBands; i++) {
  287                   int band = destinationBands[i];
  288                   if (band < 0) {
  289                       throw new IllegalArgumentException("Band value < 0!");
  290                   }
  291                   for (int j = i + 1; j < numBands; j++) {
  292                       if (band == destinationBands[j]) {
  293                           throw new IllegalArgumentException("Duplicate band value!");
  294                       }
  295                   }
  296               }
  297               this.destinationBands = (int[])destinationBands.clone();
  298           }
  299       }
  300   
  301       /**
  302        * Returns the set of band indices where data will be placed.
  303        * If no value has been set, <code>null</code> is returned to
  304        * indicate that all destination bands will be used.
  305        *
  306        * @return the indices of the destination bands to be used,
  307        * or <code>null</code>.
  308        *
  309        * @see #setDestinationBands
  310        */
  311       public int[] getDestinationBands() {
  312           if (destinationBands == null) {
  313               return null;
  314           } else {
  315               return (int[])(destinationBands.clone());
  316           }
  317       }
  318   
  319       /**
  320        * Returns <code>true</code> if this reader allows the source
  321        * image to be rendered at an arbitrary size as part of the
  322        * decoding process, by means of the
  323        * <code>setSourceRenderSize</code> method.  If this method
  324        * returns <code>false</code>, calls to
  325        * <code>setSourceRenderSize</code> will throw an
  326        * <code>UnsupportedOperationException</code>.
  327        *
  328        * @return <code>true</code> if setting source rendering size is
  329        * supported.
  330        *
  331        * @see #setSourceRenderSize
  332        */
  333       public boolean canSetSourceRenderSize() {
  334           return canSetSourceRenderSize;
  335       }
  336   
  337       /**
  338        * If the image is able to be rendered at an arbitrary size, sets
  339        * the source width and height to the supplied values.  Note that
  340        * the values returned from the <code>getWidth</code> and
  341        * <code>getHeight</code> methods on <code>ImageReader</code> are
  342        * not affected by this method; they will continue to return the
  343        * default size for the image.  Similarly, if the image is also
  344        * tiled the tile width and height are given in terms of the default
  345        * size.
  346        *
  347        * <p> Typically, the width and height should be chosen such that
  348        * the ratio of width to height closely approximates the aspect
  349        * ratio of the image, as returned from
  350        * <code>ImageReader.getAspectRatio</code>.
  351        *
  352        * <p> If this plug-in does not allow the rendering size to be
  353        * set, an <code>UnsupportedOperationException</code> will be
  354        * thrown.
  355        *
  356        * <p> To remove the render size setting, pass in a value of
  357        * <code>null</code> for <code>size</code>.
  358        *
  359        * @param size a <code>Dimension</code> indicating the desired
  360        * width and height.
  361        *
  362        * @exception IllegalArgumentException if either the width or the
  363        * height is negative or 0.
  364        * @exception UnsupportedOperationException if image resizing
  365        * is not supported by this plug-in.
  366        *
  367        * @see #getSourceRenderSize
  368        * @see ImageReader#getWidth
  369        * @see ImageReader#getHeight
  370        * @see ImageReader#getAspectRatio
  371        */
  372       public void setSourceRenderSize(Dimension size)
  373           throws UnsupportedOperationException {
  374           if (!canSetSourceRenderSize()) {
  375               throw new UnsupportedOperationException
  376                   ("Can't set source render size!");
  377           }
  378   
  379           if (size == null) {
  380               this.sourceRenderSize = null;
  381           } else {
  382               if (size.width <= 0 || size.height <= 0) {
  383                   throw new IllegalArgumentException("width or height <= 0!");
  384               }
  385               this.sourceRenderSize = (Dimension)size.clone();
  386           }
  387       }
  388   
  389       /**
  390        * Returns the width and height of the source image as it
  391        * will be rendered during decoding, if they have been set via the
  392        * <code>setSourceRenderSize</code> method.  A
  393        * <code>null</code>value indicates that no setting has been made.
  394        *
  395        * @return the rendered width and height of the source image
  396        * as a <code>Dimension</code>.
  397        *
  398        * @see #setSourceRenderSize
  399        */
  400       public Dimension getSourceRenderSize() {
  401           return (sourceRenderSize == null) ?
  402               null : (Dimension)sourceRenderSize.clone();
  403       }
  404   
  405       /**
  406        * Sets the range of progressive passes that will be decoded.
  407        * Passes outside of this range will be ignored.
  408        *
  409        * <p> A progressive pass is a re-encoding of the entire image,
  410        * generally at progressively higher effective resolutions, but
  411        * requiring greater transmission bandwidth.  The most common use
  412        * of progressive encoding is found in the JPEG format, where
  413        * successive passes include more detailed representations of the
  414        * high-frequency image content.
  415        *
  416        * <p> The actual number of passes to be decoded is determined
  417        * during decoding, based on the number of actual passes available
  418        * in the stream.  Thus if <code>minPass + numPasses - 1</code> is
  419        * larger than the index of the last available passes, decoding
  420        * will end with that pass.
  421        *
  422        * <p> A value of <code>numPasses</code> of
  423        * <code>Integer.MAX_VALUE</code> indicates that all passes from
  424        * <code>minPass</code> forward should be read.  Otherwise, the
  425        * index of the last pass (<i>i.e.</i>, <code>minPass + numPasses
  426        * - 1</code>) must not exceed <code>Integer.MAX_VALUE</code>.
  427        *
  428        * <p> There is no <code>unsetSourceProgressivePasses</code>
  429        * method; the same effect may be obtained by calling
  430        * <code>setSourceProgressivePasses(0, Integer.MAX_VALUE)</code>.
  431        *
  432        * @param minPass the index of the first pass to be decoded.
  433        * @param numPasses the maximum number of passes to be decoded.
  434        *
  435        * @exception IllegalArgumentException if <code>minPass</code> is
  436        * negative, <code>numPasses</code> is negative or 0, or
  437        * <code>numPasses</code> is smaller than
  438        * <code>Integer.MAX_VALUE</code> but <code>minPass +
  439        * numPasses - 1</code> is greater than
  440        * <code>INTEGER.MAX_VALUE</code>.
  441        *
  442        * @see #getSourceMinProgressivePass
  443        * @see #getSourceMaxProgressivePass
  444        */
  445       public void setSourceProgressivePasses(int minPass, int numPasses) {
  446           if (minPass < 0) {
  447               throw new IllegalArgumentException("minPass < 0!");
  448           }
  449           if (numPasses <= 0) {
  450               throw new IllegalArgumentException("numPasses <= 0!");
  451           }
  452           if ((numPasses != Integer.MAX_VALUE) &&
  453               (((minPass + numPasses - 1) & 0x80000000) != 0)) {
  454               throw new IllegalArgumentException
  455                   ("minPass + numPasses - 1 > INTEGER.MAX_VALUE!");
  456           }
  457   
  458           this.minProgressivePass = minPass;
  459           this.numProgressivePasses = numPasses;
  460       }
  461   
  462       /**
  463        * Returns the index of the first progressive pass that will be
  464        * decoded. If no value has been set, 0 will be returned (which is
  465        * the correct value).
  466        *
  467        * @return the index of the first pass that will be decoded.
  468        *
  469        * @see #setSourceProgressivePasses
  470        * @see #getSourceNumProgressivePasses
  471        */
  472       public int getSourceMinProgressivePass() {
  473           return minProgressivePass;
  474       }
  475   
  476       /**
  477        * If <code>getSourceNumProgressivePasses</code> is equal to
  478        * <code>Integer.MAX_VALUE</code>, returns
  479        * <code>Integer.MAX_VALUE</code>.  Otherwise, returns
  480        * <code>getSourceMinProgressivePass() +
  481        * getSourceNumProgressivePasses() - 1</code>.
  482        *
  483        * @return the index of the last pass to be read, or
  484        * <code>Integer.MAX_VALUE</code>.
  485        */
  486       public int getSourceMaxProgressivePass() {
  487           if (numProgressivePasses == Integer.MAX_VALUE) {
  488               return Integer.MAX_VALUE;
  489           } else {
  490               return minProgressivePass + numProgressivePasses - 1;
  491           }
  492       }
  493   
  494       /**
  495        * Returns the number of the progressive passes that will be
  496        * decoded. If no value has been set,
  497        * <code>Integer.MAX_VALUE</code> will be returned (which is the
  498        * correct value).
  499        *
  500        * @return the number of the passes that will be decoded.
  501        *
  502        * @see #setSourceProgressivePasses
  503        * @see #getSourceMinProgressivePass
  504        */
  505       public int getSourceNumProgressivePasses() {
  506           return numProgressivePasses;
  507       }
  508   }

Save This Page
Home » openjdk-7 » javax » imageio » [javadoc | source]