From: Jeremias Maerki Date: Tue, 3 Feb 2009 16:28:21 +0000 (+0000) Subject: Merge from Trunk revisions 735029 - 740275. X-Git-Tag: fop-1_0~115^2~72 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=46334ec875bcbbd0fba0370a62c8446c2a038f12;p=xmlgraphics-fop.git Merge from Trunk revisions 735029 - 740275. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@740340 13f79535-47bb-0310-9956-ffa450edef68 --- 46334ec875bcbbd0fba0370a62c8446c2a038f12 diff --cc src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java index ed6fe52b5,ac3a5fe98..80f36c331 --- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java @@@ -19,7 -19,7 +19,8 @@@ package org.apache.fop.render.afp; + import java.awt.Dimension; +import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.RenderedImage; import java.io.IOException; @@@ -28,8 -28,9 +29,10 @@@ import org.apache.commons.io.output.Byt import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; + import org.apache.xmlgraphics.image.loader.ImageInfo; + import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.ps.ImageEncodingHelper; import org.apache.xmlgraphics.util.MimeConstants; @@@ -38,9 -40,7 +42,9 @@@ import org.apache.fop.afp.AFPDataObject import org.apache.fop.afp.AFPImageObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.render.ImageHandler; +import org.apache.fop.render.RenderingContext; - import org.apache.fop.util.BitmapImageUtil; + import org.apache.fop.util.bitmap.BitmapImageUtil; /** * PDFImageHandler implementation which handles RenderedImage instances. @@@ -65,23 -65,53 +69,65 @@@ public class AFPImageHandlerRenderedIma = (AFPRendererContext)rendererImageInfo.getRendererContext(); AFPInfo afpInfo = rendererContext.getInfo(); AFPPaintingState paintingState = afpInfo.getPaintingState(); + ImageRendered imageRendered = (ImageRendered) rendererImageInfo.img; ++ Dimension targetSize = new Dimension(afpInfo.getWidth(), afpInfo.getHeight()); + - updateDataObjectInfo(imageObjectInfo, paintingState, imageRendered); ++ updateDataObjectInfo(imageObjectInfo, paintingState, imageRendered, targetSize); + return imageObjectInfo; + } + + private AFPDataObjectInfo updateDataObjectInfo(AFPImageObjectInfo imageObjectInfo, - AFPPaintingState paintingState, ImageRendered imageRendered) ++ AFPPaintingState paintingState, ImageRendered imageRendered, Dimension targetSize) + throws IOException { + int resolution = paintingState.getResolution(); + int maxPixelSize = paintingState.getBitsPerPixel(); + if (paintingState.isColorImages()) { + maxPixelSize *= 3; //RGB only at the moment + } - ImageRendered imageRendered = (ImageRendered) rendererImageInfo.img; + RenderedImage renderedImage = imageRendered.getRenderedImage(); - imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45); - imageObjectInfo.setDataHeightRes(resolution); - imageObjectInfo.setDataWidthRes(resolution); - ImageInfo imageInfo = rendererImageInfo.getImageInfo(); ++ ImageInfo imageInfo = imageRendered.getInfo(); + ImageSize intrinsicSize = imageInfo.getSize(); + + boolean useFS10 = (maxPixelSize == 1) || BitmapImageUtil.isMonochromeImage(renderedImage); - boolean usePageSegments = useFS10 && !imageObjectInfo.getResourceInfo().getLevel().isInline(); ++ boolean usePageSegments = useFS10 ++ && !imageObjectInfo.getResourceInfo().getLevel().isInline(); + + ImageSize effIntrinsicSize = intrinsicSize; + if (usePageSegments) { + //Resize, optionally resample and convert image + Dimension resampledDim = new Dimension( - (int)Math.ceil(UnitConv.mpt2px(afpInfo.getWidth(), resolution)), - (int)Math.ceil(UnitConv.mpt2px(afpInfo.getHeight(), resolution))); ++ (int)Math.ceil(UnitConv.mpt2px(targetSize.getWidth(), resolution)), ++ (int)Math.ceil(UnitConv.mpt2px(targetSize.getHeight(), resolution))); + + imageObjectInfo.setCreatePageSegment(true); + imageObjectInfo.getResourceInfo().setImageDimension(resampledDim); + + //Only resample/downsample if image is smaller than its intrinsic size + //to make print file smaller + boolean resample = resampledDim.width < renderedImage.getWidth() + && resampledDim.height < renderedImage.getHeight(); + if (resample) { + if (log.isDebugEnabled()) { + log.debug("Resample from " + intrinsicSize.getDimensionPx() + + " to " + resampledDim); + } + renderedImage = BitmapImageUtil.convertToMonochrome(renderedImage, resampledDim); - effIntrinsicSize = new ImageSize(resampledDim.width, resampledDim.height, resolution); ++ effIntrinsicSize = new ImageSize( ++ resampledDim.width, resampledDim.height, resolution); + } + } + if (useFS10) { + imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10); + } else { + imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS11); + } - RenderedImage renderedImage = imageRendered.getRenderedImage(); + imageObjectInfo.setDataHeightRes((int)Math.round( + effIntrinsicSize.getDpiHorizontal() * 10)); + imageObjectInfo.setDataWidthRes((int)Math.round( + effIntrinsicSize.getDpiVertical() * 10)); int dataHeight = renderedImage.getHeight(); imageObjectInfo.setDataHeight(dataHeight); @@@ -89,14 -119,6 +135,8 @@@ int dataWidth = renderedImage.getWidth(); imageObjectInfo.setDataWidth(dataWidth); + //TODO To reduce AFP file size, investigate using a compression scheme. + //Currently, all image data is uncompressed. - - int maxPixelSize = paintingState.getBitsPerPixel(); - if (paintingState.isColorImages()) { - maxPixelSize *= 3; //RGB only at the moment - } - ColorModel cm = renderedImage.getColorModel(); if (log.isTraceEnabled()) { log.trace("ColorModel: " + cm); @@@ -190,33 -218,4 +236,34 @@@ return FLAVORS; } + /** {@inheritDoc} */ + public void handleImage(RenderingContext context, Image image, Rectangle pos) + throws IOException { + AFPRenderingContext afpContext = (AFPRenderingContext)context; + + AFPImageObjectInfo imageObjectInfo = (AFPImageObjectInfo)createDataObjectInfo(); + + // set resource information + setResourceInformation(imageObjectInfo, + image.getInfo().getOriginalURI(), + afpContext.getForeignAttributes()); + + // Positioning + imageObjectInfo.setObjectAreaInfo(createObjectAreaInfo(afpContext.getPaintingState(), pos)); ++ Dimension targetSize = pos.getSize(); + + // Image content + ImageRendered imageRend = (ImageRendered)image; - updateDataObjectInfo(imageObjectInfo, afpContext.getPaintingState(), imageRend); ++ updateDataObjectInfo(imageObjectInfo, afpContext.getPaintingState(), imageRend, targetSize); + + // Create image + afpContext.getResourceManager().createObject(imageObjectInfo); + } + + /** {@inheritDoc} */ + public boolean isCompatible(RenderingContext targetContext, Image image) { + return (image == null || image instanceof ImageRendered) + && targetContext instanceof AFPRenderingContext; + } + } diff --cc src/java/org/apache/fop/render/pcl/PCLGenerator.java index 6ae3a9eff,1060b9bb6..c36d2a66e --- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java +++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java @@@ -600,51 -589,6 +601,26 @@@ public class PCLGenerator return BitmapImageUtil.isGrayscaleImage(img); } + private static int jaiAvailable = -1; //no synchronization necessary, not critical + + /** + * Indicates whether JAI is available. JAI has shown to be reliable when dithering a + * grayscale or color image to monochrome bitmaps (1-bit). + * @return true if JAI is available + */ + public static boolean isJAIAvailable() { + if (jaiAvailable < 0) { + try { - String clName = "org.apache.fop.render.pcl.JAIMonochromeBitmapConverter"; ++ String clName = "javax.media.jai.JAI"; + Class.forName(clName); + jaiAvailable = 1; + } catch (ClassNotFoundException cnfe) { + jaiAvailable = 0; + } + } + return (jaiAvailable > 0); + } + - private MonochromeBitmapConverter createMonochromeBitmapConverter() { - MonochromeBitmapConverter converter = null; - try { - String clName = "org.apache.fop.render.pcl.JAIMonochromeBitmapConverter"; - Class clazz = Class.forName(clName); - converter = (MonochromeBitmapConverter)clazz.newInstance(); - } catch (ClassNotFoundException cnfe) { - // Class was not compiled so is not available. Simply ignore. - } catch (LinkageError le) { - // This can happen if fop was build with support for a - // particular provider (e.g. a binary fop distribution) - // but the required support files (i.e. JAI) are not - // available in the current runtime environment. - // Simply continue with the backup implementation. - } catch (InstantiationException e) { - // Problem instantiating the class, simply continue with the backup implementation - } catch (IllegalAccessException e) { - // Problem instantiating the class, simply continue with the backup implementation - } - if (converter == null) { - converter = new DefaultMonochromeBitmapConverter(); - } - return converter; - } - private int calculatePCLResolution(int resolution) { return calculatePCLResolution(resolution, false); } @@@ -813,13 -739,12 +789,12 @@@ } if (src == null) { src = BitmapImageUtil.convertToGrayscale(img, effDim); - } + } - MonochromeBitmapConverter converter = createMonochromeBitmapConverter(); + MonochromeBitmapConverter converter + = BitmapImageUtil.createDefaultMonochromeBitmapConverter(); converter.setHint("quality", "false"); - BufferedImage buf = (BufferedImage)converter.convertToMonochrome(src); - - RenderedImage red = buf; + RenderedImage red = converter.convertToMonochrome(src); selectCurrentPattern(0, 0); //Solid black setTransparencyMode(sourceTransparency || mask != null, true); paintMonochromeBitmap(red, effResolution);