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 [9/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/pn...

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/GraphicsUtil.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/GraphicsUtil.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/GraphicsUtil.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/GraphicsUtil.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,1615 @@
+/*
+
+   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;
+
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.RenderContext;
+import java.awt.image.renderable.RenderableImage;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+import org.apache.flex.forks.batik.ext.awt.RenderingHintsKeyExt;
+import org.apache.flex.forks.batik.ext.awt.image.renderable.PaintRable;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.AffineRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.Any2LsRGBRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.Any2sRGBRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.BufferedImageCachableRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.CachableRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.FormatRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.RenderedImageCachableRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.TranslateRed;
+
+
+/**
+ * Set of utility methods for Graphics.
+ * These generally bypass broken methods in Java2D or provide tweaked
+ * implementations.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: GraphicsUtil.java 579990 2007-09-27 12:43:14Z cam $
+ */
+public class GraphicsUtil {
+
+    public static AffineTransform IDENTITY = new AffineTransform();
+
+    /**
+     * Draws <tt>ri</tt> into <tt>g2d</tt>.  It does this be
+     * requesting tiles from <tt>ri</tt> and drawing them individually
+     * in <tt>g2d</tt> it also takes care of some colorspace and alpha
+     * issues.
+     * @param g2d The Graphics2D to draw into.
+     * @param ri  The image to be drawn.
+     */
+    public static void drawImage(Graphics2D g2d,
+                                 RenderedImage ri) {
+        drawImage(g2d, wrap(ri));
+    }
+
+    /**
+     * Draws <tt>cr</tt> into <tt>g2d</tt>.  It does this be
+     * requesting tiles from <tt>ri</tt> and drawing them individually
+     * in <tt>g2d</tt> it also takes care of some colorspace and alpha
+     * issues.
+     * @param g2d The Graphics2D to draw into.
+     * @param cr  The image to be drawn.
+     */
+    public static void drawImage(Graphics2D g2d,
+                                 CachableRed cr) {
+
+        // System.out.println("DrawImage G: " + g2d);
+
+        AffineTransform at = null;
+        while (true) {
+            if (cr instanceof AffineRed) {
+                AffineRed ar = (AffineRed)cr;
+                if (at == null)
+                    at = ar.getTransform();
+                else
+                    at.concatenate(ar.getTransform());
+                cr = ar.getSource();
+                continue;
+            } else if (cr instanceof TranslateRed) {
+                TranslateRed tr = (TranslateRed)cr;
+                // System.out.println("testing Translate");
+                int dx = tr.getDeltaX();
+                int dy = tr.getDeltaY();
+                if (at == null)
+                    at = AffineTransform.getTranslateInstance(dx, dy);
+                else
+                    at.translate(dx, dy);
+                cr = tr.getSource();
+                continue;
+            }
+            break;
+        }
+        AffineTransform g2dAt   = g2d.getTransform();
+        if ((at == null) || (at.isIdentity()))
+            at = g2dAt;
+        else
+            at.preConcatenate(g2dAt);
+
+        ColorModel srcCM = cr.getColorModel();
+        ColorModel g2dCM = getDestinationColorModel(g2d);
+        ColorSpace g2dCS = null;
+        if (g2dCM != null)
+            g2dCS = g2dCM.getColorSpace();
+        if (g2dCS == null)
+            // Assume device is sRGB
+            g2dCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+
+        ColorModel drawCM = g2dCM;
+        if ((g2dCM == null) || !g2dCM.hasAlpha()) {
+            // If we can't find out about our device or the device
+            // does not support alpha just use SRGB unpremultiplied
+            // (Just because this seems to work for us).
+            drawCM = sRGB_Unpre;
+        }
+
+        if (cr instanceof BufferedImageCachableRed) {
+            // There is a huge win if we can use the BI directly here.
+            // This results in something like a 10x performance gain
+            // for images, the best thing is this is the common case.
+            if (g2dCS.equals(srcCM.getColorSpace()) &&
+                drawCM.equals(srcCM)) {
+                // System.err.println("Fast Case");
+                g2d.setTransform(at);
+                BufferedImageCachableRed bicr;
+                bicr = (BufferedImageCachableRed)cr;
+                g2d.drawImage(bicr.getBufferedImage(),
+                              bicr.getMinX(), bicr.getMinY(), null);
+                g2d.setTransform(g2dAt);
+                return;
+            }
+        }
+
+        // Scaling down so do it before color conversion.
+        double determinant = at.getDeterminant();
+        if (!at.isIdentity() && (determinant <= 1.0)) {
+            if (at.getType() != AffineTransform.TYPE_TRANSLATION)
+                cr = new AffineRed(cr, at, g2d.getRenderingHints());
+            else {
+                int xloc = cr.getMinX() + (int)at.getTranslateX();
+                int yloc = cr.getMinY() + (int)at.getTranslateY();
+                cr = new TranslateRed(cr, xloc, yloc);
+            }
+        }
+
+        if (g2dCS != srcCM.getColorSpace()) {
+            // System.out.println("srcCS: " + srcCM.getColorSpace());
+            // System.out.println("g2dCS: " + g2dCS);
+            // System.out.println("sRGB: " +
+            //                    ColorSpace.getInstance(ColorSpace.CS_sRGB));
+            // System.out.println("LsRGB: " +
+            //                    ColorSpace.getInstance
+            //                    (ColorSpace.CS_LINEAR_RGB));
+            if      (g2dCS == ColorSpace.getInstance(ColorSpace.CS_sRGB))
+                cr = convertTosRGB(cr);
+            else if (g2dCS == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))
+                cr = convertToLsRGB(cr);
+        }
+        srcCM = cr.getColorModel();
+        if (!drawCM.equals(srcCM))
+            cr = FormatRed.construct(cr, drawCM);
+
+        // Scaling up so do it after color conversion.
+        if (!at.isIdentity() && (determinant > 1.0))
+            cr = new AffineRed(cr, at, g2d.getRenderingHints());
+
+        // Now CR is in device space, so clear the g2d transform.
+        g2d.setTransform(IDENTITY);
+
+        // Ugly Hack alert.  This Makes it use our SrcOver implementation
+        // Which doesn't seem to have as many bugs as the JDK one when
+        // going between different src's and destinations (of course it's
+        // also a lot slower).
+        Composite g2dComposite = g2d.getComposite();
+        if (g2d.getRenderingHint(RenderingHintsKeyExt.KEY_TRANSCODING) ==
+            RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING) {
+            if (SVGComposite.OVER.equals(g2dComposite)) {
+                g2d.setComposite(SVGComposite.OVER);
+            }
+        }
+        Rectangle crR  = cr.getBounds();
+        Shape     clip = g2d.getClip();
+
+        try {
+            Rectangle clipR;
+            if (clip == null) {
+                clip  = crR;
+                clipR = crR;
+            } else {
+                clipR   = clip.getBounds();
+
+                if ( ! clipR.intersects(crR) )
+                    return; // Nothing to draw...
+                clipR = clipR.intersection(crR);
+            }
+
+            Rectangle gcR = getDestinationBounds(g2d);
+            // System.out.println("ClipRects: " + clipR + " -> " + gcR);
+            if (gcR != null) {
+                if ( ! clipR.intersects(gcR) )
+                    return; // Nothing to draw...
+                clipR = clipR.intersection(gcR);
+            }
+
+            // System.out.println("Starting Draw: " + cr);
+            // long startTime = System.currentTimeMillis();
+
+            boolean useDrawRenderedImage = false;
+
+            srcCM = cr.getColorModel();
+            SampleModel srcSM = cr.getSampleModel();
+            if ((srcSM.getWidth()*srcSM.getHeight()) >=
+                (clipR.width*clipR.height))
+                // if srcSM tiles are around the clip size
+                // then just draw the renderedImage
+                useDrawRenderedImage = true;
+
+            Object atpHint = g2d.getRenderingHint
+                (RenderingHintsKeyExt.KEY_AVOID_TILE_PAINTING);
+
+            if (atpHint == RenderingHintsKeyExt.VALUE_AVOID_TILE_PAINTING_ON)
+                useDrawRenderedImage = true; //for PDF and PS transcoders
+
+            if (atpHint == RenderingHintsKeyExt.VALUE_AVOID_TILE_PAINTING_OFF)
+                useDrawRenderedImage = false;
+
+
+            WritableRaster wr;
+            if (useDrawRenderedImage) {
+                // This can be significantly faster but can also
+                // require much more memory, so we only use it when
+                // the clip size is smaller than the tile size.
+                Raster r = cr.getData(clipR);
+                wr = ((WritableRaster)r).createWritableChild
+                    (clipR.x, clipR.y, clipR.width, clipR.height,
+                     0, 0, null);
+
+                BufferedImage bi = new BufferedImage
+                    (srcCM, wr, srcCM.isAlphaPremultiplied(), null);
+
+                // Any of the drawImage calls that take an
+                // Affine are prone to the 'CGGStackRestore: gstack
+                // underflow' bug on Mac OS X.  This should work
+                // around that problem.
+                g2d.drawImage(bi, clipR.x, clipR.y, null);
+            } else {
+                // Use tiles to draw image...
+                wr = Raster.createWritableRaster(srcSM, new Point(0,0));
+                BufferedImage bi = new BufferedImage
+                    (srcCM, wr, srcCM.isAlphaPremultiplied(), null);
+
+                int xt0 = cr.getMinTileX();
+                int xt1 = xt0+cr.getNumXTiles();
+                int yt0 = cr.getMinTileY();
+                int yt1 = yt0+cr.getNumYTiles();
+                int tw  = srcSM.getWidth();
+                int th  = srcSM.getHeight();
+
+                Rectangle tR  = new Rectangle(0,0,tw,th);
+                Rectangle iR  = new Rectangle(0,0,0,0);
+
+                if (false) {
+                    System.err.println("SrcCM: " + srcCM);
+                    System.err.println("CR: " + cr);
+                    System.err.println("CRR: " + crR + " TG: [" +
+                                       xt0 + ',' +
+                                       yt0 + ',' +
+                                       xt1 + ',' +
+                                       yt1 +"] Off: " +
+                                       cr.getTileGridXOffset() + ',' +
+                                       cr.getTileGridYOffset());
+                }
+
+                int yloc = yt0*th+cr.getTileGridYOffset();
+                int skip = (clipR.y-yloc)/th;
+                if (skip <0) skip = 0;
+                yt0+=skip;
+
+                int xloc = xt0*tw+cr.getTileGridXOffset();
+                skip = (clipR.x-xloc)/tw;
+                if (skip <0) skip = 0;
+                xt0+=skip;
+
+                int endX = clipR.x+clipR.width-1;
+                int endY = clipR.y+clipR.height-1;
+
+                if (false) {
+                    System.out.println("clipR: " + clipR + " TG: [" +
+                                       xt0 + ',' +
+                                       yt0 + ',' +
+                                       xt1 + ',' +
+                                       yt1 +"] Off: " +
+                                       cr.getTileGridXOffset() + ',' +
+                                       cr.getTileGridYOffset());
+                }
+
+
+                yloc = yt0*th+cr.getTileGridYOffset();
+                int minX = xt0*tw+cr.getTileGridXOffset();
+                int xStep = tw;
+                xloc = minX;
+                for (int y=yt0; y<yt1; y++, yloc += th) {
+                    if (yloc > endY) break;
+                    for (int x=xt0; x<xt1; x++, xloc+=xStep) {
+                        if ((xloc<minX) || (xloc > endX)) break;
+                        tR.x = xloc;
+                        tR.y = yloc;
+                        Rectangle2D.intersect(crR, tR, iR);
+
+                        WritableRaster twr;
+                        twr = wr.createWritableChild(0, 0,
+                                                     iR.width, iR.height,
+                                                     iR.x, iR.y, null);
+
+                        // System.out.println("Generating tile: " + twr);
+                        cr.copyData(twr);
+
+                        // Make sure we only draw the region that was written.
+                        BufferedImage subBI;
+                        subBI = bi.getSubimage(0, 0, iR.width,  iR.height);
+
+                        if (false) {
+                            System.out.println("Drawing: " + tR);
+                            System.out.println("IR: "      + iR);
+                        }
+
+                        // For some reason using the transform version
+                        // causes a gStackUnderflow error but if I just
+                        // use the drawImage with an x & y it works.
+                        g2d.drawImage(subBI, iR.x, iR.y, null);
+                        // AffineTransform trans
+                        //  = AffineTransform.getTranslateInstance(iR.x, iR.y);
+                        // g2d.drawImage(subBI, trans, null);
+
+                        // String label = "sub [" + x + ", " + y + "]: ";
+                        // org.ImageDisplay.showImage
+                        //     (label, subBI);
+                    }
+                    xStep = -xStep; // Reverse directions.
+                    xloc += xStep;   // Get back in bounds.
+                }
+            }
+            // long endTime = System.currentTimeMillis();
+            // System.out.println("Time: " + (endTime-startTime));
+
+
+        } finally {
+            g2d.setTransform(g2dAt);
+            g2d.setComposite(g2dComposite);
+        }
+
+        // System.out.println("Finished Draw");
+    }
+
+
+    /**
+     * Draws a <tt>Filter</tt> (<tt>RenderableImage</tt>) into a
+     * Graphics 2D after taking into account a particular
+     * <tt>RenderContext</tt>.<p>
+     *
+     * This method also attempts to unwind the rendering chain a bit.
+     * So it knows about certain operations (like affine, pad,
+     * composite), rather than applying each of these operations in
+     * turn it accounts for their affects through modifications to the
+     * Graphics2D. This avoids generating lots of intermediate images.
+     *
+     * @param g2d    The Graphics to draw into.
+     * @param filter The filter to draw
+     * @param rc The render context that controls the drawing operation.
+     */
+    public static void drawImage(Graphics2D      g2d,
+                                 RenderableImage filter,
+                                 RenderContext   rc) {
+
+        AffineTransform origDev  = g2d.getTransform();
+        Shape           origClip = g2d.getClip();
+        RenderingHints  origRH   = g2d.getRenderingHints();
+
+        Shape clip = rc.getAreaOfInterest();
+        if (clip != null)
+            g2d.clip(clip);
+        g2d.transform(rc.getTransform());
+        g2d.setRenderingHints(rc.getRenderingHints());
+
+        drawImage(g2d, filter);
+
+        g2d.setTransform(origDev);
+        g2d.setClip(origClip);
+        g2d.setRenderingHints(origRH);
+    }
+
+    /**
+     * Draws a <tt>Filter</tt> (<tt>RenderableImage</tt>) into a
+     * Graphics 2D.<p>
+     *
+     * This method also attempts to unwind the rendering chain a bit.
+     * So it knows about certain operations (like affine, pad,
+     * composite), rather than applying each of these operations in
+     * turn it accounts for their affects through modifications to the
+     * Graphics2D.  This avoids generating lots of intermediate images.
+     *
+     * @param g2d    The Graphics to draw into.
+     * @param filter The filter to draw
+     */
+    public static void drawImage(Graphics2D g2d,
+                                 RenderableImage filter) {
+        if (filter instanceof PaintRable) {
+            PaintRable pr = (PaintRable)filter;
+            if (pr.paintRable(g2d))
+                // paintRable succeeded so we are done...
+                return;
+        }
+
+        // Get our sources image...
+        // System.out.println("UnOpt: " + filter);
+        AffineTransform at = g2d.getTransform();
+        RenderedImage ri = filter.createRendering
+            (new RenderContext(at, g2d.getClip(), g2d.getRenderingHints()));
+
+        if (ri == null)
+            return;
+
+        g2d.setTransform(IDENTITY);
+        drawImage(g2d, GraphicsUtil.wrap(ri));
+        g2d.setTransform(at);
+    }
+
+    /**
+     * This is a wrapper around the system's
+     * BufferedImage.createGraphics that arranges for bi to be stored
+     * in a Rendering hint in the returned Graphics2D.
+     * This allows for accurate determination of the 'devices' size,
+     * and colorspace.
+     * @param bi The BufferedImage that the returned Graphics should
+     *           draw into.
+     * @return A Graphics2D that draws into BufferedImage with <tt>bi</tt>
+     *         stored in a rendering hint.
+     */
+    public static Graphics2D createGraphics(BufferedImage bi,
+                                            RenderingHints hints) {
+        Graphics2D g2d = bi.createGraphics();
+        if (hints != null)
+            g2d.addRenderingHints(hints);
+        g2d.setRenderingHint(RenderingHintsKeyExt.KEY_BUFFERED_IMAGE,
+                             new WeakReference(bi));
+        g2d.clip(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));
+        return g2d;
+    }
+
+
+    public static Graphics2D createGraphics(BufferedImage bi) {
+        Graphics2D g2d = bi.createGraphics();
+        g2d.setRenderingHint(RenderingHintsKeyExt.KEY_BUFFERED_IMAGE,
+                             new WeakReference(bi));
+        g2d.clip(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));
+        return g2d;
+    }
+
+
+    public static final boolean WARN_DESTINATION;
+
+    static {
+        boolean warn = true;
+        try {
+            String s = System.getProperty
+                ("org.apache.flex.forks.batik.warn_destination", "true");
+            warn = Boolean.valueOf(s).booleanValue();
+        } catch (SecurityException se) {
+        } catch (NumberFormatException nfe) {
+        } finally {
+            WARN_DESTINATION = warn;
+        }
+    }
+
+    public static BufferedImage getDestination(Graphics2D g2d) {
+        Object o = g2d.getRenderingHint
+            (RenderingHintsKeyExt.KEY_BUFFERED_IMAGE);
+        if (o != null)
+            return (BufferedImage)(((Reference)o).get());
+
+        // Check if this is a BufferedImage G2d if so throw an error...
+        GraphicsConfiguration gc = g2d.getDeviceConfiguration();
+        if (gc == null) {
+            return null;
+        }
+
+        GraphicsDevice gd = gc.getDevice();
+        if (WARN_DESTINATION &&
+            (gd.getType() == GraphicsDevice.TYPE_IMAGE_BUFFER) &&
+            (g2d.getRenderingHint(RenderingHintsKeyExt.KEY_TRANSCODING) !=
+                RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING))
+            // throw new IllegalArgumentException
+            System.err.println
+                ("Graphics2D from BufferedImage lacks BUFFERED_IMAGE hint");
+
+        return null;
+    }
+
+    public static ColorModel getDestinationColorModel(Graphics2D g2d) {
+        BufferedImage bi = getDestination(g2d);
+        if (bi != null) {
+            return bi.getColorModel();
+        }
+
+        GraphicsConfiguration gc = g2d.getDeviceConfiguration();
+        if (gc == null) {
+            return null; // Can't tell
+        }
+
+        // We are going to a BufferedImage but no hint was provided
+        // so we can't determine the destination Color Model.
+        if (gc.getDevice().getType() == GraphicsDevice.TYPE_IMAGE_BUFFER) {
+            if (g2d.getRenderingHint(RenderingHintsKeyExt.KEY_TRANSCODING) ==
+                RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING)
+                return sRGB_Unpre;
+
+            // System.out.println("CM: " + gc.getColorModel());
+            // System.out.println("CS: " + gc.getColorModel().getColorSpace());
+            return null;
+        }
+
+        return gc.getColorModel();
+    }
+
+    public static ColorSpace getDestinationColorSpace(Graphics2D g2d) {
+        ColorModel cm = getDestinationColorModel(g2d);
+        if (cm != null) return cm.getColorSpace();
+
+        return null;
+    }
+
+    public static Rectangle getDestinationBounds(Graphics2D g2d) {
+        BufferedImage bi = getDestination(g2d);
+        if (bi != null) {
+            return new Rectangle(0, 0, bi.getWidth(), bi.getHeight());
+        }
+
+        GraphicsConfiguration gc = g2d.getDeviceConfiguration();
+        if (gc == null) {
+            return null;
+        }
+
+        // We are going to a BufferedImage but no hint was provided
+        // so we can't determine the destination bounds.
+        if (gc.getDevice().getType() == GraphicsDevice.TYPE_IMAGE_BUFFER) {
+            return null;
+        }
+
+        // This is a JDK 1.3ism, so we will just return null...
+        // return gc.getBounds();
+        return null;
+    }
+
+
+    /**
+     * Standard prebuilt Linear_sRGB color model with no alpha */
+    public static final ColorModel Linear_sRGB =
+        new DirectColorModel(ColorSpace.getInstance
+                             (ColorSpace.CS_LINEAR_RGB), 24,
+                             0x00FF0000, 0x0000FF00,
+                             0x000000FF, 0x0, false,
+                             DataBuffer.TYPE_INT);
+    /**
+     * Standard prebuilt Linear_sRGB color model with premultiplied alpha.
+     */
+    public static final ColorModel Linear_sRGB_Pre =
+        new DirectColorModel(ColorSpace.getInstance
+                             (ColorSpace.CS_LINEAR_RGB), 32,
+                             0x00FF0000, 0x0000FF00,
+                             0x000000FF, 0xFF000000, true,
+                             DataBuffer.TYPE_INT);
+    /**
+     * Standard prebuilt Linear_sRGB color model with unpremultiplied alpha.
+     */
+    public static final ColorModel Linear_sRGB_Unpre =
+        new DirectColorModel(ColorSpace.getInstance
+                             (ColorSpace.CS_LINEAR_RGB), 32,
+                             0x00FF0000, 0x0000FF00,
+                             0x000000FF, 0xFF000000, false,
+                             DataBuffer.TYPE_INT);
+
+    /**
+     * Standard prebuilt sRGB color model with no alpha.
+     */
+    public static final ColorModel sRGB =
+        new DirectColorModel(ColorSpace.getInstance
+                             (ColorSpace.CS_sRGB), 24,
+                             0x00FF0000, 0x0000FF00,
+                             0x000000FF, 0x0, false,
+                             DataBuffer.TYPE_INT);
+    /**
+     * Standard prebuilt sRGB color model with premultiplied alpha.
+     */
+    public static final ColorModel sRGB_Pre =
+        new DirectColorModel(ColorSpace.getInstance
+                             (ColorSpace.CS_sRGB), 32,
+                             0x00FF0000, 0x0000FF00,
+                             0x000000FF, 0xFF000000, true,
+                             DataBuffer.TYPE_INT);
+    /**
+     * Standard prebuilt sRGB color model with unpremultiplied alpha.
+     */
+    public static final ColorModel sRGB_Unpre =
+        new DirectColorModel(ColorSpace.getInstance
+                             (ColorSpace.CS_sRGB), 32,
+                             0x00FF0000, 0x0000FF00,
+                             0x000000FF, 0xFF000000, false,
+                             DataBuffer.TYPE_INT);
+
+    /**
+     * Method that returns either Linear_sRGB_Pre or Linear_sRGB_UnPre
+     * based on premult flag.
+     * @param premult True if the ColorModel should have premultiplied alpha.
+     * @return        a ColorMdoel with Linear sRGB colorSpace and
+     *                the alpha channel set in accordance with
+     *                <tt>premult</tt>
+     */
+    public static ColorModel makeLinear_sRGBCM( boolean premult ) {
+
+         return premult ? Linear_sRGB_Pre : Linear_sRGB_Unpre;
+    }
+
+    /**
+     * Constructs a BufferedImage with a linear sRGB colorModel, and alpha.
+     * @param width   The desired width of the BufferedImage
+     * @param height  The desired height of the BufferedImage
+     * @param premult The desired state of alpha premultiplied
+     * @return        The requested BufferedImage.
+     */
+    public static BufferedImage makeLinearBufferedImage(int width,
+                                                        int height,
+                                                        boolean premult) {
+        ColorModel cm = makeLinear_sRGBCM(premult);
+        WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
+        return new BufferedImage(cm, wr, premult, null);
+    }
+
+    /**
+     * This method will return a CacheableRed that has it's data in
+     * the linear sRGB colorspace. If <tt>src</tt> is already in
+     * linear sRGB then this method does nothing and returns <tt>src</tt>.
+     * Otherwise it creates a transform that will convert
+     * <tt>src</tt>'s output to linear sRGB and returns that CacheableRed.
+     *
+     * @param src The image to convert to linear sRGB.
+     * @return    An equivilant image to <tt>src</tt> who's data is in
+     *            linear sRGB.
+     */
+    public static CachableRed convertToLsRGB(CachableRed src) {
+        ColorModel cm = src.getColorModel();
+        ColorSpace cs = cm.getColorSpace();
+        if (cs == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))
+            return src;
+
+        return new Any2LsRGBRed(src);
+    }
+
+    /**
+     * This method will return a CacheableRed that has it's data in
+     * the sRGB colorspace. If <tt>src</tt> is already in
+     * sRGB then this method does nothing and returns <tt>src</tt>.
+     * Otherwise it creates a transform that will convert
+     * <tt>src</tt>'s output to sRGB and returns that CacheableRed.
+     *
+     * @param src The image to convert to sRGB.
+     * @return    An equivilant image to <tt>src</tt> who's data is in sRGB.
+     */
+    public static CachableRed convertTosRGB(CachableRed src) {
+        ColorModel cm = src.getColorModel();
+        ColorSpace cs = cm.getColorSpace();
+        if (cs == ColorSpace.getInstance(ColorSpace.CS_sRGB))
+            return src;
+
+        return new Any2sRGBRed(src);
+    }
+
+    /**
+     * Convertes any RenderedImage to a CacheableRed.  <p>
+     * If <tt>ri</tt> is already a CacheableRed it casts it down and
+     * returns it.<p>
+     *
+     * In cases where <tt>ri</tt> is not already a CacheableRed it
+     * wraps <tt>ri</tt> with a helper class.  The wrapped
+     * CacheableRed "Pretends" that it has no sources since it has no
+     * way of inteligently handling the dependency/dirty region calls
+     * if it exposed the source.
+     * @param ri The RenderedImage to convert.
+     * @return   a CacheableRed that contains the same data as ri.
+     */
+    public static CachableRed wrap(RenderedImage ri) {
+        if (ri instanceof CachableRed)
+            return (CachableRed) ri;
+        if (ri instanceof BufferedImage)
+            return new BufferedImageCachableRed((BufferedImage)ri);
+        return new RenderedImageCachableRed(ri);
+    }
+
+    /**
+     * An internal optimized version of copyData designed to work on
+     * Integer packed data with a SinglePixelPackedSampleModel.  Only
+     * the region of overlap between src and dst is copied.
+     *
+     * Calls to this should be preflighted with is_INT_PACK_Data
+     * on both src and dest (requireAlpha can be false).
+     *
+     * @param src The source of the data
+     * @param dst The destination for the data.
+     */
+    public static void copyData_INT_PACK(Raster src, WritableRaster dst) {
+        // System.out.println("Fast copyData");
+        int x0 = dst.getMinX();
+        if (x0 < src.getMinX()) x0 = src.getMinX();
+
+        int y0 = dst.getMinY();
+        if (y0 < src.getMinY()) y0 = src.getMinY();
+
+        int x1 = dst.getMinX()+dst.getWidth()-1;
+        if (x1 > src.getMinX()+src.getWidth()-1)
+            x1 = src.getMinX()+src.getWidth()-1;
+
+        int y1 = dst.getMinY()+dst.getHeight()-1;
+        if (y1 > src.getMinY()+src.getHeight()-1)
+            y1 = src.getMinY()+src.getHeight()-1;
+
+        int width  = x1-x0+1;
+        int height = y1-y0+1;
+
+        SinglePixelPackedSampleModel srcSPPSM;
+        srcSPPSM = (SinglePixelPackedSampleModel)src.getSampleModel();
+
+        final int     srcScanStride = srcSPPSM.getScanlineStride();
+        DataBufferInt srcDB         = (DataBufferInt)src.getDataBuffer();
+        final int []  srcPixels     = srcDB.getBankData()[0];
+        final int     srcBase =
+            (srcDB.getOffset() +
+             srcSPPSM.getOffset(x0-src.getSampleModelTranslateX(),
+                                y0-src.getSampleModelTranslateY()));
+
+
+        SinglePixelPackedSampleModel dstSPPSM;
+        dstSPPSM = (SinglePixelPackedSampleModel)dst.getSampleModel();
+
+        final int     dstScanStride = dstSPPSM.getScanlineStride();
+        DataBufferInt dstDB         = (DataBufferInt)dst.getDataBuffer();
+        final int []  dstPixels     = dstDB.getBankData()[0];
+        final int     dstBase =
+            (dstDB.getOffset() +
+             dstSPPSM.getOffset(x0-dst.getSampleModelTranslateX(),
+                                y0-dst.getSampleModelTranslateY()));
+
+        if ((srcScanStride == dstScanStride) &&
+            (srcScanStride == width)) {
+            // System.out.println("VERY Fast copyData");
+
+            System.arraycopy(srcPixels, srcBase, dstPixels, dstBase,
+                             width*height);
+        } else if (width > 128) {
+            int srcSP = srcBase;
+            int dstSP = dstBase;
+            for (int y=0; y<height; y++) {
+                System.arraycopy(srcPixels, srcSP, dstPixels, dstSP, width);
+                srcSP += srcScanStride;
+                dstSP += dstScanStride;
+            }
+        } else {
+            for (int y=0; y<height; y++) {
+                int srcSP = srcBase+y*srcScanStride;
+                int dstSP = dstBase+y*dstScanStride;
+                for (int x=0; x<width; x++)
+                    dstPixels[dstSP++] = srcPixels[srcSP++];
+            }
+        }
+    }
+
+    public static void copyData_FALLBACK(Raster src, WritableRaster dst) {
+        // System.out.println("Fallback copyData");
+
+        int x0 = dst.getMinX();
+        if (x0 < src.getMinX()) x0 = src.getMinX();
+
+        int y0 = dst.getMinY();
+        if (y0 < src.getMinY()) y0 = src.getMinY();
+
+        int x1 = dst.getMinX()+dst.getWidth()-1;
+        if (x1 > src.getMinX()+src.getWidth()-1)
+            x1 = src.getMinX()+src.getWidth()-1;
+
+        int y1 = dst.getMinY()+dst.getHeight()-1;
+        if (y1 > src.getMinY()+src.getHeight()-1)
+            y1 = src.getMinY()+src.getHeight()-1;
+
+        int width  = x1-x0+1;
+        int [] data = null;
+
+        for (int y = y0; y <= y1 ; y++)  {
+            data = src.getPixels(x0,y,width,1,data);
+            dst.setPixels       (x0,y,width,1,data);
+        }
+    }
+
+    /**
+     * Copies data from one raster to another. Only the region of
+     * overlap between src and dst is copied.  <tt>Src</tt> and
+     * <tt>Dst</tt> must have compatible SampleModels.
+     *
+     * @param src The source of the data
+     * @param dst The destination for the data.
+     */
+    public static void copyData(Raster src, WritableRaster dst) {
+        if (is_INT_PACK_Data(src.getSampleModel(), false) &&
+            is_INT_PACK_Data(dst.getSampleModel(), false)) {
+            copyData_INT_PACK(src, dst);
+            return;
+        }
+
+        copyData_FALLBACK(src, dst);
+    }
+
+    /**
+     * Creates a new raster that has a <b>copy</b> of the data in
+     * <tt>ras</tt>.  This is highly optimized for speed.  There is
+     * no provision for changing any aspect of the SampleModel.
+     *
+     * This method should be used when you need to change the contents
+     * of a Raster that you do not "own" (ie the result of a
+     * <tt>getData</tt> call).
+     * @param ras The Raster to copy.
+     * @return    A writable copy of <tt>ras</tt>
+     */
+    public static WritableRaster copyRaster(Raster ras) {
+        return copyRaster(ras, ras.getMinX(), ras.getMinY());
+    }
+
+
+    /**
+     * Creates a new raster that has a <b>copy</b> of the data in
+     * <tt>ras</tt>.  This is highly optimized for speed.  There is
+     * no provision for changing any aspect of the SampleModel.
+     * However you can specify a new location for the returned raster.
+     *
+     * This method should be used when you need to change the contents
+     * of a Raster that you do not "own" (ie the result of a
+     * <tt>getData</tt> call).
+     *
+     * @param ras The Raster to copy.
+     *
+     * @param minX The x location for the upper left corner of the
+     *             returned WritableRaster.
+     *
+     * @param minY The y location for the upper left corner of the
+     *             returned WritableRaster.
+     *
+     * @return    A writable copy of <tt>ras</tt>
+     */
+    public static WritableRaster copyRaster(Raster ras, int minX, int minY) {
+        WritableRaster ret = Raster.createWritableRaster
+            (ras.getSampleModel(),
+             new Point(0,0));
+        ret = ret.createWritableChild
+            (ras.getMinX()-ras.getSampleModelTranslateX(),
+             ras.getMinY()-ras.getSampleModelTranslateY(),
+             ras.getWidth(), ras.getHeight(),
+             minX, minY, null);
+
+        // Use System.arraycopy to copy the data between the two...
+        DataBuffer srcDB = ras.getDataBuffer();
+        DataBuffer retDB = ret.getDataBuffer();
+        if (srcDB.getDataType() != retDB.getDataType()) {
+            throw new IllegalArgumentException
+                ("New DataBuffer doesn't match original");
+        }
+        int len   = srcDB.getSize();
+        int banks = srcDB.getNumBanks();
+        int [] offsets = srcDB.getOffsets();
+        for (int b=0; b< banks; b++) {
+            switch (srcDB.getDataType()) {
+            case DataBuffer.TYPE_BYTE: {
+                DataBufferByte srcDBT = (DataBufferByte)srcDB;
+                DataBufferByte retDBT = (DataBufferByte)retDB;
+                System.arraycopy(srcDBT.getData(b), offsets[b],
+                                 retDBT.getData(b), offsets[b], len);
+                break;
+            }
+            case DataBuffer.TYPE_INT: {
+                DataBufferInt srcDBT = (DataBufferInt)srcDB;
+                DataBufferInt retDBT = (DataBufferInt)retDB;
+                System.arraycopy(srcDBT.getData(b), offsets[b],
+                                 retDBT.getData(b), offsets[b], len);
+                break;
+            }
+            case DataBuffer.TYPE_SHORT: {
+                DataBufferShort srcDBT = (DataBufferShort)srcDB;
+                DataBufferShort retDBT = (DataBufferShort)retDB;
+                System.arraycopy(srcDBT.getData(b), offsets[b],
+                                 retDBT.getData(b), offsets[b], len);
+                break;
+            }
+            case DataBuffer.TYPE_USHORT: {
+                DataBufferUShort srcDBT = (DataBufferUShort)srcDB;
+                DataBufferUShort retDBT = (DataBufferUShort)retDB;
+                System.arraycopy(srcDBT.getData(b), offsets[b],
+                                 retDBT.getData(b), offsets[b], len);
+                break;
+            }
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * Coerces <tt>ras</tt> to be writable.  The returned Raster continues to
+     * reference the DataBuffer from ras, so modifications to the returned
+     * WritableRaster will be seen in ras.<p>
+     *
+     * This method should only be used if you need a WritableRaster due to
+     * an interface (such as to construct a BufferedImage), but have no
+     * intention of modifying the contents of the returned Raster.  If
+     * you have any doubt about other users of the data in <tt>ras</tt>,
+     * use copyRaster (above).
+     * @param ras The raster to make writable.
+     * @return    A Writable version of ras (shares DataBuffer with
+     *            <tt>ras</tt>).
+     */
+    public static WritableRaster makeRasterWritable(Raster ras) {
+        return makeRasterWritable(ras, ras.getMinX(), ras.getMinY());
+    }
+
+    /**
+     * Coerces <tt>ras</tt> to be writable.  The returned Raster continues to
+     * reference the DataBuffer from ras, so modifications to the returned
+     * WritableRaster will be seen in ras.<p>
+     *
+     * You can specify a new location for the returned WritableRaster, this
+     * is especially useful for constructing BufferedImages which require
+     * the Raster to be at (0,0).
+     *
+     * This method should only be used if you need a WritableRaster due to
+     * an interface (such as to construct a BufferedImage), but have no
+     * intention of modifying the contents of the returned Raster.  If
+     * you have any doubt about other users of the data in <tt>ras</tt>,
+     * use copyRaster (above).
+     *
+     * @param ras The raster to make writable.
+     *
+     * @param minX The x location for the upper left corner of the
+     *             returned WritableRaster.
+     *
+     * @param minY The y location for the upper left corner of the
+     *             returned WritableRaster.
+     *
+     * @return A Writable version of <tT>ras</tt> with it's upper left
+     *         hand coordinate set to minX, minY (shares it's DataBuffer
+     *         with <tt>ras</tt>).
+     */
+    public static WritableRaster makeRasterWritable(Raster ras,
+                                                    int minX, int minY) {
+        WritableRaster ret = Raster.createWritableRaster
+            (ras.getSampleModel(),
+             ras.getDataBuffer(),
+             new Point(0,0));
+        ret = ret.createWritableChild
+            (ras.getMinX()-ras.getSampleModelTranslateX(),
+             ras.getMinY()-ras.getSampleModelTranslateY(),
+             ras.getWidth(), ras.getHeight(),
+             minX, minY, null);
+        return ret;
+    }
+
+    /**
+     * Create a new ColorModel with it's alpha premultiplied state matching
+     * newAlphaPreMult.
+     * @param cm The ColorModel to change the alpha premult state of.
+     * @param newAlphaPreMult The new state of alpha premult.
+     * @return   A new colorModel that has isAlphaPremultiplied()
+     *           equal to newAlphaPreMult.
+     */
+    public static ColorModel
+        coerceColorModel(ColorModel cm, boolean newAlphaPreMult) {
+        if (cm.isAlphaPremultiplied() == newAlphaPreMult)
+            return cm;
+
+        // Easiest way to build proper colormodel for new Alpha state...
+        // Eventually this should switch on known ColorModel types and
+        // only fall back on this hack when the CM type is unknown.
+        WritableRaster wr = cm.createCompatibleWritableRaster(1,1);
+        return cm.coerceData(wr, newAlphaPreMult);
+    }
+
+    /**
+     * Coerces data within a bufferedImage to match newAlphaPreMult,
+     * Note that this can not change the colormodel of bi so you
+     *
+     * @param wr The raster to change the state of.
+     * @param cm The colormodel currently associated with data in wr.
+     * @param newAlphaPreMult The desired state of alpha Premult for raster.
+     * @return A new colormodel that matches newAlphaPreMult.
+     */
+    public static ColorModel
+        coerceData(WritableRaster wr, ColorModel cm, boolean newAlphaPreMult) {
+
+        // System.out.println("CoerceData: " + cm.isAlphaPremultiplied() +
+        //                    " Out: " + newAlphaPreMult);
+        if ( ! cm.hasAlpha() )
+            // Nothing to do no alpha channel
+            return cm;
+
+        if (cm.isAlphaPremultiplied() == newAlphaPreMult)
+            // nothing to do alpha state matches...
+            return cm;
+
+        // System.out.println("CoerceData: " + wr.getSampleModel());
+
+        if (newAlphaPreMult) {
+            multiplyAlpha(wr);
+        } else {
+            divideAlpha(wr);
+        }
+
+        return coerceColorModel(cm, newAlphaPreMult);
+    }
+
+    public static void multiplyAlpha(WritableRaster wr) {
+        if (is_BYTE_COMP_Data(wr.getSampleModel()))
+            mult_BYTE_COMP_Data(wr);
+        else if (is_INT_PACK_Data(wr.getSampleModel(), true))
+            mult_INT_PACK_Data(wr);
+        else {
+            int [] pixel = null;
+            int    bands = wr.getNumBands();
+            float  norm = 1.0f/255f;
+            int x0, x1, y0, y1, a, b;
+            float alpha;
+            x0 = wr.getMinX();
+            x1 = x0+wr.getWidth();
+            y0 = wr.getMinY();
+            y1 = y0+wr.getHeight();
+            for (int y=y0; y<y1; y++)
+                for (int x=x0; x<x1; x++) {
+                    pixel = wr.getPixel(x,y,pixel);
+                    a = pixel[bands-1];
+                    if ((a >= 0) && (a < 255)) {
+                        alpha = a*norm;
+                        for (b=0; b<bands-1; b++)
+                            pixel[b] = (int)(pixel[b]*alpha+0.5f);
+                        wr.setPixel(x,y,pixel);
+                    }
+                }
+        }
+    }
+
+    public static void divideAlpha(WritableRaster wr) {
+        if (is_BYTE_COMP_Data(wr.getSampleModel()))
+            divide_BYTE_COMP_Data(wr);
+        else if (is_INT_PACK_Data(wr.getSampleModel(), true))
+            divide_INT_PACK_Data(wr);
+        else {
+            int x0, x1, y0, y1, a, b;
+            float ialpha;
+            int    bands = wr.getNumBands();
+            int [] pixel = null;
+
+            x0 = wr.getMinX();
+            x1 = x0+wr.getWidth();
+            y0 = wr.getMinY();
+            y1 = y0+wr.getHeight();
+            for (int y=y0; y<y1; y++)
+                for (int x=x0; x<x1; x++) {
+                    pixel = wr.getPixel(x,y,pixel);
+                    a = pixel[bands-1];
+                    if ((a > 0) && (a < 255)) {
+                        ialpha = 255/(float)a;
+                        for (b=0; b<bands-1; b++)
+                            pixel[b] = (int)(pixel[b]*ialpha+0.5f);
+                        wr.setPixel(x,y,pixel);
+                    }
+                }
+        }
+    }
+
+    /**
+     * Copies data from one bufferedImage to another paying attention
+     * to the state of AlphaPreMultiplied.
+     *
+     * @param src The source
+     * @param dst The destination
+     */
+    public static void
+        copyData(BufferedImage src, BufferedImage dst) {
+        Rectangle srcRect = new Rectangle(0, 0,
+                                          src.getWidth(), src.getHeight());
+        copyData(src, srcRect, dst, new Point(0,0));
+    }
+
+
+    /**
+     * Copies data from one bufferedImage to another paying attention
+     * to the state of AlphaPreMultiplied.
+     *
+     * @param src The source
+     * @param srcRect The Rectangle of source data to be copied
+     * @param dst The destination
+     * @param destP The Place for the upper left corner of srcRect in dst.
+     */
+    public static void
+        copyData(BufferedImage src, Rectangle srcRect,
+                 BufferedImage dst, Point destP) {
+
+       /*
+        if (srcCS != dstCS)
+            throw new IllegalArgumentException
+                ("Images must be in the same ColorSpace in order "+
+                 "to copy Data between them");
+        */
+        boolean srcAlpha = src.getColorModel().hasAlpha();
+        boolean dstAlpha = dst.getColorModel().hasAlpha();
+
+        // System.out.println("Src has: " + srcAlpha +
+        //                    " is: " + src.isAlphaPremultiplied());
+        //
+        // System.out.println("Dst has: " + dstAlpha +
+        //                    " is: " + dst.isAlphaPremultiplied());
+
+        if (srcAlpha == dstAlpha)
+            if (( ! srcAlpha ) ||
+                (src.isAlphaPremultiplied() == dst.isAlphaPremultiplied())) {
+                // They match one another so just copy everything...
+                copyData(src.getRaster(), dst.getRaster());
+                return;
+            }
+
+        // System.out.println("Using Slow CopyData");
+
+        int [] pixel = null;
+        Raster         srcR  = src.getRaster();
+        WritableRaster dstR  = dst.getRaster();
+        int            bands = dstR.getNumBands();
+
+        int dx = destP.x-srcRect.x;
+        int dy = destP.y-srcRect.y;
+
+        int w  = srcRect.width;
+        int x0 = srcRect.x;
+        int y0 = srcRect.y;
+        int y1 = y0+srcRect.height-1;
+
+        if (!srcAlpha) {
+            // Src has no alpha dest does so set alpha to 1.0 everywhere.
+            // System.out.println("Add Alpha");
+            int [] oPix = new int[bands*w];
+            int out = (w*bands)-1; // The 2 skips alpha channel
+            while(out >= 0) {
+                // Fill alpha channel with 255's
+                oPix[out] = 255;
+                out -= bands;
+            }
+
+            int b, in;
+            for (int y=y0; y<=y1; y++) {
+                pixel = srcR.getPixels(x0,y,w,1,pixel);
+                in  = w*(bands-1)-1;
+                out = (w*bands)-2; // The 2 skips alpha channel on last pix
+                switch (bands) {
+                case 4:
+                    while(in >= 0) {
+                        oPix[out--] = pixel[in--];
+                        oPix[out--] = pixel[in--];
+                        oPix[out--] = pixel[in--];
+                        out--;
+                    }
+                    break;
+                default:
+                    while(in >= 0) {
+                        for (b=0; b<bands-1; b++)
+                            oPix[out--] = pixel[in--];
+                        out--;
+                    }
+                }
+                dstR.setPixels(x0+dx, y+dy, w, 1, oPix);
+            }
+        } else if (dstAlpha && dst.isAlphaPremultiplied()) {
+            // Src and dest have Alpha but we need to multiply it for dst.
+            // System.out.println("Mult Case");
+            int a, b, alpha, in, fpNorm = (1<<24)/255, pt5 = 1<<23;
+            for (int y=y0; y<=y1; y++) {
+                pixel = srcR.getPixels(x0,y,w,1,pixel);
+                in=bands*w-1;
+                switch (bands) {
+                case 4:
+                    while(in >= 0) {
+                        a = pixel[in];
+                        if (a == 255)
+                            in -= 4;
+                        else {
+                            in--;
+                            alpha = fpNorm*a;
+                            pixel[in] = (pixel[in]*alpha+pt5)>>>24; in--;
+                            pixel[in] = (pixel[in]*alpha+pt5)>>>24; in--;
+                            pixel[in] = (pixel[in]*alpha+pt5)>>>24; in--;
+                        }
+                    }
+                    break;
+                default:
+                    while(in >= 0) {
+                        a = pixel[in];
+                        if (a == 255)
+                            in -= bands;
+                        else {
+                            in--;
+                            alpha = fpNorm*a;
+                            for (b=0; b<bands-1; b++) {
+                                pixel[in] = (pixel[in]*alpha+pt5)>>>24;
+                                in--;
+                            }
+                        }
+                    }
+                }
+                dstR.setPixels(x0+dx, y+dy, w, 1, pixel);
+            }
+        } else if (dstAlpha && !dst.isAlphaPremultiplied()) {
+            // Src and dest have Alpha but we need to divide it out for dst.
+            // System.out.println("Div Case");
+            int a, b, ialpha, in, fpNorm = 0x00FF0000, pt5 = 1<<15;
+            for (int y=y0; y<=y1; y++) {
+                pixel = srcR.getPixels(x0,y,w,1,pixel);
+                in=(bands*w)-1;
+                switch(bands) {
+                case 4:
+                    while(in >= 0) {
+                        a = pixel[in];
+                        if ((a <= 0) || (a >= 255))
+                            in -= 4;
+                        else {
+                            in--;
+                            ialpha = fpNorm/a;
+                            pixel[in] = (pixel[in]*ialpha+pt5)>>>16; in--;
+                            pixel[in] = (pixel[in]*ialpha+pt5)>>>16; in--;
+                            pixel[in] = (pixel[in]*ialpha+pt5)>>>16; in--;
+                        }
+                    }
+                    break;
+                default:
+                    while(in >= 0) {
+                        a = pixel[in];
+                        if ((a <= 0) || (a >= 255))
+                            in -= bands;
+                        else {
+                            in--;
+                            ialpha = fpNorm/a;
+                            for (b=0; b<bands-1; b++) {
+                                pixel[in] = (pixel[in]*ialpha+pt5)>>>16;
+                                in--;
+                            }
+                        }
+                    }
+                }
+                dstR.setPixels(x0+dx, y+dy, w, 1, pixel);
+            }
+        } else if (src.isAlphaPremultiplied()) {
+            int [] oPix = new int[bands*w];
+            // Src has alpha dest does not so unpremult and store...
+            // System.out.println("Remove Alpha, Div Case");
+            int a, b, ialpha, in, out, fpNorm = 0x00FF0000, pt5 = 1<<15;
+            for (int y=y0; y<=y1; y++) {
+                pixel = srcR.getPixels(x0,y,w,1,pixel);
+                in  = (bands+1)*w -1;
+                out = (bands*w)-1;
+                while(in >= 0) {
+                    a = pixel[in]; in--;
+                    if (a > 0) {
+                        if (a < 255) {
+                            ialpha = fpNorm/a;
+                            for (b=0; b<bands; b++)
+                                oPix[out--] = (pixel[in--]*ialpha+pt5)>>>16;
+                        } else
+                            for (b=0; b<bands; b++)
+                                oPix[out--] = pixel[in--];
+                    } else {
+                        in -= bands;
+                        for (b=0; b<bands; b++)
+                            oPix[out--] = 255;
+                    }
+                }
+                dstR.setPixels(x0+dx, y+dy, w, 1, oPix);
+            }
+        } else {
+            // Src has unpremult alpha, dest does not have alpha,
+            // just copy the color channels over.
+            Rectangle dstRect = new Rectangle(destP.x, destP.y,
+                                              srcRect.width, srcRect.height);
+            for (int b=0; b<bands; b++)
+                copyBand(srcR, srcRect, b,
+                         dstR, dstRect, b);
+        }
+    }
+
+    public static void copyBand(Raster         src, int srcBand,
+                                WritableRaster dst, int dstBand) {
+
+        Rectangle sR   = src.getBounds();
+        Rectangle dR   = dst.getBounds();
+        Rectangle cpR  = sR.intersection(dR);
+
+        copyBand(src, cpR, srcBand, dst, cpR, dstBand);
+    }
+
+    public static void copyBand(Raster         src, Rectangle sR, int sBand,
+                                WritableRaster dst, Rectangle dR, int dBand) {
+        int dy = dR.y -sR.y;
+        int dx = dR.x -sR.x;
+        sR = sR.intersection(src.getBounds());
+        dR = dR.intersection(dst.getBounds());
+        int width, height;
+        if (dR.width  < sR.width)  width  = dR.width;
+        else                       width  = sR.width;
+        if (dR.height < sR.height) height = dR.height;
+        else                       height = sR.height;
+
+        int x = sR.x+dx;
+        int [] samples = null;
+        for (int y=sR.y; y< sR.y+height; y++) {
+            samples = src.getSamples(sR.x, y, width, 1, sBand, samples);
+            dst.setSamples(x, y+dy, width, 1, dBand, samples);
+        }
+    }
+
+    public static boolean is_INT_PACK_Data(SampleModel sm,
+                                           boolean requireAlpha) {
+        // Check ColorModel is of type DirectColorModel
+        if(!(sm instanceof SinglePixelPackedSampleModel)) return false;
+
+        // Check transfer type
+        if(sm.getDataType() != DataBuffer.TYPE_INT)       return false;
+
+        SinglePixelPackedSampleModel sppsm;
+        sppsm = (SinglePixelPackedSampleModel)sm;
+
+        int [] masks = sppsm.getBitMasks();
+        if (masks.length == 3) {
+            if (requireAlpha) return false;
+        } else if (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;
+    }
+
+        public static boolean is_BYTE_COMP_Data(SampleModel sm) {
+            // Check ColorModel is of type DirectColorModel
+            if(!(sm instanceof ComponentSampleModel))    return false;
+
+            // Check transfer type
+            if(sm.getDataType() != DataBuffer.TYPE_BYTE) return false;
+
+            return true;
+        }
+
+    protected static void divide_INT_PACK_Data(WritableRaster wr) {
+        // System.out.println("Divide Int");
+
+        SinglePixelPackedSampleModel sppsm;
+        sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel();
+
+        final int width = wr.getWidth();
+
+        final int scanStride = sppsm.getScanlineStride();
+        DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
+        final int base
+            = (db.getOffset() +
+               sppsm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
+                               wr.getMinY()-wr.getSampleModelTranslateY()));
+
+        // Access the pixel data array
+        final int[] pixels = db.getBankData()[0];
+        for (int y=0; y<wr.getHeight(); y++) {
+            int sp = base + y*scanStride;
+            final int end = sp + width;
+            while (sp < end) {
+                int pixel = pixels[sp];
+                int a = pixel>>>24;
+                if (a<=0) {
+                    pixels[sp] = 0x00FFFFFF;
+                } else if (a<255) {
+                    int aFP = (0x00FF0000/a);
+                    pixels[sp] =
+                        ((a << 24) |
+                         (((((pixel&0xFF0000)>>16)*aFP)&0xFF0000)    ) |
+                         (((((pixel&0x00FF00)>>8) *aFP)&0xFF0000)>>8 ) |
+                         (((((pixel&0x0000FF))    *aFP)&0xFF0000)>>16));
+                }
+                sp++;
+            }
+        }
+    }
+
+    protected static void mult_INT_PACK_Data(WritableRaster wr) {
+        // System.out.println("Multiply Int: " + wr);
+
+        SinglePixelPackedSampleModel sppsm;
+        sppsm = (SinglePixelPackedSampleModel)wr.getSampleModel();
+
+        final int width = wr.getWidth();
+
+        final int scanStride = sppsm.getScanlineStride();
+        DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
+        final int base
+            = (db.getOffset() +
+               sppsm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
+                               wr.getMinY()-wr.getSampleModelTranslateY()));
+        // Access the pixel data array
+        final int[] pixels = db.getBankData()[0];
+        for (int y=0; y<wr.getHeight(); y++) {
+            int sp = base + y*scanStride;
+            final int end = sp + width;
+            while (sp < end) {
+                int pixel = pixels[sp];
+                int a = pixel>>>24;
+                if ((a>=0) && (a<255)) {   // this does NOT include a == 255 (0xff) !
+                    pixels[sp] = ((a << 24) |
+                                  ((((pixel&0xFF0000)*a)>>8)&0xFF0000) |
+                                  ((((pixel&0x00FF00)*a)>>8)&0x00FF00) |
+                                  ((((pixel&0x0000FF)*a)>>8)&0x0000FF));
+                }
+                sp++;
+            }
+        }
+    }
+
+
+    protected static void divide_BYTE_COMP_Data(WritableRaster wr) {
+        // System.out.println("Multiply Int: " + wr);
+
+        ComponentSampleModel csm;
+        csm = (ComponentSampleModel)wr.getSampleModel();
+
+        final int width = wr.getWidth();
+
+        final int scanStride = csm.getScanlineStride();
+        final int pixStride  = csm.getPixelStride();
+        final int [] bandOff = csm.getBandOffsets();
+
+        DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
+        final int base
+            = (db.getOffset() +
+               csm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
+                             wr.getMinY()-wr.getSampleModelTranslateY()));
+
+        int aOff = bandOff[bandOff.length-1];
+        int bands = bandOff.length-1;
+
+        // Access the pixel data array
+        final byte[] pixels = db.getBankData()[0];
+        for (int y=0; y<wr.getHeight(); y++) {
+            int sp = base + y*scanStride;
+            final int end = sp + width*pixStride;
+            while (sp < end) {
+              int a = pixels[sp+aOff]&0xFF;
+              if (a==0) {
+                for ( int b=0; b<bands; b++)
+                  pixels[sp+bandOff[b]] = (byte)0xFF;
+              } else if (a<255) {         // this does NOT include a == 255 (0xff) !
+                int aFP = (0x00FF0000/a);
+                for ( int b=0; b<bands; b++) {
+                  int i = sp+bandOff[b];
+                  pixels[i] = (byte)(((pixels[i]&0xFF)*aFP)>>>16);
+                }
+              }
+              sp+=pixStride;
+            }
+        }
+    }
+
+    protected static void mult_BYTE_COMP_Data(WritableRaster wr) {
+        // System.out.println("Multiply Int: " + wr);
+
+        ComponentSampleModel csm;
+        csm = (ComponentSampleModel)wr.getSampleModel();
+
+        final int width = wr.getWidth();
+
+        final int scanStride = csm.getScanlineStride();
+        final int pixStride  = csm.getPixelStride();
+        final int [] bandOff = csm.getBandOffsets();
+
+        DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
+        final int base
+            = (db.getOffset() +
+               csm.getOffset(wr.getMinX()-wr.getSampleModelTranslateX(),
+                             wr.getMinY()-wr.getSampleModelTranslateY()));
+
+
+        int aOff = bandOff[bandOff.length-1];
+        int bands = bandOff.length-1;
+
+        // Access the pixel data array
+        final byte[] pixels = db.getBankData()[0];
+        for (int y=0; y<wr.getHeight(); y++) {
+            int sp = base + y*scanStride;
+            final int end = sp + width*pixStride;
+            while (sp < end) {
+              int a = pixels[sp+aOff]&0xFF;
+              if (a!=0xFF)
+                for ( int b=0; b<bands; b++) {
+                  int i = sp+bandOff[b];
+                  pixels[i] = (byte)(((pixels[i]&0xFF)*a)>>8);
+                }
+              sp+=pixStride;
+            }
+        }
+    }
+
+/*
+  This is skanky debugging code that might be useful in the future:
+
+            if (count == 33) {
+                String label = "sub [" + x + ", " + y + "]: ";
+                org.ImageDisplay.showImage
+                    (label, subBI);
+                org.ImageDisplay.printImage
+                    (label, subBI,
+                     new Rectangle(75-iR.x, 90-iR.y, 32, 32));
+
+            }
+
+
+            // if ((count++ % 50) == 10)
+            //     org.ImageDisplay.showImage("foo: ", subBI);
+
+
+            Graphics2D realG2D = g2d;
+            while (realG2D instanceof sun.java2d.ProxyGraphics2D) {
+                realG2D = ((sun.java2d.ProxyGraphics2D)realG2D).getDelegate();
+            }
+            if (realG2D instanceof sun.awt.image.BufferedImageGraphics2D) {
+                count++;
+                if (count == 34) {
+                    RenderedImage ri;
+                    ri = ((sun.awt.image.BufferedImageGraphics2D)realG2D).bufImg;
+                    // g2d.setComposite(SVGComposite.OVER);
+                    // org.ImageDisplay.showImage("Bar: " + count, cr);
+                    org.ImageDisplay.printImage("Bar: " + count, cr,
+                                                new Rectangle(75, 90, 32, 32));
+
+                    org.ImageDisplay.showImage ("Foo: " + count, ri);
+                    org.ImageDisplay.printImage("Foo: " + count, ri,
+                                                new Rectangle(75, 90, 32, 32));
+
+                    System.out.println("BI: "   + ri);
+                    System.out.println("BISM: " + ri.getSampleModel());
+                    System.out.println("BICM: " + ri.getColorModel());
+                    System.out.println("BICM class: " + ri.getColorModel().getClass());
+                    System.out.println("BICS: " + ri.getColorModel().getColorSpace());
+                    System.out.println
+                        ("sRGB CS: " +
+                         ColorSpace.getInstance(ColorSpace.CS_sRGB));
+                    System.out.println("G2D info");
+                    System.out.println("\tComposite: " + g2d.getComposite());
+                    System.out.println("\tTransform" + g2d.getTransform());
+                    java.awt.RenderingHints rh = g2d.getRenderingHints();
+                    java.util.Set keys = rh.keySet();
+                    java.util.Iterator iter = keys.iterator();
+                    while (iter.hasNext()) {
+                        Object o = iter.next();
+
+                        System.out.println("\t" + o.toString() + " -> " +
+                                           rh.get(o).toString());
+                    }
+
+                    ri = cr;
+                    System.out.println("RI: "   + ri);
+                    System.out.println("RISM: " + ri.getSampleModel());
+                    System.out.println("RICM: " + ri.getColorModel());
+                    System.out.println("RICM class: " + ri.getColorModel().getClass());
+                    System.out.println("RICS: " + ri.getColorModel().getColorSpace());
+                }
+            }
+*/
+
+}

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

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/IdentityTransfer.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/IdentityTransfer.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/IdentityTransfer.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/IdentityTransfer.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,56 @@
+/*
+
+   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;
+
+/**
+ * IdentityTransfer.java
+ *
+ * This class defines the Identity type transfer function for the
+ * feComponentTransfer filter, as defined in chapter 15, section 11 of the SVG
+ * specification.
+ *
+ * @author <a href="mailto:sheng.pei@sun.com">Sheng Pei</a>
+ * @version $Id: IdentityTransfer.java 475477 2006-11-15 22:44:28Z cam $ 
+ */
+public class IdentityTransfer implements TransferFunction {
+    /**
+     * This byte array stores the lookuptable data
+     */
+    public static byte [] lutData = new byte [256];
+
+    /*
+     * This method will build the lut data. Each entry
+     * has the value as its index.
+     */
+    static {
+        // as Identity, the lookup table contains
+        // the same value as the index
+        for (int j=0; j<=255; j++) {
+            lutData[j] = (byte)j;
+        }
+    }
+
+    /**
+     * This method will return the lut data in order
+     * to construct a LookUpTable object
+     */
+    public byte [] getLookupTable(){
+        return lutData;
+    }
+}

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

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/Light.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/Light.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/Light.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/Light.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,104 @@
+/*
+
+   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;
+
+import java.awt.Color;
+
+/**
+ * Top level interface to model a light element. A light is responsible for
+ * computing the light vector on a given point of a surface. A light is
+ * typically in a 3 dimensional space and the methods assumes the surface
+ * is at elevation 0.
+ *
+ * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
+ * @version $Id: Light.java 478249 2006-11-22 17:29:37Z dvholten $
+ */
+public interface Light {
+    /**
+     * @return true if the light is constant over the whole surface
+     */
+    boolean isConstant();
+
+    /**
+     * Computes the light vector in (x, y)
+     *
+     * @param x x-axis coordinate where the light should be computed
+     * @param y y-axis coordinate where the light should be computed
+     * @param z z-axis coordinate where the light should be computed
+     * @param L array of length 3 where the result is stored
+     */
+    void getLight(final double x, final double y, final double z, final double[] L);
+
+    /**
+     * Returns a light map, starting in (x, y) with dx, dy increments, a given
+     * width and height, and z elevations stored in the fourth component on the
+     * N array.
+     *
+     * @param x x-axis coordinate where the light should be computed
+     * @param y y-axis coordinate where the light should be computed
+     * @param dx delta x for computing light vectors in user space
+     * @param dy delta y for computing light vectors in user space
+     * @param width number of samples to compute on the x axis
+     * @param height number of samples to compute on the y axis
+     * @param z array containing the z elevation for all the points
+     *
+     * @return an array of height rows, width columns where each element
+     *         is an array of three components representing the x, y and z
+     *         components of the light vector.
+     */
+    double[][][] getLightMap(double x, double y,
+                                  final double dx, final double dy,
+                                  final int width, final int height,
+                                  final double[][][] z);
+
+    /**
+     * Returns a row of the light map, starting at (x, y) with dx
+     * increments, a given width, and z elevations stored in the
+     * fourth component on the N array.
+     *
+     * @param x x-axis coordinate where the light should be computed
+     * @param y y-axis coordinate where the light should be computed
+     * @param dx delta x for computing light vectors in user space
+     * @param width number of samples to compute on the x axis
+     * @param z array containing the z elevation for all the points
+     * @param lightRow array to store the light info to, if null it will
+     *                 be allocated for you and returned.
+     *
+     * @return an array width columns where each element
+     *         is an array of three components representing the x, y and z
+     *         components of the light vector.  */
+    double[][] getLightRow(double x, double y,
+                                  final double dx, final int width,
+                                  final double[][] z,
+                                  final double[][] lightRow);
+
+    /**
+     * @param  linear if true the color is returned in the Linear sRGB
+     *                colorspace otherwise the color is in the gamma
+     *                corrected sRGB color space.
+     * @return the light's color
+     */
+    double[] getColor(boolean linear);
+
+    /**
+     * Sets the light color to a new value
+     */
+    void setColor(Color color);
+}
+

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

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/LinearTransfer.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/LinearTransfer.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/LinearTransfer.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/LinearTransfer.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,90 @@
+/*
+
+   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;
+
+/**
+ * LinearTransfer.java
+ *
+ * This class defines the Linear type transfer function for the
+ * feComponentTransfer filter, as defined in chapter 15, section 11 of the SVG
+ * specification.
+ *
+ * @author <a href="mailto:sheng.pei@sun.com">Sheng Pei</a>
+ * @version $Id: LinearTransfer.java 475477 2006-11-15 22:44:28Z cam $ 
+ */
+public class LinearTransfer implements TransferFunction {
+    /**
+     * This byte array stores the lookuptable data
+     */
+    public byte [] lutData;
+
+    /**
+     * The slope of the linear function
+     */
+    public float slope;
+
+    /**
+     * The intercept of the linear function
+     */
+    public float intercept;
+
+    /**
+     * Two floats as the input for the function
+     */
+    public LinearTransfer(float slope, float intercept){
+        this.slope = slope;
+        this.intercept = intercept;
+    }
+
+    /*
+     * This method will build the lut data. Each entry's
+     * value is in form of "slope*C+intercept"
+     */
+    private void buildLutData(){
+        lutData = new byte [256];
+        int j, value;
+        float scaledInt = (intercept*255f)+0.5f;
+        for (j=0; j<=255; j++){
+            value = (int)(slope*j+scaledInt);
+            if(value < 0){
+                value = 0;
+            }
+            else if(value > 255){
+                value = 255;
+            }
+            lutData[j] = (byte)(0xff & value);
+        }
+
+        /*System.out.println("Linear : " + slope + " / " + intercept);
+        for(j=0; j<=255; j++){
+            System.out.print("[" + j + "] = " + (0xff & lutData[j]) + " ");
+        }
+
+        System.out.println();*/
+    }
+
+    /**
+     * This method will return the lut data in order
+     * to construct a LookUpTable object
+     */
+    public byte [] getLookupTable(){
+        buildLutData();
+        return lutData;
+    }
+}

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

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PadMode.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PadMode.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PadMode.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PadMode.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,82 @@
+/*
+
+   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;
+
+/**
+ * This is a typesafe enumeration of the standard Composite rules for
+ * the CompositeRable operation. (over, in, out, atop, xor, arith)
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: PadMode.java 475477 2006-11-15 22:44:28Z cam $
+ */
+public final class PadMode implements java.io.Serializable {
+      /** Pad edges with zeros */
+    public static final int MODE_ZERO_PAD = 1;
+
+      /** Pad edges by replicating edge pixels */
+    public static final int MODE_REPLICATE = 2;
+
+      /** Pad edges by wrapping around edge pixels */
+    public static final int MODE_WRAP = 3;
+
+      /** Pad edges with zeros */
+    public static final PadMode ZERO_PAD = new PadMode(MODE_ZERO_PAD);
+
+      /** Pad edges by replicating edge pixels */
+    public static final PadMode REPLICATE = new PadMode(MODE_REPLICATE);
+
+      /** Pad edges by replicating edge pixels */
+    public static final PadMode WRAP = new PadMode(MODE_WRAP);
+
+    /**
+     * Returns the mode of this pad mode.
+     */
+    public int getMode() {
+        return mode;
+    }
+
+      /**
+       * The pad mode for this object.
+       */
+    private int mode;
+
+    private PadMode(int mode) {
+        this.mode = mode;
+    }
+
+    /**
+     * This is called by the serialization code before it returns
+     * an unserialized object. To provide for unicity of
+     * instances, the instance that was read is replaced by its
+     * static equivalent. See the serialiazation specification for
+     * further details on this method's logic.
+     */
+    private Object readResolve() throws java.io.ObjectStreamException {
+        switch(mode){
+        case MODE_ZERO_PAD:
+            return ZERO_PAD;
+        case MODE_REPLICATE:
+            return REPLICATE;
+        case MODE_WRAP:
+            return WRAP;
+        default:
+            throw new Error("Unknown Pad Mode type");
+        }
+    }
+}

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

Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PointLight.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PointLight.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PointLight.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/PointLight.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,101 @@
+/*
+
+   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;
+
+import java.awt.Color;
+
+/**
+ * A light source which emits a light of constant intensity in all directions.
+ *
+ * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
+ * @version $Id: PointLight.java 478363 2006-11-22 23:01:13Z dvholten $
+ */
+public class PointLight extends AbstractLight {
+    /**
+     * The light position, in user space
+     */
+    private double lightX, lightY, lightZ;
+
+    /**
+     * @return the light's x position
+     */
+    public double getLightX(){
+        return lightX;
+    }
+
+    /**
+     * @return the light's y position
+     */
+    public double getLightY(){
+        return lightY;
+    }
+
+    /**
+     * @return the light's z position
+     */
+    public double getLightZ(){
+        return lightZ;
+    }
+
+    public PointLight(double lightX, double lightY, double lightZ,
+                      Color lightColor){
+        super(lightColor);
+        this.lightX = lightX;
+        this.lightY = lightY;
+        this.lightZ = lightZ;
+    }
+
+    /**
+     * @return true if the light is constant over the whole surface
+     */
+    public boolean isConstant(){
+        return false;
+    }
+
+    /**
+     * Computes the light vector in (x, y, z)
+     *
+     * @param x x-axis coordinate where the light should be computed
+     * @param y y-axis coordinate where the light should be computed
+     * @param z z-axis coordinate where the light should be computed
+     * @param L array of length 3 where the result is stored
+     */
+    public final void getLight(final double x, final double y, final double z,
+                               final double[] L){
+
+        double L0 = lightX - x;
+        double L1 = lightY - y;
+        double L2 = lightZ - z;
+
+        final double norm = Math.sqrt( L0*L0 + L1*L1 + L2*L2 );
+
+        if(norm > 0){
+            final double invNorm = 1.0/norm;
+            L0 *= invNorm;
+            L1 *= invNorm;
+            L2 *= invNorm;
+        }
+
+        // copy the work-variables into return-array
+        L[ 0 ] = L0;
+        L[ 1 ] = L1;
+        L[ 2 ] = L2;
+    }
+}
+

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