public Raster getData(Rectangle bounds) {
        int startX = XToTileX(bounds.x);
        int startY = YToTileY(bounds.y);
        int endX = XToTileX(bounds.x + bounds.width - 1);
        int endY = YToTileY(bounds.y + bounds.height - 1);
        Raster tile;

        if ((startX == endX) && (startY == endY)) {
            tile = getTile(startX, startY);
            return tile.createChild(bounds.x, bounds.y,
                                    bounds.width, bounds.height,
                                    bounds.x, bounds.y, null);
        } else {
            // Create a WritableRaster of the desired size
            SampleModel sm =
                sampleModel.createCompatibleSampleModel(bounds.width,
                                                       bounds.height);

            // Translate it
            WritableRaster dest =
                Raster.createWritableRaster(sm, bounds.getLocation());

            for (int j = startY; j <= endY; j++) {
                for (int i = startX; i <= endX; i++) {
                    tile = getTile(i, j);
                    Rectangle intersectRect =
                        bounds.intersection(tile.getBounds());
                    Raster liveRaster = tile.createChild(intersectRect.x,
                                                         intersectRect.y,
                                                         intersectRect.width,
                                                         intersectRect.height,
                                                         intersectRect.x,
                                                         intersectRect.y,
                                                         null);
                    dest.setDataElements(0, 0, liveRaster);
                }
            }
            return dest;
        }
    }
Returns an arbitrary rectangular region of the RenderedImage
in a Raster.  The rectangle of interest will be clipped against
the image bounds.

<p> The returned Raster is semantically a copy.  This means
that updates to the source image will not be reflected in the
returned Raster.  For non-writable (immutable) source images,
the returned value may be a reference to the image's internal
data.  The returned Raster should be considered non-writable;
any attempt to alter its pixel data (such as by casting it to
WritableRaster or obtaining and modifying its DataBuffer) may
result in undefined behavior.  The copyData method should be
used if the returned Raster is to be modified.

@param bounds the region of the RenderedImage to be returned.
plugins/svg-plugin/batik-codec-fix/src/main/java/org/apache/batik/ext/awt/image/codec/util/SimpleRenderedImage.java