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