deweese 2003/06/05 17:14:26
Modified: sources/org/apache/batik/ext/awt/image GraphicsUtil.java
sources/org/apache/batik/ext/awt/image/spi
JPEGRegistryEntry.java PNGRegistryEntry.java
Log:
Added an optimization to image drawing which makes it about 5-10x faster,
for most raster images.
Revision Changes Path
1.28 +45 -95
xml-batik/sources/org/apache/batik/ext/awt/image/GraphicsUtil.java
Index: GraphicsUtil.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/GraphicsUtil.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- GraphicsUtil.java 11 Apr 2003 13:57:32 -0000 1.27
+++ GraphicsUtil.java 6 Jun 2003 00:14:25 -0000 1.28
@@ -91,8 +91,6 @@
// System.out.println("DrawImage G: " + g2d);
- ColorModel srcCM = cr.getColorModel();
-
AffineTransform at = null;
while (true) {
if (cr instanceof AffineRed) {
@@ -117,18 +115,45 @@
}
break;
}
-
AffineTransform g2dAt = g2d.getTransform();
if ((at == null) || (at.isIdentity()))
at = g2dAt;
else
at.preConcatenate(g2dAt);
- Composite g2dComposite = g2d.getComposite();
+ ColorModel srcCM = cr.getColorModel();
+ ColorSpace g2dCS = getDestinationColorSpace(g2d);
+ ColorModel g2dCM = getDestinationColorModel(g2d);
+ if (g2dCS == null)
+ // Assume device is sRGB
+ g2dCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ ColorModel drawCM = g2dCM;
+ if (g2dCM == null) {
+ // If we can't find out about our device assume
+ // it's SRGB unpremultiplied (Just because this
+ // seems to work for us).
+ drawCM = sRGB_Unpre;
+ } else if (drawCM.hasAlpha() && g2dCM.hasAlpha() &&
+ (drawCM.isAlphaPremultiplied() !=
+ g2dCM .isAlphaPremultiplied())) {
+ drawCM = coerceColorModel(drawCM, g2dCM.isAlphaPremultiplied());
+ }
- if (false) {
- System.out.println("CR: " + cr);
- System.out.println("CRR: " + cr.getBounds());
+ if (cr instanceof BufferedImageCachableRed) {
+ // There is a huge win if we can use the BI directly here.
+ // This results in something like a 10x performance gain
+ // for images, the best thing is this is the common case.
+ if (g2dCS.equals(srcCM.getColorSpace()) &&
+ drawCM.equals(srcCM)) {
+ // System.err.println("Fast Case");
+ g2d.setTransform(at);
+ BufferedImageCachableRed bicr;
+ bicr = (BufferedImageCachableRed)cr;
+ g2d.drawImage(bicr.getBufferedImage(),
+ bicr.getMinX(), bicr.getMinY(), null);
+ g2d.setTransform(g2dAt);
+ return;
+ }
}
// Scaling down so do it before color conversion.
@@ -143,11 +168,6 @@
}
}
- ColorSpace g2dCS = getDestinationColorSpace(g2d);
- if (g2dCS == null)
- // Assume device is sRGB
- g2dCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-
if (g2dCS != srcCM.getColorSpace()) {
// System.out.println("srcCS: " + srcCM.getColorSpace());
// System.out.println("g2dCS: " + g2dCS);
@@ -161,22 +181,9 @@
else if (g2dCS == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))
cr = convertToLsRGB(cr);
}
-
srcCM = cr.getColorModel();
- ColorModel g2dCM = getDestinationColorModel(g2d);
- ColorModel drawCM = g2dCM;
- if (g2dCM == null) {
- // If we can't find out about our device assume
- // it's SRGB unpremultiplied (Just because this
- // seems to work for us).
- drawCM = sRGB_Unpre;
- } else if (drawCM.hasAlpha() && g2dCM.hasAlpha() &&
- (drawCM.isAlphaPremultiplied() !=
- g2dCM .isAlphaPremultiplied())) {
- drawCM = coerceColorModel(drawCM, g2dCM.isAlphaPremultiplied());
- }
-
- cr = FormatRed.construct(cr, drawCM);
+ if (!drawCM.equals(srcCM))
+ cr = FormatRed.construct(cr, drawCM);
// Scaling up so do it after color conversion.
if (!at.isIdentity() && (determinant > 1.0))
@@ -189,6 +196,7 @@
// Which doesn't seem to have as many bugs as the JDK one when
// going between different src's and destinations (of course it's
// also a lot slower).
+ Composite g2dComposite = g2d.getComposite();
if (g2d.getRenderingHint(RenderingHintsKeyExt.KEY_TRANSCODING) ==
RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING) {
if (SVGComposite.OVER.equals(g2dComposite)) {
@@ -219,68 +227,13 @@
clipR = clipR.intersection(gcR);
}
- if (false) {
- // There has been a problem where the render tries to
- // request a zero pixel high region (due to a bug in the
- // complex clip handling). I have at least temporarily
- // worked around this by changing the alpha state in
- // CompositeRable which changes code paths enough that the
- // renderer doesn't try to construct a zero height
- // SampleModel (which dies).
- //
- // However I suspect that this fix is fragile (other code
- // paths may trigger the bug), eventually we may need to
- // reinstate this code, which handles the clipping for the
- // Graphics2D.
- if ((clip != null) &&
- !(clip instanceof Rectangle2D)) {
-
- // This is now the clip in device space...
- clip = g2d.getClip();
-
- if (clip instanceof Rectangle2D)
- // Simple clip rect...
- cr = new PadRed(cr, clipR, PadMode.ZERO_PAD, null);
- else {
- // Complex clip...
- // System.out.println("Clip:" + clip);
- // System.out.println("ClipR: " + clipR);
- // System.out.println("crR: " + cr.getBounds());
- // System.out.println("at: " + at);
-
- if (clipR.intersects(cr.getBounds()) == false)
- return; // Nothing to draw...
- clipR = clipR.intersection(cr.getBounds());
-
- BufferedImage bi = new BufferedImage
- (clipR.width, clipR.height,
- BufferedImage.TYPE_BYTE_GRAY);
-
- Graphics2D big2d = createGraphics
- (bi, g2d.getRenderingHints());
-
- big2d.translate(-clipR.x, -clipR.y);
- big2d.setPaint(Color.white);
- big2d.fill(clip);
- big2d.dispose();
-
- CachableRed cCr;
- cCr = new BufferedImageCachableRed(bi, clipR.x,
- clipR.y);
- cr = new MultiplyAlphaRed (cr, cCr);
- }
- g2d.setClip(null);
- }
- }
-
// System.out.println("Starting Draw: " + cr);
// long startTime = System.currentTimeMillis();
boolean useDrawRenderedImage = false;
- SampleModel srcSM;
srcCM = cr.getColorModel();
- srcSM = cr.getSampleModel();
+ SampleModel srcSM = cr.getSampleModel();
if ((srcSM.getWidth()*srcSM.getHeight()) >=
(clipR.width*clipR.height))
// if srcSM tiles are larger than the clip size
@@ -292,18 +245,14 @@
// This can be significantly faster but can also
// require much more memory, so we only use it when
// the clip size is smaller than the tile size.
- wr = srcCM.createCompatibleWritableRaster
- (clipR.width, clipR.height);
-
- // If we push caching down the tree farther
- // Then this code path should probably try to
- // align with cr's tile grid to promote tile caching
- // (this of course will increase the memory required
- // in this path).
- cr.copyData(wr.createWritableTranslatedChild
- (clipR.x, clipR.y));
+ Raster r = cr.getData(clipR);
+ wr = ((WritableRaster)r).createWritableChild
+ (clipR.x, clipR.y, clipR.width, clipR.height,
+ 0, 0, null);
+
BufferedImage bi = new BufferedImage
- (srcCM, wr, srcCM.isAlphaPremultiplied(), null);
+ (srcCM, wr,
+ srcCM.isAlphaPremultiplied(), null);
// Any of the drawImage calls that take an
// Affine are prone to the 'CGGStackRestore: gstack
@@ -418,6 +367,7 @@
// System.out.println("Finished Draw");
}
+
/**
* Draws a <tt>Filter</tt> (<tt>RenderableImage</tt>) into a
1.12 +6 -0
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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- JPEGRegistryEntry.java 11 Apr 2003 13:58:16 -0000 1.11
+++ JPEGRegistryEntry.java 6 Jun 2003 00:14:26 -0000 1.12
@@ -8,6 +8,7 @@
package org.apache.batik.ext.awt.image.spi;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
@@ -19,6 +20,7 @@
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.rendered.Any2sRGBRed;
+import org.apache.batik.ext.awt.image.rendered.FormatRed;
import org.apache.batik.ext.awt.image.rendered.CachableRed;
import org.apache.batik.util.ParsedURL;
@@ -86,9 +88,13 @@
throw new IOException
("JPEG File was truncated");
}
+ dr.setBounds(new Rectangle2D.Double
+ (0, 0, image.getWidth(),
+ image.getHeight()));
CachableRed cr;
cr = GraphicsUtil.wrap(image);
cr = new Any2sRGBRed(cr);
+ cr = new FormatRed(cr, GraphicsUtil.sRGB_Unpre);
WritableRaster wr = (WritableRaster)cr.getData();
ColorModel cm = cr.getColorModel();
image = new BufferedImage
1.9 +16 -0
xml-batik/sources/org/apache/batik/ext/awt/image/spi/PNGRegistryEntry.java
Index: PNGRegistryEntry.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/spi/PNGRegistryEntry.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PNGRegistryEntry.java 11 Apr 2003 13:58:16 -0000 1.8
+++ PNGRegistryEntry.java 6 Jun 2003 00:14:26 -0000 1.9
@@ -8,16 +8,22 @@
package org.apache.batik.ext.awt.image.spi;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
import java.io.IOException;
import java.io.InputStream;
import org.apache.batik.ext.awt.image.codec.PNGDecodeParam;
import org.apache.batik.ext.awt.image.codec.PNGRed;
+import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.ext.awt.image.renderable.DeferRable;
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.rendered.Any2sRGBRed;
import org.apache.batik.ext.awt.image.rendered.CachableRed;
+import org.apache.batik.ext.awt.image.rendered.FormatRed;
import org.apache.batik.util.ParsedURL;
public class PNGRegistryEntry
@@ -70,7 +76,17 @@
param.setDisplayExponent(2.2f); // sRGB gamma
}
CachableRed cr = new PNGRed(is, param);
+ dr.setBounds(new Rectangle2D.Double
+ (0, 0, cr.getWidth(), cr.getHeight()));
+
cr = new Any2sRGBRed(cr);
+ cr = new FormatRed(cr, GraphicsUtil.sRGB_Unpre);
+ WritableRaster wr = (WritableRaster)cr.getData();
+ ColorModel cm = cr.getColorModel();
+ BufferedImage image;
+ image = new BufferedImage
+ (cm, wr, cm.isAlphaPremultiplied(), null);
+ cr = GraphicsUtil.wrap(image);
filt = new RedRable(cr);
} catch (IOException ioe) {
filt = ImageTagRegistry.getBrokenLinkImage
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]