deweese 01/07/26 11:03:08 Modified: sources/org/apache/batik/ext/awt/image/renderable DisplacementMapRable8Bit.java sources/org/apache/batik/ext/awt/image/rendered AbstractRed.java AbstractTiledRed.java Any2sRGBRed.java TileRed.java sources/org/apache/batik/ext/awt/image/spi JPEGRegistryEntry.java Added: sources/org/apache/batik/ext/awt/image/rendered DisplacementMapRed8Bit.java Removed: sources/org/apache/batik/ext/awt/image/rendered DisplacementMapOp.java Log: 1) Converted DisplacementMapOp to DisplacementMapRed (turned out to be a real bear to keep up performace...) 2) Lots of good tweaks to the pattern code. 3) Fixed a bug with the handling of B&W JPEG images (actually JDK bug I had to work around...) PR: 2821 Revision Changes Path 1.8 +18 -59 xml-batik/sources/org/apache/batik/ext/awt/image/renderable/DisplacementMapRable8Bit.java Index: DisplacementMapRable8Bit.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/renderable/DisplacementMapRable8Bit.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- DisplacementMapRable8Bit.java 2001/05/02 15:41:17 1.7 +++ DisplacementMapRable8Bit.java 2001/07/26 18:03:07 1.8 @@ -14,23 +14,15 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; - -import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.ColorModel; import java.awt.image.renderable.RenderContext; import java.util.List; -import org.apache.batik.ext.awt.image.GraphicsUtil; - import org.apache.batik.ext.awt.image.ARGBChannel; -import org.apache.batik.ext.awt.image.PadMode; -import org.apache.batik.ext.awt.image.rendered.BufferedImageCachableRed; +import org.apache.batik.ext.awt.image.GraphicsUtil; import org.apache.batik.ext.awt.image.rendered.CachableRed; -import org.apache.batik.ext.awt.image.rendered.DisplacementMapOp; +import org.apache.batik.ext.awt.image.rendered.DisplacementMapRed8Bit; import org.apache.batik.ext.awt.image.rendered.AffineRed; /** @@ -38,7 +30,7 @@ * another image to spatially displace the input image * * @author <a href="mailto:[EMAIL PROTECTED]>Sheng Pei</a> - * @version $Id: DisplacementMapRable8Bit.java,v 1.7 2001/05/02 15:41:17 tkormann Exp $ + * @version $Id: DisplacementMapRable8Bit.java,v 1.8 2001/07/26 18:03:07 deweese Exp $ */ public class DisplacementMapRable8Bit extends AbstractColorInterpolationRable @@ -171,14 +163,17 @@ // Now, apply the filter // - int scaleX = (int)(scale*atScaleX); - int scaleY = (int)(scale*atScaleY); + float scaleX = (float)(scale*atScaleX); + float scaleY = (float)(scale*atScaleY); // If both scale factors are zero then we don't // affect the source image so just return it... if ((scaleX == 0) && (scaleY == 0)) return displaced.createRendering(rc); + // if ((scaleX > 255) || (scaleY > 255)) { + // System.out.println("Scales: [" + scaleX + ", " + scaleY + "]"); + // } AffineTransform srcAt = AffineTransform.getScaleInstance(atScaleX, atScaleY); @@ -189,15 +184,10 @@ Rectangle2D aoiR = origAOI.getBounds2D(); - // Get a rendering from the displacement map - PadRable mapPad = new PadRable8Bit(map, aoiR, PadMode.ZERO_PAD); - RenderContext srcRc = new RenderContext(srcAt, aoiR, rh); - RenderedImage mapRed = mapPad.createRendering(srcRc); + RenderedImage mapRed = map.createRendering(srcRc); - if(mapRed == null){ - return null; - } + if (mapRed == null) return null; // Grow the area of interest in user space. to account for // the max surround needs of displacement map. @@ -214,43 +204,19 @@ srcRc = new RenderContext(srcAt, aoiR, rh); RenderedImage displacedRed = displaced.createRendering(srcRc); - if(displacedRed == null){ - return null; - } + if (displacedRed == null) return null; mapRed = convertSourceCS(mapRed); // - // Build a BufferedImages from the two sources + // Build a Displacement Map Red from the two sources // - - // Get Raster for displacedRed - Raster displacedRas = displacedRed.getData(); - ColorModel disCM = displacedRed.getColorModel(); - // Make sure displaced is premultiplied - disCM = GraphicsUtil.coerceData((WritableRaster)displacedRas, - disCM, true); - - // Get Raster for mapRed - Raster mapRas = mapRed.getData(); - ColorModel mapCM = mapRed.getColorModel(); - // ensure map isn't pre-multiplied. - GraphicsUtil.coerceData((WritableRaster)mapRas, mapCM, false); - - - DisplacementMapOp op - = new DisplacementMapOp(xChannelSelector, - yChannelSelector, - scaleX, scaleY, - mapRas); - - WritableRaster destRas = op.filter(displacedRas, null); - destRas = destRas.createWritableTranslatedChild(0,0); - - BufferedImage destBI = new BufferedImage(disCM, destRas, - disCM.isAlphaPremultiplied(), - null); + CachableRed cr = new DisplacementMapRed8Bit + (GraphicsUtil.wrap(displacedRed), + GraphicsUtil.wrap(mapRed), + xChannelSelector, yChannelSelector, + scaleX, scaleY, rh); // // Apply the non scaling part of the transform now, // if different from identity. @@ -260,15 +226,8 @@ shx/atScaleY, sy/atScaleY, tx, ty); - final int minX = mapRed.getMinX(); - final int minY = mapRed.getMinY(); - - CachableRed cr - = new BufferedImageCachableRed(destBI, minX, minY); - - if(!resAt.isIdentity()){ + if(!resAt.isIdentity()) cr = new AffineRed(cr, resAt, rh); - } return cr; 1.8 +5 -4 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AbstractRed.java Index: AbstractRed.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AbstractRed.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- AbstractRed.java 2001/04/30 22:01:05 1.7 +++ AbstractRed.java 2001/07/26 18:03:07 1.8 @@ -48,7 +48,7 @@ * the subclass implementation. * * @author <a href="mailto:[EMAIL PROTECTED]">Thomas DeWeese</a> - * @version $Id: AbstractRed.java,v 1.7 2001/04/30 22:01:05 deweese Exp $ + * @version $Id: AbstractRed.java,v 1.8 2001/07/26 18:03:07 deweese Exp $ */ public abstract class AbstractRed implements CachableRed { @@ -509,12 +509,13 @@ } public Raster getData(Rectangle rect) { - SampleModel smRet = sm.createCompatibleSampleModel(rect.width, - rect.height); + SampleModel smRet = sm.createCompatibleSampleModel + (rect.width, rect.height); + Point pt = new Point(rect.x, rect.y); WritableRaster wr = Raster.createWritableRaster(smRet, pt); - // System.out.println("GD DB: " + wr.getDataBuffer().getSize()); + // System.out.println("GD DB: " + wr.getDataBuffer().getSize()); return copyData(wr); } 1.11 +18 -1 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AbstractTiledRed.java Index: AbstractTiledRed.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AbstractTiledRed.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- AbstractTiledRed.java 2001/07/18 22:04:53 1.10 +++ AbstractTiledRed.java 2001/07/26 18:03:07 1.11 @@ -26,7 +26,7 @@ * the subclass implementation. * * @author <a href="mailto:[EMAIL PROTECTED]">Thomas DeWeese</a> - * @version $Id: AbstractTiledRed.java,v 1.10 2001/07/18 22:04:53 deweese Exp $ + * @version $Id: AbstractTiledRed.java,v 1.11 2001/07/26 18:03:07 deweese Exp $ */ public abstract class AbstractTiledRed extends AbstractRed @@ -250,6 +250,23 @@ 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); 1.3 +15 -10 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/Any2sRGBRed.java Index: Any2sRGBRed.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/Any2sRGBRed.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Any2sRGBRed.java 2001/05/16 12:33:39 1.2 +++ Any2sRGBRed.java 2001/07/26 18:03:07 1.3 @@ -34,7 +34,7 @@ * new image. * * @author <a href="mailto:[EMAIL PROTECTED]">Thomas DeWeese</a> - * @version $Id: Any2sRGBRed.java,v 1.2 2001/05/16 12:33:39 deweese Exp $ */ + * @version $Id: Any2sRGBRed.java,v 1.3 2001/07/26 18:03:07 deweese Exp $ */ public class Any2sRGBRed extends AbstractRed { boolean srcIsLsRGB = false; @@ -80,7 +80,7 @@ } /** - * Gamma for linear to sRGB convertion + * Exponent for linear to sRGB convertion */ private static final double GAMMA = 2.4; @@ -145,6 +145,7 @@ } public WritableRaster copyData(WritableRaster wr) { + // Get my source. CachableRed src = (CachableRed)getSources().get(0); ColorModel srcCM = src.getColorModel(); @@ -198,18 +199,22 @@ BandCombineOp op = new BandCombineOp(matrix, null); op.filter(srcRas, wr); } else { - Raster srcRas = src.getData(wr.getBounds()); - WritableRaster srcWr = (WritableRaster)srcRas; - ColorModel dstCM = getColorModel(); - if (srcCM.getColorSpace() == dstCM.getColorSpace()) { // No transform needed, just reformat data... // System.out.println("Bypassing"); - GraphicsUtil.copyData(srcRas, wr); + + 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. @@ -232,13 +237,13 @@ // System.out.println("After filter:"); + WritableRaster wr00 = wr.createWritableTranslatedChild(0,0); for (int i=0; i<dstCM.getColorSpace().getNumComponents(); i++) - copyBand(dstBI.getRaster(), i, wr, i); - + copyBand(dstBI.getRaster(), i, wr00, i); + if (dstCM.hasAlpha()) copyBand(srcWr, srcSM.getNumBands()-1, wr, getSampleModel().getNumBands()-1); - } return wr; } 1.8 +24 -17 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileRed.java Index: TileRed.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileRed.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- TileRed.java 2001/07/23 19:36:29 1.7 +++ TileRed.java 2001/07/26 18:03:07 1.8 @@ -37,7 +37,7 @@ * left corner of the tiled region. * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> - * @version $Id: TileRed.java,v 1.7 2001/07/23 19:36:29 deweese Exp $ + * @version $Id: TileRed.java,v 1.8 2001/07/26 18:03:07 deweese Exp $ */ public class TileRed extends AbstractRed implements TileGenerator { static final AffineTransform IDENTITY = new AffineTransform(); @@ -103,17 +103,18 @@ double smSz = sm.getWidth()*sm.getHeight(); double stepSz = (xStep*(double)yStep); - if (2.0*smSz > stepSz) { + // be prepaired to grow the default tile size quite a bit if + // it means the image to tile will fit in it... + if (16.1*smSz > stepSz) { int xSz = xStep; int ySz = yStep; // If the pattern size is small then have multiple copies // in our tile. - if (4*stepSz < smSz) { - double mult = smSz/stepSz; - double sqrt = Math.sqrt(mult); - xSz *= (int)sqrt; - ySz *= (int)sqrt; + if (4*stepSz <= smSz) { + int mult = (int)Math.ceil(Math.sqrt(smSz/stepSz)); + xSz *= mult; + ySz *= mult; } sm = sm.createCompatibleSampleModel(xSz, ySz); @@ -191,20 +192,26 @@ } } else { - this.tile = tile; - tiles = TileCache.getTileMap(this); + this.tile = new TileCacheRed(GraphicsUtil.wrap(tile)); } } public WritableRaster copyData(WritableRaster wr) { - int tx0 = getXTile(wr.getMinX()); - int ty0 = getYTile(wr.getMinY()); - int tx1 = getXTile(wr.getMinX()+wr.getWidth() -1); - int ty1 = getYTile(wr.getMinY()+wr.getHeight()-1); + int xOff = ((int)Math.floor(wr.getMinX()/xStep))*xStep; + int yOff = ((int)Math.floor(wr.getMinY()/yStep))*yStep; + int x0 = wr.getMinX()-xOff; + int y0 = wr.getMinY()-yOff; + int tx0 = getXTile(x0); + int ty0 = getYTile(y0); + int tx1 = getXTile(x0+wr.getWidth() -1); + int ty1 = getYTile(y0+wr.getHeight()-1); for (int y=ty0; y<=ty1; y++) for (int x=tx0; x<=tx1; x++) { Raster r = getTile(x, y); + r = r.createChild(r.getMinX(), r.getMinY(), + r.getWidth(), r.getHeight(), + r.getMinX()+xOff, r.getMinY()+yOff, null); if (is_INT_PACK) GraphicsUtil.copyData_INT_PACK(r, wr); else @@ -225,11 +232,11 @@ } // System.out.println("Checking Cache [" + x + "," + y + "]"); - return tiles.getTile(x,y); + return genTile(x,y); } public Raster genTile(int x, int y) { - // System.out.println("Cache Miss [" + x + "," + y + "]"); + // System.out.println("Cache Miss [" + x + "," + y + "]"); int tx = tileGridXOff+x*tileWidth; int ty = tileGridYOff+y*tileHeight; @@ -291,8 +298,8 @@ // src.getHeight() + "]"); // System.out.println("tileTx/tileTy : " + tileTx + " / " + tileTy); minX = curX; - while(curY <= maxY) { - while (curX <= maxX) { + while(curY < maxY) { + while (curX < maxX) { // System.out.println("curX/curY : " + curX + " / " + curY); // System.out.println("transform : " + // g.getTransform().getTranslateX() + 1.1 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/DisplacementMapRed8Bit.java Index: DisplacementMapRed8Bit.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.batik.ext.awt.image.rendered; import org.apache.batik.ext.awt.image.GraphicsUtil; import org.apache.batik.ext.awt.image.PadMode; import org.apache.batik.ext.awt.image.rendered.AbstractRed; import org.apache.batik.ext.awt.image.rendered.CachableRed; import java.awt.RenderingHints; import java.awt.Rectangle; import java.awt.Point; import java.awt.geom.Rectangle2D; import java.awt.geom.Point2D; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; import java.awt.image.Raster; import java.awt.image.RasterOp; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import org.apache.batik.ext.awt.image.ARGBChannel; /** * This implementation of RenderableImage will render its input * GraphicsNode on demand for tiles. * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> * @version $Id: DisplacementMapRed8Bit.java,v 1.1 2001/07/26 18:03:07 deweese Exp $ */ public class DisplacementMapRed8Bit extends AbstractRed { // Use these to control timing and Nearest Neighbot vs. Bilinear Interp. static private final boolean TIME = false; static private final boolean USE_NN = false; /** * The displacement scale factor along the x axis */ private float scaleX; /** * The displacement scale factor along the y axis */ private float scaleY; /** * The channel type of the operation on X axis */ private ARGBChannel xChannel; /** * The channel type of the operation on Y axis */ private ARGBChannel yChannel; /** * The image to distort. */ CachableRed image; /** * The offset image (displacement map). */ CachableRed offsets; /** * The maximum possible offsets in x and y */ int maxOffX, maxOffY; /** * The set of rendering hints */ RenderingHints hints; /** * Computed tile Offsets Soft referencces to TileOffsets instances... */ TileOffsets [] xOffsets; TileOffsets [] yOffsets; static class TileOffsets { int [] tile; int [] off; TileOffsets(int len, int base, int stride, int loc, int endLoc, int slop, int tile, int endTile) { this.tile = new int[len+1]; this.off = new int[len+1]; if (tile == endTile) endLoc -= slop; for (int i=0; i<len; i++) { this.tile[i] = tile; this.off [i] = base+(loc*stride); loc++; if (loc == endLoc) { loc = 0; tile++; if (tile == endTile) endLoc -=slop; } } this.tile[len] = this.tile[len-1]; this.off [len] = this.off [len-1]; } } /** * @param scaleX defines the scale factor of the filter operation * on the X axis. * @param scaleY defines the scale factor of the filter operation * on the Y axis * @param xChannel defines the channel of off whose values will be * on X-axis operation * @param xChannel defines the channel of off whose values will be * on X-axis operation * @param off defines the input bufferedImage whose component * values will be used in displacment operation */ public DisplacementMapRed8Bit(CachableRed image, CachableRed offsets, ARGBChannel xChannel, ARGBChannel yChannel, float scaleX, float scaleY, RenderingHints rh) { if(xChannel == null){ throw new IllegalArgumentException("Must provide xChannel"); } if(yChannel == null){ throw new IllegalArgumentException("Must provide yChannel"); } this.offsets = offsets; this.scaleX = scaleX; this.scaleY = scaleY; this.xChannel = xChannel; this.yChannel = yChannel; this.hints = rh; maxOffX = (int)Math.ceil(scaleX/2); maxOffY = (int)Math.ceil(scaleY/2); Rectangle rect = image.getBounds(); Rectangle r = image.getBounds(); r.x -= maxOffX; r.width += 2*maxOffX; r.y -= maxOffY; r.height += 2*maxOffY; image = new PadRed(image, r, PadMode.ZERO_PAD, null); image = new TileCacheRed(image); this.image = image; ColorModel cm = image.getColorModel(); if (!USE_NN) // For Bilinear we need alpha premult. cm = GraphicsUtil.coerceColorModel(cm, true); init(image, rect, cm, image.getSampleModel(), rect.x, rect.y, null); xOffsets = new TileOffsets[getNumXTiles()]; yOffsets = new TileOffsets[getNumYTiles()]; } public WritableRaster copyData(WritableRaster wr) { copyToRaster(wr); return wr; } public Raster getTile(int tileX, int tileY) { WritableRaster dest = makeTile(tileX, tileY); Rectangle srcR = dest.getBounds(); // Get Raster from offsetes Raster mapRas = offsets.getData(srcR); ColorModel mapCM = offsets.getColorModel(); // ensure map isn't pre-multiplied. GraphicsUtil.coerceData((WritableRaster)mapRas, mapCM, false); TileOffsets xinfo = getXOffsets(tileX); TileOffsets yinfo = getYOffsets(tileY); if (USE_NN) filterNN(mapRas, dest, xinfo.tile, xinfo.off, yinfo.tile, yinfo.off); else if (image.getColorModel().isAlphaPremultiplied()) filterBL(mapRas, dest, xinfo.tile, xinfo.off, yinfo.tile, yinfo.off); else filterBLPre(mapRas, dest, xinfo.tile, xinfo.off, yinfo.tile, yinfo.off); return dest; } public TileOffsets getXOffsets(int xTile) { TileOffsets ret = xOffsets[xTile-getMinTileX()]; if (ret != null) return ret; SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)image.getSampleModel(); int base = sppsm.getOffset(0, 0); int tw = sppsm.getWidth(); // The span we need to cover in the input image. int width = tw+2*maxOffX; // The start and end X in image's tile coordinate system... int x0 = (getTileGridXOffset() + (xTile*tw) - maxOffX -image.getTileGridXOffset()); int x1 = x0+width-1; int tile = (int)Math.floor(x0/(double)tw); int endTile = (int)Math.floor(x1/(double)tw); int loc = x0-(tile*tw); int endLoc = tw; // Amount not used from right edge tile int slop = ((endTile+1)*tw-1) - x1; ret = new TileOffsets(width, base, 1, loc, endLoc, slop, tile, endTile); xOffsets[xTile-getMinTileX()] = ret; return ret; } public TileOffsets getYOffsets(int yTile) { TileOffsets ret = yOffsets[yTile-getMinTileY()]; if (ret != null) return ret; SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel)image.getSampleModel(); int stride = sppsm.getScanlineStride(); int th = sppsm.getHeight(); // The span we need to cover in the input image. int height = th+2*maxOffY; // The start and end Y in image's tile coordinate system... int y0 = (getTileGridYOffset() + (yTile*th) - maxOffY -image.getTileGridYOffset()); int y1 = y0+height-1; int tile = (int)Math.floor(y0/(double)th); int endTile = (int)Math.floor(y1/(double)th); int loc = y0-(tile*th); int endLoc = th; // Amount not used from bottom edge tile int slop = ((endTile+1)*th-1) - y1; ret = new TileOffsets(height, 0, stride, loc, endLoc, slop, tile, endTile); yOffsets[yTile-getMinTileY()] = ret; return ret; } public void filterBL(Raster off, WritableRaster dst, int [] xTile, int [] xOff, int [] yTile, int [] yOff) { final int w = dst.getWidth(); final int h = dst.getHeight(); final int xStart = maxOffX; final int yStart = maxOffY; final int xEnd = xStart+w; final int yEnd = yStart+h; // Access the integer buffer for each image. DataBufferInt dstDB = (DataBufferInt)dst.getDataBuffer(); DataBufferInt offDB = (DataBufferInt)off.getDataBuffer(); // Offset defines where in the stack the real data begin SinglePixelPackedSampleModel dstSPPSM, offSPPSM; dstSPPSM = (SinglePixelPackedSampleModel)dst.getSampleModel(); final int dstOff = dstDB.getOffset() + dstSPPSM.getOffset(dst.getMinX() - dst.getSampleModelTranslateX(), dst.getMinY() - dst.getSampleModelTranslateY()); offSPPSM = (SinglePixelPackedSampleModel)off.getSampleModel(); final int offOff = offDB.getOffset() + offSPPSM.getOffset(dst.getMinX() - off.getSampleModelTranslateX(), dst.getMinY() - off.getSampleModelTranslateY()); // Stride is the distance between two consecutive column elements, // in the one-dimention dataBuffer final int dstScanStride = dstSPPSM.getScanlineStride(); final int offScanStride = offSPPSM.getScanlineStride(); final int dstAdjust = dstScanStride - w; final int offAdjust = offScanStride - w; // Access the pixel value array final int dstPixels[] = dstDB.getBankData()[0]; final int offPixels[] = offDB.getBankData()[0]; // Below is the number of shifts for each axis // e.g when xChannel is ALPHA, the pixel needs // to be shifted 24, RED 16, GREEN 8 and BLUE 0 final int xShift = xChannel.toInt()*8; final int yShift = yChannel.toInt()*8; // The pointer of img and dst indicating where the pixel values are int dp = dstOff, ip = offOff; // Fixed point representation of scale factor. final int fpScaleX = (int)((scaleX/255.0)*(1<<15)); final int fpScaleY = (int)((scaleY/255.0)*(1<<15)); final int maxDx = maxOffX; final int dangerZoneX = w-maxDx; final int maxDy = maxOffY; final int dangerZoneY = h-maxDy; long start = System.currentTimeMillis(); int sdp, pel00, pel01, pel10, pel11, xFrac, yFrac, newPel; int sp0, sp1, pel0, pel1; int x, y, x0, y0, xDisplace, yDisplace, dPel; int xt=xTile[0]-1, yt=yTile[0]-1, xt1, yt1; int [] imgPix = null; for (y=yStart; y<yEnd; y++) { for (x=xStart; x<xEnd; x++, dp++, ip++) { dPel = offPixels[ip]; xDisplace = fpScaleX*(((dPel>>xShift)&0xff) - 127); yDisplace = fpScaleY*(((dPel>>yShift)&0xff) - 127); x0 = x+(xDisplace>>15); y0 = y+(yDisplace>>15); if ((xt != xTile[x0]) || (yt != yTile[y0])) { xt = xTile[x0]; yt = yTile[y0]; imgPix = ((DataBufferInt)image.getTile(xt, yt) .getDataBuffer()).getBankData()[0]; } pel00 = imgPix[xOff[x0]+yOff[y0]]; xt1 = xTile[x0+1]; yt1 = yTile[y0+1]; if ((yt == yt1)) { // Same tile vertically, check across... if ((xt == xt1)) { // All from same tile.. pel10 = imgPix[xOff[x0+1]+yOff[y0]]; pel01 = imgPix[xOff[x0] +yOff[y0+1]]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; } else { // Different tile horizontally... pel01 = imgPix[xOff[x0]+yOff[y0+1]]; imgPix = ((DataBufferInt)image.getTile(xt1, yt) .getDataBuffer()).getBankData()[0]; pel10 = imgPix[xOff[x0+1]+yOff[y0]]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; xt = xt1; } } else { // Steped into next tile down, check across... if ((xt == xt1)) { // Different tile horizontally. pel10 = imgPix[xOff[x0+1]+yOff[y0]]; imgPix = ((DataBufferInt)image.getTile(xt, yt1) .getDataBuffer()).getBankData()[0]; pel01 = imgPix[xOff[x0] +yOff[y0+1]]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; yt = yt1; } else { // Ugg we are at the 4way intersection of tiles... imgPix = ((DataBufferInt)image.getTile(xt, yt1) .getDataBuffer()).getBankData()[0]; pel01 = imgPix[xOff[x0]+yOff[y0+1]]; imgPix = ((DataBufferInt)image.getTile(xt1, yt1) .getDataBuffer()).getBankData()[0]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; imgPix = ((DataBufferInt)image.getTile(xt1, yt) .getDataBuffer()).getBankData()[0]; pel10 = imgPix[xOff[x0+1]+yOff[y0]]; xt = xt1; } } xFrac = xDisplace&0x7FFF; yFrac = yDisplace&0x7FFF; // Combine the alpha channels. sp0 = (pel00>>>16) & 0xFF00; sp1 = (pel10>>>16) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = (pel01>>>16) & 0xFF00; sp1 = (pel11>>>16) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel = (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)<< 1; // Combine the red channels. sp0 = (pel00>> 8) & 0xFF00; sp1 = (pel10>> 8) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = (pel01>> 8) & 0xFF00; sp1 = (pel11>> 8) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel |= (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)>>> 7; // Combine the green channels. sp0 = (pel00 ) & 0xFF00; sp1 = (pel10 ) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = (pel01 ) & 0xFF00; sp1 = (pel11 ) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel |= (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)>>>15; // Combine the blue channels. sp0 = (pel00<< 8) & 0xFF00; sp1 = (pel10<< 8) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = (pel01<< 8) & 0xFF00; sp1 = (pel11<< 8) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel |= (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)>>>23; dstPixels[dp] = newPel; } dp += dstAdjust; ip += offAdjust; } if (TIME) { long end = System.currentTimeMillis(); System.out.println("Time: " + (end-start)); } }// end of the filter() method for Raster public void filterBLPre(Raster off, WritableRaster dst, int [] xTile, int [] xOff, int [] yTile, int [] yOff) { final int w = dst.getWidth(); final int h = dst.getHeight(); final int xStart = maxOffX; final int yStart = maxOffY; final int xEnd = xStart+w; final int yEnd = yStart+h; // Access the integer buffer for each image. DataBufferInt dstDB = (DataBufferInt)dst.getDataBuffer(); DataBufferInt offDB = (DataBufferInt)off.getDataBuffer(); // Offset defines where in the stack the real data begin SinglePixelPackedSampleModel dstSPPSM, offSPPSM; dstSPPSM = (SinglePixelPackedSampleModel)dst.getSampleModel(); final int dstOff = dstDB.getOffset() + dstSPPSM.getOffset(dst.getMinX() - dst.getSampleModelTranslateX(), dst.getMinY() - dst.getSampleModelTranslateY()); offSPPSM = (SinglePixelPackedSampleModel)off.getSampleModel(); final int offOff = offDB.getOffset() + offSPPSM.getOffset(dst.getMinX() - off.getSampleModelTranslateX(), dst.getMinY() - off.getSampleModelTranslateY()); // Stride is the distance between two consecutive column elements, // in the one-dimention dataBuffer final int dstScanStride = dstSPPSM.getScanlineStride(); final int offScanStride = offSPPSM.getScanlineStride(); final int dstAdjust = dstScanStride - w; final int offAdjust = offScanStride - w; // Access the pixel value array final int dstPixels[] = dstDB.getBankData()[0]; final int offPixels[] = offDB.getBankData()[0]; // Below is the number of shifts for each axis // e.g when xChannel is ALPHA, the pixel needs // to be shifted 24, RED 16, GREEN 8 and BLUE 0 final int xShift = xChannel.toInt()*8; final int yShift = yChannel.toInt()*8; // The pointer of img and dst indicating where the pixel values are int dp = dstOff, ip = offOff; // Fixed point representation of scale factor. final int fpScaleX = (int)((scaleX/255.0)*(1<<15)); final int fpScaleY = (int)((scaleY/255.0)*(1<<15)); final int maxDx = maxOffX; final int dangerZoneX = w-maxDx; final int maxDy = maxOffY; final int dangerZoneY = h-maxDy; long start = System.currentTimeMillis(); int sdp, pel00, pel01, pel10, pel11, xFrac, yFrac, newPel; int sp0, sp1, pel0, pel1, a00, a01, a10, a11; int x, y, x0, y0, xDisplace, yDisplace, dPel; final int norm = (1<<16)/255; int xt=xTile[0]-1, yt=yTile[0]-1, xt1, yt1; int [] imgPix = null; for (y=yStart; y<yEnd; y++) { for (x=xStart; x<xEnd; x++, dp++, ip++) { dPel = offPixels[ip]; xDisplace = fpScaleX*(((dPel>>xShift)&0xff) - 127); yDisplace = fpScaleY*(((dPel>>yShift)&0xff) - 127); x0 = x+(xDisplace>>15); y0 = y+(yDisplace>>15); if ((xt != xTile[x0]) || (yt != yTile[y0])) { xt = xTile[x0]; yt = yTile[y0]; imgPix = ((DataBufferInt)image.getTile(xt, yt) .getDataBuffer()).getBankData()[0]; } pel00 = imgPix[xOff[x0]+yOff[y0]]; xt1 = xTile[x0+1]; yt1 = yTile[y0+1]; if ((yt == yt1)) { // Same tile vertically, check across... if ((xt == xt1)) { // All from same tile.. pel10 = imgPix[xOff[x0+1]+yOff[y0]]; pel01 = imgPix[xOff[x0] +yOff[y0+1]]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; } else { // Different tile horizontally... pel01 = imgPix[xOff[x0]+yOff[y0+1]]; imgPix = ((DataBufferInt)image.getTile(xt1, yt) .getDataBuffer()).getBankData()[0]; pel10 = imgPix[xOff[x0+1]+yOff[y0]]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; xt = xt1; } } else { // Steped into next tile down, check across... if ((xt == xt1)) { // Different tile horizontally. pel10 = imgPix[xOff[x0+1]+yOff[y0]]; imgPix = ((DataBufferInt)image.getTile(xt, yt1) .getDataBuffer()).getBankData()[0]; pel01 = imgPix[xOff[x0] +yOff[y0+1]]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; yt = yt1; } else { // Ugg we are at the 4way intersection of tiles... imgPix = ((DataBufferInt)image.getTile(xt, yt1) .getDataBuffer()).getBankData()[0]; pel01 = imgPix[xOff[x0]+yOff[y0+1]]; imgPix = ((DataBufferInt)image.getTile(xt1, yt1) .getDataBuffer()).getBankData()[0]; pel11 = imgPix[xOff[x0+1]+yOff[y0+1]]; imgPix = ((DataBufferInt)image.getTile(xt1, yt) .getDataBuffer()).getBankData()[0]; pel10 = imgPix[xOff[x0+1]+yOff[y0]]; xt = xt1; } } xFrac = xDisplace&0x7FFF; yFrac = yDisplace&0x7FFF; // Combine the alpha channels. sp0 = (pel00>>>16) & 0xFF00; sp1 = (pel10>>>16) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; a00 = (sp0>>8)*norm; a10 = (sp1>>8)*norm; sp0 = (pel01>>>16) & 0xFF00; sp1 = (pel11>>>16) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; a01 = (sp0>>8)*norm; a11 = (sp1>>8)*norm; newPel = (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)<< 1; // Combine the red channels. sp0 = ((((pel00>> 16) & 0xFF)*a00)>>8) & 0xFF00; sp1 = ((((pel10>> 16) & 0xFF)*a10)>>8) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = ((((pel01>> 16) & 0xFF)*a01)>>8) & 0xFF00; sp1 = ((((pel11>> 16) & 0xFF)*a11)>>8) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel |= (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)>>> 7; // Combine the green channels. sp0 = ((((pel00>> 8) & 0xFF)*a00)>>8) & 0xFF00; sp1 = ((((pel10>> 8) & 0xFF)*a10)>>8) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = ((((pel01>> 8) & 0xFF)*a01)>>8) & 0xFF00; sp1 = ((((pel11>> 8) & 0xFF)*a11)>>8) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel |= (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)>>>15; // Combine the blue channels. sp0 = (((pel00 & 0xFF)*a00)>>8) & 0xFF00; sp1 = (((pel10 & 0xFF)*a10)>>8) & 0xFF00; pel0 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; sp0 = (((pel01 & 0xFF)*a01)>>8) & 0xFF00; sp1 = (((pel11 & 0xFF)*a11)>>8) & 0xFF00; pel1 = (sp0 + (((sp1-sp0)*xFrac)>>15)) & 0xFFFF; newPel |= (((pel0<<15) + (pel1-pel0)*yFrac)&0x7F800000)>>>23; dstPixels[dp] = newPel; } dp += dstAdjust; ip += offAdjust; } if (TIME) { long end = System.currentTimeMillis(); System.out.println("Time: " + (end-start)); } }// end of the filter() method for Raster /** * Does displacement map using Nearest neighbor interpolation * * @param img the Raster to be filtered * @param dst stores the filtered image. If null, a destination will * be created. img and dst can refer to the same Raster, in * which situation the img will be modified. */ public void filterNN(Raster off, WritableRaster dst, int [] xTile, int [] xOff, int [] yTile, int [] yOff) { final int w = dst.getWidth(); final int h = dst.getHeight(); final int xStart = maxOffX; final int yStart = maxOffY; final int xEnd = xStart+w; final int yEnd = yStart+h; // Access the integer buffer for each image. DataBufferInt dstDB = (DataBufferInt)dst.getDataBuffer(); DataBufferInt offDB = (DataBufferInt)off.getDataBuffer(); // Offset defines where in the stack the real data begin SinglePixelPackedSampleModel dstSPPSM, offSPPSM; dstSPPSM = (SinglePixelPackedSampleModel)dst.getSampleModel(); final int dstOff = dstDB.getOffset() + dstSPPSM.getOffset(dst.getMinX() - dst.getSampleModelTranslateX(), dst.getMinY() - dst.getSampleModelTranslateY()); offSPPSM = (SinglePixelPackedSampleModel)off.getSampleModel(); final int offOff = offDB.getOffset() + offSPPSM.getOffset(off.getMinX() - off.getSampleModelTranslateX(), off.getMinY() - off.getSampleModelTranslateY()); // Stride is the distance between two consecutive column elements, // in the one-dimention dataBuffer final int dstScanStride = dstSPPSM.getScanlineStride(); final int offScanStride = offSPPSM.getScanlineStride(); final int dstAdjust = dstScanStride - w; final int offAdjust = offScanStride - w; // Access the pixel value array final int dstPixels[] = dstDB.getBankData()[0]; final int offPixels[] = offDB.getBankData()[0]; // Below is the number of shifts for each axis // e.g when xChannel is ALPHA, the pixel needs // to be shifted 24, RED 16, GREEN 8 and BLUE 0 final int xShift = xChannel.toInt()*8; final int yShift = yChannel.toInt()*8; final int fpScaleX = (int)(scaleX*(1<<16)/255 + 0.5f); final int fpScaleY = (int)(scaleY*(1<<16)/255 + 0.5f); // The pointer of img and dst indicating where the pixel values are int dp = dstOff, ip = offOff; long start = System.currentTimeMillis(); int y=yStart, xt=xTile[0]-1, yt=yTile[0]-1; int [] imgPix = null; while (y<yEnd) { int x=xStart; while (x<xEnd) { int pel = offPixels[ip]; final int xDisplace = fpScaleX*(((pel>>xShift)&0xff) - 127); final int yDisplace = fpScaleY*(((pel>>yShift)&0xff) - 127); final int x0 = x+(xDisplace>>16); final int y0 = y+(yDisplace>>16); if ((xt != xTile[x0]) || (yt != yTile[y0])) { xt = xTile[x0]; yt = yTile[y0]; imgPix = ((DataBufferInt)image.getTile(xt, yt) .getDataBuffer()).getBankData()[0]; } dstPixels[dp] = imgPix[xOff[x0]+yOff[y0]]; dp++; ip++; x++; } dp += dstAdjust; ip += offAdjust; y++; } if (TIME) { long end = System.currentTimeMillis(); System.out.println("Time: " + (end-start)); } }// end of the filter() method for Raster } 1.5 +6 -1 xml-batik/sources/org/apache/batik/ext/awt/image/spi/JPEGRegistryEntry.java Index: JPEGRegistryEntry.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/spi/JPEGRegistryEntry.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- JPEGRegistryEntry.java 2001/07/18 22:04:54 1.4 +++ JPEGRegistryEntry.java 2001/07/26 18:03:08 1.5 @@ -19,6 +19,8 @@ import org.apache.batik.ext.awt.image.renderable.Filter; import org.apache.batik.ext.awt.image.renderable.RedRable; import org.apache.batik.ext.awt.image.renderable.DeferRable; +import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed; +import org.apache.batik.ext.awt.image.rendered.CachableRed; import org.apache.batik.util.ParsedURL; public class JPEGRegistryEntry @@ -67,7 +69,10 @@ decoder = JPEGCodec.createJPEGDecoder(is); BufferedImage image; image = decoder.decodeAsBufferedImage(); - filt = new RedRable(GraphicsUtil.wrap(image)); + CachableRed cr; + cr = GraphicsUtil.wrap(image); + cr = new Any2sRGBRed(cr); + filt = new RedRable(cr); } catch (IOException ioe) { // Something bad happened here... filt = ImageTagRegistry.getBrokenLinkImage --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]