Thanks for noticing!
-Peter
Vadim Gritsenko wrote:
Pete wrote:
+ * <dt><offset(Red|Green|Blue)></dt>...
+ offsetColor[0] = par.getParameterAsFloat("offsetBlue",0.0f);
+ offsetColor[1] = par.getParameterAsFloat("offsetBlue",0.0f);
+ offsetColor[2] = par.getParameterAsFloat("offsetBlue",0.0f);
Pete,
You may want to do one more iteration of the patch ;-P
Vadim
Index: ImageReader.java =================================================================== RCS file: /home/cvspublic/cocoon-2.1/src/java/org/apache/cocoon/reading/ImageReader.java,v retrieving revision 1.4 diff -u -r1.4 ImageReader.java --- ImageReader.java 12 Dec 2003 09:41:33 -0000 1.4 +++ ImageReader.java 17 Feb 2004 13:44:44 -0000 @@ -62,9 +62,13 @@ import com.sun.image.codec.jpeg.JPEGImageEncoder; import org.xml.sax.SAXException; +import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; -import java.awt.image.Raster; +import java.awt.image.BufferedImage; +import java.awt.image.ColorConvertOp; +import java.awt.image.DataBuffer; +import java.awt.image.RescaleOp; import java.awt.image.WritableRaster; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -87,19 +91,40 @@ * <dd>This parameter is optional. When specified it determines the height * of the image that should be served. * </dd> + * <dt><scale(Red|Green|Blue)></dt> + * <dd>This parameter is optional. When specified it will cause the + * specified color component in the image to be multiplied by the + * specified floating point value. + * </dd> + * <dt><offset(Red|Green|Blue)></dt> + * <dd>This parameter is optional. When specified it will cause the + * specified color component in the image to be incremented by the + * specified floating point value. + * </dd> + * <dt><grayscale></dt> + * <dd>This parameter is optional. When specified and set to true it + * will cause each image pixel to be normalized. + * </dd> * </dl> * * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a> * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a> - * @version CVS $Id: ImageReader.java,v 1.4 2003/12/12 09:41:33 huber Exp $ + * @version CVS $Id: ImageReader.java,v 1.3 2003/09/24 21:41:11 cziegeler Exp $ */ final public class ImageReader extends ResourceReader { private int width; private int height; + private float[] scaleColor = new float[3]; + private float[] offsetColor = new float[3]; + private ColorConvertOp grayscaleFilter = null; + private RescaleOp colorFilter = null; + private boolean enlarge; private final static String ENLARGE_DEFAULT = "true"; + + private final static String GRAYSCALE_DEFAULT = "false"; public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { @@ -108,7 +133,38 @@ width = par.getParameterAsInteger("width", 0); height = par.getParameterAsInteger("height", 0); - + + scaleColor[0] = par.getParameterAsFloat("scaleRed",-1.0f); + scaleColor[1] = par.getParameterAsFloat("scaleGreen",-1.0f); + scaleColor[2] = par.getParameterAsFloat("scaleBlue",-1.0f); + offsetColor[0] = par.getParameterAsFloat("offsetRed",0.0f); + offsetColor[1] = par.getParameterAsFloat("offsetGreen",0.0f); + offsetColor[2] = par.getParameterAsFloat("offsetBlue",0.0f); + + boolean filterColor = false; + + for(int i = 0; i < 3; ++i) + { + if(scaleColor[i] != -1.0f) filterColor = true; else scaleColor[i] = 1.0f; + if(offsetColor[i] != 0.0f) filterColor = true; + } + + if(true == filterColor) + { + colorFilter = new RescaleOp(scaleColor, offsetColor, null); + } + else + { + colorFilter = null; + } + + String grayscalePar = par.getParameter("grayscale", GRAYSCALE_DEFAULT); + if ("true".equalsIgnoreCase(grayscalePar) || "yes".equalsIgnoreCase(grayscalePar)){ + grayscaleFilter = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY),null); + } else { + grayscaleFilter = null; + } + String enlargePar = par.getParameter("allow-enlarging", ENLARGE_DEFAULT); if ("true".equalsIgnoreCase(enlargePar) || "yes".equalsIgnoreCase(enlargePar)){ enlarge = true; @@ -121,7 +177,7 @@ * Returns the affine transform that implements the scaling. * The behavior is the following: if both the new width and height values * are positive, the image is rescaled according to these new values and - * the original aspect ration is lost. + * the original aspect ratio is lost. * Otherwise, if one of the two parameters is zero or negative, the * aspect ratio is maintained and the positive parameter indicates the * scaling. @@ -160,7 +216,7 @@ } protected void processStream() throws IOException, ProcessingException { - if (width > 0 || height > 0) { + if (width > 0 || height > 0 || null != colorFilter) { if (getLogger().isDebugEnabled()) { getLogger().debug("image " + ((width==0)?"?":Integer.toString(width)) + "x" + ((height==0)?"?":Integer.toString(height)) @@ -193,40 +249,48 @@ */ try { + JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(inputStream); - Raster original = decoder.decodeAsRaster(); + BufferedImage original = decoder.decodeAsBufferedImage(); JPEGDecodeParam decodeParam = decoder.getJPEGDecodeParam(); - double ow = decodeParam.getWidth(); - double oh = decodeParam.getHeight(); - AffineTransformOp filter = new AffineTransformOp(getTransform(ow, oh, width, height), AffineTransformOp.TYPE_BILINEAR); - WritableRaster scaled = filter.createCompatibleDestRaster(original); - filter.filter(original, scaled); - - if (!handleJVMBug()) { - if (getLogger().isDebugEnabled()) { - getLogger().debug( "No need to handle JVM bug" ); - } - JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); - encoder.encode(scaled); - } else { - if (getLogger().isDebugEnabled()) { - getLogger().debug( "Need to handle JVM bug" ); - } - ByteArrayOutputStream bstream = new ByteArrayOutputStream(); - JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bstream); - encoder.encode(scaled); - out.write(bstream.toByteArray()); - } + + BufferedImage currentImage = original; + + if(width > 0 || height > 0) + { + double ow = decodeParam.getWidth(); + double oh = decodeParam.getHeight(); + + AffineTransformOp filter = new AffineTransformOp(getTransform(ow, oh, width, height), AffineTransformOp.TYPE_BILINEAR); + WritableRaster intermediateRaster = filter.createCompatibleDestRaster(currentImage.getRaster()); + + filter.filter(currentImage.getRaster(), intermediateRaster); + + currentImage = new BufferedImage(original.getColorModel(), intermediateRaster, true, null); + } + + if(null != grayscaleFilter) + { + grayscaleFilter.filter(currentImage, currentImage); + } + if(null != colorFilter) + { + colorFilter.filter(currentImage, currentImage); + } + + // JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); + + ByteArrayOutputStream bstream = new ByteArrayOutputStream(); + JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bstream); + encoder.encode(currentImage); + out.write(bstream.toByteArray()); out.flush(); } catch (ImageFormatException e) { throw new ProcessingException("Error reading the image. Note that only JPEG images are currently supported."); - } finally { - // Bugzilla Bug 25069, close inputStream in finally block - // this will close inputStream even if processStream throws - // an exception - inputStream.close(); } + + inputStream.close(); } else { // only read the resource - no modifications requested if (getLogger().isDebugEnabled()) { @@ -240,48 +304,20 @@ * Generate the unique key. * This key must be unique inside the space of this component. * - * @return The generated key consists from src and width and height + * @return The generated key consists of the src and width and height, and the color transform * parameters */ public Serializable getKey() { - if (width > 0 || height > 0) { - return this.inputSource.getURI() + ':' + this.width + ':' + this.height; - } else { - return super.getKey(); - } - } - - /** - * Determine if workaround for Bug Id 4502892 is neccessary. - * This method assumes that Bug is present if - * java.version is undeterminable, and for java.version - * 1.1, 1.2, 1.3, all other java.version do not need the Bug handling - * - * @return true if we should handle the JVM bug, else false - */ - protected boolean handleJVMBug() { - // java.version=1.4.0 - String java_version = System.getProperty( "java.version", "0.0.0" ); - boolean handleJVMBug = true; - - char major = java_version.charAt(0); - char minor = java_version.charAt(2); - - // make 0.0, 1.1, 1.2, 1.3 handleJVMBug = true - if (major == '0' || major == '1') { - if (minor == '0' || minor == '1' || minor == '2' || minor == '3') { - handleJVMBug = true; - } else { - handleJVMBug = false; - } - } else { - handleJVMBug = true; - } - if (getLogger().isDebugEnabled()) { - getLogger().debug( "Running java.version " + String.valueOf(java_version) + - " need to handle JVM bug " + String.valueOf(handleJVMBug) ); - } - - return handleJVMBug; + return this.inputSource.getURI() + + ':' + this.width + + ':' + this.height + + ":" + this.scaleColor[0] + + ":" + this.scaleColor[1] + + ":" + this.scaleColor[2] + + ":" + this.offsetColor[0] + + ":" + this.offsetColor[1] + + ":" + this.offsetColor[2] + + ":" + ((null == this.grayscaleFilter)?"color":"grayscale") + + ":" + super.getKey(); } }
