/*
 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.imageio.plugins.common;

import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import javax.imageio.stream.ImageInputStream;

This class contains utility methods that may be useful to ImageReader plugins. Ideally these methods would be in the ImageReader base class so that all subclasses could benefit from them, but that would be an addition to the existing API, and it is not yet clear whether these methods are universally useful, so for now we will leave them here.
/** * This class contains utility methods that may be useful to ImageReader * plugins. Ideally these methods would be in the ImageReader base class * so that all subclasses could benefit from them, but that would be an * addition to the existing API, and it is not yet clear whether these methods * are universally useful, so for now we will leave them here. */
public class ReaderUtil { // Helper for computeUpdatedPixels method private static void computeUpdatedPixels(int sourceOffset, int sourceExtent, int destinationOffset, int dstMin, int dstMax, int sourceSubsampling, int passStart, int passExtent, int passPeriod, int[] vals, int offset) { // We need to satisfy the congruences: // dst = destinationOffset + (src - sourceOffset)/sourceSubsampling // // src - passStart == 0 (mod passPeriod) // src - sourceOffset == 0 (mod sourceSubsampling) // // subject to the inequalities: // // src >= passStart // src < passStart + passExtent // src >= sourceOffset // src < sourceOffset + sourceExtent // dst >= dstMin // dst <= dstmax // // where // // dst = destinationOffset + (src - sourceOffset)/sourceSubsampling // // For now we use a brute-force approach although we could // attempt to analyze the congruences. If passPeriod and // sourceSubsamling are relatively prime, the period will be // their product. If they share a common factor, either the // period will be equal to the larger value, or the sequences // will be completely disjoint, depending on the relationship // between passStart and sourceOffset. Since we only have to do this // twice per image (once each for X and Y), it seems cheap enough // to do it the straightforward way. boolean gotPixel = false; int firstDst = -1; int secondDst = -1; int lastDst = -1; for (int i = 0; i < passExtent; i++) { int src = passStart + i*passPeriod; if (src < sourceOffset) { continue; } if ((src - sourceOffset) % sourceSubsampling != 0) { continue; } if (src >= sourceOffset + sourceExtent) { break; } int dst = destinationOffset + (src - sourceOffset)/sourceSubsampling; if (dst < dstMin) { continue; } if (dst > dstMax) { break; } if (!gotPixel) { firstDst = dst; // Record smallest valid pixel gotPixel = true; } else if (secondDst == -1) { secondDst = dst; // Record second smallest valid pixel } lastDst = dst; // Record largest valid pixel } vals[offset] = firstDst; // If we never saw a valid pixel, set width to 0 if (!gotPixel) { vals[offset + 2] = 0; } else { vals[offset + 2] = lastDst - firstDst + 1; } // The period is given by the difference of any two adjacent pixels vals[offset + 4] = Math.max(secondDst - firstDst, 1); }
A utility method that computes the exact set of destination pixels that will be written during a particular decoding pass. The intent is to simplify the work done by readers in combining the source region, source subsampling, and destination offset information obtained from the ImageReadParam with the offsets and periods of a progressive or interlaced decoding pass.
Params:
  • sourceRegion – a Rectangle containing the source region being read, offset by the source subsampling offsets, and clipped against the source bounds, as returned by the getSourceRegion method.
  • destinationOffset – a Point containing the coordinates of the upper-left pixel to be written in the destination.
  • dstMinX – the smallest X coordinate (inclusive) of the destination Raster.
  • dstMinY – the smallest Y coordinate (inclusive) of the destination Raster.
  • dstMaxX – the largest X coordinate (inclusive) of the destination Raster.
  • dstMaxY – the largest Y coordinate (inclusive) of the destination Raster.
  • sourceXSubsampling – the X subsampling factor.
  • sourceYSubsampling – the Y subsampling factor.
  • passXStart – the smallest source X coordinate (inclusive) of the current progressive pass.
  • passYStart – the smallest source Y coordinate (inclusive) of the current progressive pass.
  • passWidth – the width in pixels of the current progressive pass.
  • passHeight – the height in pixels of the current progressive pass.
  • passPeriodX – the X period (horizontal spacing between pixels) of the current progressive pass.
  • passPeriodY – the Y period (vertical spacing between pixels) of the current progressive pass.
Returns:an array of 6 ints containing the destination min X, min Y, width, height, X period and Y period of the region that will be updated.
/** * A utility method that computes the exact set of destination * pixels that will be written during a particular decoding pass. * The intent is to simplify the work done by readers in combining * the source region, source subsampling, and destination offset * information obtained from the {@code ImageReadParam} with * the offsets and periods of a progressive or interlaced decoding * pass. * * @param sourceRegion a {@code Rectangle} containing the * source region being read, offset by the source subsampling * offsets, and clipped against the source bounds, as returned by * the {@code getSourceRegion} method. * @param destinationOffset a {@code Point} containing the * coordinates of the upper-left pixel to be written in the * destination. * @param dstMinX the smallest X coordinate (inclusive) of the * destination {@code Raster}. * @param dstMinY the smallest Y coordinate (inclusive) of the * destination {@code Raster}. * @param dstMaxX the largest X coordinate (inclusive) of the destination * {@code Raster}. * @param dstMaxY the largest Y coordinate (inclusive) of the destination * {@code Raster}. * @param sourceXSubsampling the X subsampling factor. * @param sourceYSubsampling the Y subsampling factor. * @param passXStart the smallest source X coordinate (inclusive) * of the current progressive pass. * @param passYStart the smallest source Y coordinate (inclusive) * of the current progressive pass. * @param passWidth the width in pixels of the current progressive * pass. * @param passHeight the height in pixels of the current progressive * pass. * @param passPeriodX the X period (horizontal spacing between * pixels) of the current progressive pass. * @param passPeriodY the Y period (vertical spacing between * pixels) of the current progressive pass. * * @return an array of 6 {@code int}s containing the * destination min X, min Y, width, height, X period and Y period * of the region that will be updated. */
public static int[] computeUpdatedPixels(Rectangle sourceRegion, Point destinationOffset, int dstMinX, int dstMinY, int dstMaxX, int dstMaxY, int sourceXSubsampling, int sourceYSubsampling, int passXStart, int passYStart, int passWidth, int passHeight, int passPeriodX, int passPeriodY) { int[] vals = new int[6]; computeUpdatedPixels(sourceRegion.x, sourceRegion.width, destinationOffset.x, dstMinX, dstMaxX, sourceXSubsampling, passXStart, passWidth, passPeriodX, vals, 0); computeUpdatedPixels(sourceRegion.y, sourceRegion.height, destinationOffset.y, dstMinY, dstMaxY, sourceYSubsampling, passYStart, passHeight, passPeriodY, vals, 1); return vals; } public static int readMultiByteInteger(ImageInputStream iis) throws IOException { int value = iis.readByte(); int result = value & 0x7f; while((value & 0x80) == 0x80) { result <<= 7; value = iis.readByte(); result |= (value & 0x7f); } return result; } }