Author: nbelaevski
Date: 2010-10-27 10:23:10 -0400 (Wed, 27 Oct 2010)
New Revision: 19684
Added:
branches/RF-7817/core/api/src/main/java/org/richfaces/renderkit/util/ColorUtils.java
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/Java2DAnimatedUserResource.java
branches/RF-7817/core/impl/richfaces-suppressions.xml
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/AnimationResource.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/GlobalResourcesViewHandler.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DAnimatedUserResourceWrapperImpl.java
branches/RF-7817/core/impl/src/main/resources/META-INF/global-resources.faces-config.xml
Removed:
branches/RF-7817/core/impl/checkstyle-suppressions.xml
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/component/util/ComponentUtil.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/context/SkinningResourcesPhaseListener.java
branches/RF-7817/core/impl/src/main/resources/META-INF/skinning-resources-listener.faces-config.xml
branches/RF-7817/core/impl/src/test/java/org/richfaces/component/util/ComponentUtilTest.java
Modified:
branches/RF-7817/core/api/pom.xml
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/javascript/JSLiteral.java
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/ImageType.java
branches/RF-7817/core/api/src/main/java/org/richfaces/skin/Skin.java
branches/RF-7817/core/impl/pom.xml
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/Java2Dresource.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/renderkit/html/CustomizeableGradient.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DUserResourceWrapperImpl.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/jquery.position.js
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-event.js
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces.js
branches/RF-7817/core/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java
branches/RF-7817/core/parent/pom.xml
branches/RF-7817/core/pom.xml
Log:
Merged revisions
19156-19157,19159-19160,19176,19186-19187,19190,19194,19196,19199,19203-19204,19231-19234,19248-19249,19255-19256,19258-19262,19276,19279-19281,19283,19285,19291-19299,19307,19312,19315,19318-19319,19325,19341-19342,19345-19351,19353-19355,19358-19359,19364,19367-19369,19371,19374-19377,19379-19385,19387,19393-19394,19400,19402-19404,19418-19422,19426,19430-19431,19434-19441,19443-19444,19446,19468,19470,19477,19491,19498-19499,19501,19504,19506-19507,19517-19519,19525,19542-19543,19548,19550,19555,19557,19560-19561,19565-19566,19571-19573,19582-19585,19592-19593,19599,19601-19602,19613,19646,19657-19659,19665,19671-19674
via svnmerge from
https://svn.jboss.org/repos/richfaces/trunk
Modified: branches/RF-7817/core/api/pom.xml
===================================================================
--- branches/RF-7817/core/api/pom.xml 2010-10-27 12:23:39 UTC (rev 19683)
+++ branches/RF-7817/core/api/pom.xml 2010-10-27 14:23:10 UTC (rev 19684)
@@ -70,7 +70,15 @@
<scope>test</scope>
</dependency>
</dependencies>
-
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
<scm>
<
connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/trunk/core...
<
developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/trun...
Modified: branches/RF-7817/core/api/src/main/java/org/ajax4jsf/javascript/JSLiteral.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/javascript/JSLiteral.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/javascript/JSLiteral.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -23,12 +23,14 @@
package org.ajax4jsf.javascript;
+import java.io.Serializable;
+
/**
* Class provides creation of simple literal javascript to be set in ajax response data
* @author Andrey Markavtsov
*
*/
-public class JSLiteral extends ScriptStringBase {
+public class JSLiteral extends ScriptStringBase implements Serializable{
public static final JSLiteral EMPTY_HASH = new ImmutableJSLiteral("{}");
public static final JSLiteral EMPTY_LIST = new ImmutableJSLiteral("[]");
Copied:
branches/RF-7817/core/api/src/main/java/org/richfaces/renderkit/util/ColorUtils.java (from
rev 19674, trunk/core/api/src/main/java/org/richfaces/renderkit/util/ColorUtils.java)
===================================================================
--- branches/RF-7817/core/api/src/main/java/org/richfaces/renderkit/util/ColorUtils.java
(rev 0)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/renderkit/util/ColorUtils.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,235 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.richfaces.renderkit.util;
+
+import java.awt.Color;
+
+/**
+ * Utility methods that are useful for color processing.
+ *
+ * @author carcasser
+ */
+public final class ColorUtils {
+
+ private ColorUtils() {
+ }
+
+ /**
+ * Converts the components of a color, as specified by the default RGB
+ * model, to an equivalent set of values for hue, saturation, and lightness
+ * that are the three components of the HSL model.
+ *
+ * @param r
+ * the red component of the color
+ * @param g
+ * the green component of the color
+ * @param b
+ * the blue component of the color
+ * @return an array of three elements containing the hue, saturation, and
+ * lightness (in that order), of the color with the indicated red,
+ * green, and blue components.
+ */
+ public static float[] convertRGBtoHSL(int r, int g, int b) {
+ float varR = (r / 255f);
+ float varG = (g / 255f);
+ float varB = (b / 255f);
+
+ float varMin = Math.min(varR, Math.min(varG, varB)); // Min value of RGB
+ float varMax = Math.max(varR, Math.max(varG, varB)); // Max value of RGB
+ float delMax = varMax - varMin; // Delta RGB value
+
+ float h = 0;
+ float s = 0;
+ float l = (varMax + varMin) / 2;
+
+ if (delMax == 0 || l == 0) {
+ s = 0;
+ } else if (l == 1) {
+ s = 1;
+ } else if (l <= 0.5) {
+ s = delMax / (2 * (1 - l));
+ } else if (l > 0.5) {
+ s = delMax / (2 * l);
+ }
+
+ if (delMax == 0) {
+ h = 0;
+ } else if (varMax == varR && g >= b) {
+ h = 60 * (varG - varB) / delMax + 0;
+ } else if (varMax == varR && varG < b) {
+ h = 60 * (varG - varB) / delMax + 360;
+ } else if (varMax == varG) {
+ h = 60 * (varB - varR) / delMax + 120;
+ } else if (varMax == varB) {
+ h = 60 * (varR - varG) / delMax + 240;
+ }
+
+ return new float[] { h, s, l };
+ }
+
+ /**
+ * Converts the components of a color, as specified by the HSL model, to an
+ * equivalent set of values for the default RGB model.
+ * <p>
+ * The <code>saturation</code> and <code>lightness</code>
components
+ * should be floating-point values between zero and one (numbers in the
+ * range 0.0-1.0). The <code>hue</code> component can be any
+ * floating-point number. The floor of this number is subtracted from it to
+ * create a fraction between 0 and 1. This fractional number is then
+ * multiplied by 360 to produce the hue angle in the HSB color model.
+ *
+ * @param h
+ * the hue component of the color
+ * @param s
+ * the saturation of the color
+ * @param l
+ * the lightness of the color
+ * @return the RGB value of the color with the indicated hue, saturation,
+ * and lightness
+ */
+ public static Color convertHSLtoRGB(float h, float s, float l) {
+ float q;
+ if (l < 0.5) {
+ q = l * (1 + s);
+ } else {
+ q = l + s - (l * s);
+ }
+
+ float p = 2 * l - q;
+ float hNorm = h / 360;
+
+ float tR = hNorm + 1f / 3f;
+ float tG = hNorm;
+ float tB = hNorm - 1f / 3f;
+
+ float r = tC2C(tR, p, q);
+ float g = tC2C(tG, p, q);
+ float b = tC2C(tB, p, q);
+
+ return new Color(r, g, b);
+ }
+
+ private static float tC2C(float tC, float p, float q) {
+ float retVal;
+
+ if (tC < 0) {
+ tC += 1;
+ }
+
+ if (tC > 1) {
+ tC -= 1;
+ }
+
+ if ((6 * tC) < 1) {
+ retVal = (p + (q - p) * 6 * tC);
+ } else if ((2 * tC) < 1) {
+ retVal = q;
+ } else if ((3 * tC) < 2) {
+ retVal = (p + (q - p) * 6 * (2f / 3f - tC));
+ } else {
+ retVal = p;
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Increases/decreases brightness of the given color by the specified
+ * <code>difference</code>.
+ * <p>
+ * The <code>difference</code> values in the range (-1.0, 1.0): 1.0 -
the
+ * brightest value; -1.0 - the dimmest value.
+ *
+ * @param c
+ * color to adjust
+ * @param difference
+ * value to be added to the current brightness
+ *
+ * @return a new <code>Color</code> instance with increased/decreased
+ * brightness by specified <code>difference</code>
+ * @throws IllegalArgumentException
+ * if difference is outside of the range -1.0 to 1.0, inclusive
+ */
+ public static Color adjustBrightness(Color c, float difference) {
+ if (difference < -1.0 || difference > 1.0) {
+ throw new IllegalArgumentException("Difference parameter outside of
expected range: "
+ + "Difference parameter should be floating-point values between
-1 and 1");
+ }
+
+ Color retVal = null;
+ if (c != null) {
+ float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
+ float brightness = Math.min(1.0f, Math.max(0.0f, hsb[2] + difference));
+ retVal = new Color(Color.HSBtoRGB(hsb[0], hsb[1], brightness));
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Increases/decreases lightness of the given color by the specified
+ * <code>difference</code>.
+ * <p>
+ * The <code>difference</code> values in the range (-1.0, 1.0): 1.0 -
the
+ * lightest value; -1.0 - on the contrary.
+ *
+ * @param c
+ * color to adjust
+ * @param difference
+ * value to be added to the current lightness
+ *
+ * @return a new <code>Color</code> instance with increased/decreased
+ * lightness by specified <code>difference</code>
+ * @throws IllegalArgumentException
+ * if difference is outside of the range -1.0 to 1.0, inclusive
+ */
+ public static Color adjustLightness(Color c, float difference) {
+ if (difference < -1.0 || difference > 1.0) {
+ throw new IllegalArgumentException("Difference parameter outside of
expected range: "
+ + "Difference parameter should be floating-point values between
-1 and 1");
+ }
+
+ Color retVal = null;
+ if (c != null) {
+ float[] hsl = convertRGBtoHSL(c.getRed(), c.getGreen(), c.getBlue());
+ float lightness = Math.min(1.0f, Math.max(0.0f, hsl[2] + difference));
+ retVal = convertHSLtoRGB(hsl[0], hsl[1], lightness);
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Overwrites alpha value for given color.
+ *
+ * @param c color to overwrite
+ * @param alpha a new value of alpha
+ * @return a new <code>Color</code> object with a new specified alpha
value
+ */
+ public static Color overwriteAlpha(Color c, float alpha) {
+ Color retVal = c;
+ if (c != null) {
+ retVal = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (alpha * 255
+ 0.5));
+ }
+ return retVal;
+ }
+
+}
Modified: branches/RF-7817/core/api/src/main/java/org/richfaces/resource/ImageType.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/ImageType.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/ImageType.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -21,6 +21,7 @@
*/
package org.richfaces.resource;
+import java.awt.Dimension;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
@@ -115,6 +116,10 @@
public abstract BufferedImage createImage(int width, int height);
+ public BufferedImage createImage(Dimension dimension) {
+ return createImage(dimension.width, dimension.height);
+ }
+
public String getFormatName() {
return formatName;
}
Copied:
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/Java2DAnimatedUserResource.java
(from rev 19674,
trunk/core/api/src/main/java/org/richfaces/resource/Java2DAnimatedUserResource.java)
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/Java2DAnimatedUserResource.java
(rev 0)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/resource/Java2DAnimatedUserResource.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.resource;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface Java2DAnimatedUserResource extends Java2DUserResource {
+
+ public boolean isLooped();
+
+ public int getFrameDelay();
+
+ public void startFramesSequence();
+
+ public boolean hasNextFrame();
+
+ public void paint(Graphics2D graphics2d, Dimension dimension);
+
+}
Modified: branches/RF-7817/core/api/src/main/java/org/richfaces/skin/Skin.java
===================================================================
--- branches/RF-7817/core/api/src/main/java/org/richfaces/skin/Skin.java 2010-10-27
12:23:39 UTC (rev 19683)
+++ branches/RF-7817/core/api/src/main/java/org/richfaces/skin/Skin.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -252,6 +252,8 @@
*/
public static final String TAB_WEIGHT_FONT = "tabWeightFont";
+ public static final String TAB_BACKGROUND_COLOR = "tabBackgroundColor";
+
public static final String TRIM_COLOR = "trimColor";
/**
Deleted: branches/RF-7817/core/impl/checkstyle-suppressions.xml
===================================================================
--- branches/RF-7817/core/impl/checkstyle-suppressions.xml 2010-10-27 12:23:39 UTC (rev
19683)
+++ branches/RF-7817/core/impl/checkstyle-suppressions.xml 2010-10-27 14:23:10 UTC (rev
19684)
@@ -1,40 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE suppressions PUBLIC
- "-//Puppy Crawl//DTD Suppressions 1.0//EN"
- "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
-
-<!-- NOTE: Because of issues with maven checkstyle plugin each suppression
- file must have all suppressions defined.
-
- See RF-9077 for details. -->
-<suppressions>
- <suppress checks="DoubleCheckedLocking"
files="MultipartRequestRegistry.java" />
- <suppress checks="FallThrough" files="JSMin.java" />
- <suppress checks="IllegalCatch" files="UISwitchablePanel.java"
/>
- <suppress checks="ModifiedControlVariable"
files="MultipartRequest.java" />
- <suppress checks="IllegalCatch" files="StagingServer.java"
/>
- <suppress checks="IllegalCatch"
files="PartialViewContextImpl.java" />
- <suppress checks="FallThrough" files="StagingServer.java"
/>
- <suppress checks="ModifiedControlVariable" files="Cookie.java"
/>
- <suppress checks="IllegalCatch" files="CacheManager.java"
/>
- <suppress checks="MissingSwitchDefault"
files="JSONTokener.java" />
- <suppress checks="IllegalCatch" files="AjaxViewRoot.java"
/>
- <suppress checks="FallThrough" files="XMLTokener.java" />
- <suppress checks="IllegalCatch"
files="ResourceHandlerImpl.java" />
- <suppress checks="IllegalThrows"
files="AbstractThreadedTest.java" />
- <suppress checks="ModifiedControlVariable"
files="URLCodec.java" />
-
- <!-- TODO it is hot fix for building process, this files belong to the test-base
module,
- and must be removed from here -->
- <suppress checks="IllegalCatch"
files="AbstractThreadedTest.java" />
- <suppress checks="IllegalCatch" files="StagingServer.java"
/>
-
- <!-- TODO it is hot fix for building process, this files belong to the
ui/output/trunk/panela/ui module,
- and must be removed from here -->
- <suppress checks="IllegalCatch"
files="AbstractTogglePanel.java" />
-
- <!-- TODO it is hot fix for building process, this files belong to the
push-redesign module,
- and must be removed from here -->
- <suppress checks="IllegalCatch" files="AbstractRequest.java"
/>
-</suppressions>
Modified: branches/RF-7817/core/impl/pom.xml
===================================================================
--- branches/RF-7817/core/impl/pom.xml 2010-10-27 12:23:39 UTC (rev 19683)
+++ branches/RF-7817/core/impl/pom.xml 2010-10-27 14:23:10 UTC (rev 19684)
@@ -116,7 +116,7 @@
<!-- Checkstyle only required here because suppressions needed -->
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
-
<suppressionsLocation>checkstyle-suppressions.xml</suppressionsLocation>
+
<suppressionsLocation>${project.basedir}/richfaces-suppressions.xml</suppressionsLocation>
</configuration>
</plugin>
Copied: branches/RF-7817/core/impl/richfaces-suppressions.xml (from rev 19674,
trunk/core/impl/richfaces-suppressions.xml)
===================================================================
--- branches/RF-7817/core/impl/richfaces-suppressions.xml (rev 0)
+++ branches/RF-7817/core/impl/richfaces-suppressions.xml 2010-10-27 14:23:10 UTC (rev
19684)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE suppressions PUBLIC
+ "-//Puppy Crawl//DTD Suppressions 1.0//EN"
+ "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
+
+<suppressions>
+ <suppress checks="DoubleCheckedLocking"
files="MultipartRequestRegistry.java" />
+ <suppress checks="FallThrough" files="JSMin.java" />
+ <suppress checks="IllegalCatch" files="UISwitchablePanel.java"
/>
+ <suppress checks="ModifiedControlVariable"
files="MultipartRequest.java" />
+ <suppress checks="IllegalCatch" files="StagingServer.java"
/>
+ <suppress checks="IllegalCatch"
files="PartialViewContextImpl.java" />
+ <suppress checks="FallThrough" files="StagingServer.java"
/>
+ <suppress checks="IllegalCatch" files="CacheManager.java"
/>
+ <suppress checks="IllegalCatch"
files="ResourceHandlerImpl.java" />
+ <suppress checks="IllegalThrows"
files="AbstractThreadedTest.java" />
+ <suppress checks="ModifiedControlVariable"
files="URLCodec.java" />
+</suppressions>
Copied:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/AnimationResource.java
(from rev 19674,
trunk/core/impl/src/main/java/org/ajax4jsf/resource/AnimationResource.java)
===================================================================
--- branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/AnimationResource.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/AnimationResource.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,105 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.ajax4jsf.resource;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import org.ajax4jsf.resource.image.animatedgif.AnimatedGifEncoder;
+import org.richfaces.resource.ImageType;
+
+public abstract class AnimationResource extends Java2Dresource {
+
+ private int[] delays;
+ private int currFrameIndex = 0;
+
+ public AnimationResource() {
+ super(ImageType.GIF);
+ }
+
+ protected abstract Dimension getFrameSize();
+
+ protected abstract int getNumberOfFrames();
+
+ protected int getRepeat() {
+ return -1;
+ }
+
+ protected int[] getFrameDelays() {
+ if (delays == null) {
+ delays = new int[getNumberOfFrames()];
+ Arrays.fill(delays, 0);
+ }
+
+ return delays;
+ }
+
+
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream output = new DataOutputStream(baos);
+ Dimension frameSize = getFrameSize();
+ int numberOfFrames = getNumberOfFrames();
+ BufferedImage frame = null;
+ currFrameIndex = 0;
+ if (frameSize.getHeight() > 0.0 && frameSize.getWidth() > 0.0
+ && numberOfFrames > 0) {
+ AnimatedGifEncoder encoder = new AnimatedGifEncoder();
+ encoder.start(output);
+ encoder.setRepeat(getRepeat());
+ int[] delays = getFrameDelays();
+ while (currFrameIndex < numberOfFrames) {
+ frame = getImageType().createImage(frameSize.width,
+ frameSize.height);
+ Graphics2D graphics = frame.createGraphics();
+ paint(graphics, currFrameIndex++);
+ graphics.dispose();
+ encoder.addFrame(frame);
+ if (delays != null && delays.length > currFrameIndex) {
+ encoder.setDelay(delays[currFrameIndex]);
+ }
+ }
+ encoder.finish();
+ }
+ output.flush();
+ output.close();
+ return new ByteArrayInputStream(baos.toByteArray());
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ protected abstract void paint(Graphics2D graphics2D, int frameIndex);
+
+}
Modified:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/Java2Dresource.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/Java2Dresource.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/Java2Dresource.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -55,7 +55,9 @@
super();
this.imageType = imageType;
}
-
+ public ImageType getImageType() {
+ return this.imageType;
+ }
/**
* Primary calculation of image dimensions - used when HTML code is
* generated to render IMG's width and height Subclasses should override
Copied: branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif
(from rev 19674, trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif)
Deleted:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java
===================================================================
---
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java 2010-10-26
17:10:27 UTC (rev 19674)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,486 +0,0 @@
-package org.ajax4jsf.resource.image.animatedgif;
-
-import java.io.*;
-import java.awt.*;
-import java.awt.image.*;
-
-/**
- * Class AnimatedGifEncoder - Encodes a GIF file consisting of one or
- * more frames.
- * <pre>
- * Example:
- * AnimatedGifEncoder e = new AnimatedGifEncoder();
- * e.start(outputFileName);
- * e.setDelay(1000); // 1 frame per sec
- * e.addFrame(image1);
- * e.addFrame(image2);
- * e.finish();
- * </pre>
- * No copyright asserted on the source code of this class. May be used
- * for any purpose, however, refer to the Unisys LZW patent for restrictions
- * on use of the associated LZWEncoder class. Please forward any corrections
- * to kweiner(a)fmsware.com.
- *
- * @author Kevin Weiner, FM Software
- * @version 1.03 November 2003
- *
- */
-
-public class AnimatedGifEncoder {
-
- protected int width; // image size
- protected int height;
- protected Color transparent = null; // transparent color if given
- protected int transIndex; // transparent index in color table
- protected int repeat = -1; // no repeat
- protected int delay = 0; // frame delay (hundredths)
- protected boolean started = false; // ready to output frames
- protected OutputStream out;
- protected BufferedImage image; // current frame
- protected byte[] pixels; // BGR byte array from frame
- protected byte[] indexedPixels; // converted frame indexed to palette
- protected int colorDepth; // number of bit planes
- protected byte[] colorTab; // RGB palette
- protected boolean[] usedEntry = new boolean[256]; // active palette entries
- protected int palSize = 7; // color table size (bits-1)
- protected int dispose = -1; // disposal code (-1 = use default)
- protected boolean closeStream = false; // close stream when finished
- protected boolean firstFrame = true;
- protected boolean sizeSet = false; // if false, get size from first frame
- protected int sample = 10; // default sample interval for quantizer
-
- /**
- * Sets the delay time between each frame, or changes it
- * for subsequent frames (applies to last frame added).
- *
- * @param ms int delay time in milliseconds
- */
- public void setDelay(int ms) {
- delay = Math.round(ms / 10.0f);
- }
-
- /**
- * Sets the GIF frame disposal code for the last added frame
- * and any subsequent frames. Default is 0 if no transparent
- * color has been set, otherwise 2.
- * @param code int disposal code.
- */
- public void setDispose(int code) {
- if (code >= 0) {
- dispose = code;
- }
- }
-
- /**
- * Sets the number of times the set of GIF frames
- * should be played. Default is 1; 0 means play
- * indefinitely. Must be invoked before the first
- * image is added.
- *
- * @param iter int number of iterations.
- * @return
- */
- public void setRepeat(int iter) {
- if (iter >= 0) {
- repeat = iter;
- }
- }
-
- /**
- * Sets the transparent color for the last added frame
- * and any subsequent frames.
- * Since all colors are subject to modification
- * in the quantization process, the color in the final
- * palette for each frame closest to the given color
- * becomes the transparent color for that frame.
- * May be set to null to indicate no transparent color.
- *
- * @param c Color to be treated as transparent on display.
- */
- public void setTransparent(Color c) {
- transparent = c;
- }
-
- /**
- * Adds next GIF frame. The frame is not written immediately, but is
- * actually deferred until the next frame is received so that timing
- * data can be inserted. Invoking <code>finish()</code> flushes all
- * frames. If <code>setSize</code> was not invoked, the size of the
- * first image is used for all subsequent frames.
- *
- * @param im BufferedImage containing frame to write.
- * @return true if successful.
- */
- public boolean addFrame(BufferedImage im) {
- if ((im == null) || !started) {
- return false;
- }
- boolean ok = true;
- try {
- if (!sizeSet) {
- // use first frame's size
- setSize(im.getWidth(), im.getHeight());
- }
- image = im;
- getImagePixels(); // convert to correct format if necessary
- analyzePixels(); // build color table & map pixels
- if (firstFrame) {
- writeLSD(); // logical screen descriptior
- writePalette(); // global color table
- if (repeat >= 0) {
- // use NS app extension to indicate reps
- writeNetscapeExt();
- }
- }
- writeGraphicCtrlExt(); // write graphic control extension
- writeImageDesc(); // image descriptor
- if (!firstFrame) {
- writePalette(); // local color table
- }
- writePixels(); // encode and write pixel data
- firstFrame = false;
- } catch (IOException e) {
- ok = false;
- }
-
- return ok;
- }
-
- /**
- * Flushes any pending data and closes output file.
- * If writing to an OutputStream, the stream is not
- * closed.
- */
- public boolean finish() {
- if (!started) {
- return false;
- }
- boolean ok = true;
- started = false;
- try {
- out.write(0x3b); // gif trailer
- out.flush();
- if (closeStream) {
- out.close();
- }
- } catch (IOException e) {
- ok = false;
- }
-
- // reset for subsequent use
- transIndex = 0;
- out = null;
- image = null;
- pixels = null;
- indexedPixels = null;
- colorTab = null;
- closeStream = false;
- firstFrame = true;
-
- return ok;
- }
-
- /**
- * Sets frame rate in frames per second. Equivalent to
- * <code>setDelay(1000/fps)</code>.
- *
- * @param fps float frame rate (frames per second)
- */
- public void setFrameRate(float fps) {
- if (fps != 0f) {
- delay = Math.round(100f / fps);
- }
- }
-
- /**
- * Sets quality of color quantization (conversion of images
- * to the maximum 256 colors allowed by the GIF specification).
- * Lower values (minimum = 1) produce better colors, but slow
- * processing significantly. 10 is the default, and produces
- * good color mapping at reasonable speeds. Values greater
- * than 20 do not yield significant improvements in speed.
- *
- * @param quality int greater than 0.
- * @return
- */
- public void setQuality(int quality) {
- if (quality < 1) {
- quality = 1;
- }
- sample = quality;
- }
-
- /**
- * Sets the GIF frame size. The default size is the
- * size of the first frame added if this method is
- * not invoked.
- *
- * @param w int frame width.
- * @param h int frame width.
- */
- public void setSize(int w, int h) {
- if (started && !firstFrame) {
- return;
- }
- width = w;
- height = h;
- if (width < 1) {
- width = 320;
- }
- if (height < 1) {
- height = 240;
- }
- sizeSet = true;
- }
-
- /**
- * Initiates GIF file creation on the given stream. The stream
- * is not closed automatically.
- *
- * @param os OutputStream on which GIF images are written.
- * @return false if initial write failed.
- */
- public boolean start(OutputStream os) {
- if (os == null) {
- return false;
- }
- boolean ok = true;
- closeStream = false;
- out = os;
- try {
- writeString("GIF89a"); // header
- } catch (IOException e) {
- ok = false;
- }
- started = ok;
- return started;
- }
-
- /**
- * Initiates writing of a GIF file with the specified name.
- *
- * @param file String containing output file name.
- * @return false if open or initial write failed.
- */
- public boolean start(String file) {
- boolean ok = true;
- try {
- out = new BufferedOutputStream(new FileOutputStream(file));
- ok = start(out);
- closeStream = true;
- } catch (IOException e) {
- ok = false;
- }
- started = ok;
- return started;
- }
-
- /**
- * Analyzes image colors and creates color map.
- */
- protected void analyzePixels() {
- int len = pixels.length;
- int nPix = len / 3;
- indexedPixels = new byte[nPix];
- NeuQuant nq = new NeuQuant(pixels, len, sample);
- // initialize quantizer
- colorTab = nq.process(); // create reduced palette
- // convert map from BGR to RGB
- for (int i = 0; i < colorTab.length; i += 3) {
- byte temp = colorTab[i];
- colorTab[i] = colorTab[i + 2];
- colorTab[i + 2] = temp;
- usedEntry[i / 3] = false;
- }
- // map image pixels to new palette
- int k = 0;
- for (int i = 0; i < nPix; i++) {
- int index =
- nq.map(pixels[k++] & 0xff,
- pixels[k++] & 0xff,
- pixels[k++] & 0xff);
- usedEntry[index] = true;
- indexedPixels[i] = (byte) index;
- }
- pixels = null;
- colorDepth = 8;
- palSize = 7;
- // get closest match to transparent color if specified
- if (transparent != null) {
- transIndex = findClosest(transparent);
- }
- }
-
- /**
- * Returns index of palette color closest to c
- *
- */
- protected int findClosest(Color c) {
- if (colorTab == null) {
- return -1;
- }
- int r = c.getRed();
- int g = c.getGreen();
- int b = c.getBlue();
- int minpos = 0;
- int dmin = 256 * 256 * 256;
- int len = colorTab.length;
- for (int i = 0; i < len; i += 3) {
- int dr = r - (colorTab[i] & 0xff);
- int dg = g - (colorTab[i + 1] & 0xff);
- int db = b - (colorTab[i + 2] & 0xff);
- int d = dr * dr + dg * dg + db * db;
- int index = i + 2 / 3;
- if (usedEntry[index] && (d < dmin)) {
- dmin = d;
- minpos = index;
- }
-
- }
- return minpos;
- }
-
- /**
- * Extracts image pixels into byte array "pixels"
- */
- protected void getImagePixels() {
- int w = image.getWidth();
- int h = image.getHeight();
- int type = image.getType();
- if ((w != width)
- || (h != height)
- || (type != BufferedImage.TYPE_3BYTE_BGR)) {
- // create new image with right size/format
- BufferedImage temp =
- new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
- Graphics2D g = temp.createGraphics();
- g.drawImage(image, 0, 0, null);
- image = temp;
- }
- pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
- }
-
- /**
- * Writes Graphic Control Extension
- */
- protected void writeGraphicCtrlExt() throws IOException {
- out.write(0x21); // extension introducer
- out.write(0xf9); // GCE label
- out.write(4); // data block size
- int transp;
- int disp;
- if (transparent == null) {
- transp = 0;
- disp = 0; // dispose = no action
- } else {
- transp = 1;
- disp = 2; // force clear if using transparent color
- }
- if (dispose >= 0) {
- disp = dispose & 7; // user override
- }
- disp <<= 2;
-
- // packed fields
- out.write(0 | // 1:3 reserved
- disp | // 4:6 disposal
- 0 | // 7 user input - 0 = none
- transp); // 8 transparency flag
-
- writeShort(delay); // delay x 1/100 sec
- out.write(transIndex); // transparent color index
- out.write(0); // block terminator
- }
-
- /**
- * Writes Image Descriptor
- */
- protected void writeImageDesc() throws IOException {
- out.write(0x2c); // image separator
- writeShort(0); // image position x,y = 0,0
- writeShort(0);
- writeShort(width); // image size
- writeShort(height);
- // packed fields
- if (firstFrame) {
- // no LCT - GCT is used for first (or only) frame
- out.write(0);
- } else {
- // specify normal LCT
- out.write(0x80 | // 1 local color table 1=yes
- 0 | // 2 interlace - 0=no
- 0 | // 3 sorted - 0=no
- 0 | // 4-5 reserved
- palSize); // 6-8 size of color table
- }
- }
-
- /**
- * Writes Logical Screen Descriptor
- */
- protected void writeLSD() throws IOException {
- // logical screen size
- writeShort(width);
- writeShort(height);
- // packed fields
- out.write((0x80 | // 1 : global color table flag = 1 (gct used)
- 0x70 | // 2-4 : color resolution = 7
- 0x00 | // 5 : gct sort flag = 0
- palSize)); // 6-8 : gct size
-
- out.write(0); // background color index
- out.write(0); // pixel aspect ratio - assume 1:1
- }
-
- /**
- * Writes Netscape application extension to define
- * repeat count.
- */
- protected void writeNetscapeExt() throws IOException {
- out.write(0x21); // extension introducer
- out.write(0xff); // app extension label
- out.write(11); // block size
- writeString("NETSCAPE" + "2.0"); // app id + auth code
- out.write(3); // sub-block size
- out.write(1); // loop sub-block id
- writeShort(repeat); // loop count (extra iterations, 0=repeat forever)
- out.write(0); // block terminator
- }
-
- /**
- * Writes color table
- */
- protected void writePalette() throws IOException {
- out.write(colorTab, 0, colorTab.length);
- int n = (3 * 256) - colorTab.length;
- for (int i = 0; i < n; i++) {
- out.write(0);
- }
- }
-
- /**
- * Encodes and writes pixel data
- */
- protected void writePixels() throws IOException {
- LZWEncoder encoder =
- new LZWEncoder(width, height, indexedPixels, colorDepth);
- encoder.encode(out);
- }
-
- /**
- * Write 16-bit value to output stream, LSB first
- */
- protected void writeShort(int value) throws IOException {
- out.write(value & 0xff);
- out.write((value >> 8) & 0xff);
- }
-
- /**
- * Writes string to output stream
- */
- protected void writeString(String s) throws IOException {
- for (int i = 0; i < s.length(); i++) {
- out.write((byte) s.charAt(i));
- }
- }
-}
Copied:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java
(from rev 19674,
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/AnimatedGifEncoder.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,486 @@
+package org.ajax4jsf.resource.image.animatedgif;
+
+import java.io.*;
+import java.awt.*;
+import java.awt.image.*;
+
+/**
+ * Class AnimatedGifEncoder - Encodes a GIF file consisting of one or
+ * more frames.
+ * <pre>
+ * Example:
+ * AnimatedGifEncoder e = new AnimatedGifEncoder();
+ * e.start(outputFileName);
+ * e.setDelay(1000); // 1 frame per sec
+ * e.addFrame(image1);
+ * e.addFrame(image2);
+ * e.finish();
+ * </pre>
+ * No copyright asserted on the source code of this class. May be used
+ * for any purpose, however, refer to the Unisys LZW patent for restrictions
+ * on use of the associated LZWEncoder class. Please forward any corrections
+ * to kweiner(a)fmsware.com.
+ *
+ * @author Kevin Weiner, FM Software
+ * @version 1.03 November 2003
+ *
+ */
+
+public class AnimatedGifEncoder {
+
+ protected int width; // image size
+ protected int height;
+ protected Color transparent = null; // transparent color if given
+ protected int transIndex; // transparent index in color table
+ protected int repeat = -1; // no repeat
+ protected int delay = 0; // frame delay (hundredths)
+ protected boolean started = false; // ready to output frames
+ protected OutputStream out;
+ protected BufferedImage image; // current frame
+ protected byte[] pixels; // BGR byte array from frame
+ protected byte[] indexedPixels; // converted frame indexed to palette
+ protected int colorDepth; // number of bit planes
+ protected byte[] colorTab; // RGB palette
+ protected boolean[] usedEntry = new boolean[256]; // active palette entries
+ protected int palSize = 7; // color table size (bits-1)
+ protected int dispose = -1; // disposal code (-1 = use default)
+ protected boolean closeStream = false; // close stream when finished
+ protected boolean firstFrame = true;
+ protected boolean sizeSet = false; // if false, get size from first frame
+ protected int sample = 10; // default sample interval for quantizer
+
+ /**
+ * Sets the delay time between each frame, or changes it
+ * for subsequent frames (applies to last frame added).
+ *
+ * @param ms int delay time in milliseconds
+ */
+ public void setDelay(int ms) {
+ delay = Math.round(ms / 10.0f);
+ }
+
+ /**
+ * Sets the GIF frame disposal code for the last added frame
+ * and any subsequent frames. Default is 0 if no transparent
+ * color has been set, otherwise 2.
+ * @param code int disposal code.
+ */
+ public void setDispose(int code) {
+ if (code >= 0) {
+ dispose = code;
+ }
+ }
+
+ /**
+ * Sets the number of times the set of GIF frames
+ * should be played. Default is 1; 0 means play
+ * indefinitely. Must be invoked before the first
+ * image is added.
+ *
+ * @param iter int number of iterations.
+ * @return
+ */
+ public void setRepeat(int iter) {
+ if (iter >= 0) {
+ repeat = iter;
+ }
+ }
+
+ /**
+ * Sets the transparent color for the last added frame
+ * and any subsequent frames.
+ * Since all colors are subject to modification
+ * in the quantization process, the color in the final
+ * palette for each frame closest to the given color
+ * becomes the transparent color for that frame.
+ * May be set to null to indicate no transparent color.
+ *
+ * @param c Color to be treated as transparent on display.
+ */
+ public void setTransparent(Color c) {
+ transparent = c;
+ }
+
+ /**
+ * Adds next GIF frame. The frame is not written immediately, but is
+ * actually deferred until the next frame is received so that timing
+ * data can be inserted. Invoking <code>finish()</code> flushes all
+ * frames. If <code>setSize</code> was not invoked, the size of the
+ * first image is used for all subsequent frames.
+ *
+ * @param im BufferedImage containing frame to write.
+ * @return true if successful.
+ */
+ public boolean addFrame(BufferedImage im) {
+ if ((im == null) || !started) {
+ return false;
+ }
+ boolean ok = true;
+ try {
+ if (!sizeSet) {
+ // use first frame's size
+ setSize(im.getWidth(), im.getHeight());
+ }
+ image = im;
+ getImagePixels(); // convert to correct format if necessary
+ analyzePixels(); // build color table & map pixels
+ if (firstFrame) {
+ writeLSD(); // logical screen descriptior
+ writePalette(); // global color table
+ if (repeat >= 0) {
+ // use NS app extension to indicate reps
+ writeNetscapeExt();
+ }
+ }
+ writeGraphicCtrlExt(); // write graphic control extension
+ writeImageDesc(); // image descriptor
+ if (!firstFrame) {
+ writePalette(); // local color table
+ }
+ writePixels(); // encode and write pixel data
+ firstFrame = false;
+ } catch (IOException e) {
+ ok = false;
+ }
+
+ return ok;
+ }
+
+ /**
+ * Flushes any pending data and closes output file.
+ * If writing to an OutputStream, the stream is not
+ * closed.
+ */
+ public boolean finish() {
+ if (!started) {
+ return false;
+ }
+ boolean ok = true;
+ started = false;
+ try {
+ out.write(0x3b); // gif trailer
+ out.flush();
+ if (closeStream) {
+ out.close();
+ }
+ } catch (IOException e) {
+ ok = false;
+ }
+
+ // reset for subsequent use
+ transIndex = 0;
+ out = null;
+ image = null;
+ pixels = null;
+ indexedPixels = null;
+ colorTab = null;
+ closeStream = false;
+ firstFrame = true;
+
+ return ok;
+ }
+
+ /**
+ * Sets frame rate in frames per second. Equivalent to
+ * <code>setDelay(1000/fps)</code>.
+ *
+ * @param fps float frame rate (frames per second)
+ */
+ public void setFrameRate(float fps) {
+ if (fps != 0f) {
+ delay = Math.round(100f / fps);
+ }
+ }
+
+ /**
+ * Sets quality of color quantization (conversion of images
+ * to the maximum 256 colors allowed by the GIF specification).
+ * Lower values (minimum = 1) produce better colors, but slow
+ * processing significantly. 10 is the default, and produces
+ * good color mapping at reasonable speeds. Values greater
+ * than 20 do not yield significant improvements in speed.
+ *
+ * @param quality int greater than 0.
+ * @return
+ */
+ public void setQuality(int quality) {
+ if (quality < 1) {
+ quality = 1;
+ }
+ sample = quality;
+ }
+
+ /**
+ * Sets the GIF frame size. The default size is the
+ * size of the first frame added if this method is
+ * not invoked.
+ *
+ * @param w int frame width.
+ * @param h int frame width.
+ */
+ public void setSize(int w, int h) {
+ if (started && !firstFrame) {
+ return;
+ }
+ width = w;
+ height = h;
+ if (width < 1) {
+ width = 320;
+ }
+ if (height < 1) {
+ height = 240;
+ }
+ sizeSet = true;
+ }
+
+ /**
+ * Initiates GIF file creation on the given stream. The stream
+ * is not closed automatically.
+ *
+ * @param os OutputStream on which GIF images are written.
+ * @return false if initial write failed.
+ */
+ public boolean start(OutputStream os) {
+ if (os == null) {
+ return false;
+ }
+ boolean ok = true;
+ closeStream = false;
+ out = os;
+ try {
+ writeString("GIF89a"); // header
+ } catch (IOException e) {
+ ok = false;
+ }
+ started = ok;
+ return started;
+ }
+
+ /**
+ * Initiates writing of a GIF file with the specified name.
+ *
+ * @param file String containing output file name.
+ * @return false if open or initial write failed.
+ */
+ public boolean start(String file) {
+ boolean ok = true;
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(file));
+ ok = start(out);
+ closeStream = true;
+ } catch (IOException e) {
+ ok = false;
+ }
+ started = ok;
+ return started;
+ }
+
+ /**
+ * Analyzes image colors and creates color map.
+ */
+ protected void analyzePixels() {
+ int len = pixels.length;
+ int nPix = len / 3;
+ indexedPixels = new byte[nPix];
+ NeuQuant nq = new NeuQuant(pixels, len, sample);
+ // initialize quantizer
+ colorTab = nq.process(); // create reduced palette
+ // convert map from BGR to RGB
+ for (int i = 0; i < colorTab.length; i += 3) {
+ byte temp = colorTab[i];
+ colorTab[i] = colorTab[i + 2];
+ colorTab[i + 2] = temp;
+ usedEntry[i / 3] = false;
+ }
+ // map image pixels to new palette
+ int k = 0;
+ for (int i = 0; i < nPix; i++) {
+ int index =
+ nq.map(pixels[k++] & 0xff,
+ pixels[k++] & 0xff,
+ pixels[k++] & 0xff);
+ usedEntry[index] = true;
+ indexedPixels[i] = (byte) index;
+ }
+ pixels = null;
+ colorDepth = 8;
+ palSize = 7;
+ // get closest match to transparent color if specified
+ if (transparent != null) {
+ transIndex = findClosest(transparent);
+ }
+ }
+
+ /**
+ * Returns index of palette color closest to c
+ *
+ */
+ protected int findClosest(Color c) {
+ if (colorTab == null) {
+ return -1;
+ }
+ int r = c.getRed();
+ int g = c.getGreen();
+ int b = c.getBlue();
+ int minpos = 0;
+ int dmin = 256 * 256 * 256;
+ int len = colorTab.length;
+ for (int i = 0; i < len; i += 3) {
+ int dr = r - (colorTab[i] & 0xff);
+ int dg = g - (colorTab[i + 1] & 0xff);
+ int db = b - (colorTab[i + 2] & 0xff);
+ int d = dr * dr + dg * dg + db * db;
+ int index = i + 2 / 3;
+ if (usedEntry[index] && (d < dmin)) {
+ dmin = d;
+ minpos = index;
+ }
+
+ }
+ return minpos;
+ }
+
+ /**
+ * Extracts image pixels into byte array "pixels"
+ */
+ protected void getImagePixels() {
+ int w = image.getWidth();
+ int h = image.getHeight();
+ int type = image.getType();
+ if ((w != width)
+ || (h != height)
+ || (type != BufferedImage.TYPE_3BYTE_BGR)) {
+ // create new image with right size/format
+ BufferedImage temp =
+ new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
+ Graphics2D g = temp.createGraphics();
+ g.drawImage(image, 0, 0, null);
+ image = temp;
+ }
+ pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
+ }
+
+ /**
+ * Writes Graphic Control Extension
+ */
+ protected void writeGraphicCtrlExt() throws IOException {
+ out.write(0x21); // extension introducer
+ out.write(0xf9); // GCE label
+ out.write(4); // data block size
+ int transp;
+ int disp;
+ if (transparent == null) {
+ transp = 0;
+ disp = 0; // dispose = no action
+ } else {
+ transp = 1;
+ disp = 2; // force clear if using transparent color
+ }
+ if (dispose >= 0) {
+ disp = dispose & 7; // user override
+ }
+ disp <<= 2;
+
+ // packed fields
+ out.write(0 | // 1:3 reserved
+ disp | // 4:6 disposal
+ 0 | // 7 user input - 0 = none
+ transp); // 8 transparency flag
+
+ writeShort(delay); // delay x 1/100 sec
+ out.write(transIndex); // transparent color index
+ out.write(0); // block terminator
+ }
+
+ /**
+ * Writes Image Descriptor
+ */
+ protected void writeImageDesc() throws IOException {
+ out.write(0x2c); // image separator
+ writeShort(0); // image position x,y = 0,0
+ writeShort(0);
+ writeShort(width); // image size
+ writeShort(height);
+ // packed fields
+ if (firstFrame) {
+ // no LCT - GCT is used for first (or only) frame
+ out.write(0);
+ } else {
+ // specify normal LCT
+ out.write(0x80 | // 1 local color table 1=yes
+ 0 | // 2 interlace - 0=no
+ 0 | // 3 sorted - 0=no
+ 0 | // 4-5 reserved
+ palSize); // 6-8 size of color table
+ }
+ }
+
+ /**
+ * Writes Logical Screen Descriptor
+ */
+ protected void writeLSD() throws IOException {
+ // logical screen size
+ writeShort(width);
+ writeShort(height);
+ // packed fields
+ out.write((0x80 | // 1 : global color table flag = 1 (gct used)
+ 0x70 | // 2-4 : color resolution = 7
+ 0x00 | // 5 : gct sort flag = 0
+ palSize)); // 6-8 : gct size
+
+ out.write(0); // background color index
+ out.write(0); // pixel aspect ratio - assume 1:1
+ }
+
+ /**
+ * Writes Netscape application extension to define
+ * repeat count.
+ */
+ protected void writeNetscapeExt() throws IOException {
+ out.write(0x21); // extension introducer
+ out.write(0xff); // app extension label
+ out.write(11); // block size
+ writeString("NETSCAPE" + "2.0"); // app id + auth code
+ out.write(3); // sub-block size
+ out.write(1); // loop sub-block id
+ writeShort(repeat); // loop count (extra iterations, 0=repeat forever)
+ out.write(0); // block terminator
+ }
+
+ /**
+ * Writes color table
+ */
+ protected void writePalette() throws IOException {
+ out.write(colorTab, 0, colorTab.length);
+ int n = (3 * 256) - colorTab.length;
+ for (int i = 0; i < n; i++) {
+ out.write(0);
+ }
+ }
+
+ /**
+ * Encodes and writes pixel data
+ */
+ protected void writePixels() throws IOException {
+ LZWEncoder encoder =
+ new LZWEncoder(width, height, indexedPixels, colorDepth);
+ encoder.encode(out);
+ }
+
+ /**
+ * Write 16-bit value to output stream, LSB first
+ */
+ protected void writeShort(int value) throws IOException {
+ out.write(value & 0xff);
+ out.write((value >> 8) & 0xff);
+ }
+
+ /**
+ * Writes string to output stream
+ */
+ protected void writeString(String s) throws IOException {
+ for (int i = 0; i < s.length(); i++) {
+ out.write((byte) s.charAt(i));
+ }
+ }
+}
Deleted:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java
===================================================================
---
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java 2010-10-26
17:10:27 UTC (rev 19674)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,817 +0,0 @@
-package org.ajax4jsf.resource.image.animatedgif;
-
-import java.net.*;
-import java.io.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.image.*;
-
-/**
- * Class GifDecoder - Decodes a GIF file into one or more frames.
- * <br><pre>
- * Example:
- * GifDecoder d = new GifDecoder();
- * d.read("sample.gif");
- * int n = d.getFrameCount();
- * for (int i = 0; i < n; i++) {
- * BufferedImage frame = d.getFrame(i); // frame i
- * int t = d.getDelay(i); // display duration of frame in milliseconds
- * // do something with frame
- * }
- * </pre>
- * No copyright asserted on the source code of this class. May be used for
- * any purpose, however, refer to the Unisys LZW patent for any additional
- * restrictions. Please forward any corrections to kweiner(a)fmsware.com.
- *
- * @author Kevin Weiner, FM Software; LZW decoder adapted from John Cristy's
ImageMagick.
- * @version 1.03 November 2003
- *
- */
-
-public class GifDecoder {
-
- /**
- * File read status: No errors.
- */
- public static final int STATUS_OK = 0;
-
- /**
- * File read status: Error decoding file (may be partially decoded)
- */
- public static final int STATUS_FORMAT_ERROR = 1;
-
- /**
- * File read status: Unable to open source.
- */
- public static final int STATUS_OPEN_ERROR = 2;
- protected static final int MAXSTACKSIZE = 4096;
- protected BufferedInputStream in;
- protected int status;
-
- protected int width; // full image width
- protected int height; // full image height
- protected boolean gctFlag; // global color table used
- protected int gctSize; // size of global color table
- protected int loopCount = 1; // iterations; 0 = repeat forever
-
- protected int[] gct; // global color table
- protected int[] lct; // local color table
- protected int[] act; // active color table
-
- protected int bgIndex; // background color index
- protected int bgColor; // background color
- protected int lastBgColor; // previous bg color
- protected int pixelAspect; // pixel aspect ratio
-
- protected boolean lctFlag; // local color table flag
- protected boolean interlace; // interlace flag
- protected int lctSize; // local color table size
-
- protected int ix;
- protected int iy;
- protected int iw;
- protected int ih; // current image rectangle
- protected Rectangle lastRect; // last image rect
- protected BufferedImage image; // current frame
- protected BufferedImage lastImage; // previous frame
-
- protected byte[] block = new byte[256]; // current data block
- protected int blockSize = 0; // block size
-
- // last graphic control extension info
- protected int dispose = 0;
- // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
- protected int lastDispose = 0;
- protected boolean transparency = false; // use transparent color
- protected int delay = 0; // delay in milliseconds
- protected int transIndex; // transparent color index
-
-
- // max decoder pixel stack size
-
- // LZW decoder working arrays
- protected short[] prefix;
- protected byte[] suffix;
- protected byte[] pixelStack;
- protected byte[] pixels;
-
- protected ArrayList frames; // frames read from current file
- protected int frameCount;
-
- static class GifFrame {
- private BufferedImage image;
- private int delay;
- public GifFrame(BufferedImage im, int del) {
- image = im;
- delay = del;
- }
-
- public BufferedImage getImage() {
- return image;
- }
-
- public int getDelay() {
- return delay;
- }
- }
-
- /**
- * Gets display duration for specified frame.
- *
- * @param n int index of frame
- * @return delay in milliseconds
- */
- public int getDelay(int n) {
- //
- delay = -1;
- if ((n >= 0) && (n < frameCount)) {
- delay = ((GifFrame) frames.get(n)).delay;
- }
- return delay;
- }
-
- /**
- * Gets the number of frames read from file.
- * @return frame count
- */
- public int getFrameCount() {
- return frameCount;
- }
-
- /**
- * Gets the first (or only) image read.
- *
- * @return BufferedImage containing first frame, or null if none.
- */
- public BufferedImage getImage() {
- return getFrame(0);
- }
-
- /**
- * Gets the "Netscape" iteration count, if any.
- * A count of 0 means repeat indefinitiely.
- *
- * @return iteration count if one was specified, else 1.
- */
- public int getLoopCount() {
- return loopCount;
- }
-
- /**
- * Creates new frame image from current data (and previous
- * frames as specified by their disposition codes).
- */
- protected void setPixels() {
- // expose destination image's pixels as int array
- int[] dest =
- ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
-
- // fill in starting image contents based on last image's dispose code
- if (lastDispose > 0) {
- if (lastDispose == 3) {
- // use image before last
- int n = frameCount - 2;
- if (n > 0) {
- lastImage = getFrame(n - 1);
- } else {
- lastImage = null;
- }
- }
-
- if (lastImage != null) {
- int[] prev =
- ((DataBufferInt) lastImage.getRaster().getDataBuffer()).getData();
- System.arraycopy(prev, 0, dest, 0, width * height);
- // copy pixels
-
- if (lastDispose == 2) {
- // fill last image rect area with background color
- Graphics2D g = image.createGraphics();
- Color c = null;
- if (transparency) {
- c = new Color(0, 0, 0, 0); // assume background is transparent
- } else {
- c = new Color(lastBgColor); // use given background color
- }
- g.setColor(c);
- g.setComposite(AlphaComposite.Src); // replace area
- g.fill(lastRect);
- g.dispose();
- }
- }
- }
-
- // copy each source line to the appropriate place in the destination
- int pass = 1;
- int inc = 8;
- int iline = 0;
- for (int i = 0; i < ih; i++) {
- int line = i;
- if (interlace) {
- if (iline >= ih) {
- pass++;
- switch (pass) {
- case 2 :
- iline = 4;
- break;
- case 3 :
- iline = 2;
- inc = 4;
- break;
- case 4 :
- iline = 1;
- inc = 2;
- break;
- default:
- break;
- }
- }
- line = iline;
- iline += inc;
- }
- line += iy;
- if (line < height) {
- int k = line * width;
- int dx = k + ix; // start of line in dest
- int dlim = dx + iw; // end of dest line
- if ((k + width) < dlim) {
- dlim = k + width; // past dest edge
- }
- int sx = i * iw; // start of line in source
- while (dx < dlim) {
- // map color and insert in destination
- int index = ((int) pixels[sx++]) & 0xff;
- int c = act[index];
- if (c != 0) {
- dest[dx] = c;
- }
- dx++;
- }
- }
- }
- }
-
- /**
- * Gets the image contents of frame n.
- *
- * @return BufferedImage representation of frame, or null if n is invalid.
- */
- public BufferedImage getFrame(int n) {
- BufferedImage im = null;
- if ((n >= 0) && (n < frameCount)) {
- im = ((GifFrame) frames.get(n)).image;
- }
- return im;
- }
-
- /**
- * Gets image size.
- *
- * @return GIF image dimensions
- */
- public Dimension getFrameSize() {
- return new Dimension(width, height);
- }
-
- /**
- * Reads GIF image from stream
- *
- * @param BufferedInputStream containing GIF file.
- * @return read status code (0 = no errors)
- */
- public int read(BufferedInputStream is) {
- init();
- if (is != null) {
- in = is;
- readHeader();
- if (!err()) {
- readContents();
- if (frameCount < 0) {
- status = STATUS_FORMAT_ERROR;
- }
- }
- } else {
- status = STATUS_OPEN_ERROR;
- }
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return status;
- }
-
- /**
- * Reads GIF image from stream
- *
- * @param InputStream containing GIF file.
- * @return read status code (0 = no errors)
- */
- public int read(InputStream is) {
- init();
- if (is != null) {
- if (!(is instanceof BufferedInputStream)) {
- is = new BufferedInputStream(is);
- }
- in = (BufferedInputStream) is;
- readHeader();
- if (!err()) {
- readContents();
- if (frameCount < 0) {
- status = STATUS_FORMAT_ERROR;
- }
- }
- } else {
- status = STATUS_OPEN_ERROR;
- }
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return status;
- }
-
- /**
- * Reads GIF file from specified file/URL source
- * (URL assumed if name contains ":/" or "file:")
- *
- * @param name String containing source
- * @return read status code (0 = no errors)
- */
- public int read(String name) {
- status = STATUS_OK;
- try {
- name = name.trim().toLowerCase();
- if ((name.indexOf("file:") >= 0) ||
- (name.indexOf(":/") > 0)) {
- URL url = new URL(name);
- in = new BufferedInputStream(url.openStream());
- } else {
- in = new BufferedInputStream(new FileInputStream(name));
- }
- status = read(in);
- } catch (IOException e) {
- status = STATUS_OPEN_ERROR;
- }
-
- return status;
- }
-
- /**
- * Decodes LZW image data into pixel array.
- * Adapted from John Cristy's ImageMagick.
- */
- protected void decodeImageData() {
- int nullCode = -1;
- int npix = iw * ih;
- int available;
- int clear;
- int codeMask;
- int codeSize;
- int endOfInformation;
- int inCode;
- int oldCode;
- int bits;
- int code;
- int count;
- int i;
- int datum;
- int dataSize;
- int first;
- int top;
- int bi;
- int pi;
-
- if ((pixels == null) || (pixels.length < npix)) {
- pixels = new byte[npix]; // allocate new pixel array
- }
- if (prefix == null) {
- prefix = new short[MAXSTACKSIZE];
- }
- if (suffix == null) {
- suffix = new byte[MAXSTACKSIZE];
- }
- if (pixelStack == null) {
- pixelStack = new byte[MAXSTACKSIZE + 1];
- }
-
- // Initialize GIF data stream decoder.
-
- dataSize = read();
- clear = 1 << dataSize;
- endOfInformation = clear + 1;
- available = clear + 2;
- oldCode = nullCode;
- codeSize = dataSize + 1;
- codeMask = (1 << codeSize) - 1;
- for (code = 0; code < clear; code++) {
- prefix[code] = 0;
- suffix[code] = (byte) code;
- }
-
- // Decode GIF pixel stream.
- bi = 0;
- datum = 0;
- bits = 0;
- count = 0;
- first = 0;
- top = 0;
- pi = 0;
- bi = 0;
-
- for (i = 0; i < npix;) {
- if (top == 0) {
- if (bits < codeSize) {
- // Load bytes until there are enough bits for a code.
- if (count == 0) {
- // Read a new data block.
- count = readBlock();
- if (count <= 0) {
- break;
- }
- bi = 0;
- }
- datum += (((int) block[bi]) & 0xff) << bits;
- bits += 8;
- bi++;
- count--;
- continue;
- }
-
- // Get the next code.
-
- code = datum & codeMask;
- datum >>= codeSize;
- bits -= codeSize;
-
- // Interpret the code
-
- if ((code > available) || (code == endOfInformation)) {
- break;
- }
- if (code == clear) {
- // Reset decoder.
- codeSize = dataSize + 1;
- codeMask = (1 << codeSize) - 1;
- available = clear + 2;
- oldCode = nullCode;
- continue;
- }
- if (oldCode == nullCode) {
- pixelStack[top++] = suffix[code];
- oldCode = code;
- first = code;
- continue;
- }
- inCode = code;
- if (code == available) {
- pixelStack[top++] = (byte) first;
- code = oldCode;
- }
- while (code > clear) {
- pixelStack[top++] = suffix[code];
- code = prefix[code];
- }
- first = ((int) suffix[code]) & 0xff;
-
- // Add a new string to the string table,
-
- if (available >= MAXSTACKSIZE) {
- break;
- }
- pixelStack[top++] = (byte) first;
- prefix[available] = (short) oldCode;
- suffix[available] = (byte) first;
- available++;
- if (((available & codeMask) == 0)
- && (available < MAXSTACKSIZE)) {
- codeSize++;
- codeMask += available;
- }
- oldCode = inCode;
- }
-
- // Pop a pixel off the pixel stack.
-
- top--;
- pixels[pi++] = pixelStack[top];
- i++;
- }
-
- for (i = pi; i < npix; i++) {
- pixels[i] = 0; // clear missing pixels
- }
-
- }
-
- /**
- * Returns true if an error was encountered during reading/decoding
- */
- protected boolean err() {
- return status != STATUS_OK;
- }
-
- /**
- * Initializes or re-initializes reader
- */
- protected void init() {
- status = STATUS_OK;
- frameCount = 0;
- frames = new ArrayList();
- gct = null;
- lct = null;
- }
-
- /**
- * Reads a single byte from the input stream.
- */
- protected int read() {
- int curByte = 0;
- try {
- curByte = in.read();
- } catch (IOException e) {
- status = STATUS_FORMAT_ERROR;
- }
- return curByte;
- }
-
- /**
- * Reads next variable length block from input.
- *
- * @return number of bytes stored in "buffer"
- */
- protected int readBlock() {
- blockSize = read();
- int n = 0;
- if (blockSize > 0) {
- try {
- int count = 0;
- while (n < blockSize) {
- count = in.read(block, n, blockSize - n);
- if (count == -1) {
- break;
- }
- n += count;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- if (n < blockSize) {
- status = STATUS_FORMAT_ERROR;
- }
- }
- return n;
- }
-
- /**
- * Reads color table as 256 RGB integer values
- *
- * @param ncolors int number of colors to read
- * @return int array containing 256 colors (packed ARGB with full alpha)
- */
- protected int[] readColorTable(int ncolors) {
- int nbytes = 3 * ncolors;
- int[] tab = null;
- byte[] c = new byte[nbytes];
- int n = 0;
- try {
- n = in.read(c);
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (n < nbytes) {
- status = STATUS_FORMAT_ERROR;
- } else {
- tab = new int[256]; // max size to avoid bounds checks
- int i = 0;
- int j = 0;
- while (i < ncolors) {
- int r = ((int) c[j++]) & 0xff;
- int g = ((int) c[j++]) & 0xff;
- int b = ((int) c[j++]) & 0xff;
- tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
- }
- }
- return tab;
- }
-
- /**
- * Main file parser. Reads GIF content blocks.
- */
- protected void readContents() {
- // read GIF file content blocks
- boolean done = false;
- while (!(done || err())) {
- int code = read();
- switch (code) {
-
- case 0x2C : // image separator
- readImage();
- break;
-
- case 0x21 : // extension
- code = read();
- switch (code) {
- case 0xf9 : // graphics control extension
- readGraphicControlExt();
- break;
-
- case 0xff : // application extension
- readBlock();
- String app = "";
- for (int i = 0; i < 11; i++) {
- app += (char) block[i];
- }
- if (app.equals("NETSCAPE2.0")) {
- readNetscapeExt();
- } else {
- skip();
- }// don't care
- break;
-
- default : // uninteresting extension
- skip();
- }
- break;
-
- case 0x3b : // terminator
- done = true;
- break;
-
- case 0x00 : // bad byte, but keep going and see what happens
- break;
-
- default :
- status = STATUS_FORMAT_ERROR;
- }
- }
- }
-
- /**
- * Reads Graphics Control Extension values
- */
- protected void readGraphicControlExt() {
- read(); // block size
- int packed = read(); // packed fields
- dispose = (packed & 0x1c) >> 2; // disposal method
- if (dispose == 0) {
- dispose = 1; // elect to keep old image if discretionary
- }
- transparency = (packed & 1) != 0;
- delay = readShort() * 10; // delay in milliseconds
- transIndex = read(); // transparent color index
- read(); // block terminator
- }
-
- /**
- * Reads GIF file header information.
- */
- protected void readHeader() {
- String id = "";
- for (int i = 0; i < 6; i++) {
- id += (char) read();
- }
- if (!id.startsWith("GIF")) {
- status = STATUS_FORMAT_ERROR;
- return;
- }
-
- readLSD();
- if (gctFlag && !err()) {
- gct = readColorTable(gctSize);
- bgColor = gct[bgIndex];
- }
- }
-
- /**
- * Reads next frame image
- */
- protected void readImage() {
- ix = readShort(); // (sub)image position & size
- iy = readShort();
- iw = readShort();
- ih = readShort();
-
- int packed = read();
- lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
- interlace = (packed & 0x40) != 0; // 2 - interlace flag
- // 3 - sort flag
- // 4-5 - reserved
- lctSize = 2 << (packed & 7); // 6-8 - local color table size
-
- if (lctFlag) {
- lct = readColorTable(lctSize); // read table
- act = lct; // make local table active
- } else {
- act = gct; // make global table active
- if (bgIndex == transIndex) {
- bgColor = 0;
- }
- }
- int save = 0;
- if (transparency) {
- save = act[transIndex];
- act[transIndex] = 0; // set transparent color if specified
- }
-
- if (act == null) {
- status = STATUS_FORMAT_ERROR; // no color table defined
- }
-
- if (err()) {
- return;
- }
-
- decodeImageData(); // decode pixel data
- skip();
-
- if (err()) {
- return;
- }
-
- frameCount++;
-
- // create new image to receive frame data
- image =
- new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
-
- setPixels(); // transfer pixel data to image
-
- frames.add(new GifFrame(image, delay)); // add image to frame list
-
- if (transparency) {
- act[transIndex] = save;
- }
- resetFrame();
-
- }
-
- /**
- * Reads Logical Screen Descriptor
- */
- protected void readLSD() {
-
- // logical screen size
- width = readShort();
- height = readShort();
-
- // packed fields
- int packed = read();
- gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
- // 2-4 : color resolution
- // 5 : gct sort flag
- gctSize = 2 << (packed & 7); // 6-8 : gct size
-
- bgIndex = read(); // background color index
- pixelAspect = read(); // pixel aspect ratio
- }
-
- /**
- * Reads Netscape extenstion to obtain iteration count
- */
- protected void readNetscapeExt() {
- do {
- readBlock();
- if (block[0] == 1) {
- // loop count sub-block
- int b1 = ((int) block[1]) & 0xff;
- int b2 = ((int) block[2]) & 0xff;
- loopCount = (b2 << 8) | b1;
- }
- } while ((blockSize > 0) && !err());
- }
-
- /**
- * Reads next 16-bit value, LSB first
- */
- protected int readShort() {
- // read 16-bit value, LSB first
- return read() | (read() << 8);
- }
-
- /**
- * Resets frame state for reading next image.
- */
- protected void resetFrame() {
- lastDispose = dispose;
- lastRect = new Rectangle(ix, iy, iw, ih);
- lastImage = image;
- lastBgColor = bgColor;
- int dispose = 0;
- boolean transparency = false;
- int delay = 0;
- lct = null;
- }
-
- /**
- * Skips variable length blocks up to and including
- * next zero length block.
- */
- protected void skip() {
- do {
- readBlock();
- } while ((blockSize > 0) && !err());
- }
-}
Copied:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java
(from rev 19674,
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/GifDecoder.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,817 @@
+package org.ajax4jsf.resource.image.animatedgif;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.image.*;
+
+/**
+ * Class GifDecoder - Decodes a GIF file into one or more frames.
+ * <br><pre>
+ * Example:
+ * GifDecoder d = new GifDecoder();
+ * d.read("sample.gif");
+ * int n = d.getFrameCount();
+ * for (int i = 0; i < n; i++) {
+ * BufferedImage frame = d.getFrame(i); // frame i
+ * int t = d.getDelay(i); // display duration of frame in milliseconds
+ * // do something with frame
+ * }
+ * </pre>
+ * No copyright asserted on the source code of this class. May be used for
+ * any purpose, however, refer to the Unisys LZW patent for any additional
+ * restrictions. Please forward any corrections to kweiner(a)fmsware.com.
+ *
+ * @author Kevin Weiner, FM Software; LZW decoder adapted from John Cristy's
ImageMagick.
+ * @version 1.03 November 2003
+ *
+ */
+
+public class GifDecoder {
+
+ /**
+ * File read status: No errors.
+ */
+ public static final int STATUS_OK = 0;
+
+ /**
+ * File read status: Error decoding file (may be partially decoded)
+ */
+ public static final int STATUS_FORMAT_ERROR = 1;
+
+ /**
+ * File read status: Unable to open source.
+ */
+ public static final int STATUS_OPEN_ERROR = 2;
+ protected static final int MAXSTACKSIZE = 4096;
+ protected BufferedInputStream in;
+ protected int status;
+
+ protected int width; // full image width
+ protected int height; // full image height
+ protected boolean gctFlag; // global color table used
+ protected int gctSize; // size of global color table
+ protected int loopCount = 1; // iterations; 0 = repeat forever
+
+ protected int[] gct; // global color table
+ protected int[] lct; // local color table
+ protected int[] act; // active color table
+
+ protected int bgIndex; // background color index
+ protected int bgColor; // background color
+ protected int lastBgColor; // previous bg color
+ protected int pixelAspect; // pixel aspect ratio
+
+ protected boolean lctFlag; // local color table flag
+ protected boolean interlace; // interlace flag
+ protected int lctSize; // local color table size
+
+ protected int ix;
+ protected int iy;
+ protected int iw;
+ protected int ih; // current image rectangle
+ protected Rectangle lastRect; // last image rect
+ protected BufferedImage image; // current frame
+ protected BufferedImage lastImage; // previous frame
+
+ protected byte[] block = new byte[256]; // current data block
+ protected int blockSize = 0; // block size
+
+ // last graphic control extension info
+ protected int dispose = 0;
+ // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
+ protected int lastDispose = 0;
+ protected boolean transparency = false; // use transparent color
+ protected int delay = 0; // delay in milliseconds
+ protected int transIndex; // transparent color index
+
+
+ // max decoder pixel stack size
+
+ // LZW decoder working arrays
+ protected short[] prefix;
+ protected byte[] suffix;
+ protected byte[] pixelStack;
+ protected byte[] pixels;
+
+ protected ArrayList frames; // frames read from current file
+ protected int frameCount;
+
+ static class GifFrame {
+ private BufferedImage image;
+ private int delay;
+ public GifFrame(BufferedImage im, int del) {
+ image = im;
+ delay = del;
+ }
+
+ public BufferedImage getImage() {
+ return image;
+ }
+
+ public int getDelay() {
+ return delay;
+ }
+ }
+
+ /**
+ * Gets display duration for specified frame.
+ *
+ * @param n int index of frame
+ * @return delay in milliseconds
+ */
+ public int getDelay(int n) {
+ //
+ delay = -1;
+ if ((n >= 0) && (n < frameCount)) {
+ delay = ((GifFrame) frames.get(n)).delay;
+ }
+ return delay;
+ }
+
+ /**
+ * Gets the number of frames read from file.
+ * @return frame count
+ */
+ public int getFrameCount() {
+ return frameCount;
+ }
+
+ /**
+ * Gets the first (or only) image read.
+ *
+ * @return BufferedImage containing first frame, or null if none.
+ */
+ public BufferedImage getImage() {
+ return getFrame(0);
+ }
+
+ /**
+ * Gets the "Netscape" iteration count, if any.
+ * A count of 0 means repeat indefinitiely.
+ *
+ * @return iteration count if one was specified, else 1.
+ */
+ public int getLoopCount() {
+ return loopCount;
+ }
+
+ /**
+ * Creates new frame image from current data (and previous
+ * frames as specified by their disposition codes).
+ */
+ protected void setPixels() {
+ // expose destination image's pixels as int array
+ int[] dest =
+ ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
+
+ // fill in starting image contents based on last image's dispose code
+ if (lastDispose > 0) {
+ if (lastDispose == 3) {
+ // use image before last
+ int n = frameCount - 2;
+ if (n > 0) {
+ lastImage = getFrame(n - 1);
+ } else {
+ lastImage = null;
+ }
+ }
+
+ if (lastImage != null) {
+ int[] prev =
+ ((DataBufferInt) lastImage.getRaster().getDataBuffer()).getData();
+ System.arraycopy(prev, 0, dest, 0, width * height);
+ // copy pixels
+
+ if (lastDispose == 2) {
+ // fill last image rect area with background color
+ Graphics2D g = image.createGraphics();
+ Color c = null;
+ if (transparency) {
+ c = new Color(0, 0, 0, 0); // assume background is transparent
+ } else {
+ c = new Color(lastBgColor); // use given background color
+ }
+ g.setColor(c);
+ g.setComposite(AlphaComposite.Src); // replace area
+ g.fill(lastRect);
+ g.dispose();
+ }
+ }
+ }
+
+ // copy each source line to the appropriate place in the destination
+ int pass = 1;
+ int inc = 8;
+ int iline = 0;
+ for (int i = 0; i < ih; i++) {
+ int line = i;
+ if (interlace) {
+ if (iline >= ih) {
+ pass++;
+ switch (pass) {
+ case 2 :
+ iline = 4;
+ break;
+ case 3 :
+ iline = 2;
+ inc = 4;
+ break;
+ case 4 :
+ iline = 1;
+ inc = 2;
+ break;
+ default:
+ break;
+ }
+ }
+ line = iline;
+ iline += inc;
+ }
+ line += iy;
+ if (line < height) {
+ int k = line * width;
+ int dx = k + ix; // start of line in dest
+ int dlim = dx + iw; // end of dest line
+ if ((k + width) < dlim) {
+ dlim = k + width; // past dest edge
+ }
+ int sx = i * iw; // start of line in source
+ while (dx < dlim) {
+ // map color and insert in destination
+ int index = ((int) pixels[sx++]) & 0xff;
+ int c = act[index];
+ if (c != 0) {
+ dest[dx] = c;
+ }
+ dx++;
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the image contents of frame n.
+ *
+ * @return BufferedImage representation of frame, or null if n is invalid.
+ */
+ public BufferedImage getFrame(int n) {
+ BufferedImage im = null;
+ if ((n >= 0) && (n < frameCount)) {
+ im = ((GifFrame) frames.get(n)).image;
+ }
+ return im;
+ }
+
+ /**
+ * Gets image size.
+ *
+ * @return GIF image dimensions
+ */
+ public Dimension getFrameSize() {
+ return new Dimension(width, height);
+ }
+
+ /**
+ * Reads GIF image from stream
+ *
+ * @param BufferedInputStream containing GIF file.
+ * @return read status code (0 = no errors)
+ */
+ public int read(BufferedInputStream is) {
+ init();
+ if (is != null) {
+ in = is;
+ readHeader();
+ if (!err()) {
+ readContents();
+ if (frameCount < 0) {
+ status = STATUS_FORMAT_ERROR;
+ }
+ }
+ } else {
+ status = STATUS_OPEN_ERROR;
+ }
+ try {
+ is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return status;
+ }
+
+ /**
+ * Reads GIF image from stream
+ *
+ * @param InputStream containing GIF file.
+ * @return read status code (0 = no errors)
+ */
+ public int read(InputStream is) {
+ init();
+ if (is != null) {
+ if (!(is instanceof BufferedInputStream)) {
+ is = new BufferedInputStream(is);
+ }
+ in = (BufferedInputStream) is;
+ readHeader();
+ if (!err()) {
+ readContents();
+ if (frameCount < 0) {
+ status = STATUS_FORMAT_ERROR;
+ }
+ }
+ } else {
+ status = STATUS_OPEN_ERROR;
+ }
+ try {
+ is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return status;
+ }
+
+ /**
+ * Reads GIF file from specified file/URL source
+ * (URL assumed if name contains ":/" or "file:")
+ *
+ * @param name String containing source
+ * @return read status code (0 = no errors)
+ */
+ public int read(String name) {
+ status = STATUS_OK;
+ try {
+ name = name.trim().toLowerCase();
+ if ((name.indexOf("file:") >= 0) ||
+ (name.indexOf(":/") > 0)) {
+ URL url = new URL(name);
+ in = new BufferedInputStream(url.openStream());
+ } else {
+ in = new BufferedInputStream(new FileInputStream(name));
+ }
+ status = read(in);
+ } catch (IOException e) {
+ status = STATUS_OPEN_ERROR;
+ }
+
+ return status;
+ }
+
+ /**
+ * Decodes LZW image data into pixel array.
+ * Adapted from John Cristy's ImageMagick.
+ */
+ protected void decodeImageData() {
+ int nullCode = -1;
+ int npix = iw * ih;
+ int available;
+ int clear;
+ int codeMask;
+ int codeSize;
+ int endOfInformation;
+ int inCode;
+ int oldCode;
+ int bits;
+ int code;
+ int count;
+ int i;
+ int datum;
+ int dataSize;
+ int first;
+ int top;
+ int bi;
+ int pi;
+
+ if ((pixels == null) || (pixels.length < npix)) {
+ pixels = new byte[npix]; // allocate new pixel array
+ }
+ if (prefix == null) {
+ prefix = new short[MAXSTACKSIZE];
+ }
+ if (suffix == null) {
+ suffix = new byte[MAXSTACKSIZE];
+ }
+ if (pixelStack == null) {
+ pixelStack = new byte[MAXSTACKSIZE + 1];
+ }
+
+ // Initialize GIF data stream decoder.
+
+ dataSize = read();
+ clear = 1 << dataSize;
+ endOfInformation = clear + 1;
+ available = clear + 2;
+ oldCode = nullCode;
+ codeSize = dataSize + 1;
+ codeMask = (1 << codeSize) - 1;
+ for (code = 0; code < clear; code++) {
+ prefix[code] = 0;
+ suffix[code] = (byte) code;
+ }
+
+ // Decode GIF pixel stream.
+ bi = 0;
+ datum = 0;
+ bits = 0;
+ count = 0;
+ first = 0;
+ top = 0;
+ pi = 0;
+ bi = 0;
+
+ for (i = 0; i < npix;) {
+ if (top == 0) {
+ if (bits < codeSize) {
+ // Load bytes until there are enough bits for a code.
+ if (count == 0) {
+ // Read a new data block.
+ count = readBlock();
+ if (count <= 0) {
+ break;
+ }
+ bi = 0;
+ }
+ datum += (((int) block[bi]) & 0xff) << bits;
+ bits += 8;
+ bi++;
+ count--;
+ continue;
+ }
+
+ // Get the next code.
+
+ code = datum & codeMask;
+ datum >>= codeSize;
+ bits -= codeSize;
+
+ // Interpret the code
+
+ if ((code > available) || (code == endOfInformation)) {
+ break;
+ }
+ if (code == clear) {
+ // Reset decoder.
+ codeSize = dataSize + 1;
+ codeMask = (1 << codeSize) - 1;
+ available = clear + 2;
+ oldCode = nullCode;
+ continue;
+ }
+ if (oldCode == nullCode) {
+ pixelStack[top++] = suffix[code];
+ oldCode = code;
+ first = code;
+ continue;
+ }
+ inCode = code;
+ if (code == available) {
+ pixelStack[top++] = (byte) first;
+ code = oldCode;
+ }
+ while (code > clear) {
+ pixelStack[top++] = suffix[code];
+ code = prefix[code];
+ }
+ first = ((int) suffix[code]) & 0xff;
+
+ // Add a new string to the string table,
+
+ if (available >= MAXSTACKSIZE) {
+ break;
+ }
+ pixelStack[top++] = (byte) first;
+ prefix[available] = (short) oldCode;
+ suffix[available] = (byte) first;
+ available++;
+ if (((available & codeMask) == 0)
+ && (available < MAXSTACKSIZE)) {
+ codeSize++;
+ codeMask += available;
+ }
+ oldCode = inCode;
+ }
+
+ // Pop a pixel off the pixel stack.
+
+ top--;
+ pixels[pi++] = pixelStack[top];
+ i++;
+ }
+
+ for (i = pi; i < npix; i++) {
+ pixels[i] = 0; // clear missing pixels
+ }
+
+ }
+
+ /**
+ * Returns true if an error was encountered during reading/decoding
+ */
+ protected boolean err() {
+ return status != STATUS_OK;
+ }
+
+ /**
+ * Initializes or re-initializes reader
+ */
+ protected void init() {
+ status = STATUS_OK;
+ frameCount = 0;
+ frames = new ArrayList();
+ gct = null;
+ lct = null;
+ }
+
+ /**
+ * Reads a single byte from the input stream.
+ */
+ protected int read() {
+ int curByte = 0;
+ try {
+ curByte = in.read();
+ } catch (IOException e) {
+ status = STATUS_FORMAT_ERROR;
+ }
+ return curByte;
+ }
+
+ /**
+ * Reads next variable length block from input.
+ *
+ * @return number of bytes stored in "buffer"
+ */
+ protected int readBlock() {
+ blockSize = read();
+ int n = 0;
+ if (blockSize > 0) {
+ try {
+ int count = 0;
+ while (n < blockSize) {
+ count = in.read(block, n, blockSize - n);
+ if (count == -1) {
+ break;
+ }
+ n += count;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ if (n < blockSize) {
+ status = STATUS_FORMAT_ERROR;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Reads color table as 256 RGB integer values
+ *
+ * @param ncolors int number of colors to read
+ * @return int array containing 256 colors (packed ARGB with full alpha)
+ */
+ protected int[] readColorTable(int ncolors) {
+ int nbytes = 3 * ncolors;
+ int[] tab = null;
+ byte[] c = new byte[nbytes];
+ int n = 0;
+ try {
+ n = in.read(c);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (n < nbytes) {
+ status = STATUS_FORMAT_ERROR;
+ } else {
+ tab = new int[256]; // max size to avoid bounds checks
+ int i = 0;
+ int j = 0;
+ while (i < ncolors) {
+ int r = ((int) c[j++]) & 0xff;
+ int g = ((int) c[j++]) & 0xff;
+ int b = ((int) c[j++]) & 0xff;
+ tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
+ }
+ }
+ return tab;
+ }
+
+ /**
+ * Main file parser. Reads GIF content blocks.
+ */
+ protected void readContents() {
+ // read GIF file content blocks
+ boolean done = false;
+ while (!(done || err())) {
+ int code = read();
+ switch (code) {
+
+ case 0x2C : // image separator
+ readImage();
+ break;
+
+ case 0x21 : // extension
+ code = read();
+ switch (code) {
+ case 0xf9 : // graphics control extension
+ readGraphicControlExt();
+ break;
+
+ case 0xff : // application extension
+ readBlock();
+ String app = "";
+ for (int i = 0; i < 11; i++) {
+ app += (char) block[i];
+ }
+ if (app.equals("NETSCAPE2.0")) {
+ readNetscapeExt();
+ } else {
+ skip();
+ }// don't care
+ break;
+
+ default : // uninteresting extension
+ skip();
+ }
+ break;
+
+ case 0x3b : // terminator
+ done = true;
+ break;
+
+ case 0x00 : // bad byte, but keep going and see what happens
+ break;
+
+ default :
+ status = STATUS_FORMAT_ERROR;
+ }
+ }
+ }
+
+ /**
+ * Reads Graphics Control Extension values
+ */
+ protected void readGraphicControlExt() {
+ read(); // block size
+ int packed = read(); // packed fields
+ dispose = (packed & 0x1c) >> 2; // disposal method
+ if (dispose == 0) {
+ dispose = 1; // elect to keep old image if discretionary
+ }
+ transparency = (packed & 1) != 0;
+ delay = readShort() * 10; // delay in milliseconds
+ transIndex = read(); // transparent color index
+ read(); // block terminator
+ }
+
+ /**
+ * Reads GIF file header information.
+ */
+ protected void readHeader() {
+ String id = "";
+ for (int i = 0; i < 6; i++) {
+ id += (char) read();
+ }
+ if (!id.startsWith("GIF")) {
+ status = STATUS_FORMAT_ERROR;
+ return;
+ }
+
+ readLSD();
+ if (gctFlag && !err()) {
+ gct = readColorTable(gctSize);
+ bgColor = gct[bgIndex];
+ }
+ }
+
+ /**
+ * Reads next frame image
+ */
+ protected void readImage() {
+ ix = readShort(); // (sub)image position & size
+ iy = readShort();
+ iw = readShort();
+ ih = readShort();
+
+ int packed = read();
+ lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
+ interlace = (packed & 0x40) != 0; // 2 - interlace flag
+ // 3 - sort flag
+ // 4-5 - reserved
+ lctSize = 2 << (packed & 7); // 6-8 - local color table size
+
+ if (lctFlag) {
+ lct = readColorTable(lctSize); // read table
+ act = lct; // make local table active
+ } else {
+ act = gct; // make global table active
+ if (bgIndex == transIndex) {
+ bgColor = 0;
+ }
+ }
+ int save = 0;
+ if (transparency) {
+ save = act[transIndex];
+ act[transIndex] = 0; // set transparent color if specified
+ }
+
+ if (act == null) {
+ status = STATUS_FORMAT_ERROR; // no color table defined
+ }
+
+ if (err()) {
+ return;
+ }
+
+ decodeImageData(); // decode pixel data
+ skip();
+
+ if (err()) {
+ return;
+ }
+
+ frameCount++;
+
+ // create new image to receive frame data
+ image =
+ new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
+
+ setPixels(); // transfer pixel data to image
+
+ frames.add(new GifFrame(image, delay)); // add image to frame list
+
+ if (transparency) {
+ act[transIndex] = save;
+ }
+ resetFrame();
+
+ }
+
+ /**
+ * Reads Logical Screen Descriptor
+ */
+ protected void readLSD() {
+
+ // logical screen size
+ width = readShort();
+ height = readShort();
+
+ // packed fields
+ int packed = read();
+ gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
+ // 2-4 : color resolution
+ // 5 : gct sort flag
+ gctSize = 2 << (packed & 7); // 6-8 : gct size
+
+ bgIndex = read(); // background color index
+ pixelAspect = read(); // pixel aspect ratio
+ }
+
+ /**
+ * Reads Netscape extenstion to obtain iteration count
+ */
+ protected void readNetscapeExt() {
+ do {
+ readBlock();
+ if (block[0] == 1) {
+ // loop count sub-block
+ int b1 = ((int) block[1]) & 0xff;
+ int b2 = ((int) block[2]) & 0xff;
+ loopCount = (b2 << 8) | b1;
+ }
+ } while ((blockSize > 0) && !err());
+ }
+
+ /**
+ * Reads next 16-bit value, LSB first
+ */
+ protected int readShort() {
+ // read 16-bit value, LSB first
+ return read() | (read() << 8);
+ }
+
+ /**
+ * Resets frame state for reading next image.
+ */
+ protected void resetFrame() {
+ lastDispose = dispose;
+ lastRect = new Rectangle(ix, iy, iw, ih);
+ lastImage = image;
+ lastBgColor = bgColor;
+ int dispose = 0;
+ boolean transparency = false;
+ int delay = 0;
+ lct = null;
+ }
+
+ /**
+ * Skips variable length blocks up to and including
+ * next zero length block.
+ */
+ protected void skip() {
+ do {
+ readBlock();
+ } while ((blockSize > 0) && !err());
+ }
+}
Deleted:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java
===================================================================
---
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java 2010-10-26
17:10:27 UTC (rev 19674)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,291 +0,0 @@
-package org.ajax4jsf.resource.image.animatedgif;
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-//==============================================================================
-// Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott.
-// K Weiner 12/00
-
-class LZWEncoder {
- static final int BITS = 12;
- static final int HSIZE = 5003;
- private static final int EOF = -1;
- private int imgW;
- private int imgH;
- private byte[] pixAry;
- private int initCodeSize;
- private int remaining;
- private int curPixel;
-
- private int nBits; // number of bits/code
- private int maxbits = BITS; // user settable max # bits/code
- private int maxcode; // maximum code, given n_bits
- private int maxmaxcode = 1 << BITS; // should NEVER generate this code
-
- private int[] htab = new int[HSIZE];
- private int[] codetab = new int[HSIZE];
-
- private int hsize = HSIZE; // for dynamic table sizing
-
- private int freeEnt = 0; // first unused entry
-
- // block compression parameters -- after all codes are used up,
- // and compression rate changes, start over.
- private boolean clearFlg = false;
-
- // Algorithm: use open addressing double hashing (no chaining) on the
- // prefix code / next character combination. We do a variant of Knuth's
- // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
- // secondary probe. Here, the modular division first probe is gives way
- // to a faster exclusive-or manipulation. Also do block compression with
- // an adaptive reset, whereby the code table is cleared when the compression
- // ratio decreases, but after the table fills. The variable-length output
- // codes are re-sized at this point, and a special CLEAR code is generated
- // for the decompressor. Late addition: construct the table according to
- // file size for noticeable speed improvement on small files. Please direct
- // questions about this implementation to ames!jaw.
-
- private int gInitBits;
-
- private int clearCode;
- private int eOFCode;
-
- // output
- //
- // Output the given code.
- // Inputs:
- // code: A n_bits-bit integer. If == -1, then EOF. This assumes
- // that n_bits =< wordsize - 1.
- // Outputs:
- // Outputs code to the file.
- // Assumptions:
- // Chars are 8 bits long.
- // Algorithm:
- // Maintain a BITS character long buffer (so that 8 codes will
- // fit in it exactly). Use the VAX insv instruction to insert each
- // code in turn. When the buffer fills up empty it and start over.
-
- private int curAccum = 0;
- private int curBits = 0;
- private int aCount;
-
- // Define the storage for the packet accumulator
- private byte[] accum = new byte[256];
-
- private int[] masks =
- {
- 0x0000,
- 0x0001,
- 0x0003,
- 0x0007,
- 0x000F,
- 0x001F,
- 0x003F,
- 0x007F,
- 0x00FF,
- 0x01FF,
- 0x03FF,
- 0x07FF,
- 0x0FFF,
- 0x1FFF,
- 0x3FFF,
- 0x7FFF,
- 0xFFFF
- };
-
- LZWEncoder(int width, int height, byte[] pixels, int colorDepth) {
- imgW = width;
- imgH = height;
- pixAry = pixels;
- initCodeSize = Math.max(2, colorDepth);
- }
-
- // Add a character to the end of the current packet, and if it is 254
- // characters, flush the packet to disk.
- void charOut(byte c, OutputStream outs) throws IOException {
- accum[aCount++] = c;
- if (aCount >= 254) {
- flushChar(outs);
- }
- }
-
- // Clear out the hash table
-
- // table clear for block compress
- void clBlock(OutputStream outs) throws IOException {
- clHash(hsize);
- freeEnt = clearCode + 2;
- clearFlg = true;
-
- output(clearCode, outs);
- }
-
- // reset code table
- void clHash(int hsize) {
- for (int i = 0; i < hsize; ++i) {
- htab[i] = -1;
- }
- }
-
- void compress(int initBits, OutputStream outs) throws IOException {
- int fcode;
- int i /* = 0 */;
- int c;
- int ent;
- int disp;
- int hsizeReg;
- int hshift;
-
- // Set up the globals: g_init_bits - initial number of bits
- gInitBits = initBits;
-
- // Set up the necessary values
- clearFlg = false;
- nBits = gInitBits;
- maxcode = maxcode(nBits);
-
- clearCode = 1 << (initBits - 1);
- eOFCode = clearCode + 1;
- freeEnt = clearCode + 2;
-
- aCount = 0; // clear packet
-
- ent = nextPixel();
-
- hshift = 0;
- for (fcode = hsize; fcode < 65536; fcode *= 2) {
- ++hshift;
- }
- hshift = 8 - hshift; // set hash code range bound
-
- hsizeReg = hsize;
- clHash(hsizeReg); // clear hash table
-
- output(clearCode, outs);
-
- outer_loop :
- while ((c = nextPixel()) != EOF) {
- fcode = (c << maxbits) + ent;
- i = (c << hshift) ^ ent; // xor hashing
-
- if (htab[i] == fcode) {
- ent = codetab[i];
- continue;
- } else if (htab[i] >= 0) {
- disp = hsizeReg - i; // secondary hash (after G. Knott)
- if (i == 0) {
- disp = 1;
- }
- do {
- i -= disp;
- if (i < 0) {
- i += hsizeReg;
- }
-
- if (htab[i] == fcode) {
- ent = codetab[i];
- continue outer_loop;
- }
- } while (htab[i] >= 0);
- }
- output(ent, outs);
- ent = c;
- if (freeEnt < maxmaxcode) {
- codetab[i] = freeEnt++; // code -> hashtable
- htab[i] = fcode;
- } else {
- clBlock(outs);
- }
- }
- // Put out the final code.
- output(ent, outs);
- output(eOFCode, outs);
- }
-
- //----------------------------------------------------------------------------
- void encode(OutputStream os) throws IOException {
- os.write(initCodeSize); // write "initial code size" byte
-
- remaining = imgW * imgH; // reset navigation variables
- curPixel = 0;
-
- compress(initCodeSize + 1, os); // compress and write the pixel data
-
- os.write(0); // write block terminator
- }
-
- // Flush the packet to disk, and reset the accumulator
- void flushChar(OutputStream outs) throws IOException {
- if (aCount > 0) {
- outs.write(aCount);
- outs.write(accum, 0, aCount);
- aCount = 0;
- }
- }
-
- final int maxcode(int nBits) {
- return (1 << nBits) - 1;
- }
-
- //----------------------------------------------------------------------------
- // Return the next pixel from the image
- //----------------------------------------------------------------------------
- private int nextPixel() {
- if (remaining == 0) {
- return EOF;
- }
-
- --remaining;
-
- byte pix = pixAry[curPixel++];
-
- return pix & 0xff;
- }
-
- void output(int code, OutputStream outs) throws IOException {
- curAccum &= masks[curBits];
-
- if (curBits > 0) {
- curAccum |= (code << curBits);
- } else {
- curAccum = code;
- }
-
- curBits += nBits;
-
- while (curBits >= 8) {
- charOut((byte) (curAccum & 0xff), outs);
- curAccum >>= 8;
- curBits -= 8;
- }
-
- // If the next entry is going to be too big for the code size,
- // then increase it, if possible.
- if (freeEnt > maxcode || clearFlg) {
- if (clearFlg) {
- nBits = gInitBits;
- maxcode = maxcode(nBits);
- clearFlg = false;
- } else {
- ++nBits;
- if (nBits == maxbits) {
- maxcode = maxmaxcode;
- } else {
- maxcode = maxcode(nBits);
- }
- }
- }
-
- if (code == eOFCode) {
- // At EOF, write the rest of the buffer.
- while (curBits > 0) {
- charOut((byte) (curAccum & 0xff), outs);
- curAccum >>= 8;
- curBits -= 8;
- }
-
- flushChar(outs);
- }
- }
-}
Copied:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java
(from rev 19674,
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/LZWEncoder.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,291 @@
+package org.ajax4jsf.resource.image.animatedgif;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+//==============================================================================
+// Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott.
+// K Weiner 12/00
+
+class LZWEncoder {
+ static final int BITS = 12;
+ static final int HSIZE = 5003;
+ private static final int EOF = -1;
+ private int imgW;
+ private int imgH;
+ private byte[] pixAry;
+ private int initCodeSize;
+ private int remaining;
+ private int curPixel;
+
+ private int nBits; // number of bits/code
+ private int maxbits = BITS; // user settable max # bits/code
+ private int maxcode; // maximum code, given n_bits
+ private int maxmaxcode = 1 << BITS; // should NEVER generate this code
+
+ private int[] htab = new int[HSIZE];
+ private int[] codetab = new int[HSIZE];
+
+ private int hsize = HSIZE; // for dynamic table sizing
+
+ private int freeEnt = 0; // first unused entry
+
+ // block compression parameters -- after all codes are used up,
+ // and compression rate changes, start over.
+ private boolean clearFlg = false;
+
+ // Algorithm: use open addressing double hashing (no chaining) on the
+ // prefix code / next character combination. We do a variant of Knuth's
+ // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ // secondary probe. Here, the modular division first probe is gives way
+ // to a faster exclusive-or manipulation. Also do block compression with
+ // an adaptive reset, whereby the code table is cleared when the compression
+ // ratio decreases, but after the table fills. The variable-length output
+ // codes are re-sized at this point, and a special CLEAR code is generated
+ // for the decompressor. Late addition: construct the table according to
+ // file size for noticeable speed improvement on small files. Please direct
+ // questions about this implementation to ames!jaw.
+
+ private int gInitBits;
+
+ private int clearCode;
+ private int eOFCode;
+
+ // output
+ //
+ // Output the given code.
+ // Inputs:
+ // code: A n_bits-bit integer. If == -1, then EOF. This assumes
+ // that n_bits =< wordsize - 1.
+ // Outputs:
+ // Outputs code to the file.
+ // Assumptions:
+ // Chars are 8 bits long.
+ // Algorithm:
+ // Maintain a BITS character long buffer (so that 8 codes will
+ // fit in it exactly). Use the VAX insv instruction to insert each
+ // code in turn. When the buffer fills up empty it and start over.
+
+ private int curAccum = 0;
+ private int curBits = 0;
+ private int aCount;
+
+ // Define the storage for the packet accumulator
+ private byte[] accum = new byte[256];
+
+ private int[] masks =
+ {
+ 0x0000,
+ 0x0001,
+ 0x0003,
+ 0x0007,
+ 0x000F,
+ 0x001F,
+ 0x003F,
+ 0x007F,
+ 0x00FF,
+ 0x01FF,
+ 0x03FF,
+ 0x07FF,
+ 0x0FFF,
+ 0x1FFF,
+ 0x3FFF,
+ 0x7FFF,
+ 0xFFFF
+ };
+
+ LZWEncoder(int width, int height, byte[] pixels, int colorDepth) {
+ imgW = width;
+ imgH = height;
+ pixAry = pixels;
+ initCodeSize = Math.max(2, colorDepth);
+ }
+
+ // Add a character to the end of the current packet, and if it is 254
+ // characters, flush the packet to disk.
+ void charOut(byte c, OutputStream outs) throws IOException {
+ accum[aCount++] = c;
+ if (aCount >= 254) {
+ flushChar(outs);
+ }
+ }
+
+ // Clear out the hash table
+
+ // table clear for block compress
+ void clBlock(OutputStream outs) throws IOException {
+ clHash(hsize);
+ freeEnt = clearCode + 2;
+ clearFlg = true;
+
+ output(clearCode, outs);
+ }
+
+ // reset code table
+ void clHash(int hsize) {
+ for (int i = 0; i < hsize; ++i) {
+ htab[i] = -1;
+ }
+ }
+
+ void compress(int initBits, OutputStream outs) throws IOException {
+ int fcode;
+ int i /* = 0 */;
+ int c;
+ int ent;
+ int disp;
+ int hsizeReg;
+ int hshift;
+
+ // Set up the globals: g_init_bits - initial number of bits
+ gInitBits = initBits;
+
+ // Set up the necessary values
+ clearFlg = false;
+ nBits = gInitBits;
+ maxcode = maxcode(nBits);
+
+ clearCode = 1 << (initBits - 1);
+ eOFCode = clearCode + 1;
+ freeEnt = clearCode + 2;
+
+ aCount = 0; // clear packet
+
+ ent = nextPixel();
+
+ hshift = 0;
+ for (fcode = hsize; fcode < 65536; fcode *= 2) {
+ ++hshift;
+ }
+ hshift = 8 - hshift; // set hash code range bound
+
+ hsizeReg = hsize;
+ clHash(hsizeReg); // clear hash table
+
+ output(clearCode, outs);
+
+ outer_loop :
+ while ((c = nextPixel()) != EOF) {
+ fcode = (c << maxbits) + ent;
+ i = (c << hshift) ^ ent; // xor hashing
+
+ if (htab[i] == fcode) {
+ ent = codetab[i];
+ continue;
+ } else if (htab[i] >= 0) {
+ disp = hsizeReg - i; // secondary hash (after G. Knott)
+ if (i == 0) {
+ disp = 1;
+ }
+ do {
+ i -= disp;
+ if (i < 0) {
+ i += hsizeReg;
+ }
+
+ if (htab[i] == fcode) {
+ ent = codetab[i];
+ continue outer_loop;
+ }
+ } while (htab[i] >= 0);
+ }
+ output(ent, outs);
+ ent = c;
+ if (freeEnt < maxmaxcode) {
+ codetab[i] = freeEnt++; // code -> hashtable
+ htab[i] = fcode;
+ } else {
+ clBlock(outs);
+ }
+ }
+ // Put out the final code.
+ output(ent, outs);
+ output(eOFCode, outs);
+ }
+
+ //----------------------------------------------------------------------------
+ void encode(OutputStream os) throws IOException {
+ os.write(initCodeSize); // write "initial code size" byte
+
+ remaining = imgW * imgH; // reset navigation variables
+ curPixel = 0;
+
+ compress(initCodeSize + 1, os); // compress and write the pixel data
+
+ os.write(0); // write block terminator
+ }
+
+ // Flush the packet to disk, and reset the accumulator
+ void flushChar(OutputStream outs) throws IOException {
+ if (aCount > 0) {
+ outs.write(aCount);
+ outs.write(accum, 0, aCount);
+ aCount = 0;
+ }
+ }
+
+ final int maxcode(int nBits) {
+ return (1 << nBits) - 1;
+ }
+
+ //----------------------------------------------------------------------------
+ // Return the next pixel from the image
+ //----------------------------------------------------------------------------
+ private int nextPixel() {
+ if (remaining == 0) {
+ return EOF;
+ }
+
+ --remaining;
+
+ byte pix = pixAry[curPixel++];
+
+ return pix & 0xff;
+ }
+
+ void output(int code, OutputStream outs) throws IOException {
+ curAccum &= masks[curBits];
+
+ if (curBits > 0) {
+ curAccum |= (code << curBits);
+ } else {
+ curAccum = code;
+ }
+
+ curBits += nBits;
+
+ while (curBits >= 8) {
+ charOut((byte) (curAccum & 0xff), outs);
+ curAccum >>= 8;
+ curBits -= 8;
+ }
+
+ // If the next entry is going to be too big for the code size,
+ // then increase it, if possible.
+ if (freeEnt > maxcode || clearFlg) {
+ if (clearFlg) {
+ nBits = gInitBits;
+ maxcode = maxcode(nBits);
+ clearFlg = false;
+ } else {
+ ++nBits;
+ if (nBits == maxbits) {
+ maxcode = maxmaxcode;
+ } else {
+ maxcode = maxcode(nBits);
+ }
+ }
+ }
+
+ if (code == eOFCode) {
+ // At EOF, write the rest of the buffer.
+ while (curBits > 0) {
+ charOut((byte) (curAccum & 0xff), outs);
+ curAccum >>= 8;
+ curBits -= 8;
+ }
+
+ flushChar(outs);
+ }
+ }
+}
Deleted:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java
===================================================================
---
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java 2010-10-26
17:10:27 UTC (rev 19674)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,519 +0,0 @@
-/* NeuQuant Neural-Net Quantization Algorithm
- * ------------------------------------------
- *
- * Copyright (c) 1994 Anthony Dekker
- *
- * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
- * See "Kohonen neural networks for optimal colour quantization"
- * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
- * for a discussion of the algorithm.
- *
- * Any party obtaining a copy of these files from the author, directly or
- * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
- * world-wide, paid up, royalty-free, nonexclusive right and license to deal
- * in this software and documentation files (the "Software"), including
without
- * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons who receive
- * copies from any such party to do so, with the only requirement being
- * that this copyright notice remain intact.
- */
-package org.ajax4jsf.resource.image.animatedgif;
-
-// Ported to Java 12/00 K Weiner
-
-public class NeuQuant {
-
- protected static final int NETSIZE = 256; /* number of colours used */
-
- /* four primes near 500 - assume no image has a length so large */
- /* that it is divisible by all four primes */
- protected static final int PRIME1 = 499;
- protected static final int PRIME2 = 491;
- protected static final int PRIME3 = 487;
- protected static final int PRIME4 = 503;
-
- protected static final int MINPICTUREBYTES = (3 * PRIME4);
- /* minimum size for input image */
-
- /* Program Skeleton
- ----------------
- [select samplefac in range 1..30]
- [read image from input file]
- pic = (unsigned char*) malloc(3*width*height);
- initnet(pic,3*width*height,samplefac);
- learn();
- unbiasnet();
- [write output image header, using writecolourmap(f)]
- inxbuild();
- write output image using inxsearch(b,g,r) */
-
- /* Network Definitions
- ------------------- */
-
- protected static final int MAXNETPOS = (NETSIZE - 1);
- protected static final int NETBIASSHIFT = 4; /* bias for colour values */
- protected static final int NCYCLES = 100; /* no. of learning cycles */
-
- /* defs for freq and bias */
- protected static final int INTBIASSHIFT = 16; /* bias for fractions */
- protected static final int INTBIAS = (((int) 1) << INTBIASSHIFT);
- protected static final int GAMMASHIFT = 10; /* gamma = 1024 */
- protected static final int GAMMA = (((int) 1) << GAMMASHIFT);
- protected static final int BETASHIFT = 10;
- protected static final int BETA = (INTBIAS >> BETASHIFT); /* beta = 1/1024 */
- protected static final int BETAGAMMA =
- (INTBIAS << (GAMMASHIFT - BETASHIFT));
-
- /* defs for decreasing radius factor */
- protected static final int INITRAD = (NETSIZE >> 3); /* for 256 cols, radius
starts */
- protected static final int RADIUSBIASSHIFT = 6; /* at 32.0 biased by 6 bits */
- protected static final int RADIUSBIAS = (((int) 1) << RADIUSBIASSHIFT);
- protected static final int INITRADIUS = (INITRAD * RADIUSBIAS); /* and decreases by a
*/
- protected static final int RADIUSDEC = 30; /* factor of 1/30 each cycle */
-
- /* defs for decreasing alpha factor */
- protected static final int ALPHABIASSHIFT = 10; /* alpha starts at 1.0 */
- protected static final int INITALPHA = (((int) 1) << ALPHABIASSHIFT);
-
- protected static final int RADBIASSHIFT = 8;
- protected static final int RADBIAS = (((int) 1) << RADBIASSHIFT);
- protected static final int ALPHARADBSHIFT = (ALPHABIASSHIFT + RADBIASSHIFT);
- protected static final int ALPHARADBIAS = (((int) 1) << ALPHARADBSHIFT);
-
- protected int alphadec; /* biased by 10 bits */
-
- /* radbias and alpharadbias used for radpower calculation */
-
-
- /* Types and Global Variables
- -------------------------- */
-
- protected byte[] thepicture; /* the input image itself */
- protected int lengthcount; /* lengthcount = H*W*3 */
-
- protected int samplefac; /* sampling factor 1..30 */
-
- // typedef int pixel[4]; /* BGRc */
- protected int[][] network; /* the network itself - [netsize][4] */
-
- protected int[] netindex = new int[256];
- /* for network lookup - really 256 */
-
- protected int[] bias = new int[NETSIZE];
- /* bias and freq arrays for learning */
- protected int[] freq = new int[NETSIZE];
- protected int[] radpower = new int[INITRAD];
- /* radpower for precomputation */
-
- /* Initialise network in range (0,0,0) to (255,255,255) and set parameters
- ----------------------------------------------------------------------- */
- public NeuQuant(byte[] thepic, int len, int sample) {
-
- int i;
- int[] p;
-
- thepicture = thepic;
- lengthcount = len;
- samplefac = sample;
-
- network = new int[NETSIZE][];
- for (i = 0; i < NETSIZE; i++) {
- network[i] = new int[4];
- p = network[i];
- p[0] = (i << (NETBIASSHIFT + 8)) / NETSIZE;
- p[1] = (i << (NETBIASSHIFT + 8)) / NETSIZE;
- p[2] = (i << (NETBIASSHIFT + 8)) / NETSIZE;
- freq[i] = INTBIAS / NETSIZE; /* 1/netsize */
- bias[i] = 0;
- }
- }
-
- public byte[] colorMap() {
- byte[] map = new byte[3 * NETSIZE];
- int[] index = new int[NETSIZE];
- for (int i = 0; i < NETSIZE; i++) {
- index[network[i][3]] = i;
- }
- int k = 0;
- for (int i = 0; i < NETSIZE; i++) {
- int j = index[i];
- map[k++] = (byte) (network[j][0]);
- map[k++] = (byte) (network[j][1]);
- map[k++] = (byte) (network[j][2]);
- }
- return map;
- }
-
- /* Insertion sort of network and building of netindex[0..255] (to do after unbias)
- -------------------------------------------------------------------------------
*/
- public void inxbuild() {
-
- int i;
- int j;
- int smallpos;
- int smallval;
- int[] p;
- int[] q;
- int previouscol;
- int startpos;
-
- previouscol = 0;
- startpos = 0;
- for (i = 0; i < NETSIZE; i++) {
- p = network[i];
- smallpos = i;
- smallval = p[1]; /* index on g */
- /* find smallest in i..netsize-1 */
- for (j = i + 1; j < NETSIZE; j++) {
- q = network[j];
- if (q[1] < smallval) { /* index on g */
- smallpos = j;
- smallval = q[1]; /* index on g */
- }
- }
- q = network[smallpos];
- /* swap p (i) and q (smallpos) entries */
- if (i != smallpos) {
- j = q[0];
- q[0] = p[0];
- p[0] = j;
- j = q[1];
- q[1] = p[1];
- p[1] = j;
- j = q[2];
- q[2] = p[2];
- p[2] = j;
- j = q[3];
- q[3] = p[3];
- p[3] = j;
- }
- /* smallval entry is now in position i */
- if (smallval != previouscol) {
- netindex[previouscol] = (startpos + i) >> 1;
- for (j = previouscol + 1; j < smallval; j++) {
- netindex[j] = i;
- }
- previouscol = smallval;
- startpos = i;
- }
- }
- netindex[previouscol] = (startpos + MAXNETPOS) >> 1;
- for (j = previouscol + 1; j < 256; j++) {
- netindex[j] = MAXNETPOS; /* really 256 */
- }
- }
-
- /* Main Learning Loop
- ------------------ */
- public void learn() {
-
- int i;
- int j;
- int b;
- int g;
- int r;
- int radius;
- int rad;
- int alpha;
- int step;
- int delta;
- int samplepixels;
- byte[] p;
- int pix;
- int lim;
-
- if (lengthcount < MINPICTUREBYTES){
- samplefac = 1;
- }
-
- alphadec = 30 + ((samplefac - 1) / 3);
- p = thepicture;
- pix = 0;
- lim = lengthcount;
- samplepixels = lengthcount / (3 * samplefac);
- delta = samplepixels / NCYCLES;
- alpha = INITALPHA;
- radius = INITRADIUS;
-
- rad = radius >> RADIUSBIASSHIFT;
- if (rad <= 1) {
- rad = 0;
- }
- for (i = 0; i < rad; i++) {
- radpower[i] =
- alpha * (((rad * rad - i * i) * RADBIAS) / (rad * rad));
- }
-
- //fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad);
-
- if (lengthcount < MINPICTUREBYTES) {
- step = 3;
- } else if ((lengthcount % PRIME1) != 0) {
- step = 3 * PRIME1;
- } else {
- if ((lengthcount % PRIME2) != 0) {
- step = 3 * PRIME2;
- } else {
- if ((lengthcount % PRIME3) != 0) {
- step = 3 * PRIME3;
- } else {
- step = 3 * PRIME4;
- }
- }
- }
-
- i = 0;
- while (i < samplepixels) {
- b = (p[pix + 0] & 0xff) << NETBIASSHIFT;
- g = (p[pix + 1] & 0xff) << NETBIASSHIFT;
- r = (p[pix + 2] & 0xff) << NETBIASSHIFT;
- j = contest(b, g, r);
-
- altersingle(alpha, j, b, g, r);
- if (rad != 0) {
- alterneigh(rad, j, b, g, r); /* alter neighbours */
- }
-
- pix += step;
- if (pix >= lim) {
- pix -= lengthcount;
- }
-
- i++;
- if (delta == 0) {
- delta = 1;
- }
- if (i % delta == 0) {
- alpha -= alpha / alphadec;
- radius -= radius / RADIUSDEC;
- rad = radius >> RADIUSBIASSHIFT;
- if (rad <= 1) {
- rad = 0;
- }
- for (j = 0; j < rad; j++) {
- radpower[j] =
- alpha * (((rad * rad - j * j) * RADBIAS) / (rad * rad));
- }
- }
- }
- //fprintf(stderr,"finished 1D learning: final alpha=%f
!\n",((float)alpha)/initalpha);
- }
-
- /* Search for BGR values 0..255 (after net is unbiased) and return colour index
- ---------------------------------------------------------------------------- */
- public int map(int b, int g, int r) {
-
- int i;
- int j;
- int dist;
- int a;
- int bestd;
- int[] p;
- int best;
-
- bestd = 1000; /* biggest possible dist is 256*3 */
- best = -1;
- i = netindex[g]; /* index on g */
- j = i - 1; /* start at netindex[g] and work outwards */
-
- while ((i < NETSIZE) || (j >= 0)) {
- if (i < NETSIZE) {
- p = network[i];
- dist = p[1] - g; /* inx key */
- if (dist >= bestd) {
- i = NETSIZE; /* stop iter */
- } else {
- i++;
- if (dist < 0) {
- dist = -dist;
- }
- a = p[0] - b;
- if (a < 0) {
- a = -a;
- }
- dist += a;
- if (dist < bestd) {
- a = p[2] - r;
- if (a < 0) {
- a = -a;
- }
- dist += a;
- if (dist < bestd) {
- bestd = dist;
- best = p[3];
- }
- }
- }
- }
- if (j >= 0) {
- p = network[j];
- dist = g - p[1]; /* inx key - reverse dif */
- if (dist >= bestd) {
- j = -1; /* stop iter */
- } else {
- j--;
- if (dist < 0) {
- dist = -dist;
- }
- a = p[0] - b;
- if (a < 0) {
- a = -a;
- }
- dist += a;
- if (dist < bestd) {
- a = p[2] - r;
- if (a < 0) {
- a = -a;
- }
- dist += a;
- if (dist < bestd) {
- bestd = dist;
- best = p[3];
- }
- }
- }
- }
- }
- return (best);
- }
- public byte[] process() {
- learn();
- unbiasnet();
- inxbuild();
- return colorMap();
- }
-
- /* Unbias network to give byte values 0..255 and record position i to prepare for
sort
-
----------------------------------------------------------------------------------- */
- public void unbiasnet() {
-
- int i;
- int j;
-
- for (i = 0; i < NETSIZE; i++) {
- network[i][0] >>= NETBIASSHIFT;
- network[i][1] >>= NETBIASSHIFT;
- network[i][2] >>= NETBIASSHIFT;
- network[i][3] = i; /* record colour no */
- }
- }
-
- /* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
- ---------------------------------------------------------------------------------
*/
- protected void alterneigh(int rad, int i, int b, int g, int r) {
-
- int j;
- int k;
- int lo;
- int hi;
- int a;
- int m;
- int[] p;
-
- lo = i - rad;
- if (lo < -1) {
- lo = -1;
- }
- hi = i + rad;
- if (hi > NETSIZE) {
- hi = NETSIZE;
- }
-
- j = i + 1;
- k = i - 1;
- m = 1;
- while ((j < hi) || (k > lo)) {
- a = radpower[m++];
- if (j < hi) {
- p = network[j++];
- try {
- p[0] -= (a * (p[0] - b)) / ALPHARADBIAS;
- p[1] -= (a * (p[1] - g)) / ALPHARADBIAS;
- p[2] -= (a * (p[2] - r)) / ALPHARADBIAS;
- } catch (Exception e) {
- e.printStackTrace();
- } // prevents 1.3 miscompilation
- }
- if (k > lo) {
- p = network[k--];
- try {
- p[0] -= (a * (p[0] - b)) / ALPHARADBIAS;
- p[1] -= (a * (p[1] - g)) / ALPHARADBIAS;
- p[2] -= (a * (p[2] - r)) / ALPHARADBIAS;
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- /* Move neuron i towards biased (b,g,r) by factor alpha
- ---------------------------------------------------- */
- protected void altersingle(int alpha, int i, int b, int g, int r) {
-
- /* alter hit neuron */
- int[] n = network[i];
- n[0] -= (alpha * (n[0] - b)) / INITALPHA;
- n[1] -= (alpha * (n[1] - g)) / INITALPHA;
- n[2] -= (alpha * (n[2] - r)) / INITALPHA;
- }
-
- /* Search for biased BGR values
- ---------------------------- */
- protected int contest(int b, int g, int r) {
-
- /* finds closest neuron (min dist) and updates freq */
- /* finds best neuron (min dist-bias) and returns position */
- /* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
- /* bias[i] = gamma*((1/netsize)-freq[i]) */
-
- int i;
- int dist;
- int a;
- int biasdist;
- int betafreq;
- int bestpos;
- int bestbiaspos;
- int bestd;
- int bestbiasd;
- int[] n;
-
- bestd = ~(((int) 1) << 31);
- bestbiasd = bestd;
- bestpos = -1;
- bestbiaspos = bestpos;
-
- for (i = 0; i < NETSIZE; i++) {
- n = network[i];
- dist = n[0] - b;
- if (dist < 0) {
- dist = -dist;
- }
- a = n[1] - g;
- if (a < 0) {
- a = -a;
- }
- dist += a;
- a = n[2] - r;
- if (a < 0) {
- a = -a;
- }
- dist += a;
- if (dist < bestd) {
- bestd = dist;
- bestpos = i;
- }
- biasdist = dist - ((bias[i]) >> (INTBIASSHIFT - NETBIASSHIFT));
- if (biasdist < bestbiasd) {
- bestbiasd = biasdist;
- bestbiaspos = i;
- }
- betafreq = (freq[i] >> BETASHIFT);
- freq[i] -= betafreq;
- bias[i] += (betafreq << GAMMASHIFT);
- }
- freq[bestpos] += BETA;
- bias[bestpos] -= BETAGAMMA;
- return (bestbiaspos);
- }
-}
Copied:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java
(from rev 19674,
trunk/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/resource/image/animatedgif/NeuQuant.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,519 @@
+/* NeuQuant Neural-Net Quantization Algorithm
+ * ------------------------------------------
+ *
+ * Copyright (c) 1994 Anthony Dekker
+ *
+ * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
+ * See "Kohonen neural networks for optimal colour quantization"
+ * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
+ * for a discussion of the algorithm.
+ *
+ * Any party obtaining a copy of these files from the author, directly or
+ * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
+ * world-wide, paid up, royalty-free, nonexclusive right and license to deal
+ * in this software and documentation files (the "Software"), including
without
+ * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons who receive
+ * copies from any such party to do so, with the only requirement being
+ * that this copyright notice remain intact.
+ */
+package org.ajax4jsf.resource.image.animatedgif;
+
+// Ported to Java 12/00 K Weiner
+
+public class NeuQuant {
+
+ protected static final int NETSIZE = 256; /* number of colours used */
+
+ /* four primes near 500 - assume no image has a length so large */
+ /* that it is divisible by all four primes */
+ protected static final int PRIME1 = 499;
+ protected static final int PRIME2 = 491;
+ protected static final int PRIME3 = 487;
+ protected static final int PRIME4 = 503;
+
+ protected static final int MINPICTUREBYTES = (3 * PRIME4);
+ /* minimum size for input image */
+
+ /* Program Skeleton
+ ----------------
+ [select samplefac in range 1..30]
+ [read image from input file]
+ pic = (unsigned char*) malloc(3*width*height);
+ initnet(pic,3*width*height,samplefac);
+ learn();
+ unbiasnet();
+ [write output image header, using writecolourmap(f)]
+ inxbuild();
+ write output image using inxsearch(b,g,r) */
+
+ /* Network Definitions
+ ------------------- */
+
+ protected static final int MAXNETPOS = (NETSIZE - 1);
+ protected static final int NETBIASSHIFT = 4; /* bias for colour values */
+ protected static final int NCYCLES = 100; /* no. of learning cycles */
+
+ /* defs for freq and bias */
+ protected static final int INTBIASSHIFT = 16; /* bias for fractions */
+ protected static final int INTBIAS = (((int) 1) << INTBIASSHIFT);
+ protected static final int GAMMASHIFT = 10; /* gamma = 1024 */
+ protected static final int GAMMA = (((int) 1) << GAMMASHIFT);
+ protected static final int BETASHIFT = 10;
+ protected static final int BETA = (INTBIAS >> BETASHIFT); /* beta = 1/1024 */
+ protected static final int BETAGAMMA =
+ (INTBIAS << (GAMMASHIFT - BETASHIFT));
+
+ /* defs for decreasing radius factor */
+ protected static final int INITRAD = (NETSIZE >> 3); /* for 256 cols, radius
starts */
+ protected static final int RADIUSBIASSHIFT = 6; /* at 32.0 biased by 6 bits */
+ protected static final int RADIUSBIAS = (((int) 1) << RADIUSBIASSHIFT);
+ protected static final int INITRADIUS = (INITRAD * RADIUSBIAS); /* and decreases by a
*/
+ protected static final int RADIUSDEC = 30; /* factor of 1/30 each cycle */
+
+ /* defs for decreasing alpha factor */
+ protected static final int ALPHABIASSHIFT = 10; /* alpha starts at 1.0 */
+ protected static final int INITALPHA = (((int) 1) << ALPHABIASSHIFT);
+
+ protected static final int RADBIASSHIFT = 8;
+ protected static final int RADBIAS = (((int) 1) << RADBIASSHIFT);
+ protected static final int ALPHARADBSHIFT = (ALPHABIASSHIFT + RADBIASSHIFT);
+ protected static final int ALPHARADBIAS = (((int) 1) << ALPHARADBSHIFT);
+
+ protected int alphadec; /* biased by 10 bits */
+
+ /* radbias and alpharadbias used for radpower calculation */
+
+
+ /* Types and Global Variables
+ -------------------------- */
+
+ protected byte[] thepicture; /* the input image itself */
+ protected int lengthcount; /* lengthcount = H*W*3 */
+
+ protected int samplefac; /* sampling factor 1..30 */
+
+ // typedef int pixel[4]; /* BGRc */
+ protected int[][] network; /* the network itself - [netsize][4] */
+
+ protected int[] netindex = new int[256];
+ /* for network lookup - really 256 */
+
+ protected int[] bias = new int[NETSIZE];
+ /* bias and freq arrays for learning */
+ protected int[] freq = new int[NETSIZE];
+ protected int[] radpower = new int[INITRAD];
+ /* radpower for precomputation */
+
+ /* Initialise network in range (0,0,0) to (255,255,255) and set parameters
+ ----------------------------------------------------------------------- */
+ public NeuQuant(byte[] thepic, int len, int sample) {
+
+ int i;
+ int[] p;
+
+ thepicture = thepic;
+ lengthcount = len;
+ samplefac = sample;
+
+ network = new int[NETSIZE][];
+ for (i = 0; i < NETSIZE; i++) {
+ network[i] = new int[4];
+ p = network[i];
+ p[0] = (i << (NETBIASSHIFT + 8)) / NETSIZE;
+ p[1] = (i << (NETBIASSHIFT + 8)) / NETSIZE;
+ p[2] = (i << (NETBIASSHIFT + 8)) / NETSIZE;
+ freq[i] = INTBIAS / NETSIZE; /* 1/netsize */
+ bias[i] = 0;
+ }
+ }
+
+ public byte[] colorMap() {
+ byte[] map = new byte[3 * NETSIZE];
+ int[] index = new int[NETSIZE];
+ for (int i = 0; i < NETSIZE; i++) {
+ index[network[i][3]] = i;
+ }
+ int k = 0;
+ for (int i = 0; i < NETSIZE; i++) {
+ int j = index[i];
+ map[k++] = (byte) (network[j][0]);
+ map[k++] = (byte) (network[j][1]);
+ map[k++] = (byte) (network[j][2]);
+ }
+ return map;
+ }
+
+ /* Insertion sort of network and building of netindex[0..255] (to do after unbias)
+ -------------------------------------------------------------------------------
*/
+ public void inxbuild() {
+
+ int i;
+ int j;
+ int smallpos;
+ int smallval;
+ int[] p;
+ int[] q;
+ int previouscol;
+ int startpos;
+
+ previouscol = 0;
+ startpos = 0;
+ for (i = 0; i < NETSIZE; i++) {
+ p = network[i];
+ smallpos = i;
+ smallval = p[1]; /* index on g */
+ /* find smallest in i..netsize-1 */
+ for (j = i + 1; j < NETSIZE; j++) {
+ q = network[j];
+ if (q[1] < smallval) { /* index on g */
+ smallpos = j;
+ smallval = q[1]; /* index on g */
+ }
+ }
+ q = network[smallpos];
+ /* swap p (i) and q (smallpos) entries */
+ if (i != smallpos) {
+ j = q[0];
+ q[0] = p[0];
+ p[0] = j;
+ j = q[1];
+ q[1] = p[1];
+ p[1] = j;
+ j = q[2];
+ q[2] = p[2];
+ p[2] = j;
+ j = q[3];
+ q[3] = p[3];
+ p[3] = j;
+ }
+ /* smallval entry is now in position i */
+ if (smallval != previouscol) {
+ netindex[previouscol] = (startpos + i) >> 1;
+ for (j = previouscol + 1; j < smallval; j++) {
+ netindex[j] = i;
+ }
+ previouscol = smallval;
+ startpos = i;
+ }
+ }
+ netindex[previouscol] = (startpos + MAXNETPOS) >> 1;
+ for (j = previouscol + 1; j < 256; j++) {
+ netindex[j] = MAXNETPOS; /* really 256 */
+ }
+ }
+
+ /* Main Learning Loop
+ ------------------ */
+ public void learn() {
+
+ int i;
+ int j;
+ int b;
+ int g;
+ int r;
+ int radius;
+ int rad;
+ int alpha;
+ int step;
+ int delta;
+ int samplepixels;
+ byte[] p;
+ int pix;
+ int lim;
+
+ if (lengthcount < MINPICTUREBYTES){
+ samplefac = 1;
+ }
+
+ alphadec = 30 + ((samplefac - 1) / 3);
+ p = thepicture;
+ pix = 0;
+ lim = lengthcount;
+ samplepixels = lengthcount / (3 * samplefac);
+ delta = samplepixels / NCYCLES;
+ alpha = INITALPHA;
+ radius = INITRADIUS;
+
+ rad = radius >> RADIUSBIASSHIFT;
+ if (rad <= 1) {
+ rad = 0;
+ }
+ for (i = 0; i < rad; i++) {
+ radpower[i] =
+ alpha * (((rad * rad - i * i) * RADBIAS) / (rad * rad));
+ }
+
+ //fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad);
+
+ if (lengthcount < MINPICTUREBYTES) {
+ step = 3;
+ } else if ((lengthcount % PRIME1) != 0) {
+ step = 3 * PRIME1;
+ } else {
+ if ((lengthcount % PRIME2) != 0) {
+ step = 3 * PRIME2;
+ } else {
+ if ((lengthcount % PRIME3) != 0) {
+ step = 3 * PRIME3;
+ } else {
+ step = 3 * PRIME4;
+ }
+ }
+ }
+
+ i = 0;
+ while (i < samplepixels) {
+ b = (p[pix + 0] & 0xff) << NETBIASSHIFT;
+ g = (p[pix + 1] & 0xff) << NETBIASSHIFT;
+ r = (p[pix + 2] & 0xff) << NETBIASSHIFT;
+ j = contest(b, g, r);
+
+ altersingle(alpha, j, b, g, r);
+ if (rad != 0) {
+ alterneigh(rad, j, b, g, r); /* alter neighbours */
+ }
+
+ pix += step;
+ if (pix >= lim) {
+ pix -= lengthcount;
+ }
+
+ i++;
+ if (delta == 0) {
+ delta = 1;
+ }
+ if (i % delta == 0) {
+ alpha -= alpha / alphadec;
+ radius -= radius / RADIUSDEC;
+ rad = radius >> RADIUSBIASSHIFT;
+ if (rad <= 1) {
+ rad = 0;
+ }
+ for (j = 0; j < rad; j++) {
+ radpower[j] =
+ alpha * (((rad * rad - j * j) * RADBIAS) / (rad * rad));
+ }
+ }
+ }
+ //fprintf(stderr,"finished 1D learning: final alpha=%f
!\n",((float)alpha)/initalpha);
+ }
+
+ /* Search for BGR values 0..255 (after net is unbiased) and return colour index
+ ---------------------------------------------------------------------------- */
+ public int map(int b, int g, int r) {
+
+ int i;
+ int j;
+ int dist;
+ int a;
+ int bestd;
+ int[] p;
+ int best;
+
+ bestd = 1000; /* biggest possible dist is 256*3 */
+ best = -1;
+ i = netindex[g]; /* index on g */
+ j = i - 1; /* start at netindex[g] and work outwards */
+
+ while ((i < NETSIZE) || (j >= 0)) {
+ if (i < NETSIZE) {
+ p = network[i];
+ dist = p[1] - g; /* inx key */
+ if (dist >= bestd) {
+ i = NETSIZE; /* stop iter */
+ } else {
+ i++;
+ if (dist < 0) {
+ dist = -dist;
+ }
+ a = p[0] - b;
+ if (a < 0) {
+ a = -a;
+ }
+ dist += a;
+ if (dist < bestd) {
+ a = p[2] - r;
+ if (a < 0) {
+ a = -a;
+ }
+ dist += a;
+ if (dist < bestd) {
+ bestd = dist;
+ best = p[3];
+ }
+ }
+ }
+ }
+ if (j >= 0) {
+ p = network[j];
+ dist = g - p[1]; /* inx key - reverse dif */
+ if (dist >= bestd) {
+ j = -1; /* stop iter */
+ } else {
+ j--;
+ if (dist < 0) {
+ dist = -dist;
+ }
+ a = p[0] - b;
+ if (a < 0) {
+ a = -a;
+ }
+ dist += a;
+ if (dist < bestd) {
+ a = p[2] - r;
+ if (a < 0) {
+ a = -a;
+ }
+ dist += a;
+ if (dist < bestd) {
+ bestd = dist;
+ best = p[3];
+ }
+ }
+ }
+ }
+ }
+ return (best);
+ }
+ public byte[] process() {
+ learn();
+ unbiasnet();
+ inxbuild();
+ return colorMap();
+ }
+
+ /* Unbias network to give byte values 0..255 and record position i to prepare for
sort
+
----------------------------------------------------------------------------------- */
+ public void unbiasnet() {
+
+ int i;
+ int j;
+
+ for (i = 0; i < NETSIZE; i++) {
+ network[i][0] >>= NETBIASSHIFT;
+ network[i][1] >>= NETBIASSHIFT;
+ network[i][2] >>= NETBIASSHIFT;
+ network[i][3] = i; /* record colour no */
+ }
+ }
+
+ /* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
+ ---------------------------------------------------------------------------------
*/
+ protected void alterneigh(int rad, int i, int b, int g, int r) {
+
+ int j;
+ int k;
+ int lo;
+ int hi;
+ int a;
+ int m;
+ int[] p;
+
+ lo = i - rad;
+ if (lo < -1) {
+ lo = -1;
+ }
+ hi = i + rad;
+ if (hi > NETSIZE) {
+ hi = NETSIZE;
+ }
+
+ j = i + 1;
+ k = i - 1;
+ m = 1;
+ while ((j < hi) || (k > lo)) {
+ a = radpower[m++];
+ if (j < hi) {
+ p = network[j++];
+ try {
+ p[0] -= (a * (p[0] - b)) / ALPHARADBIAS;
+ p[1] -= (a * (p[1] - g)) / ALPHARADBIAS;
+ p[2] -= (a * (p[2] - r)) / ALPHARADBIAS;
+ } catch (Exception e) {
+ e.printStackTrace();
+ } // prevents 1.3 miscompilation
+ }
+ if (k > lo) {
+ p = network[k--];
+ try {
+ p[0] -= (a * (p[0] - b)) / ALPHARADBIAS;
+ p[1] -= (a * (p[1] - g)) / ALPHARADBIAS;
+ p[2] -= (a * (p[2] - r)) / ALPHARADBIAS;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /* Move neuron i towards biased (b,g,r) by factor alpha
+ ---------------------------------------------------- */
+ protected void altersingle(int alpha, int i, int b, int g, int r) {
+
+ /* alter hit neuron */
+ int[] n = network[i];
+ n[0] -= (alpha * (n[0] - b)) / INITALPHA;
+ n[1] -= (alpha * (n[1] - g)) / INITALPHA;
+ n[2] -= (alpha * (n[2] - r)) / INITALPHA;
+ }
+
+ /* Search for biased BGR values
+ ---------------------------- */
+ protected int contest(int b, int g, int r) {
+
+ /* finds closest neuron (min dist) and updates freq */
+ /* finds best neuron (min dist-bias) and returns position */
+ /* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
+ /* bias[i] = gamma*((1/netsize)-freq[i]) */
+
+ int i;
+ int dist;
+ int a;
+ int biasdist;
+ int betafreq;
+ int bestpos;
+ int bestbiaspos;
+ int bestd;
+ int bestbiasd;
+ int[] n;
+
+ bestd = ~(((int) 1) << 31);
+ bestbiasd = bestd;
+ bestpos = -1;
+ bestbiaspos = bestpos;
+
+ for (i = 0; i < NETSIZE; i++) {
+ n = network[i];
+ dist = n[0] - b;
+ if (dist < 0) {
+ dist = -dist;
+ }
+ a = n[1] - g;
+ if (a < 0) {
+ a = -a;
+ }
+ dist += a;
+ a = n[2] - r;
+ if (a < 0) {
+ a = -a;
+ }
+ dist += a;
+ if (dist < bestd) {
+ bestd = dist;
+ bestpos = i;
+ }
+ biasdist = dist - ((bias[i]) >> (INTBIASSHIFT - NETBIASSHIFT));
+ if (biasdist < bestbiasd) {
+ bestbiasd = biasdist;
+ bestbiaspos = i;
+ }
+ betafreq = (freq[i] >> BETASHIFT);
+ freq[i] -= betafreq;
+ bias[i] += (betafreq << GAMMASHIFT);
+ }
+ freq[bestpos] += BETA;
+ bias[bestpos] -= BETAGAMMA;
+ return (bestbiaspos);
+ }
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/GlobalResourcesViewHandler.java
(from rev 19674,
trunk/core/impl/src/main/java/org/richfaces/application/GlobalResourcesViewHandler.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/GlobalResourcesViewHandler.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/GlobalResourcesViewHandler.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application;
+
+import java.io.ObjectStreamException;
+import java.util.List;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.application.ViewHandlerWrapper;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIOutput;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import org.richfaces.application.configuration.ConfigurationService;
+import org.richfaces.el.BaseReadOnlyValueExpression;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class GlobalResourcesViewHandler extends ViewHandlerWrapper {
+
+ private static final String SKINNING_RESOURCE_ID =
"__rf_skinning_resource";
+
+ private static final String CLASSES_ECSS = "_classes.ecss";
+
+ private static final String ECSS = ".ecss";
+
+ private static final String BOTH_ECSS = "_both.ecss";
+
+ private static final String CONTROLS_SKINNING;
+
+ private static final String BOTH_SKINNING;
+
+ private static final String CLASSES_SKINNING;
+
+ private static final String HEAD = "head";
+
+ static {
+ String skinningName = "skinning";
+
+ CONTROLS_SKINNING = skinningName + ECSS;
+ BOTH_SKINNING = skinningName + BOTH_ECSS;
+ CLASSES_SKINNING = skinningName + CLASSES_ECSS;
+
+ }
+
+ private ViewHandler viewHandler;
+
+ public GlobalResourcesViewHandler(ViewHandler viewHandler) {
+ super();
+ this.viewHandler = viewHandler;
+ }
+
+ @Override
+ public ViewHandler getWrapped() {
+ return viewHandler;
+ }
+
+ private static final class SkinningResourceNameExpression extends
BaseReadOnlyValueExpression {
+
+ public static final ValueExpression INSTANCE = new
SkinningResourceNameExpression();
+
+ private static final long serialVersionUID = 7520575496522682120L;
+
+ private SkinningResourceNameExpression() {
+ super(String.class);
+ }
+
+ @Override
+ public Object getValue(ELContext context) {
+ FacesContext facesContext = getFacesContext(context);
+
+ ConfigurationService configurationService =
ServiceTracker.getService(ConfigurationService.class);
+
+ boolean controls = configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinning);
+ boolean classes = configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinningClasses);
+
+ if (controls && classes) {
+ return BOTH_SKINNING;
+ }
+
+ if (classes) {
+ return CLASSES_SKINNING;
+ }
+
+ return CONTROLS_SKINNING;
+ }
+
+ private Object readResolve() throws ObjectStreamException {
+ return INSTANCE;
+ }
+
+ }
+
+ private static final class SkinningResourceRenderedExpression extends
BaseReadOnlyValueExpression {
+
+ public static final ValueExpression INSTANCE = new
SkinningResourceRenderedExpression();
+
+ private static final long serialVersionUID = -1579256471133808739L;
+
+ private SkinningResourceRenderedExpression() {
+ super(Boolean.TYPE);
+ }
+
+ @Override
+ public Object getValue(ELContext context) {
+ FacesContext facesContext = getFacesContext(context);
+
+ ConfigurationService configurationService =
ServiceTracker.getService(ConfigurationService.class);
+
+ return configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinning) ||
+ configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinningClasses);
+ }
+
+ private Object readResolve() throws ObjectStreamException {
+ return INSTANCE;
+ }
+ }
+
+ private UIComponent createComponentResource(FacesContext context) {
+ Application application = context.getApplication();
+
+ //renderkit id is not set on FacesContext at this point, so calling
+ //application.createComponent(context, componentType, rendererType) causes NPE
+ UIComponent resourceComponent =
application.createComponent(UIOutput.COMPONENT_TYPE);
+
+ String rendererType =
application.getResourceHandler().getRendererTypeForResourceName(BOTH_SKINNING);
+ resourceComponent.setRendererType(rendererType);
+
+ return resourceComponent;
+ }
+
+ @Override
+ public UIViewRoot createView(FacesContext context, String viewId) {
+ UIViewRoot viewRoot = super.createView(context, viewId);
+
+ boolean skinningResourceFound = false;
+ List<UIComponent> resources = viewRoot.getComponentResources(context,
HEAD);
+ for (UIComponent resource : resources) {
+ if (SKINNING_RESOURCE_ID.equals(resource.getId())) {
+ skinningResourceFound = true;
+ break;
+ }
+ }
+
+ if (!skinningResourceFound) {
+ //it's important for skinning resources to come *before* any
users/components stylesheet,
+ //that's why they are *always* added here
+ UIComponent basic = createComponentResource(context);
+ basic.setValueExpression("name",
SkinningResourceNameExpression.INSTANCE);
+ basic.setValueExpression("rendered",
SkinningResourceRenderedExpression.INSTANCE);
+ basic.setId(SKINNING_RESOURCE_ID);
+
+ //workaround for Mojarra: RF-8937
+ boolean initialProcessingEvents = context.isProcessingEvents();
+ context.setProcessingEvents(false);
+ viewRoot.addComponentResource(context, basic);
+ context.setProcessingEvents(initialProcessingEvents);
+ }
+
+ return viewRoot;
+ }
+}
Deleted:
branches/RF-7817/core/impl/src/main/java/org/richfaces/component/util/ComponentUtil.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/component/util/ComponentUtil.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/component/util/ComponentUtil.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,83 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.component.util;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * @author Nick Belaevski
- * mailto:nbelaevski@exadel.com
- * created 20.07.2007
- */
-public final class ComponentUtil {
- private ComponentUtil() {
- }
-
- public static String[] asArray(Object object) {
- if (object == null) {
- return null;
- }
-
- Class componentType = object.getClass().getComponentType();
-
- if (String.class.equals(componentType)) {
- return (String[]) object;
- } else if (componentType != null) {
- Object[] objects = (Object[]) object;
- String[] result = new String[objects.length];
-
- for (int i = 0; i < objects.length; i++) {
- Object o = objects[i];
-
- if (o == null) {
- continue;
- }
-
- result[i] = o.toString();
- }
-
- return result;
- } else if (object instanceof Collection) {
- Collection collection = (Collection) object;
- String[] result = new String[collection.size()];
- Iterator iterator = collection.iterator();
-
- for (int i = 0; i < result.length; i++) {
- Object next = iterator.next();
-
- if (next == null) {
- continue;
- }
-
- result[i] = next.toString();
- }
-
- return result;
- } else {
- String string = object.toString().trim();
- String[] split = string.split("\\s*,\\s*");
-
- return split;
- }
- }
-}
Deleted:
branches/RF-7817/core/impl/src/main/java/org/richfaces/context/SkinningResourcesPhaseListener.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/context/SkinningResourcesPhaseListener.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/context/SkinningResourcesPhaseListener.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,167 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.richfaces.context;
-
-import java.util.List;
-
-import javax.el.ELContext;
-import javax.faces.application.Application;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIOutput;
-import javax.faces.component.UIViewRoot;
-import javax.faces.context.FacesContext;
-import javax.faces.event.PhaseEvent;
-import javax.faces.event.PhaseId;
-import javax.faces.event.PhaseListener;
-
-import org.richfaces.application.CoreConfiguration;
-import org.richfaces.application.ServiceTracker;
-import org.richfaces.application.configuration.ConfigurationService;
-import org.richfaces.el.BaseReadOnlyValueExpression;
-
-/**
- * @author Nick Belaevski
- *
- */
-public class SkinningResourcesPhaseListener implements PhaseListener {
-
- private static final long serialVersionUID = 7430448731396547419L;
-
- private static final String SKINNING_RESOURCE_MARKER =
SkinningResourcesPhaseListener.class.getName();
-
- private static final String CLASSES_ECSS = "_classes.ecss";
-
- private static final String ECSS = ".ecss";
-
- private static final String BOTH_ECSS = "_both.ecss";
-
- private static final String CONTROLS_SKINNING;
-
- private static final String BOTH_SKINNING;
-
- private static final String CLASSES_SKINNING;
-
- private static final String HEAD = "head";
-
- static {
- String skinningName = "skinning";
-
- CONTROLS_SKINNING = skinningName + ECSS;
- BOTH_SKINNING = skinningName + BOTH_ECSS;
- CLASSES_SKINNING = skinningName + CLASSES_ECSS;
-
- }
-
- private static final class SkinningResourceNameExpression extends
BaseReadOnlyValueExpression {
-
- private static final long serialVersionUID = 7520575496522682120L;
-
- public SkinningResourceNameExpression() {
- super(String.class);
- }
-
- @Override
- public Object getValue(ELContext context) {
- FacesContext facesContext = getFacesContext(context);
-
- ConfigurationService configurationService =
ServiceTracker.getService(ConfigurationService.class);
-
- boolean controls = configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinning);
- boolean classes = configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinningClasses);
-
- if (controls && classes) {
- return BOTH_SKINNING;
- }
-
- if (classes) {
- return CLASSES_SKINNING;
- }
-
- return CONTROLS_SKINNING;
- }
-
- }
-
- private static final class SkinningResourceRenderedExpression extends
BaseReadOnlyValueExpression {
-
- private static final long serialVersionUID = -1579256471133808739L;
-
- public SkinningResourceRenderedExpression() {
- super(Boolean.TYPE);
- }
-
- @Override
- public Object getValue(ELContext context) {
- FacesContext facesContext = getFacesContext(context);
-
- ConfigurationService configurationService =
ServiceTracker.getService(ConfigurationService.class);
-
- return configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinning) ||
- configurationService.getBooleanValue(facesContext,
CoreConfiguration.Items.standardControlsSkinningClasses);
- }
-
- }
-
- private UIComponent createComponentResource(FacesContext context) {
- Application application = context.getApplication();
- String rendererType =
application.getResourceHandler().getRendererTypeForResourceName(BOTH_SKINNING);
- UIComponent resourceComponent = application.createComponent(context,
UIOutput.COMPONENT_TYPE, rendererType);
-
- return resourceComponent;
- }
-
- public void afterPhase(PhaseEvent event) {
- //not used
- }
-
- public void beforePhase(PhaseEvent event) {
- //it's important for skinning resources to come *before* any users/components
stylesheet,
- //that's why they are added via phase listener
-
- FacesContext context = event.getFacesContext();
- UIViewRoot viewRoot = context.getViewRoot();
-
- assert viewRoot != null;
-
- boolean skinnigResourceFound = false;
- List<UIComponent> resources = viewRoot.getComponentResources(context,
HEAD);
- for (UIComponent resource : resources) {
- if (resource.getAttributes().get(SKINNING_RESOURCE_MARKER) != null) {
- skinnigResourceFound = true;
- break;
- }
- }
-
- if (!skinnigResourceFound) {
- UIComponent basic = createComponentResource(context);
- basic.setValueExpression("name", new
SkinningResourceNameExpression());
- basic.setValueExpression("rendered", new
SkinningResourceRenderedExpression());
- basic.getAttributes().put(SKINNING_RESOURCE_MARKER, Boolean.TRUE);
-
- viewRoot.addComponentResource(context, basic);
- }
- }
-
- public PhaseId getPhaseId() {
- return PhaseId.RENDER_RESPONSE;
- }
-}
Modified:
branches/RF-7817/core/impl/src/main/java/org/richfaces/renderkit/html/CustomizeableGradient.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/renderkit/html/CustomizeableGradient.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/renderkit/html/CustomizeableGradient.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -47,7 +47,7 @@
* created 02.02.2007
*/
@DynamicResource
-public class CustomizeableGradient extends Java2Dresource {
+public abstract class CustomizeableGradient extends Java2Dresource {
private static final String BASE_COLOR = "baseColor";
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DAnimatedUserResourceWrapperImpl.java
(from rev 19674,
trunk/core/impl/src/main/java/org/richfaces/resource/Java2DAnimatedUserResourceWrapperImpl.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DAnimatedUserResourceWrapperImpl.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DAnimatedUserResourceWrapperImpl.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,161 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.resource;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Iterator;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.stream.ImageOutputStream;
+
+import org.w3c.dom.Node;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class Java2DAnimatedUserResourceWrapperImpl extends Java2DUserResourceWrapperImpl
{
+
+ public Java2DAnimatedUserResourceWrapperImpl(Java2DAnimatedUserResource
resourceObject) {
+ super(resourceObject);
+ }
+
+ private static ImageWriter getSequenceCapableImageWriter(ImageType imageType) {
+ Iterator<ImageWriter> imageWriters =
ImageIO.getImageWritersByFormatName(imageType.getFormatName());
+
+ while (imageWriters.hasNext()) {
+ ImageWriter imageWriter = imageWriters.next();
+
+ if (imageWriter.canWriteSequence()) {
+ return imageWriter;
+ }
+ }
+
+ throw new IllegalArgumentException(MessageFormat.format("Cannot find
sequence-capable image writer for {0} format",
+ imageType.getFormatName()));
+ }
+
+ private static Node getOrCreateChild(Node root, String name) {
+ Node result = null;
+
+ for (Node node = root.getFirstChild(); (node != null) && (result ==
null); node = node.getNextSibling()) {
+ if (name.equals(node.getNodeName())) {
+ result = node;
+ }
+ }
+
+ if (result == null) {
+ result = new IIOMetadataNode(name);
+ root.appendChild(result);
+ }
+
+ return result;
+ }
+
+ private static void checkSupportedFormat(ImageType imageType) {
+ if (imageType != ImageType.GIF) {
+ throw new IllegalArgumentException(MessageFormat.format("Image format
{0} is not supported", imageType.getFormatName()));
+ }
+ }
+
+ @Override
+ public String getRequestPath() {
+ //detect unsupported types early
+ checkSupportedFormat(getWrapped().getImageType());
+ return super.getRequestPath();
+ }
+
+ @Override
+ protected void paintAndWrite(ImageOutputStream outputStream) throws IOException {
+ Java2DAnimatedUserResource userResource = (Java2DAnimatedUserResource)
getWrapped();
+
+ ImageType imageType = userResource.getImageType();
+ checkSupportedFormat(imageType);
+ ImageWriter imageWriter = getSequenceCapableImageWriter(imageType);
+ Dimension dimension = userResource.getDimension();
+ BufferedImage image = imageType.createImage(dimension);
+
+ try {
+ imageWriter.setOutput(outputStream);
+
+ ImageWriteParam defaultImageWriteParam = imageWriter.getDefaultWriteParam();
+ IIOMetadata imageMetaData =
imageWriter.getDefaultImageMetadata(ImageTypeSpecifier.createFromBufferedImageType(
+ BufferedImage.TYPE_INT_RGB),
+ defaultImageWriteParam);
+ String metaFormatName = imageMetaData.getNativeMetadataFormatName();
+ Node root = imageMetaData.getAsTree(metaFormatName);
+ IIOMetadataNode graphicsControlExtensionNode = (IIOMetadataNode)
getOrCreateChild(root, "GraphicControlExtension");
+
+ //
http://java.sun.com/javase/6/docs/api/javax/imageio/metadata/doc-files/gi...
+ graphicsControlExtensionNode.setAttribute("disposalMethod",
"none");
+ graphicsControlExtensionNode.setAttribute("userInputFlag",
"FALSE");
+ graphicsControlExtensionNode.setAttribute("transparentColorFlag",
"FALSE");
+ graphicsControlExtensionNode.setAttribute("delayTime",
Integer.toString(userResource.getFrameDelay() / 100));
+ graphicsControlExtensionNode.setAttribute("transparentColorIndex",
"0");
+
+ Node applicationExtensionsNode = getOrCreateChild(root,
"ApplicationExtensions");
+ IIOMetadataNode netscapeExtension = new
IIOMetadataNode("ApplicationExtension");
+
+ netscapeExtension.setAttribute("applicationID",
"NETSCAPE");
+ netscapeExtension.setAttribute("authenticationCode",
"2.0");
+
+ byte numLoops = (byte) (userResource.isLooped() ? 0x0 : 0x1);
+
+ netscapeExtension.setUserObject(new byte[]{0x1, numLoops, 0x0});
+ applicationExtensionsNode.appendChild(netscapeExtension);
+ imageMetaData.setFromTree(metaFormatName, root);
+
+ imageWriter.prepareWriteSequence(null);
+
+ userResource.startFramesSequence();
+
+ while (userResource.hasNextFrame()) {
+ Graphics2D g2d = null;
+ try {
+ g2d = createGraphics(image);
+ userResource.paint(g2d, dimension);
+ imageWriter.writeToSequence(new IIOImage(image, null,
imageMetaData),
+ defaultImageWriteParam);
+ } finally {
+ if (g2d != null) {
+ g2d.dispose();
+ }
+ }
+ }
+
+ imageWriter.endWriteSequence();
+ } finally {
+ imageWriter.dispose();
+ }
+ }
+
+}
Modified:
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DUserResourceWrapperImpl.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DUserResourceWrapperImpl.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/Java2DUserResourceWrapperImpl.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -34,6 +34,7 @@
import javax.faces.context.FacesContext;
import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
import org.ajax4jsf.util.HtmlColor;
import org.richfaces.renderkit.util.HtmlDimensions;
@@ -52,54 +53,33 @@
}
public InputStream getInputStream() throws IOException {
- Java2DUserResource j2DUserResource = getWrapped();
- Dimension dimension = j2DUserResource.getDimension();
- int width = dimension.width;
- int height = dimension.height;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- ImageType imageType = j2DUserResource.getImageType();
-
- if ((width > 0) && (height > 0)) {
- BufferedImage image = imageType.createImage(width, height);
- Graphics2D g2d = image.createGraphics();
-
- try {
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
- g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
-
- g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
- RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
- g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
- g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
-
- j2DUserResource.paint(g2d, dimension);
- } finally {
- g2d.dispose();
- }
-
- try {
- ImageIO.write(image, imageType.getFormatName(), baos);
- } finally {
+ ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(baos);
+ try {
+ paintAndWrite(imageOutputStream);
+ } finally {
+ if (imageOutputStream != null) {
try {
- baos.close();
+ imageOutputStream.close();
} catch (IOException e) {
-
- // TODO Auto-generated catch block
+ // TODO: handle exception
e.printStackTrace();
}
}
}
-
return new ByteArrayInputStream(baos.toByteArray());
}
+ protected void write(BufferedImage image, String formatName, ImageOutputStream
imageOutputStream) throws IOException {
+ ImageIO.write(image, formatName, imageOutputStream);
+ }
+
public String getContentType() {
return getWrapped().getImageType().getMimeType();
}
protected String getValueParameter(FacesContext context, String name) {
- SkinFactory skinFactory = SkinFactory.getInstance();
+ SkinFactory skinFactory = SkinFactory.getInstance(context);
Skin skin = skinFactory.getSkin(context);
String value = (String) skin.getParameter(context, name);
@@ -115,16 +95,16 @@
protected Integer getColorValueParameter(FacesContext context, String name, boolean
useDefault) {
Skin skin;
if (useDefault) {
- skin = SkinFactory.getInstance().getDefaultSkin(context);
+ skin = SkinFactory.getInstance(context).getDefaultSkin(context);
} else {
- skin = SkinFactory.getInstance().getSkin(context);
+ skin = SkinFactory.getInstance(context).getSkin(context);
}
return decodeColor((String) skin.getParameter(context, name));
}
protected Integer getHeight(FacesContext context, String heightParamName) {
- SkinFactory skinFactory = SkinFactory.getInstance();
+ SkinFactory skinFactory = SkinFactory.getInstance(context);
Skin skin = skinFactory.getSkin(context);
String height = (String) skin.getParameter(context, heightParamName);
@@ -157,4 +137,33 @@
protected Date getLastModified(FacesContext context) {
return getWrapped().getLastModified();
}
+
+ protected void paintAndWrite(ImageOutputStream outputStream) throws IOException {
+ Java2DUserResource resource = getWrapped();
+ ImageType imageType = resource.getImageType();
+
+ BufferedImage image = imageType.createImage(resource.getDimension());
+ Graphics2D g2d = null;
+ try {
+ g2d = createGraphics(image);
+ resource.paint(g2d, new Dimension(image.getWidth(), image.getHeight()));
+ ImageIO.write(image, imageType.getFormatName(), outputStream);
+ } finally {
+ if (g2d != null) {
+ g2d.dispose();
+ }
+ }
+ }
+
+ protected Graphics2D createGraphics(BufferedImage image) {
+ Graphics2D g2d = image.createGraphics();
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
+
+ g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
+ RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
+ g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+ g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
+ return g2d;
+ }
}
Modified:
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/resource/ResourceFactoryImpl.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -260,7 +260,11 @@
if (legitimateResource) {
Object wrappedResource;
- if (Java2DUserResource.class.isAssignableFrom(loadedClass)) {
+ if (Java2DAnimatedUserResource.class.isAssignableFrom(loadedClass))
{
+ Java2DAnimatedUserResource java2DAnimatedUserResource =
(Java2DAnimatedUserResource) loadedClass.newInstance();
+ wrappedResource = java2DAnimatedUserResource;
+ resource = new
Java2DAnimatedUserResourceWrapperImpl(java2DAnimatedUserResource);
+ } else if (Java2DUserResource.class.isAssignableFrom(loadedClass)) {
Java2DUserResource java2DUserResource = (Java2DUserResource)
loadedClass.newInstance();
wrappedResource = java2DUserResource;
resource = new
Java2DUserResourceWrapperImpl(java2DUserResource);
Copied:
branches/RF-7817/core/impl/src/main/resources/META-INF/global-resources.faces-config.xml
(from rev 19674,
trunk/core/impl/src/main/resources/META-INF/global-resources.faces-config.xml)
===================================================================
---
branches/RF-7817/core/impl/src/main/resources/META-INF/global-resources.faces-config.xml
(rev 0)
+++
branches/RF-7817/core/impl/src/main/resources/META-INF/global-resources.faces-config.xml 2010-10-27
14:23:10 UTC (rev 19684)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
version="2.0">
+ <name>richfaces</name>
+
+ <application>
+
<view-handler>org.richfaces.application.GlobalResourcesViewHandler</view-handler>
+ </application>
+
+</faces-config>
\ No newline at end of file
Modified:
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/jquery.position.js
===================================================================
---
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/jquery.position.js 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/jquery.position.js 2010-10-27
14:23:10 UTC (rev 19684)
@@ -67,7 +67,7 @@
var stype = typeof source;
if (stype == "object" || stype == "string") {
var rect = {};
- if (stype == "string" || source.nodeType || source instanceof jQuery) {
+ if (stype == "string" || source.nodeType || source instanceof jQuery ||
typeof source.length!="undefined") {
rect = getElementRect(source);
} else if (source.type) {
rect = getPointerRect(source);
@@ -135,7 +135,49 @@
function getElementRect (element) {
var jqe = $(element);
var offset = jqe.offset();
- return {width: jqe.width(), height: jqe.height(), left: Math.floor(offset.left), top:
Math.floor(offset.top)};
+ var rect = {width: jqe.outerWidth(), height: jqe.outerHeight(), left:
Math.floor(offset.left), top: Math.floor(offset.top)};
+ if (jqe.length>1) {
+ var width, height, offset;
+ var e;
+ for (var i=1;i<jqe.length;i++) {
+ e = jqe.eq(i);
+ if (e.css('display')=="none") continue;
+ width = e.outerWidth();
+ height = e.outerHeight();
+ offset = e.offset();
+ var d = rect.left - offset.left;
+ if (d<0) {
+ rect.width = (width > rect.width) ? width : rect.width - d;
+ } else {
+ if (d + width > rect.width) rect.width = d + width;
+ }
+ var d = rect.top - offset.top;
+ if (d<0) {
+ rect.height = (height > rect.height) ? height : rect.height - d;
+ } else {
+ if (d + height > rect.height) rect.height = d + height;
+ }
+ if (offset.left < rect.left) rect.left = offset.left;
+ if (offset.top < rect.top) rect.top = offset.top;
+ }
+ }
+
+ return rect;
+ /*
+ var jqe = $(element);
+ var offset = jqe.offset();
+ var width = jqe.width();
+ var height = jqe.height();
+ if (width == 0 && height==0) {
+ //TODO: create getComputedStyle function for this
+ var e = jqe.get(0);
+ if (e.currentStyle) {
+ width = parseInt(e.currentStyle['width'],10) || 0;
+ height = parseInt(e.currentStyle['height'],10) || 0;
+ }
+ }
+ return {width: width, height: height, left: Math.floor(offset.left), top:
Math.floor(offset.top)};
+ */
};
function checkCollision (elementRect, windowRect) {
@@ -147,9 +189,10 @@
return 0;
// return collision squire
var rect = {left: (elementRect.left>windowRect.left ? elementRect.left :
windowRect.left),
- top: (elementRect.top>windowRect.top ? elementRect.top : windowRect.top),
- right: (elementRect.right<windowRect.right ? elementRect.right :
windowRect.right),
- bottom: (elementRect.bottom<windowRect.bottom ? elementRect.bottom :
windowRect.bottom)};
+ top: (elementRect.top>windowRect.top ? elementRect.top : windowRect.top)};
+ rect.right = elementRect.right<windowRect.right ?
(elementRect.right==elementRect.left ? rect.left : elementRect.right) : windowRect.right;
+ rect.bottom = elementRect.bottom<windowRect.bottom ?
(elementRect.bottom==elementRect.top ? rect.top : elementRect.bottom) :
windowRect.bottom;
+
return (rect.right-rect.left) * (rect.bottom-rect.top);
};
Modified:
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js
===================================================================
---
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js 2010-10-27
14:23:10 UTC (rev 19684)
@@ -19,6 +19,13 @@
richfaces.MyComponent = function(componentId, [options]) {
// call constructor of parent class
$super.constructor.call(this, componentId, [options]);
+
+ <span style="color:red">
+ // call this.attachToDom method to attach component to dom element
+ // its required for the client side API calls and to clean up after ajax request or
page unload:
+ // destroy method will be called if component attached to dom
+ this.attachToDom(componentId);
+ </span>
};
// define private method
@@ -35,7 +42,14 @@
$.extend(richfaces.MyComponent.prototype, (function (params) {
return {
name:"MyComponent",
- f:function (){alert("hello");
+ f:function (){alert("hello"),
+ // destroy method definition for clean up
+ destroy: function () {
+ // clean up code here
+
+ // call parent's destroy method
+ $super.destroy.call(this);
+ }
}
};
})(params));
@@ -50,6 +64,7 @@
* */
richfaces.BaseComponent = function(componentId) {
this.id = componentId;
+ this.options = {};
};
var $p = {};
@@ -149,7 +164,7 @@
$.extend(DerivedClass.prototype, methods);
return DerivedClass;
- },
+ };
$.extend(richfaces.BaseComponent.prototype, (function (params) {
return {
@@ -160,7 +175,7 @@
* @type String
* */
name: "BaseComponent",
-
+
/**
* Method for converting object to string
*
@@ -177,6 +192,13 @@
result[result.length] = this.name;
return result.join(', ');
},
+
+ /** TODO: add jsdocs and qunit tests
+ *
+ */
+ getValue: function() {
+ return;
+ },
/**
* Method returns element's id for event handlers binding.
@@ -193,6 +215,8 @@
/**
* Attach component object to DOM element by component id, DOM element or jQuery
object and returns the element
+ * Its required for the client side API calls and to clean up after ajax request or
document unload by
+ * calling destroy method
*
* @function
* @name RichFaces.BaseComponent#attachToDom
@@ -223,7 +247,45 @@
var element = richfaces.getDomElement(source);
element && element.richfaces && (element.richfaces.component=null);
},
+
+ /** TODO: add jsdocs and qunit tests
+ *
+ */
+ invokeEvent: function(eventType, element, event, data) {
+ var handlerResult, result;
+ var eventObj = $.extend({}, event, {type: eventType});
+ if (!eventObj)
+ {
+ if( document.createEventObject )
+ {
+ eventObj = document.createEventObject();
+ eventObj.type = eventType;
+ }
+ else if( document.createEvent )
+ {
+ eventObj = document.createEvent('Events');
+ eventObj.initEvent( eventType, true, false );
+ }
+ }
+ eventObj[richfaces.RICH_CONTAINER] = {component:this, data: data};
+
+ var eventHandler = this.options['on'+eventType];
+
+ if (typeof eventHandler == "function")
+ {
+ handlerResult = eventHandler.call(element, eventObj);
+ }
+
+ if (richfaces.Event) {
+ result = richfaces.Event.callHandler(this, eventType, data);
+ }
+
+ if (result!=false && handlerResult!=false) result=true;
+
+ return result;
+ },
+
/**
* Destroy method. Will be called before remove component from the page
*
Modified:
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-event.js
===================================================================
---
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-event.js 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces-event.js 2010-10-27
14:23:10 UTC (rev 19684)
@@ -191,6 +191,25 @@
return $(document.getElementById(id)).unbind(eventType, fn);
},
+ // TODO add jsdocs and qunits
+ bindScrollEventHandlers: function(element, handler, component) {
+ var elements = [];
+ element = richfaces.getDomElement(element).parentNode;
+ while (element && element!=window.document.body)
+ {
+ if (element.offsetWidth!=element.scrollWidth ||
element.offsetHeight!=element.scrollHeight)
+ {
+ elements.push(element);
+ richfaces.Event.bind(element, "scroll"+component.getNamespace(), handler,
component);
+ }
+ element = element.parentNode;
+ }
+ return elements;
+ },
+ unbindScrollEventHandlers: function(elements, component) {
+ richfaces.Event.unbind(elements, "scroll"+component.getNamespace());
+ },
+
/**
* Execute all handlers and behaviors attached to the matched elements for the given
event type.
* @function
Modified: branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces.js
===================================================================
---
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces.js 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/resources/META-INF/resources/richfaces.js 2010-10-27
14:23:10 UTC (rev 19684)
@@ -41,6 +41,17 @@
return (element["richfaces"] || {})["component"];
}
}
+
+ richfaces.$$ = function(componentName, element)
+ {
+ while (element.parentNode) {
+ var e = element[richfaces.RICH_CONTAINER];
+ if (e && e.component && e.component.name==componentName)
+ return e.component;
+ else
+ element = element.parentNode;
+ }
+ }
// find component and call his method
richfaces.invokeMethod = function(source, method) {
Deleted:
branches/RF-7817/core/impl/src/main/resources/META-INF/skinning-resources-listener.faces-config.xml
===================================================================
---
branches/RF-7817/core/impl/src/main/resources/META-INF/skinning-resources-listener.faces-config.xml 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/main/resources/META-INF/skinning-resources-listener.faces-config.xml 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
version="2.0">
- <name>richfaces</name>
- <lifecycle>
- <phase-listener>org.richfaces.context.SkinningResourcesPhaseListener</phase-listener>
- </lifecycle>
-</faces-config>
\ No newline at end of file
Deleted:
branches/RF-7817/core/impl/src/test/java/org/richfaces/component/util/ComponentUtilTest.java
===================================================================
---
branches/RF-7817/core/impl/src/test/java/org/richfaces/component/util/ComponentUtilTest.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/test/java/org/richfaces/component/util/ComponentUtilTest.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -1,93 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-package org.richfaces.component.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.TreeSet;
-
-import junit.framework.TestCase;
-
-/**
- * @author Nick Belaevski
- * mailto:nbelaevski@exadel.com
- * created 20.07.2007
- *
- */
-public class ComponentUtilTest extends TestCase {
- public void testAsArray() {
- assertNull(ComponentUtil.asArray(null));
- }
-
- public void testAsArray1() {
- String[] strings = new String[] {"a", "b"};
- String[] array = ComponentUtil.asArray(strings);
-
- assertSame(strings, array);
- }
-
- public void testAsArray2() {
- Object[] objects = new Object[] {Integer.valueOf(12), null, Integer.valueOf(22),
Integer.valueOf(42)};
- String[] array = ComponentUtil.asArray(objects);
- String[] etalon = new String[] {"12", null, "22",
"42"};
-
- assertTrue(Arrays.equals(etalon, array));
- }
-
- public void testAsArray3() {
- ArrayList list = new ArrayList();
-
- list.add(new Integer(12));
- list.add(null);
- list.add(new Integer(22));
- list.add(new Integer(42));
-
- String[] array = ComponentUtil.asArray(list);
- String[] etalon = new String[] {"12", null, "22",
"42"};
-
- assertTrue(Arrays.equals(etalon, array));
- }
-
- public void testAsArray31() {
- Set set = new TreeSet();
-
- set.add(new Integer(12));
- set.add(new Integer(22));
- set.add(new Integer(42));
-
- String[] array = ComponentUtil.asArray(set);
- String[] etalon = new String[] {"12", "22", "42"};
-
- assertTrue(Arrays.equals(etalon, array));
- }
-
- public void testAsArray4() {
- String string = " a , \t\n b \n , c ";
- String[] strings = ComponentUtil.asArray(string);
- String[] etalon = new String[] {"a", "b", "c"};
-
- assertTrue(Arrays.equals(etalon, strings));
- }
-}
Modified:
branches/RF-7817/core/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java
===================================================================
---
branches/RF-7817/core/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java 2010-10-27
12:23:39 UTC (rev 19683)
+++
branches/RF-7817/core/impl/src/test/java/org/richfaces/resource/CachedResourceImplTest.java 2010-10-27
14:23:10 UTC (rev 19684)
@@ -84,7 +84,8 @@
}
private CachedResourceImpl createCachedResource(Map<String, String> headers,
InputStream stream)
- throws IOException {
+ throws IOException {
+
MockHeadersResourceImpl mockResource = new MockHeadersResourceImpl(headers,
stream);
CachedResourceImpl cachedResource = new MockCachedResourceImpl();
Modified: branches/RF-7817/core/parent/pom.xml
===================================================================
--- branches/RF-7817/core/parent/pom.xml 2010-10-27 12:23:39 UTC (rev 19683)
+++ branches/RF-7817/core/parent/pom.xml 2010-10-27 14:23:10 UTC (rev 19684)
@@ -45,14 +45,6 @@
</dependencies>
</dependencyManagement>
- <build>
- <plugins>
- <!-- Trigger checkstyle checking for this module -->
- <plugin>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
<scm>
<
connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/trunk/core...
<
developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/trun...
Modified: branches/RF-7817/core/pom.xml
===================================================================
--- branches/RF-7817/core/pom.xml 2010-10-27 12:23:39 UTC (rev 19683)
+++ branches/RF-7817/core/pom.xml 2010-10-27 14:23:10 UTC (rev 19684)
@@ -24,7 +24,7 @@
<groupId>org.richfaces</groupId>
<artifactId>richfaces-parent</artifactId>
<version>10</version>
-<relativePath>../build/parent/pom.xml</relativePath>
+ <relativePath>../build/parent/pom.xml</relativePath>
</parent>
<groupId>org.richfaces.core</groupId>