2898 lines · 116.6 KB · Java
RawDownload
    /**     * Restores the <code>ImageReader</code> to its initial state.     *     * <p> The default implementation calls <code>setInput(null,     * false)</code>, <code>setLocale(null)</code>,     * <code>removeAllIIOReadUpdateListeners()</code>,     * <code>removeAllIIOReadWarningListeners()</code>,     * <code>removeAllIIOReadProgressListeners()</code>, and     * <code>clearAbortRequest</code>.     */    public void reset() {        setInput(null, false, false);        setLocale(null);        removeAllIIOReadUpdateListeners();        removeAllIIOReadProgressListeners();        removeAllIIOReadWarningListeners();        clearAbortRequest();    }     /**     * Allows any resources held by this object to be released.  The     * result of calling any other method (other than     * <code>finalize</code>) subsequent to a call to this method     * is undefined.     *     * <p>It is important for applications to call this method when they     * know they will no longer be using this <code>ImageReader</code>.     * Otherwise, the reader may continue to hold on to resources     * indefinitely.     *     * <p>The default implementation of this method in the superclass does     * nothing.  Subclass implementations should ensure that all resources,     * especially native resources, are released.     */    public void dispose() {    }     // Utility methods     /**     * A utility method that may be used by readers to compute the     * region of the source image that should be read, taking into     * account any source region and subsampling offset settings in     * the supplied <code>ImageReadParam</code>.  The actual     * subsampling factors, destination size, and destination offset     * are <em>not</em> taken into consideration, thus further     * clipping must take place.  The {@link #computeRegions     * <code>computeRegions</code>} method performs all necessary     * clipping.     *     * @param param the <code>ImageReadParam</code> being used, or     * <code>null</code>.     * @param srcWidth the width of the source image.     * @param srcHeight the height of the source image.     *     * @return the source region as a <code>Rectangle</code>.     */    protected static Rectangle getSourceRegion(ImageReadParam param,                                               int srcWidth,                                               int srcHeight) {        Rectangle sourceRegion = new Rectangle(0, 0, srcWidth, srcHeight);        if (param != null) {            Rectangle region = param.getSourceRegion();            if (region != null) {                sourceRegion = sourceRegion.intersection(region);            }             int subsampleXOffset = param.getSubsamplingXOffset();            int subsampleYOffset = param.getSubsamplingYOffset();            sourceRegion.x += subsampleXOffset;            sourceRegion.y += subsampleYOffset;            sourceRegion.width -= subsampleXOffset;            sourceRegion.height -= subsampleYOffset;        }         return sourceRegion;    }     /**     * Computes the source region of interest and the destination     * region of interest, taking the width and height of the source     * image, an optional destination image, and an optional     * <code>ImageReadParam</code> into account.  The source region     * begins with the entire source image.  Then that is clipped to     * the source region specified in the <code>ImageReadParam</code>,     * if one is specified.     *     * <p> If either of the destination offsets are negative, the     * source region is clipped so that its top left will coincide     * with the top left of the destination image, taking subsampling     * into account.  Then the result is clipped to the destination     * image on the right and bottom, if one is specified, taking     * subsampling and destination offsets into account.     *     * <p> Similarly, the destination region begins with the source     * image, is translated to the destination offset given in the     * <code>ImageReadParam</code> if there is one, and finally is     * clipped to the destination image, if there is one.     *     * <p> If either the source or destination regions end up having a     * width or height of 0, an <code>IllegalArgumentException</code>     * is thrown.     *     * <p> The {@link #getSourceRegion <code>getSourceRegion</code>}     * method may be used if only source clipping is desired.     *     * @param param an <code>ImageReadParam</code>, or <code>null</code>.     * @param srcWidth the width of the source image.     * @param srcHeight the height of the source image.     * @param image a <code>BufferedImage</code> that will be the     * destination image, or <code>null</code>.     * @param srcRegion a <code>Rectangle</code> that will be filled with     * the source region of interest.     * @param destRegion a <code>Rectangle</code> that will be filled with     * the destination region of interest.     * @exception IllegalArgumentException if <code>srcRegion</code>     * is <code>null</code>.     * @exception IllegalArgumentException if <code>dstRegion</code>     * is <code>null</code>.     * @exception IllegalArgumentException if the resulting source or     * destination region is empty.     */    protected static void computeRegions(ImageReadParam param,                                         int srcWidth,                                         int srcHeight,                                         BufferedImage image,                                         Rectangle srcRegion,                                         Rectangle destRegion) {        if (srcRegion == null) {            throw new IllegalArgumentException("srcRegion == null!");        }        if (destRegion == null) {            throw new IllegalArgumentException("destRegion == null!");        }         // Start with the entire source image        srcRegion.setBounds(0, 0, srcWidth, srcHeight);         // Destination also starts with source image, as that is the        // maximum extent if there is no subsampling        destRegion.setBounds(0, 0, srcWidth, srcHeight);         // Clip that to the param region, if there is one        int periodX = 1;        int periodY = 1;        int gridX = 0;        int gridY = 0;        if (param != null) {            Rectangle paramSrcRegion = param.getSourceRegion();            if (paramSrcRegion != null) {                srcRegion.setBounds(srcRegion.intersection(paramSrcRegion));            }            periodX = param.getSourceXSubsampling();            periodY = param.getSourceYSubsampling();            gridX = param.getSubsamplingXOffset();            gridY = param.getSubsamplingYOffset();            srcRegion.translate(gridX, gridY);            srcRegion.width -= gridX;            srcRegion.height -= gridY;            destRegion.setLocation(param.getDestinationOffset());        }         // Now clip any negative destination offsets, i.e. clip        // to the top and left of the destination image        if (destRegion.x < 0) {            int delta = -destRegion.x*periodX;            srcRegion.x += delta;            srcRegion.width -= delta;            destRegion.x = 0;        }        if (destRegion.y < 0) {            int delta = -destRegion.y*periodY;            srcRegion.y += delta;            srcRegion.height -= delta;            destRegion.y = 0;        }         // Now clip the destination Region to the subsampled width and height        int subsampledWidth = (srcRegion.width + periodX - 1)/periodX;        int subsampledHeight = (srcRegion.height + periodY - 1)/periodY;        destRegion.width = subsampledWidth;        destRegion.height = subsampledHeight;         // Now clip that to right and bottom of the destination image,        // if there is one, taking subsampling into account        if (image != null) {            Rectangle destImageRect = new Rectangle(0, 0,                                                    image.getWidth(),                                                    image.getHeight());            destRegion.setBounds(destRegion.intersection(destImageRect));            if (destRegion.isEmpty()) {                throw new IllegalArgumentException                    ("Empty destination region!");            }             int deltaX = destRegion.x + subsampledWidth - image.getWidth();            if (deltaX > 0) {                srcRegion.width -= deltaX*periodX;            }            int deltaY =  destRegion.y + subsampledHeight - image.getHeight();            if (deltaY > 0) {                srcRegion.height -= deltaY*periodY;            }        }        if (srcRegion.isEmpty() || destRegion.isEmpty()) {            throw new IllegalArgumentException("Empty region!");        }    }     /**     * A utility method that may be used by readers to test the     * validity of the source and destination band settings of an     * <code>ImageReadParam</code>.  This method may be called as soon     * as the reader knows both the number of bands of the source     * image as it exists in the input stream, and the number of bands     * of the destination image that being written.     *     * <p> The method retrieves the source and destination band     * setting arrays from param using the <code>getSourceBands</code>     * and <code>getDestinationBands</code>methods (or considers them     * to be <code>null</code> if <code>param</code> is     * <code>null</code>).  If the source band setting array is     * <code>null</code>, it is considered to be equal to the array     * <code>{ 0, 1, ..., numSrcBands - 1 }</code>, and similarly for     * the destination band setting array.     *     * <p> The method then tests that both arrays are equal in length,     * and that neither array contains a value larger than the largest     * available band index.     *     * <p> Any failure results in an     * <code>IllegalArgumentException</code> being thrown; success     * results in the method returning silently.     *     * @param param the <code>ImageReadParam</code> being used to read     * the image.     * @param numSrcBands the number of bands of the image as it exists     * int the input source.     * @param numDstBands the number of bands in the destination image     * being written.     *     * @exception IllegalArgumentException if <code>param</code>     * contains an invalid specification of a source and/or     * destination band subset.     */    protected static void checkReadParamBandSettings(ImageReadParam param,                                                     int numSrcBands,                                                     int numDstBands) {        // A null param is equivalent to srcBands == dstBands == null.        int[] srcBands = null;        int[] dstBands = null;        if (param != null) {            srcBands = param.getSourceBands();            dstBands = param.getDestinationBands();        }         int paramSrcBandLength =            (srcBands == null) ? numSrcBands : srcBands.length;        int paramDstBandLength =            (dstBands == null) ? numDstBands : dstBands.length;         if (paramSrcBandLength != paramDstBandLength) {            throw new IllegalArgumentException("ImageReadParam num source & dest bands differ!");        }         if (srcBands != null) {            for (int i = 0; i < srcBands.length; i++) {                if (srcBands[i] >= numSrcBands) {                    throw new IllegalArgumentException("ImageReadParam source bands contains a value >= the number of source bands!");                }            }        }         if (dstBands != null) {            for (int i = 0; i < dstBands.length; i++) {                if (dstBands[i] >= numDstBands) {                    throw new IllegalArgumentException("ImageReadParam dest bands contains a value >= the number of dest bands!");                }            }        }    }     /**     * Returns the <code>BufferedImage</code> to which decoded pixel     * data should be written.  The image is determined by inspecting     * the supplied <code>ImageReadParam</code> if it is     * non-<code>null</code>; if its <code>getDestination</code>     * method returns a non-<code>null</code> value, that image is     * simply returned.  Otherwise,     * <code>param.getDestinationType</code> method is called to     * determine if a particular image type has been specified.  If     * so, the returned <code>ImageTypeSpecifier</code> is used after     * checking that it is equal to one of those included in     * <code>imageTypes</code>.     *     * <p> If <code>param</code> is <code>null</code> or the above     * steps have not yielded an image or an     * <code>ImageTypeSpecifier</code>, the first value obtained from     * the <code>imageTypes</code> parameter is used.  Typically, the     * caller will set <code>imageTypes</code> to the value of     * <code>getImageTypes(imageIndex)</code>.     *     * <p> Next, the dimensions of the image are determined by a call     * to <code>computeRegions</code>.  The actual width and height of     * the image being decoded are passed in as the <code>width</code>     * and <code>height</code> parameters.     *     * @param param an <code>ImageReadParam</code> to be used to get     * the destination image or image type, or <code>null</code>.     * @param imageTypes an <code>Iterator</code> of     * <code>ImageTypeSpecifier</code>s indicating the legal image     * types, with the default first.     * @param width the true width of the image or tile begin decoded.     * @param height the true width of the image or tile being decoded.     *     * @return the <code>BufferedImage</code> to which decoded pixel     * data should be written.     *     * @exception IIOException if the <code>ImageTypeSpecifier</code>     * specified by <code>param</code> does not match any of the legal     * ones from <code>imageTypes</code>.     * @exception IllegalArgumentException if <code>imageTypes</code>     * is <code>null</code> or empty, or if an object not of type     * <code>ImageTypeSpecifier</code> is retrieved from it.     * @exception IllegalArgumentException if the resulting image would     * have a width or height less than 1.     * @exception IllegalArgumentException if the product of     * <code>width</code> and <code>height</code> is greater than     * <code>Integer.MAX_VALUE</code>.     */    protected static BufferedImage        getDestination(ImageReadParam param,                       Iterator<ImageTypeSpecifier> imageTypes,                       int width, int height)        throws IIOException {        if (imageTypes == null || !imageTypes.hasNext()) {            throw new IllegalArgumentException("imageTypes null or empty!");        }        if ((long)width*height > Integer.MAX_VALUE) {            throw new IllegalArgumentException                ("width*height > Integer.MAX_VALUE!");        }         BufferedImage dest = null;        ImageTypeSpecifier imageType = null;         // If param is non-null, use it        if (param != null) {            // Try to get the image itself            dest = param.getDestination();            if (dest != null) {                return dest;            }             // No image, get the image type            imageType = param.getDestinationType();        }         // No info from param, use fallback image type        if (imageType == null) {            Object o = imageTypes.next();            if (!(o instanceof ImageTypeSpecifier)) {                throw new IllegalArgumentException                    ("Non-ImageTypeSpecifier retrieved from imageTypes!");            }            imageType = (ImageTypeSpecifier)o;        } else {            boolean foundIt = false;            while (imageTypes.hasNext()) {                ImageTypeSpecifier type =                    (ImageTypeSpecifier)imageTypes.next();                if (type.equals(imageType)) {                    foundIt = true;                    break;                }            }             if (!foundIt) {                throw new IIOException                    ("Destination type from ImageReadParam does not match!");            }        }         Rectangle srcRegion = new Rectangle(0,0,0,0);        Rectangle destRegion = new Rectangle(0,0,0,0);        computeRegions(param,                       width,                       height,                       null,                       srcRegion,                       destRegion);         int destWidth = destRegion.x + destRegion.width;        int destHeight = destRegion.y + destRegion.height;        // Create a new image based on the type specifier        return imageType.createBufferedImage(destWidth, destHeight);    }}

Lines 2501–2898 of 2898. Previous lines