You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/10/25 21:01:49 UTC

svn commit: r1402274 [25/31] - in /incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext: ./ awt/ awt/color/ awt/font/ awt/g2d/ awt/geom/ awt/image/ awt/image/codec/ awt/image/codec/jpeg/ awt/image/codec/p...

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractTiledRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractTiledRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractTiledRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractTiledRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,638 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+import org.apache.flex.forks.batik.util.HaltingThread;
+
+/**
+ * This is an abstract base class that takes care of most of the
+ * normal issues surrounding the implementation of the CachableRed
+ * (RenderedImage) interface.  It tries to make no assumptions about
+ * the subclass implementation.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: AbstractTiledRed.java 489226 2006-12-21 00:05:36Z cam $
+ */
+public abstract class AbstractTiledRed
+    extends    AbstractRed
+    implements TileGenerator {
+
+    private TileStore tiles;
+
+    private static int defaultTileSize = 128;
+    public static int getDefaultTileSize() { return defaultTileSize; }
+
+    /**
+     * void constructor. The subclass must call one of the
+     * flavors of init before the object becomes usable.
+     * This is useful when the proper parameters to the init
+     * method need to be computed in the subclasses constructor.
+     */
+    protected AbstractTiledRed() { }
+
+
+    /**
+     * Construct an Abstract RenderedImage from a bounds rect and props
+     * (may be null).  The srcs Vector will be empty.
+     * @param bounds this defines the extent of the rable in the
+     * user coordinate system.
+     * @param props this initializes the props Map (may be null)
+     */
+    protected AbstractTiledRed(Rectangle bounds, Map props) {
+        super(bounds, props);
+    }
+
+    /**
+     * Construct an Abstract RenderedImage from a source image and
+     * props (may be null).
+     * @param src will be the first (and only) member of the srcs
+     * Vector. Src is also used to set the bounds, ColorModel,
+     * SampleModel, and tile grid offsets.
+     * @param props this initializes the props Map.  */
+    protected AbstractTiledRed(CachableRed src, Map props) {
+        super(src, props);
+    }
+
+    /**
+     * Construct an Abstract RenderedImage from a source image, bounds
+     * rect and props (may be null).
+     * @param src will be the first (and only) member of the srcs
+     * Vector. Src is also used to set the ColorModel, SampleModel,
+     * and tile grid offsets.
+     * @param bounds The bounds of this image.
+     * @param props this initializes the props Map.  */
+    protected AbstractTiledRed(CachableRed src, Rectangle bounds, Map props) {
+        super(src, bounds, props);
+    }
+
+    /**
+     * Construct an Abstract RenderedImage from a source image, bounds
+     * rect and props (may be null).
+     * @param src will be the first (and only) member of the srcs
+     * Vector. Src is also used to set the ColorModel, SampleModel,
+     * and tile grid offsets.
+     * @param bounds The bounds of this image.
+     * @param cm The ColorModel to use. If null it will default to
+     * ComponentColorModel.
+     * @param sm The sample model to use. If null it will construct
+     * a sample model the matches the given/generated ColorModel and is
+     * the size of bounds.
+     * @param props this initializes the props Map.  */
+    protected AbstractTiledRed(CachableRed src, Rectangle bounds,
+                          ColorModel cm, SampleModel sm,
+                          Map props) {
+        super(src, bounds, cm, sm, props);
+    }
+
+    /**
+     * Construct an Abstract Rable from a bounds rect and props
+     * (may be null).  The srcs Vector will be empty.
+     * @param src will be the first (and only) member of the srcs
+     * Vector. Src is also used to set the ColorModel, SampleModel,
+     * and tile grid offsets.
+     * @param bounds this defines the extent of the rable in the
+     * user coordinate system.
+     * @param cm The ColorModel to use. If null it will default to
+     * ComponentColorModel.
+     * @param sm The sample model to use. If null it will construct
+     * a sample model the matches the given/generated ColorModel and is
+     * the size of bounds.
+     * @param tileGridXOff The x location of tile 0,0.
+     * @param tileGridYOff The y location of tile 0,0.
+     * @param props this initializes the props Map.
+     */
+    protected AbstractTiledRed(CachableRed src, Rectangle bounds,
+                          ColorModel cm, SampleModel sm,
+                          int tileGridXOff, int tileGridYOff,
+                          Map props) {
+        super(src, bounds, cm, sm, tileGridXOff, tileGridYOff, props);
+    }
+
+    /**
+     * This is one of two basic init function (this is for single
+     * source rendereds).
+     * It is provided so subclasses can compute various values
+     * before initializing all the state in the base class.
+     * You really should call this method before returning from
+     * your subclass constructor.
+     *
+     * @param src    The source for the filter
+     * @param bounds The bounds of the image
+     * @param cm     The ColorModel to use. If null it defaults to
+     *               ComponentColorModel/ src's ColorModel.
+     * @param sm     The Sample modle to use. If this is null it will
+     *               use the src's sample model if that is null it will
+     *               construct a sample model that matches the ColorModel
+     *               and is the size of the whole image.
+     * @param tileGridXOff The x location of tile 0,0.
+     * @param tileGridYOff The y location of tile 0,0.
+     * @param props  Any properties you want to associate with the image.
+     */
+    protected void init(CachableRed src, Rectangle   bounds,
+                        ColorModel  cm,   SampleModel sm,
+                        int tileGridXOff, int tileGridYOff,
+                        Map props) {
+        init(src, bounds, cm, sm, tileGridXOff, tileGridYOff, null, props);
+    }
+
+
+    /**
+     * This is one of two basic init function (this is for single
+     * source rendereds).
+     * It is provided so subclasses can compute various values
+     * before initializing all the state in the base class.
+     * You really should call this method before returning from
+     * your subclass constructor.
+     *
+     * @param src    The source for the filter
+     * @param bounds The bounds of the image
+     * @param cm     The ColorModel to use. If null it defaults to
+     *               ComponentColorModel/ src's ColorModel.
+     * @param sm     The Sample modle to use. If this is null it will
+     *               use the src's sample model if that is null it will
+     *               construct a sample model that matches the ColorModel
+     *               and is the size of the whole image.
+     * @param tileGridXOff The x location of tile 0,0.
+     * @param tileGridYOff The y location of tile 0,0.
+     * @param tiles  The tileStore to use (or null).
+     * @param props  Any properties you want to associate with the image.
+     */
+    protected void init(CachableRed src, Rectangle   bounds,
+                        ColorModel  cm,   SampleModel sm,
+                        int tileGridXOff, int tileGridYOff,
+                        TileStore tiles,
+                        Map props) {
+        super.init(src, bounds, cm, sm, tileGridXOff, tileGridYOff, props);
+        this.tiles = tiles;
+        if (this.tiles == null)
+            this.tiles = createTileStore();
+    }
+
+    /**
+     * Construct an Abstract Rable from a List of sources a bounds rect
+     * and props (may be null).
+     * @param srcs This is used to initialize the srcs Vector.  All
+     * the members of srcs must be CachableRed otherwise an error
+     * will be thrown.
+     * @param bounds this defines the extent of the rendered in pixels
+     * @param props this initializes the props Map.
+     */
+    protected AbstractTiledRed(List srcs, Rectangle bounds, Map props) {
+        super(srcs, bounds, props);
+    }
+
+    /**
+     * Construct an Abstract RenderedImage from a bounds rect,
+     * ColorModel (may be null), SampleModel (may be null) and props
+     * (may be null).  The srcs Vector will be empty.
+     * @param srcs This is used to initialize the srcs Vector.  All
+     * the members of srcs must be CachableRed otherwise an error
+     * will be thrown.
+     * @param bounds this defines the extent of the rendered in pixels
+     * @param cm The ColorModel to use. If null it will default to
+     * ComponentColorModel.
+     * @param sm The sample model to use. If null it will construct
+     * a sample model the matches the given/generated ColorModel and is
+     * the size of bounds.
+     * @param props this initializes the props Map.
+     */
+    protected AbstractTiledRed(List srcs, Rectangle bounds,
+                          ColorModel cm, SampleModel sm,
+                          Map props) {
+        super(srcs, bounds, cm, sm, props);
+    }
+
+    /**
+     * Construct an Abstract RenderedImage from a bounds rect,
+     * ColorModel (may be null), SampleModel (may be null), tile grid
+     * offsets and props (may be null).  The srcs Vector will be
+     * empty.
+     * @param srcs This is used to initialize the srcs Vector.  All
+     * the members of srcs must be CachableRed otherwise an error
+     * will be thrown.
+     * @param bounds this defines the extent of the rable in the
+     * user coordinate system.
+     * @param cm The ColorModel to use. If null it will default to
+     * ComponentColorModel.
+     * @param sm The sample model to use. If null it will construct
+     * a sample model the matches the given/generated ColorModel and is
+     * the size of bounds.
+     * @param tileGridXOff The x location of tile 0,0.
+     * @param tileGridYOff The y location of tile 0,0.
+     * @param props this initializes the props Map.
+     */
+    protected AbstractTiledRed(List srcs, Rectangle bounds,
+                          ColorModel cm, SampleModel sm,
+                          int tileGridXOff, int tileGridYOff,
+                          Map props) {
+        super(srcs, bounds, cm, sm, tileGridXOff, tileGridYOff, props);
+    }
+
+    /**
+     * This is the basic init function.
+     * It is provided so subclasses can compute various values
+     * before initializing all the state in the base class.
+     * You really should call this method before returning from
+     * your subclass constructor.
+     *
+     * @param srcs   The list of sources
+     * @param bounds The bounds of the image
+     * @param cm     The ColorModel to use. If null it defaults to
+     *               ComponentColorModel.
+     * @param sm     The Sample modle to use. If this is null it will
+     *               construct a sample model that matches the ColorModel
+     *               and is the size of the whole image.
+     * @param tileGridXOff The x location of tile 0,0.
+     * @param tileGridYOff The y location of tile 0,0.
+     * @param props  Any properties you want to associate with the image.
+     */
+    protected void init(List srcs, Rectangle bounds,
+                        ColorModel cm, SampleModel sm,
+                        int tileGridXOff, int tileGridYOff,
+                        Map props) {
+        super.init(srcs, bounds, cm, sm, tileGridXOff, tileGridYOff, props);
+        tiles = createTileStore();
+    }
+
+    public TileStore getTileStore() {
+        return tiles;
+    }
+
+    protected void setTileStore(TileStore tiles) {
+        this.tiles = tiles;
+    }
+
+    protected TileStore createTileStore() {
+        return TileCache.getTileMap(this);
+    }
+
+    public WritableRaster copyData(WritableRaster wr) {
+        copyToRasterByBlocks(wr);
+        return wr;
+    }
+
+
+    public Raster getData(Rectangle rect) {
+        int xt0 = getXTile(rect.x);
+        int xt1 = getXTile(rect.x+rect.width-1);
+        int yt0 = getYTile(rect.y);
+        int yt1 = getYTile(rect.y+rect.height-1);
+
+        if ((xt0 == xt1) && (yt0 == yt1)) {
+            Raster r = getTile(xt0, yt0);
+            return r.createChild(rect.x, rect.y, rect.width, rect.height,
+                                 rect.x, rect.y, null);
+        }
+        // rect crosses tile boundries...
+        return super.getData(rect);
+    }
+
+
+    public Raster getTile(int x, int y) {
+        return tiles.getTile(x, y);
+    }
+
+    public Raster genTile(int x, int y) {
+        WritableRaster wr = makeTile(x, y);
+        genRect(wr);
+        return wr;
+    }
+
+    public abstract void genRect(WritableRaster wr);
+    // { copyToRaster(wr); }
+
+
+    public void setTile(int x, int y, Raster ras) {
+        tiles.setTile(x, y, ras);
+    }
+
+    public void copyToRasterByBlocks(WritableRaster wr) {
+        final boolean is_INT_PACK =
+            GraphicsUtil.is_INT_PACK_Data(getSampleModel(), false);
+
+        Rectangle bounds = getBounds();
+        Rectangle wrR    = wr.getBounds();
+
+        int tx0 = getXTile(wrR.x);
+        int ty0 = getYTile(wrR.y);
+        int tx1 = getXTile(wrR.x+wrR.width -1);
+        int ty1 = getYTile(wrR.y+wrR.height-1);
+
+        if (tx0 < minTileX) tx0 = minTileX;
+        if (ty0 < minTileY) ty0 = minTileY;
+
+        if (tx1 >= minTileX+numXTiles) tx1 = minTileX+numXTiles-1;
+        if (ty1 >= minTileY+numYTiles) ty1 = minTileY+numYTiles-1;
+
+        if ((tx1 < tx0) || (ty1 < ty0))
+            return;
+
+        // System.out.println("WR: " + wrR);
+        // System.out.println("ME: " + bounds);
+
+        int insideTx0 = tx0;
+        int insideTx1 = tx1;
+
+        int insideTy0 = ty0;
+        int insideTy1 = ty1;
+
+        // Now figure out what tiles lie completely inside wr...
+        int tx, ty;
+        tx = tx0*tileWidth+tileGridXOff;
+        if ((tx < wrR.x)  && (bounds.x != wrR.x))
+            // Partial tile off the left.
+            insideTx0++;
+
+        ty= ty0*tileHeight+tileGridYOff;
+        if ((ty < wrR.y) && (bounds.y != wrR.y))
+            // Partial tile off the top.
+            insideTy0++;
+
+        tx= (tx1+1)*tileWidth+tileGridXOff-1;
+        if ((tx >= (wrR.x+wrR.width)) &&
+            ((bounds.x+bounds.width) != (wrR.x+wrR.width)))
+            // Partial tile off right
+            insideTx1--;
+
+        ty= (ty1+1)*tileHeight+tileGridYOff-1;
+        if ((ty >= (wrR.y+wrR.height)) &&
+            ((bounds.y+bounds.height) != (wrR.y+wrR.height)))
+            // Partial tile off bottom
+            insideTy1--;
+
+        int xtiles = insideTx1-insideTx0+1;
+        int ytiles = insideTy1-insideTy0+1;
+        boolean [] occupied = null;
+        if ((xtiles > 0) && (ytiles > 0))
+            occupied = new boolean[xtiles*ytiles];
+
+        boolean [] got = new boolean[2*(tx1-tx0+1) + 2*(ty1-ty0+1)];
+        int idx = 0;
+        int numFound = 0;
+        // Collect all the tiles that we currently have in cache...
+        for (int y=ty0; y<=ty1; y++) {
+            for (int x=tx0; x<=tx1; x++) {
+                Raster ras = tiles.getTileNoCompute(x, y);
+                boolean found = (ras != null);
+                if ((y>=insideTy0) && (y<=insideTy1) &&
+                    (x>=insideTx0) && (x<=insideTx1))
+                    occupied[(x-insideTx0)+(y-insideTy0)*xtiles] = found;
+                else
+                    got[idx++] = found;
+
+                if (!found) continue;
+
+                numFound++;
+
+                if (is_INT_PACK)
+                    GraphicsUtil.copyData_INT_PACK(ras, wr);
+                else
+                    GraphicsUtil.copyData_FALLBACK(ras, wr);
+            }
+        }
+
+        // System.out.println("Found: " + numFound + " out of " +
+        //                    ((tx1-tx0+1)*(ty1-ty0+1)));
+
+        // Compute the stuff from the middle in the largest possible Chunks.
+        if ((xtiles > 0) && (ytiles > 0)) {
+            TileBlock block = new TileBlock
+                (insideTx0, insideTy0, xtiles, ytiles, occupied,
+                 0, 0, xtiles, ytiles);
+            // System.out.println("Starting Splits");
+            drawBlock(block, wr);
+            // Exception e= new Exception("Foo");
+            // e.printStackTrace();
+        }
+
+        // Check If we should halt early.
+        Thread currentThread = Thread.currentThread();
+        if (HaltingThread.hasBeenHalted())
+            return;
+
+        idx = 0;
+        // Fill in the ones that weren't in the cache.
+        for (ty=ty0; ty<=ty1; ty++) {
+
+            for (tx=tx0; tx<=tx1; tx++) {
+                // At least touch the tile...
+                Raster ras = tiles.getTileNoCompute(tx, ty);
+
+                if ((ty>=insideTy0) && (ty<=insideTy1) &&
+                    (tx>=insideTx0) && (tx<=insideTx1)) {
+
+                    if (ras != null) continue;
+
+                    // Fill the tile from wr (since wr is full now
+                    // at least in the middle).
+                    WritableRaster tile = makeTile(tx, ty);
+                    if (is_INT_PACK)
+                        GraphicsUtil.copyData_INT_PACK(wr, tile);
+                    else
+                        GraphicsUtil.copyData_FALLBACK(wr, tile);
+
+                    tiles.setTile(tx, ty, tile);
+                }
+                else {
+                    if (got[idx++]) continue;
+
+                    // System.out.println("Computing : " + x + "," + y);
+
+                    ras = getTile(tx, ty);// Compute the tile..
+                    // Check If we should halt early.
+                    if (HaltingThread.hasBeenHalted( currentThread ))
+                        return;
+
+                    if (is_INT_PACK)
+                        GraphicsUtil.copyData_INT_PACK(ras, wr);
+                    else
+                        GraphicsUtil.copyData_FALLBACK(ras, wr);
+                }
+            }
+        }
+
+        // System.out.println("Ending Computation: " + this);
+    }
+
+    /**
+     * Copies data from this images tile grid into wr.  wr may
+     * extend outside the bounds of this image in which case the
+     * data in wr outside the bounds will not be touched.
+     * @param wr Raster to fill with image data.
+     */
+    public void copyToRaster(WritableRaster wr) {
+        Rectangle wrR = wr.getBounds();
+
+        int tx0 = getXTile(wrR.x);
+        int ty0 = getYTile(wrR.y);
+        int tx1 = getXTile(wrR.x+wrR.width -1);
+        int ty1 = getYTile(wrR.y+wrR.height-1);
+
+        if (tx0 < minTileX) tx0 = minTileX;
+        if (ty0 < minTileY) ty0 = minTileY;
+
+        if (tx1 >= minTileX+numXTiles) tx1 = minTileX+numXTiles-1;
+        if (ty1 >= minTileY+numYTiles) ty1 = minTileY+numYTiles-1;
+
+        final boolean is_INT_PACK =
+            GraphicsUtil.is_INT_PACK_Data(getSampleModel(), false);
+
+        int xtiles = (tx1-tx0+1);
+        boolean [] got = new boolean[xtiles*(ty1-ty0+1)];
+
+        // Run through and get the tiles that are just sitting in the
+        // cache...
+        for (int y=ty0; y<=ty1; y++)
+            for (int x=tx0; x<=tx1; x++) {
+                Raster r = tiles.getTileNoCompute(x, y);
+                if (r == null) continue; // Not there.
+
+                got[x-tx0 + (y-ty0)*xtiles] = true;
+
+                if (is_INT_PACK)
+                    GraphicsUtil.copyData_INT_PACK(r, wr);
+                else
+                    GraphicsUtil.copyData_FALLBACK(r, wr);
+            }
+
+        // Run through and pick up the ones we need to compute...
+        for (int y=ty0; y<=ty1; y++)
+            for (int x=tx0; x<=tx1; x++) {
+                if (got[x-tx0 + (y-ty0)*xtiles]) continue; // already have.
+
+                Raster r = getTile(x, y);
+                if (is_INT_PACK)
+                    GraphicsUtil.copyData_INT_PACK(r, wr);
+                else
+                    GraphicsUtil.copyData_FALLBACK(r, wr);
+            }
+    }
+
+    protected void drawBlock( TileBlock block, WritableRaster wr ) {
+        TileBlock [] blocks = block.getBestSplit();
+        if ( blocks == null ) {
+            return;
+        }
+
+        drawBlockInPlace( blocks, wr );
+    }
+
+    protected void drawBlockAndCopy( TileBlock []blocks, WritableRaster wr ) {
+
+        if ( blocks.length == 1 ) {
+            TileBlock curr = blocks[ 0 ];
+            int xloc = curr.getXLoc() * tileWidth + tileGridXOff;
+            int yloc = curr.getYLoc() * tileHeight + tileGridYOff;
+            if ( ( xloc == wr.getMinX() ) &&
+                 ( yloc == wr.getMinY() ) ) {
+                // Safe to draw in place...
+                drawBlockInPlace( blocks, wr );
+                return;
+            }
+        }
+
+        int workTileWidth = tileWidth;    // local is cheaper
+        int workTileHeight = tileHeight;  // local is cheaper
+        int maxTileSize = 0;
+        for ( int i = 0; i < blocks.length; i++ ) {
+            TileBlock curr = blocks[ i ];
+            int sz = ( ( curr.getWidth() * workTileWidth ) *
+                       ( curr.getHeight() * workTileHeight ) );
+            if ( sz > maxTileSize ) {
+                maxTileSize = sz;
+            }
+        }
+        DataBufferInt dbi = new DataBufferInt( maxTileSize );
+        int [] masks = {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000};
+        boolean use_INT_PACK = GraphicsUtil.is_INT_PACK_Data( wr.getSampleModel(), false );
+
+        // cache for reuse in hasBeenHalted()
+        Thread currentThread = Thread.currentThread();
+
+        for ( int i = 0; i < blocks.length; i++ ) {
+            TileBlock curr = blocks[ i ];
+            int xloc = curr.getXLoc() * workTileWidth + tileGridXOff;
+            int yloc = curr.getYLoc() * workTileHeight + tileGridYOff;
+            Rectangle tb = new Rectangle( xloc, yloc,
+                    curr.getWidth() * workTileWidth,
+                    curr.getHeight() * workTileHeight );
+            tb = tb.intersection( bounds );
+            Point loc = new Point( tb.x, tb.y );
+            WritableRaster child = Raster.createPackedRaster( dbi, tb.width, tb.height, tb.width, masks, loc );
+            genRect( child );
+            if ( use_INT_PACK ) {
+                GraphicsUtil.copyData_INT_PACK( child, wr );
+            } else {
+                GraphicsUtil.copyData_FALLBACK( child, wr );
+            }
+
+            // Check If we should halt early.
+            if ( HaltingThread.hasBeenHalted( currentThread ) ) {
+                return;
+            }
+        }
+    }
+
+
+    protected void drawBlockInPlace( TileBlock [] blocks, WritableRaster wr ) {
+        // System.out.println("Ending Splits: " + blocks.length);
+
+        // cache for reuse in hasBeenHalted()
+        Thread currentThread = Thread.currentThread();
+
+        int workTileWidth = tileWidth;    // local is cheaper
+        int workTileHeight = tileHeight;  // local is cheaper
+
+        for ( int i = 0; i < blocks.length; i++ ) {
+            TileBlock curr = blocks[ i ];
+
+            // System.out.println("Block " + i + ":\n" + curr);
+
+            int xloc = curr.getXLoc() * workTileWidth + tileGridXOff;
+            int yloc = curr.getYLoc() * workTileHeight + tileGridYOff;
+            Rectangle tb = new Rectangle( xloc, yloc,
+                    curr.getWidth() * workTileWidth,
+                    curr.getHeight() * workTileHeight );
+            tb = tb.intersection( bounds );
+
+            WritableRaster child =
+                    wr.createWritableChild( tb.x, tb.y, tb.width, tb.height,
+                            tb.x, tb.y, null );
+            // System.out.println("Computing : " + child);
+            genRect( child );
+
+            // Check If we should halt early.
+            if ( HaltingThread.hasBeenHalted( currentThread ) ) {
+                return;
+            }
+        }
+    }
+}
+

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractTiledRed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AffineRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AffineRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AffineRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AffineRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,261 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+
+/**
+ * This is an implementation of an affine operation as a RenderedImage.
+ * Right now the implementation makes use of the AffineBufferedImageOp
+ * to do the work.  Eventually this may move to be more tiled in nature.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: AffineRed.java 478276 2006-11-22 18:33:37Z dvholten $ */
+public class AffineRed extends AbstractRed {
+
+    RenderingHints  hints;
+    AffineTransform src2me;
+    AffineTransform me2src;
+
+    public AffineTransform getTransform() {
+        return (AffineTransform)src2me.clone();
+    }
+
+    public CachableRed getSource() {
+        return (CachableRed)getSources().get(0);
+    }
+
+    public AffineRed(CachableRed     src,
+                     AffineTransform src2me,
+                     RenderingHints  hints) {
+        super(); // We _must_ call init...
+
+        this.src2me = src2me;
+        this.hints  = hints;
+
+        try {
+            me2src = src2me.createInverse();
+        } catch (NoninvertibleTransformException nite) {
+            me2src = null;
+        }
+
+        // Calculate my bounds by applying the affine transform to
+        // my input data..codec/
+        Rectangle srcBounds = src.getBounds();
+        // srcBounds.grow(-1,-1);
+        Rectangle myBounds;
+        myBounds = src2me.createTransformedShape(srcBounds).getBounds();
+
+        // If the output buffer is not premultiplied in certain cases it
+        // fails to properly divide out the Alpha (it always does
+        // the affine on premultiplied data), hence you get ugly
+        // back aliasing effects...
+        ColorModel cm = fixColorModel(src);
+
+        // fix my sample model so it makes sense given my size.
+        SampleModel sm = fixSampleModel(src, cm, myBounds);
+
+        Point2D pt = new Point2D.Float(src.getTileGridXOffset(),
+                                       src.getTileGridYOffset());
+        pt = src2me.transform(pt, null);
+
+        // Finish initializing our base class...
+        init(src, myBounds, cm, sm,
+             (int)pt.getX(), (int)pt.getY(), null);
+    }
+
+    public WritableRaster copyData(WritableRaster wr) {
+
+        // System.out.println("Affine CopyData:" + wr);
+
+        // copyToRaster(wr);
+        PadRed.ZeroRecter zr = PadRed.ZeroRecter.getZeroRecter(wr);
+        zr.zeroRect(new Rectangle(wr.getMinX(), wr.getMinY(),
+                                  wr.getWidth(), wr.getHeight()));
+        genRect(wr);
+        return wr;
+    }
+
+    public Raster getTile(int x, int y) {
+        if (me2src == null)
+            return null;
+
+        int tx = tileGridXOff+x*tileWidth;
+        int ty = tileGridYOff+y*tileHeight;
+        Point pt = new Point(tx, ty);
+        WritableRaster wr = Raster.createWritableRaster(sm, pt);
+        genRect(wr);
+
+        return wr;
+    }
+
+    public void genRect(WritableRaster wr) {
+        if (me2src == null)
+            return;
+
+        Rectangle srcR
+            = me2src.createTransformedShape(wr.getBounds()).getBounds();
+
+        // System.out.println("Affine wrR: " + wr.getBounds());
+        // System.out.println("Affine srcR: " + srcR);
+
+        // Outset by two pixels so we get context for interpolation...
+        srcR.setBounds(srcR.x-1, srcR.y-1, srcR.width+2, srcR.height+2);
+
+        // Don't try and get data from src that it doesn't have...
+        CachableRed src = (CachableRed)getSources().get(0);
+
+        // Raster srcRas = src.getData(srcR);
+
+        if ( ! srcR.intersects(src.getBounds()) )
+            return;
+        Raster srcRas = src.getData(srcR.intersection(src.getBounds()));
+
+        if (srcRas == null)
+            return;
+
+        // This works around the problem that the buffered ops
+        // completely ignore the coords of the Rasters passed in.
+        AffineTransform aff = (AffineTransform)src2me.clone();
+
+        // Translate what is at 0,0 (which will be what our current
+        // minX/Y is) to our current minX,minY.
+        aff.concatenate(AffineTransform.getTranslateInstance
+                        (srcRas.getMinX(), srcRas.getMinY()));
+
+        Point2D srcPt = new Point2D.Float(wr.getMinX(), wr.getMinY());
+        srcPt         = me2src.transform(srcPt, null);
+
+        Point2D destPt = new Point2D.Double(srcPt.getX()-srcRas.getMinX(),
+                                            srcPt.getY()-srcRas.getMinY());
+
+        destPt = aff.transform(destPt, null);
+
+
+        // Translate what will be at minX,minY to zero, zero
+        // which where java2d will think the real minX,minY is.
+        aff.preConcatenate(AffineTransform.getTranslateInstance
+                           (-destPt.getX(), -destPt.getY()));
+
+        AffineTransformOp op = new AffineTransformOp(aff, hints);
+
+        BufferedImage srcBI, myBI;
+        ColorModel srcCM = src.getColorModel();
+        ColorModel myCM = getColorModel();
+
+        WritableRaster srcWR = (WritableRaster)srcRas;
+        // If the output buffer is not premultiplied in certain cases
+        // it fails to properly divide out the Alpha (it always does
+        // the affine on premultiplied data). We help it out by
+        // premultiplying for it.
+        srcCM = GraphicsUtil.coerceData(srcWR, srcCM, true);
+        srcBI = new BufferedImage(srcCM,
+                                  srcWR.createWritableTranslatedChild(0,0),
+                                  srcCM.isAlphaPremultiplied(), null);
+
+        myBI = new BufferedImage(myCM,wr.createWritableTranslatedChild(0,0),
+                                 myCM.isAlphaPremultiplied(), null);
+
+        op.filter(srcBI, myBI);
+
+        // if ((count % 40) == 0) {
+        //     org.apache.flex.forks.batik.ImageDisplay.showImage("Src: " , srcBI);
+        //     org.apache.flex.forks.batik.ImageDisplay.showImage("Dst: " , myBI);
+        // }
+        // count++;
+    }
+
+    // int count=0;
+
+    protected static ColorModel fixColorModel(CachableRed src) {
+        ColorModel  cm = src.getColorModel();
+
+        if (cm.hasAlpha()) {
+            if (!cm.isAlphaPremultiplied())
+                cm = GraphicsUtil.coerceColorModel(cm, true);
+            return cm;
+        }
+
+        ColorSpace cs = cm.getColorSpace();
+
+        int b = src.getSampleModel().getNumBands()+1;
+        if (b == 4) {
+            int [] masks = new int[4];
+            for (int i=0; i < b-1; i++)
+                masks[i] = 0xFF0000 >> (8*i);
+            masks[3] = 0xFF << (8*(b-1));
+
+            return new DirectColorModel(cs, 8*b, masks[0], masks[1],
+                                        masks[2], masks[3],
+                                        true, DataBuffer.TYPE_INT);
+        }
+
+        int [] bits = new int[b];
+        for (int i=0; i<b; i++)
+            bits[i] = 8;
+        return new ComponentColorModel(cs, bits, true, true,
+                                       Transparency.TRANSLUCENT,
+                                       DataBuffer.TYPE_INT);
+
+    }
+
+    /**
+         * This function 'fixes' the source's sample model.
+         * right now it just ensures that the sample model isn't
+         * much larger than my width.
+         */
+    protected SampleModel fixSampleModel(CachableRed src,
+                                         ColorModel  cm,
+                                         Rectangle   bounds) {
+        SampleModel sm = src.getSampleModel();
+        int defSz = AbstractTiledRed.getDefaultTileSize();
+
+        int w = sm.getWidth();
+        if (w < defSz) w = defSz;
+        if (w > bounds.width)  w = bounds.width;
+        int h = sm.getHeight();
+        if (h < defSz) h = defSz;
+        if (h > bounds.height) h = bounds.height;
+
+        if ((w <= 0) || (h <= 0)) {
+            w = 1;
+            h = 1;
+        }
+
+        return cm.createCompatibleSampleModel(w, h);
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AffineRed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LsRGBRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LsRGBRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LsRGBRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LsRGBRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,301 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.color.ColorSpace;
+import java.awt.image.BandCombineOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+
+/**
+ * This function will tranform an image from any colorspace into a
+ * luminance image.  The alpha channel if any will be copied to the
+ * new image.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: Any2LsRGBRed.java 478276 2006-11-22 18:33:37Z dvholten $ */
+public class Any2LsRGBRed extends AbstractRed {
+
+    boolean srcIssRGB = false;
+
+    /**
+     * Construct a luminace image from src.
+     *
+     * @param src The image to convert to a luminance image
+     */
+    public Any2LsRGBRed(CachableRed src) {
+        super(src,src.getBounds(),
+              fixColorModel(src),
+              fixSampleModel(src),
+              src.getTileGridXOffset(),
+              src.getTileGridYOffset(),
+              null);
+
+        ColorModel srcCM = src.getColorModel();
+        if (srcCM == null) return;
+        ColorSpace srcCS = srcCM.getColorSpace();
+        if (srcCS == ColorSpace.getInstance(ColorSpace.CS_sRGB))
+            srcIssRGB = true;
+    }
+
+    /**
+     * Gamma for linear to sRGB convertion
+     */
+    private static final double GAMMA = 2.4;
+    private static final double LFACT = 1.0/12.92;
+
+
+    public static final double sRGBToLsRGB(double value) {
+        if(value <= 0.003928)
+            return value*LFACT;
+        return Math.pow((value+0.055)/1.055, GAMMA);
+    }
+
+    /**
+     * Lookup tables for RGB lookups. The linearToSRGBLut is used
+     * when noise values are considered to be on a linearScale. The
+     * linearToLinear table is used when the values are considered to
+     * be on the sRGB scale to begin with.
+     */
+    private static final int[] sRGBToLsRGBLut = new int[256];
+    static {
+        final double scale = 1.0/255;
+
+        // System.out.print("S2L: ");
+        for(int i=0; i<256; i++){
+            double value = sRGBToLsRGB(i*scale);
+            sRGBToLsRGBLut[i] = (int)Math.round(value*255.0);
+            // System.out.print(sRGBToLsRGBLut[i] + ",");
+        }
+        // System.out.println("");
+    }
+
+    public WritableRaster copyData(WritableRaster wr) {
+        // Get my source.
+        CachableRed src   = (CachableRed)getSources().get(0);
+        ColorModel  srcCM = src.getColorModel();
+        SampleModel srcSM = src.getSampleModel();
+
+        // Fast case, SRGB source, INT Pack writable raster...
+        if (srcIssRGB &&
+            Any2sRGBRed.is_INT_PACK_COMP(wr.getSampleModel())) {
+            src.copyData(wr);
+            if (srcCM.hasAlpha())
+                GraphicsUtil.coerceData(wr, srcCM, false);
+            Any2sRGBRed.applyLut_INT(wr, sRGBToLsRGBLut);
+            return wr;
+        }
+
+        if (srcCM == null) {
+            // We don't really know much about this source, let's
+            // guess based on the number of bands...
+
+            float [][] matrix = null;
+            switch (srcSM.getNumBands()) {
+            case 1:
+                matrix = new float[1][3];
+                matrix[0][0] = 1; // Red
+                matrix[0][1] = 1; // Grn
+                matrix[0][2] = 1; // Blu
+                break;
+            case 2:
+                matrix = new float[2][4];
+                matrix[0][0] = 1; // Red
+                matrix[0][1] = 1; // Grn
+                matrix[0][2] = 1; // Blu
+                matrix[1][3] = 1; // Alpha
+                break;
+            case 3:
+                matrix = new float[3][3];
+                matrix[0][0] = 1; // Red
+                matrix[1][1] = 1; // Grn
+                matrix[2][2] = 1; // Blu
+                break;
+            default:
+                matrix = new float[srcSM.getNumBands()][4];
+                matrix[0][0] = 1; // Red
+                matrix[1][1] = 1; // Grn
+                matrix[2][2] = 1; // Blu
+                matrix[3][3] = 1; // Alpha
+                break;
+            }
+
+            Raster srcRas = src.getData(wr.getBounds());
+            BandCombineOp op = new BandCombineOp(matrix, null);
+            op.filter(srcRas, wr);
+        } else {
+            ColorModel dstCM = getColorModel();
+            BufferedImage dstBI;
+
+            if (!dstCM.hasAlpha()) {
+                // No alpha ao we don't have to work around the bug
+                // in the color convert op.
+                dstBI = new BufferedImage
+                    (dstCM, wr.createWritableTranslatedChild(0,0),
+                     dstCM.isAlphaPremultiplied(), null);
+            } else {
+                // All this nonsense is to work around the fact that
+                // the Color convert op doesn't properly copy the
+                // Alpha from src to dst.
+                SinglePixelPackedSampleModel dstSM;
+                dstSM = (SinglePixelPackedSampleModel)wr.getSampleModel();
+                int [] masks = dstSM.getBitMasks();
+                SampleModel dstSMNoA = new SinglePixelPackedSampleModel
+                    (dstSM.getDataType(), dstSM.getWidth(), dstSM.getHeight(),
+                     dstSM.getScanlineStride(),
+                     new int[] {masks[0], masks[1], masks[2]});
+                ColorModel dstCMNoA = GraphicsUtil.Linear_sRGB;
+
+                WritableRaster dstWr;
+                dstWr = Raster.createWritableRaster(dstSMNoA,
+                                                    wr.getDataBuffer(),
+                                                    new Point(0,0));
+                dstWr = dstWr.createWritableChild
+                    (wr.getMinX()-wr.getSampleModelTranslateX(),
+                     wr.getMinY()-wr.getSampleModelTranslateY(),
+                     wr.getWidth(), wr.getHeight(),
+                     0, 0, null);
+
+                dstBI = new BufferedImage(dstCMNoA, dstWr, false, null);
+            }
+
+            // Divide out alpha if we have it.  We need to do this since
+            // the color convert may not be a linear operation which may
+            // lead to out of range values.
+            ColorModel srcBICM = srcCM;
+            WritableRaster srcWr;
+            if ( srcCM.hasAlpha() && srcCM.isAlphaPremultiplied() ) {
+                Rectangle wrR = wr.getBounds();
+                SampleModel sm = srcCM.createCompatibleSampleModel
+                    (wrR.width, wrR.height);
+
+                srcWr = Raster.createWritableRaster
+                    (sm, new Point(wrR.x, wrR.y));
+                src.copyData(srcWr);
+                srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false);
+            } else {
+                Raster srcRas = src.getData(wr.getBounds());
+                srcWr = GraphicsUtil.makeRasterWritable(srcRas);
+            }
+
+            BufferedImage srcBI;
+            srcBI = new BufferedImage(srcBICM,
+                                      srcWr.createWritableTranslatedChild(0,0),
+                                      false,
+                                      null);
+
+            /*
+             * System.out.println("src: " + srcBI.getWidth() + "x" +
+             *                    srcBI.getHeight());
+             * System.out.println("dst: " + dstBI.getWidth() + "x" +
+             *                    dstBI.getHeight());
+             */
+
+            ColorConvertOp op = new ColorConvertOp(null);
+            op.filter(srcBI, dstBI);
+
+            if (dstCM.hasAlpha())
+                copyBand(srcWr, srcSM.getNumBands()-1,
+                         wr,    getSampleModel().getNumBands()-1);
+        }
+        return wr;
+    }
+
+        /**
+         * This function 'fixes' the source's color model.  Right now
+         * it just selects if it should have one or two bands based on
+         * if the source had an alpha channel.
+         */
+    protected static ColorModel fixColorModel(CachableRed src) {
+        ColorModel  cm = src.getColorModel();
+        if (cm != null) {
+            if (cm.hasAlpha())
+                return GraphicsUtil.Linear_sRGB_Unpre;
+
+            return GraphicsUtil.Linear_sRGB;
+        }
+        else {
+            // No ColorModel so try to make some intelligent
+            // decisions based just on the number of bands...
+            // 1 bands -> replicated into RGB
+            // 2 bands -> Band 0 replicated into RGB & Band 1 -> alpha premult
+            // 3 bands -> sRGB (not-linear?)
+            // 4 bands -> sRGB premult (not-linear?)
+            SampleModel sm = src.getSampleModel();
+
+            switch (sm.getNumBands()) {
+            case 1:
+                return GraphicsUtil.Linear_sRGB;
+            case 2:
+                return GraphicsUtil.Linear_sRGB_Unpre;
+            case 3:
+                return GraphicsUtil.Linear_sRGB;
+            }
+            return GraphicsUtil.Linear_sRGB_Unpre;
+        }
+    }
+
+    /**
+     * This function 'fixes' the source's sample model.
+     * Right now it just selects if it should have 3 or 4 bands
+     * based on if the source had an alpha channel.
+     */
+    protected static SampleModel fixSampleModel(CachableRed src) {
+        SampleModel sm = src.getSampleModel();
+        ColorModel  cm = src.getColorModel();
+
+        boolean alpha = false;
+
+        if (cm != null)
+            alpha = cm.hasAlpha();
+        else {
+            switch (sm.getNumBands()) {
+            case 1: case 3:
+                alpha = false;
+                break;
+            default:
+                alpha = true;
+                break;
+            }
+        }
+        if (alpha)
+            return new SinglePixelPackedSampleModel
+                (DataBuffer.TYPE_INT,
+                 sm.getWidth(),
+                 sm.getHeight(),
+                 new int [] {0xFF0000, 0xFF00, 0xFF, 0xFF000000});
+        else
+            return new SinglePixelPackedSampleModel
+                (DataBuffer.TYPE_INT,
+                 sm.getWidth(),
+                 sm.getHeight(),
+                 new int [] {0xFF0000, 0xFF00, 0xFF});
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LsRGBRed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LumRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LumRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LumRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LumRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,236 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BandCombineOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.flex.forks.batik.ext.awt.ColorSpaceHintKey;
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+
+/**
+ * This function will tranform an image from any colorspace into a
+ * luminance image.  The alpha channel if any will be copied to the
+ * new image.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: Any2LumRed.java 475477 2006-11-15 22:44:28Z cam $ */
+public class Any2LumRed extends AbstractRed {
+
+    /**
+     * Construct a luminace image from src.
+     *
+     * @param src The image to convert to a luminance image
+     */
+    public Any2LumRed(CachableRed src) {
+        super(src,src.getBounds(), 
+              fixColorModel(src),
+              fixSampleModel(src),
+              src.getTileGridXOffset(),
+              src.getTileGridYOffset(),
+              null);
+
+        props.put(ColorSpaceHintKey.PROPERTY_COLORSPACE,
+                  ColorSpaceHintKey.VALUE_COLORSPACE_GREY);
+    }
+
+    public WritableRaster copyData(WritableRaster wr) {
+        // Get my source.
+        CachableRed src = (CachableRed)getSources().get(0);
+
+        SampleModel sm     = src.getSampleModel();
+        ColorModel  srcCM  = src.getColorModel();
+        Raster      srcRas = src.getData(wr.getBounds());
+        if (srcCM == null) {
+            // We don't really know much about this source.
+
+            float [][] matrix = null;
+            if (sm.getNumBands() == 2) {
+                matrix = new float[2][2];
+                matrix[0][0] = 1;
+                matrix[1][1] = 1;
+            } else {
+                matrix = new float[sm.getNumBands()][1];
+                matrix[0][0] = 1;
+            }
+
+            BandCombineOp op = new BandCombineOp(matrix, null);
+            op.filter(srcRas, wr);
+        } else {
+            WritableRaster srcWr  = (WritableRaster)srcRas;
+
+            // Divide out alpha if we have it.  We need to do this since
+            // the color convert may not be a linear operation which may 
+            // lead to out of range values.
+            if (srcCM.hasAlpha())
+                GraphicsUtil.coerceData(srcWr, srcCM, false);
+
+            BufferedImage srcBI, dstBI;
+            srcBI = new BufferedImage(srcCM, 
+                                      srcWr.createWritableTranslatedChild(0,0),
+                                      false, 
+                                      null);
+            ColorModel dstCM = getColorModel();
+            if (!dstCM.hasAlpha()) {
+                // No alpha ao we don't have to work around the bug
+                // in the color convert op.
+                dstBI = new BufferedImage
+                    (dstCM, wr.createWritableTranslatedChild(0,0),
+                     dstCM.isAlphaPremultiplied(), null);
+            } else {
+                // All this nonsense is to work around the fact that the
+                // Color convert op doesn't properly copy the Alpha from
+                // src to dst.
+                PixelInterleavedSampleModel dstSM;
+                dstSM = (PixelInterleavedSampleModel)wr.getSampleModel();
+                SampleModel smna = new PixelInterleavedSampleModel
+                    (dstSM.getDataType(),    
+                     dstSM.getWidth(),       dstSM.getHeight(),
+                     dstSM.getPixelStride(), dstSM.getScanlineStride(),
+                     new int [] { 0 });
+
+                WritableRaster dstWr;
+                dstWr = Raster.createWritableRaster(smna,
+                                                    wr.getDataBuffer(),
+                                                    new Point(0,0));
+                dstWr = dstWr.createWritableChild
+                    (wr.getMinX()-wr.getSampleModelTranslateX(),
+                     wr.getMinY()-wr.getSampleModelTranslateY(),
+                     wr.getWidth(), wr.getHeight(),
+                     0, 0, null);
+                
+                ColorModel cmna = new ComponentColorModel
+                    (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                     new int [] {8}, false, false,
+                     Transparency.OPAQUE, 
+                     DataBuffer.TYPE_BYTE);
+
+                dstBI = new BufferedImage(cmna, dstWr, false, null);
+            }
+
+            ColorConvertOp op = new ColorConvertOp(null);
+            op.filter(srcBI, dstBI);
+
+            // Have to 'fix' alpha premult
+            if (dstCM.hasAlpha()) {
+                copyBand(srcWr, sm.getNumBands()-1,
+                         wr,    getSampleModel().getNumBands()-1);
+                if (dstCM.isAlphaPremultiplied())
+                    GraphicsUtil.multiplyAlpha(wr);
+            }
+        }
+        return wr;
+    }
+
+    /**
+     * This function 'fixes' the source's color model.  Right now
+     * it just selects if it should have one or two bands based on
+     * if the source had an alpha channel.
+     */
+    protected static ColorModel fixColorModel(CachableRed src) {
+        ColorModel  cm = src.getColorModel();
+        if (cm != null) {
+            if (cm.hasAlpha())
+                return new ComponentColorModel
+                    (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                     new int [] {8,8}, true,
+                     cm.isAlphaPremultiplied(),
+                     Transparency.TRANSLUCENT, 
+                     DataBuffer.TYPE_BYTE);
+
+            return new ComponentColorModel
+                (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                 new int [] {8}, false, false,
+                 Transparency.OPAQUE, 
+                 DataBuffer.TYPE_BYTE);
+        } 
+        else {
+            // No ColorModel so try to make some intelligent
+            // decisions based just on the number of bands...
+            // 1 bands -> lum
+            // 2 bands -> lum (Band 0) & alpha (Band 1)
+            // >2 bands -> lum (Band 0) - No color conversion...
+            SampleModel sm = src.getSampleModel();
+
+            if (sm.getNumBands() == 2)
+                return new ComponentColorModel
+                    (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                     new int [] {8,8}, true,
+                     true, Transparency.TRANSLUCENT, 
+                     DataBuffer.TYPE_BYTE);
+
+            return new ComponentColorModel
+                (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                 new int [] {8}, false, false,
+                 Transparency.OPAQUE, 
+                 DataBuffer.TYPE_BYTE);
+        }
+    }
+
+    /**
+     * This function 'fixes' the source's sample model.
+     * Right now it just selects if it should have one or two bands
+     * based on if the source had an alpha channel.
+     */
+    protected static SampleModel fixSampleModel(CachableRed src) {
+        SampleModel sm = src.getSampleModel();
+
+        int width  = sm.getWidth();
+        int height = sm.getHeight();
+
+        ColorModel  cm = src.getColorModel();
+        if (cm != null) {
+            if (cm.hasAlpha()) 
+                return new PixelInterleavedSampleModel
+                    (DataBuffer.TYPE_BYTE, width, height, 2, 2*width,
+                     new int [] { 0, 1 });
+
+            return new PixelInterleavedSampleModel
+                (DataBuffer.TYPE_BYTE, width, height, 1, width,
+                 new int [] { 0 });
+        }
+        else {
+            // No ColorModel so try to make some intelligent
+            // decisions based just on the number of bands...
+            // 1 bands -> lum
+            // 2 bands -> lum (Band 0) & alpha (Band 1)
+            // >2 bands -> lum (Band 0) - No color conversion...
+            if (sm.getNumBands() == 2)
+                return new PixelInterleavedSampleModel
+                    (DataBuffer.TYPE_BYTE, width, height, 2, 2*width,
+                     new int [] { 0, 1 });
+
+            return new PixelInterleavedSampleModel
+                (DataBuffer.TYPE_BYTE, width, height, 1, width,
+                 new int [] { 0 });
+        }
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2LumRed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2sRGBRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2sRGBRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2sRGBRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2sRGBRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,364 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+
+import java.awt.color.ColorSpace;
+import java.awt.image.BandCombineOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+
+/**
+ * This function will tranform an image from any colorspace into a
+ * luminance image.  The alpha channel if any will be copied to the
+ * new image.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: Any2sRGBRed.java 537934 2007-05-14 18:23:15Z dvholten $
+ */
+public class Any2sRGBRed extends AbstractRed {
+
+    boolean srcIsLsRGB = false;
+
+    /**
+     * Construct a luminance image from src.
+     *
+     * @param src The image to convert to a luminance image
+     */
+    public Any2sRGBRed(CachableRed src) {
+        super(src,src.getBounds(),
+              fixColorModel(src),
+              fixSampleModel(src),
+              src.getTileGridXOffset(),
+              src.getTileGridYOffset(),
+              null);
+
+        ColorModel srcCM = src.getColorModel();
+        if (srcCM == null) return;
+        ColorSpace srcCS = srcCM.getColorSpace();
+        if (srcCS == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))
+            srcIsLsRGB = true;
+    }
+
+    public static boolean is_INT_PACK_COMP(SampleModel sm) {
+        if(!(sm instanceof SinglePixelPackedSampleModel)) return false;
+
+        // Check transfer types
+        if(sm.getDataType() != DataBuffer.TYPE_INT)       return false;
+
+        SinglePixelPackedSampleModel sppsm;
+        sppsm = (SinglePixelPackedSampleModel)sm;
+
+        int [] masks = sppsm.getBitMasks();
+        if ((masks.length != 3) && (masks.length != 4)) return false;
+        if(masks[0] != 0x00ff0000) return false;
+        if(masks[1] != 0x0000ff00) return false;
+        if(masks[2] != 0x000000ff) return false;
+        if ((masks.length == 4) &&
+            (masks[3] != 0xff000000)) return false;
+
+        return true;
+   }
+
+    /**
+     * Exponent for linear to sRGB convertion
+     */
+    private static final double GAMMA = 2.4;
+
+    /**
+     * Lookup tables for RGB lookups. The linearToSRGBLut is used
+     * when noise values are considered to be on a linearScale. The
+     * linearToLinear table is used when the values are considered to
+     * be on the sRGB scale to begin with.
+     */
+    private static final int[] linearToSRGBLut = new int[256];
+
+    static {
+        final double scale = 1.0/255;
+        final double exp   = 1.0/GAMMA;
+        // System.out.print("L2S: ");
+        for(int i=0; i<256; i++){
+            double value = i*scale;
+            if(value <= 0.0031308)
+                value *= 12.92;
+            else
+                value = 1.055 * Math.pow(value, exp) - 0.055;
+
+            linearToSRGBLut[i] = (int)Math.round(value*255.0);
+            // System.out.print(linearToSRGBLut[i] + ",");
+        }
+        // System.out.println("");
+    }
+
+    public static WritableRaster applyLut_INT(WritableRaster wr,
+                                              final int []lut) {
+        SinglePixelPackedSampleModel sm =
+            (SinglePixelPackedSampleModel)wr.getSampleModel();
+        DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
+
+        final int     srcBase
+            = (db.getOffset() +
+               sm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
+                            wr.getMinY()-wr.getSampleModelTranslateY()));
+        // Access the pixel data array
+        final int[] pixels   = db.getBankData()[0];
+        final int width      = wr.getWidth();
+        final int height     = wr.getHeight();
+        final int scanStride = sm.getScanlineStride();
+
+        int end, pix;
+
+        // For alpha premult we need to multiply all comps.
+        for (int y=0; y<height; y++) {
+            int sp  = srcBase + y*scanStride;
+            end = sp + width;
+
+            while (sp<end) {
+                pix = pixels[sp];
+                pixels[sp] =
+                    ((     pix      &0xFF000000)|
+                     (lut[(pix>>>16)&0xFF]<<16) |
+                     (lut[(pix>>> 8)&0xFF]<< 8) |
+                     (lut[(pix     )&0xFF]    ));
+                sp++;
+            }
+        }
+
+        return wr;
+    }
+
+    public WritableRaster copyData(WritableRaster wr) {
+
+        // Get my source.
+        CachableRed src   = (CachableRed)getSources().get(0);
+        ColorModel  srcCM = src.getColorModel();
+        SampleModel srcSM = src.getSampleModel();
+
+
+        // Fast case, Linear SRGB source, INT Pack writable raster...
+        if (srcIsLsRGB &&
+            is_INT_PACK_COMP(wr.getSampleModel())) {
+            src.copyData(wr);
+            if (srcCM.hasAlpha())
+                GraphicsUtil.coerceData(wr, srcCM, false);
+            applyLut_INT(wr, linearToSRGBLut);
+            return wr;
+        }
+
+        if (srcCM == null) {
+            // We don't really know much about this source, let's
+            // guess based on the number of bands...
+
+            float [][] matrix = null;
+            switch (srcSM.getNumBands()) {
+            case 1:
+                matrix = new float[3][1];
+                matrix[0][0] = 1; // Red
+                matrix[1][0] = 1; // Grn
+                matrix[2][0] = 1; // Blu
+                break;
+            case 2:
+                matrix = new float[4][2];
+                matrix[0][0] = 1; // Red
+                matrix[1][0] = 1; // Grn
+                matrix[2][0] = 1; // Blu
+                matrix[3][1] = 1; // Alpha
+                break;
+            case 3:
+                matrix = new float[3][3];
+                matrix[0][0] = 1; // Red
+                matrix[1][1] = 1; // Grn
+                matrix[2][2] = 1; // Blu
+                break;
+            default:
+                matrix = new float[4][srcSM.getNumBands()];
+                matrix[0][0] = 1; // Red
+                matrix[1][1] = 1; // Grn
+                matrix[2][2] = 1; // Blu
+                matrix[3][3] = 1; // Alpha
+                break;
+            }
+            Raster srcRas = src.getData(wr.getBounds());
+            BandCombineOp op = new BandCombineOp(matrix, null);
+            op.filter(srcRas, wr);
+            return wr;
+        }
+
+        if (srcCM.getColorSpace() ==
+            ColorSpace.getInstance(ColorSpace.CS_GRAY)) {
+
+            // This is a little bit of a hack.  There is only
+            // a linear grayscale ICC profile in the JDK so
+            // many things use this when the data _really_
+            // has sRGB gamma applied.
+            try {
+                float [][] matrix = null;
+                switch (srcSM.getNumBands()) {
+                case 1:
+                    matrix = new float[3][1];
+                    matrix[0][0] = 1; // Red
+                    matrix[1][0] = 1; // Grn
+                    matrix[2][0] = 1; // Blu
+                    break;
+                case 2:
+                default:
+                    matrix = new float[4][2];
+                    matrix[0][0] = 1; // Red
+                    matrix[1][0] = 1; // Grn
+                    matrix[2][0] = 1; // Blu
+                    matrix[3][1] = 1; // Alpha
+                    break;
+                }
+                Raster srcRas = src.getData(wr.getBounds());
+                BandCombineOp op = new BandCombineOp(matrix, null);
+                op.filter(srcRas, wr);
+            } catch (Throwable t) {
+                t.printStackTrace();
+            }
+            return wr;
+        }
+
+        ColorModel dstCM = getColorModel();
+        if (srcCM.getColorSpace() == dstCM.getColorSpace()) {
+            // No transform needed, just reformat data...
+            // System.out.println("Bypassing");
+
+            if (is_INT_PACK_COMP(srcSM))
+                src.copyData(wr);
+            else
+                GraphicsUtil.copyData(src.getData(wr.getBounds()), wr);
+
+            return wr;
+        }
+
+        Raster srcRas = src.getData(wr.getBounds());
+        WritableRaster srcWr  = (WritableRaster)srcRas;
+
+        // Divide out alpha if we have it.  We need to do this since
+        // the color convert may not be a linear operation which may
+        // lead to out of range values.
+        ColorModel srcBICM = srcCM;
+        if (srcCM.hasAlpha())
+            srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false);
+
+        BufferedImage srcBI, dstBI;
+        srcBI = new BufferedImage(srcBICM,
+                                  srcWr.createWritableTranslatedChild(0,0),
+                                  false,
+                                  null);
+
+        // System.out.println("src: " + srcBI.getWidth() + "x" +
+        //                    srcBI.getHeight());
+
+        ColorConvertOp op = new ColorConvertOp(dstCM.getColorSpace(),
+                                               null);
+        dstBI = op.filter(srcBI, null);
+
+        // System.out.println("After filter:");
+
+        WritableRaster wr00 = wr.createWritableTranslatedChild(0,0);
+        for (int i=0; i<dstCM.getColorSpace().getNumComponents(); i++)
+            copyBand(dstBI.getRaster(), i, wr00,    i);
+
+        if (dstCM.hasAlpha())
+            copyBand(srcWr, srcSM.getNumBands()-1,
+                     wr,    getSampleModel().getNumBands()-1);
+        return wr;
+    }
+
+    /**
+     * This function 'fixes' the source's color model.  Right now
+     * it just selects if it should have one or two bands based on
+     * if the source had an alpha channel.
+     */
+    protected static ColorModel fixColorModel(CachableRed src) {
+        ColorModel  cm = src.getColorModel();
+        if (cm != null) {
+            if (cm.hasAlpha())
+                return GraphicsUtil.sRGB_Unpre;
+
+            return GraphicsUtil.sRGB;
+        }
+        else {
+            // No ColorModel so try to make some intelligent
+            // decisions based just on the number of bands...
+            // 1 bands -> replicated into RGB
+            // 2 bands -> Band 0 replicated into RGB & Band 1 -> alpha premult
+            // 3 bands -> sRGB (not-linear?)
+            // 4 bands -> sRGB premult (not-linear?)
+            SampleModel sm = src.getSampleModel();
+
+            switch (sm.getNumBands()) {
+            case 1:
+                return GraphicsUtil.sRGB;
+            case 2:
+                return GraphicsUtil.sRGB_Unpre;
+            case 3:
+                return GraphicsUtil.sRGB;
+            }
+            return GraphicsUtil.sRGB_Unpre;
+        }
+    }
+
+    /**
+     * This function 'fixes' the source's sample model.
+     * Right now it just selects if it should have 3 or 4 bands
+     * based on if the source had an alpha channel.
+     */
+    protected static SampleModel fixSampleModel(CachableRed src) {
+        SampleModel sm = src.getSampleModel();
+        ColorModel  cm = src.getColorModel();
+
+        boolean alpha = false;
+
+        if (cm != null)
+            alpha = cm.hasAlpha();
+        else {
+            switch (sm.getNumBands()) {
+            case 1: case 3:
+                alpha = false;
+                break;
+            default:
+                alpha = true;
+                break;
+            }
+        }
+        if (alpha)
+            return new SinglePixelPackedSampleModel
+                (DataBuffer.TYPE_INT,
+                 sm.getWidth(),
+                 sm.getHeight(),
+                 new int [] {0xFF0000, 0xFF00, 0xFF, 0xFF000000});
+        else
+            return new SinglePixelPackedSampleModel
+                (DataBuffer.TYPE_INT,
+                 sm.getWidth(),
+                 sm.getHeight(),
+                 new int [] {0xFF0000, 0xFF00, 0xFF});
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/Any2sRGBRed.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/BufferedImageCachableRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/BufferedImageCachableRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/BufferedImageCachableRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/BufferedImageCachableRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,135 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+/**
+ * This implements CachableRed based on a BufferedImage.
+ * You can use this to wrap a BufferedImage that you want to
+ * appear as a CachableRed.
+ * It essentially ignores the dependency and dirty region methods.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: BufferedImageCachableRed.java 478276 2006-11-22 18:33:37Z dvholten $ */
+public class BufferedImageCachableRed extends AbstractRed {
+    // The bufferedImage that we wrap...
+    BufferedImage bi;
+
+    /**
+     * Construct an instance of CachableRed around a BufferedImage.
+     */
+    public BufferedImageCachableRed(BufferedImage bi) {
+        super((CachableRed)null,
+              new Rectangle(bi.getMinX(),  bi.getMinY(),
+                            bi.getWidth(), bi.getHeight()),
+              bi.getColorModel(), bi.getSampleModel(),
+              bi.getMinX(), bi.getMinY(), null);
+
+        this.bi = bi;
+    }
+
+    public BufferedImageCachableRed(BufferedImage bi,
+                                            int xloc, int yloc) {
+        super((CachableRed)null, new Rectangle(xloc,  yloc,
+                                               bi.getWidth(),
+                                               bi.getHeight()),
+              bi.getColorModel(), bi.getSampleModel(), xloc, yloc, null);
+
+        this.bi = bi;
+    }
+
+    public Rectangle getBounds() {
+        return new Rectangle(getMinX(),
+                             getMinY(),
+                             getWidth(),
+                             getHeight());
+    }
+
+    /**
+     * fetch the bufferedImage from this node.
+     */
+    public BufferedImage getBufferedImage() {
+        return bi;
+    }
+
+    public Object getProperty(String name) {
+        return bi.getProperty(name);
+    }
+
+    public String [] getPropertyNames() {
+        return bi.getPropertyNames();
+    }
+
+    public Raster getTile(int tileX, int tileY) {
+        return bi.getTile(tileX,tileY);
+    }
+
+    public Raster getData() {
+        Raster r = bi.getData();
+        return r.createTranslatedChild(getMinX(), getMinY());
+    }
+
+    public Raster getData(Rectangle rect) {
+        Rectangle r = (Rectangle)rect.clone();
+
+        if ( ! r.intersects(getBounds()) )
+            return null;
+        r = r.intersection(getBounds());
+        r.translate(-getMinX(), - getMinY());
+
+        Raster ret = bi.getData(r);
+        return ret.createTranslatedChild(ret.getMinX()+getMinX(),
+                                         ret.getMinY()+getMinY());
+    }
+
+    public WritableRaster copyData(WritableRaster wr) {
+        WritableRaster wr2 = wr.createWritableTranslatedChild
+            (wr.getMinX()-getMinX(),
+             wr.getMinY()-getMinY());
+
+        GraphicsUtil.copyData(bi.getRaster(), wr2);
+
+        /* This was the original code. This is _bad_ since it causes a
+         * multiply and divide of the alpha channel to do the draw
+         * operation.  I believe that at some point I switched to
+         * drawImage in order to avoid some issues with
+         * BufferedImage's copyData implementation but I can't
+         * reproduce them now. Anyway I'm now using GraphicsUtil which
+         * should generally be as fast if not faster...
+         */
+        /*
+          BufferedImage dest;
+         dest = new BufferedImage(bi.getColorModel(),
+                                  wr.createWritableTranslatedChild(0,0),
+                                  bi.getColorModel().isAlphaPremultiplied(),
+                                  null);
+         java.awt.Graphics2D g2d = dest.createGraphics();
+         g2d.drawImage(bi, null, getMinX()-wr.getMinX(),
+                       getMinY()-wr.getMinY());
+         g2d.dispose();
+         */
+        return wr;
+    }
+}

Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/BufferedImageCachableRed.java
------------------------------------------------------------------------------
    svn:eol-style = native