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]