This commit was manufactured by cvs2svn to create branch

'refactor_scripting_04_02'.
This commit is contained in:
hns 2002-04-05 17:09:26 +00:00
parent ca66d7ba90
commit 9ecef6e720
230 changed files with 0 additions and 43959 deletions

View file

@ -1,93 +0,0 @@
This is the README file for version 1.2 of Helma Object Publisher.
============================
ABOUT HELMA OBJECT PUBLISHER
============================
Helma Object Publisher is a web application server.
With Helma Object Publisher (sometimes simply refered to as Helma or
Hop) you can define Objects and map them to a relational database
table. These so-called HopObjects can be created, modified and deleted
using a comfortable object/container model. Hence, no manual fiddling
around with database code is necessary.
HopObjects are extended JavaScript objects which can be scripted using
server-side JavaScript. Beyond the common JavaScript features, Helma
provides special "skin" and template functionalities which facilitate
the rendering of objects via a web interface.
Thanks to Helma's relational database mapping technology, HopObjects
create a hierarchical structure, the Url space of a Helma site. The
parts between slashes in a Helma Url represent HopObjects (similar to
the document tree in static sites). The Helma Url space can be thought
of as an analogy to the Document Object Model (Dom) in client-side
JavaScript.
===================
SYSTEM REQUIREMENTS
===================
Windows: 1) On Windows Helma won't run with Microsoft's version of
Java (jview). You can get a compatible Java runtime from Sun or IBM:
http://java.sun.com/j2se/1.3/jre/download-windows.html
http://www.ibm.com/java/jdk/download/ 2) In the Windows start script
I've hardcoded c:\java\lib\classes.zip in the CLASSPATH argument. Not
good.
Macintosh: 1) If you are using the Mac version you should own a G3 CPU
and/or have MRJ 2.2 (http://www.apple.com/java) installed. Other
platforms have less frustration potential. The Mac OS version
currently is not up-to-date (version 0.1).
Linux: The recomended virtual machine for running Helma on Linux is
Blackdown's port of JDK 1.2.2 RC4
(http://www.blackdown.org/java-linux/mirrors.html). JDK 1.1.7v3 will
work, but much slower and show a lot of CPU activity even when the
Helma is idle. IBM's version of JDK 1.1.8 also works well, but this
JVM has some problems of its own with thread handling.
============================
INSTALLING AND RUNNING HELMA
============================
Simply unzip the contents of the archive file into any place on your
hard disk. Start Helma by opening the file hop.bat or hop.sh,
respectively.
If you manage to get it running you should be able to connect your
browser to http://127.0.0.1:8080/ (port 8080, that is).
This version is set up to use its own embedded Web server and a very
basic embedded object database. For this reason it is able to run
virtually without installation on any platform with a Java 1.1 virtual
machine.
On the other hand, the embedded Web server and object db are meant for
development work and not ready for prime time deployment. For that
you'd probably use an external relational database, the Berkeley DB
package and a full featured Web server like Apache.
=====================================
DOCUMENTATION AND FURTHER INFORMATION
=====================================
Currently, a documentation-in-progress is available online only.
Please refer to http://helma.org/docs/.
For further information http://helma.org generally is a good place.
There is also a mailing-list about Helma-related stuff available at
http://helma.org/lists/listinfo/hop.
For questions, comments or suggestions feel free to contact
tobi@helma.at.
--
This document was last modified on Friday 22 June 2001 by
tobi@helma.at

View file

@ -1,9 +0,0 @@
# List of apps to start.
base=self
manage=self
bloggerapi
himp
lillebror
hopblog

View file

@ -1,67 +0,0 @@
This is the README file for the Helma build files as part of the Helma Object Publisher. It is included in the current distribution (version 1.2pre as of 8 November 2001) downloadable at <http://helma.org/download>.
The build directory consists of the following files:
ant.jar
build.bat
build.sh
build.xml
crimson.jar
jaxp.jar
README
PREREQUISITES
=============
The Helma build script is using a software called Ant. Ant is a build system that was developed for the Jakarta Tomcat project. For more information about Ant, see <http://jakarta.apache.org/ant/>.
To run Ant, you also need JDK 1.3 or higher <http://java.sun.com/j2se/>.
For checking out the source files from Helma's CVS you also need a local installation of a CVS command-line client. More information about CVS at <http://www.cvshome.org/>.
STARTING BUILD
==============
The build system is started by invoking the shell script appropriate to your platform, ie. build.sh for *nix (Linux, NetBSD etc.) and build.bat for Windows systems.
The generic syntax is
./build target
The parameter "target" specifies one of the following build targets.
BUILD TARGETS
=============
checkout
Fetches (or updates, resp.) the Helma source files from the CVS and copies them into the src/ directory (which will be created if necessary).
compile
Compiles the source files contained in the src/ directory into the class/ directory (which will be created if necessary).
jar
Stuffs the files in class/ together and saves them as .jar archive in the build directory. The file is named helma-yyyymmdd.jar.
javadoc
Creates the Java API documentation for the Helma classes. The resulting files are saved into the docs/apidocs/ directory (which will be created if necessary).
package
Builds all previous targets (checkout, compile, jar, javadoc) and saves the created files in the directory helma-1.x/ (with 1.x being the version number). All directories will be created if necessary.
package-zip
Same as "package". Additionally, the files in the output directory will be compressed as .zip file.
package-tgz
Same as "package". Additionall, the file in the output directory will be compressed as .tar.gz file.
package-all
Builds all previous targets. The result is a complete and up-to-date (as in the CVS) installation of Helma, the API documentation, source and build files as well as compressed packages for *nix and Windows systems including all the files.
--
This README was last updated on 8 November 2001 by tobi@helma.org.

Binary file not shown.

View file

@ -1,93 +0,0 @@
This is the README file for version 1.2 of Helma Object Publisher.
============================
ABOUT HELMA OBJECT PUBLISHER
============================
Helma Object Publisher is a web application server.
With Helma Object Publisher (sometimes simply refered to as Helma or
Hop) you can define Objects and map them to a relational database
table. These so-called HopObjects can be created, modified and deleted
using a comfortable object/container model. Hence, no manual fiddling
around with database code is necessary.
HopObjects are extended JavaScript objects which can be scripted using
server-side JavaScript. Beyond the common JavaScript features, Helma
provides special "skin" and template functionalities which facilitate
the rendering of objects via a web interface.
Thanks to Helma's relational database mapping technology, HopObjects
create a hierarchical structure, the Url space of a Helma site. The
parts between slashes in a Helma Url represent HopObjects (similar to
the document tree in static sites). The Helma Url space can be thought
of as an analogy to the Document Object Model (Dom) in client-side
JavaScript.
===================
SYSTEM REQUIREMENTS
===================
Windows: 1) On Windows Helma won't run with Microsoft's version of
Java (jview). You can get a compatible Java runtime from Sun or IBM:
http://java.sun.com/j2se/1.3/jre/download-windows.html
http://www.ibm.com/java/jdk/download/ 2) In the Windows start script
I've hardcoded c:\java\lib\classes.zip in the CLASSPATH argument. Not
good.
Macintosh: 1) If you are using the Mac version you should own a G3 CPU
and/or have MRJ 2.2 (http://www.apple.com/java) installed. Other
platforms have less frustration potential. The Mac OS version
currently is not up-to-date (version 0.1).
Linux: The recomended virtual machine for running Helma on Linux is
Blackdown's port of JDK 1.2.2 RC4
(http://www.blackdown.org/java-linux/mirrors.html). JDK 1.1.7v3 will
work, but much slower and show a lot of CPU activity even when the
Helma is idle. IBM's version of JDK 1.1.8 also works well, but this
JVM has some problems of its own with thread handling.
============================
INSTALLING AND RUNNING HELMA
============================
Simply unzip the contents of the archive file into any place on your
hard disk. Start Helma by opening the file hop.bat or hop.sh,
respectively.
If you manage to get it running you should be able to connect your
browser to http://127.0.0.1:8080/ (port 8080, that is).
This version is set up to use its own embedded Web server and a very
basic embedded object database. For this reason it is able to run
virtually without installation on any platform with a Java 1.1 virtual
machine.
On the other hand, the embedded Web server and object db are meant for
development work and not ready for prime time deployment. For that
you'd probably use an external relational database, the Berkeley DB
package and a full featured Web server like Apache.
=====================================
DOCUMENTATION AND FURTHER INFORMATION
=====================================
Currently, a documentation-in-progress is available online only.
Please refer to http://helma.org/docs/.
For further information http://helma.org generally is a good place.
There is also a mailing-list about Helma-related stuff available at
http://helma.org/lists/listinfo/hop.
For questions, comments or suggestions feel free to contact
tobi@helma.at.
--
This document was last modified on Friday 22 June 2001 by
tobi@helma.at

View file

@ -1,16 +0,0 @@
# This is where you specify relational data sources to
# map Helma types to relational databases.
#
# If you want to define a data source just for one
# application, simply copy the db.properties file to
# the application directory.
#
# The actual mapping of types is done in the
# type.properties file in the prototype directories.
#
# Properties of JDBC data sources
myDataSource.url = jdbc:mysql://db.domain.com/space
myDataSource.driver = org.gjt.mm.mysql.Driver
myDataSource.user = username
myDataSource.password = xyz

View file

@ -1,50 +0,0 @@
Copyright (c) 1999-2001 Helma Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The end-user documentation included with the redistribution,
if any, must include the following acknowledgment:
"This product includes software developed by the Helma Project
for use in the Helma Object Publisher (http://www.helma.org/)."
Alternately, this acknowledgment may appear in the software itself,
if and wherever such third-party acknowledgments normally appear.
4. The names "Helma" and "Hop" must not be used to endorse or
promote products derived from this software without prior written
permission. For written permission, please contact
helma@helma.org.
5. Products derived from this software may not be called "Helma"
or "Hop", nor may "Helma" or "Hop" appear in their name, without
prior written permission of the Helma Project Group.
6. We ask you to give credit to the Helma Project for sites which build
upon Helma. This would normally consist of a text or graphic link
to http://helma.org/ with the line "Powered by Helma" somewhere on the
site. While it is not a breach of this license to omit this, it's a
great way for you to make help the Helma Project to continue
to flourish and grow.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE HELMA PROJECT OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,33 +0,0 @@
# The SMTP server to use for sending mails. Set and
# uncomment this line before trying to send mails from
# Helma applications.
#
# smtp=mail.yourdomain.com
# Some examples for server-wide locale settings
# (please refer to http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
# for country codes, resp. http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
# for language codes).
#
# country = AT
# language = de
#
# country = UK
# language = en
#
# country = FR
# language = fr
#
# country = CZ
# language = cs
# list ip addresses for admin-application here:
allowAdmin=127.0.0.1, 192.168.0.1
# md5-encrypted username and password for admin-app
# the default is test/test
adminUsername=098f6bcd4621d373cade4e832627b4f6
adminPassword=098f6bcd4621d373cade4e832627b4f6

View file

@ -1,47 +0,0 @@
@echo off
REM --------------------------------------------
REM Defualt == jar
REM "checkout" target gets sources from helma.org
REM "compile" target compiles java sources
REM "jar" target compiles and builds jar
REM "javadoc" target builds the javadoc
REM "package" target builds core + jar + javadoc + distribution
REM --------------------------------------------
set TARGET=%1%
REM --------------------------------------------
REM No need to edit anything past here
REM --------------------------------------------
set BUILDFILE=build.xml
if "%TARGET%" == "" goto setdist
goto final
:setdist
set TARGET=jar
goto final
:final
if "%JAVA_HOME%" == "" goto javahomeerror
set CP=%CLASSPATH%;ant.jar;jaxp.jar;crimson.jar
if exist %JAVA_HOME%\lib\tools.jar set CP=%CP%;%JAVA_HOME%\lib\tools.jar
echo Classpath: %CP%
echo JAVA_HOME: %JAVA_HOME%
%JAVA_HOME%\bin\java.exe -classpath "%CP%" org.apache.tools.ant.Main -buildfile %BUILDFILE% %TARGET%
goto end
REM -----------ERROR-------------
:javahomeerror
echo "ERROR: JAVA_HOME not found in your environment."
echo "Please, set the JAVA_HOME variable in your environment to match the"
echo "location of the Java Virtual Machine you want to use."
:end

View file

@ -1,49 +0,0 @@
#!/bin/sh
# --------------------------------------------
# Default == jar
# "checkout" target gets sources from helma.org
# "compile" target compiles java sources
# "jar" target compiles and builds jar
# "javadoc" target builds the javadoc
# "package" target builds core + jar + javadoc + distribution
# --------------------------------------------
TARGET=${1}
# export JAVA_HOME=/usr/lib/java
export CVSHOME=:pserver:anonymous@coletta.helma.at:/opt/cvs
# comment this out to log in to CVS server
# cvs -d :pserver:anonymous@coletta.helma.at:/opt/cvs login
#--------------------------------------------
# No need to edit anything past here
#--------------------------------------------
if test -z "${JAVA_HOME}" ; then
echo "ERROR: JAVA_HOME not found in your environment."
echo "Please, set the JAVA_HOME variable in your environment to match the"
echo "location of the Java Virtual Machine you want to use."
exit
fi
if test -z "${TARGET}" ; then
TARGET=jar
fi
if test -f ${JAVA_HOME}/lib/tools.jar ; then
CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar
fi
echo "Now building ${TARGET}..."
CP=${CLASSPATH}:ant.jar:jaxp.jar:crimson.jar:../lib/netcomponents.jar
echo "Classpath: ${CP}"
echo "JAVA_HOME: ${JAVA_HOME}"
BUILDFILE=build.xml
${JAVA_HOME}/bin/java -classpath ${CP} org.apache.tools.ant.Main -buildfile ${BUILDFILE} ${TARGET}

View file

@ -1,264 +0,0 @@
<?xml version="1.0"?>
<!-- ======================================================================= -->
<!-- Hop build file -->
<!-- ======================================================================= -->
<project name="Hop" default="main" basedir=".">
<!-- =================================================================== -->
<!-- Initializes some variables -->
<!-- =================================================================== -->
<target name="init">
<property name="Name" value="helma"/>
<property name="year" value="1998-2002"/>
<property name="version" value="1.2pre3"/>
<property name="project" value="helma"/>
<property name="build.compiler" value="classic"/>
<property name="build.dir" value=".."/>
<property name="build.src" value="${build.dir}/src"/>
<property name="build.dest" value="${build.dir}/classes"/>
<property name="build.work" value="${build.dir}/work"/>
<property name="build.checkout" value="${build.work}/checkout"/>
<property name="cvs.root" value=":pserver:anonymous@coletta.helma.at:/opt/cvs"/>
<property name="javadoc.destdir" value="../docs/apidocs"/>
<property name="jar.name" value="helma"/>
<property name="final.name" value="${project}-${version}"/>
<property name="final.dir" value="../${final.name}/"/>
<property name="debug" value="off"/>
<property name="optimize" value="on"/>
<property name="deprecation" value="off"/>
<tstamp/>
<filter token="year" value="${year}"/>
<filter token="version" value="${version}"/>
<filter token="date" value="${TODAY}"/>
<!-- JDK1.1 collections support -->
<property name="coll.import" value="com.sun.java.util.collections"/>
<available classname="${coll.import}.Collection" property="coll.present"/>
</target>
<!-- =================================================================== -->
<!-- Copies the source code to the build directory and does filtering -->
<!-- =================================================================== -->
<target name="checkout" depends="init">
<!-- cvspass cvsroot="${cvs.root}" password=""/ -->
<mkdir dir="${build.src}"/>
<mkdir dir="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="hop" dest="${build.checkout}"/>
<copy todir="${build.src}">
<fileset dir="${build.checkout}/hop"
includes="helma/**/*.java,FESI/**/*.java,Acme/**/*.java"/>
</copy>
<cvs cvsRoot="${cvs.root}" package="hopbuild/lib" dest="${build.checkout}"/>
<copy todir="${build.dir}/lib">
<fileset dir="${build.checkout}/hopbuild/lib"/>
</copy>
<cvs cvsRoot="${cvs.root}" package="hopbuild/skeleton" dest="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/base" dest="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/hopblog" dest="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/himp" dest="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/bloggerapi" dest="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/lillebror" dest="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/manage" dest="${build.checkout}"/>
</target>
<!-- =================================================================== -->
<!-- Does replacement on files for dealing with collections. -->
<!-- XXX The efficiency could be improved here; all replacements should -->
<!-- XXX happen during one read/write phase and only for files that have -->
<!-- XXX changed. -->
<!-- =================================================================== -->
<target name="collections" if="coll.present" depends="init">
<replace dir="${build.src}/helma" includes="**"
token="java.util.Collection" value="${coll.import}.Collection"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.Map" value="${coll.import}.Map"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.HashMap" value="${coll.import}.HashMap"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.List" value="${coll.import}.List"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.LinkedList" value="${coll.import}.LinkedList"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.ArrayList" value="${coll.import}.ArrayList"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.Set" value="${coll.import}.Set"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.HashSet" value="${coll.import}.HashSet"/>
<replace dir="${build.src}/helma" includes="**"
token="java.util.Iterator" value="${coll.import}.Iterator"/>
<!-- The following replace handles the "import java.util.*" case by -->
<!-- adding an "import com.sun.java.util.collections.*" after it. -->
<!-- BTW, \u000a is the Unicode escape for a new line. (jhunter) -->
<replace dir="${build.src}/helma/framework/core" includes="**"
token="java.util.*"
value="java.util.*;\u000aimport ${coll.import}.*"/>
<replace dir="${build.src}/helma/objectmodel" includes="**"
token="java.util.*"
value="java.util.*;\u000aimport ${coll.import}.*"/>
</target>
<!-- =================================================================== -->
<!-- Compiles the source directory -->
<!-- =================================================================== -->
<target name="compile" depends="init">
<mkdir dir="${build.dest}"/>
<javac srcdir="${build.src}"
destdir="${build.dest}"
debug="${debug}"
deprecation="${deprecation}"
optimize="${optimize}">
<classpath>
<fileset dir="${build.dir}/lib">
<exclude name="**/helma*.jar" />
<include name="**/*.jar" />
</fileset>
<pathelement path="${classpath}" />
</classpath>
</javac>
<rmic classname="helma.framework.core.Application" base="${build.dest}"/>
<rmic classname="helma.image.Server" base="${build.dest}"/>
<rmic classname="helma.image.RemoteImage" base="${build.dest}"/>
</target>
<!-- =================================================================== -->
<!-- Creates a .jar file -->
<!-- =================================================================== -->
<target name="jar" depends="compile">
<jar jarfile="${build.dir}/${jar.name}-${DSTAMP}.jar"
basedir="${build.dest}"
excludes="**/package.html"/>
</target>
<!-- =================================================================== -->
<!-- Creates the API documentation -->
<!-- =================================================================== -->
<target name="javadocs" depends="init">
<mkdir dir="${javadoc.destdir}"/>
<javadoc packagenames="helma.*"
sourcepath="${build.src}"
destdir="${javadoc.destdir}"
author="false"
private="false"
version="false"
windowtitle="${Name} ${version} API"
doctitle="${Name} ${version} API"
bottom="Copyright &#169; 1998-2001 Helma.org. All Rights Reserved."
/>
</target>
<!-- =================================================================== -->
<!-- Package -->
<!-- =================================================================== -->
<target name="package" depends="checkout, jar, javadocs">
<mkdir dir="${final.dir}"/>
<!-- mkdir dir="${final.dir}/static"/ -->
<mkdir dir="${final.dir}/src"/>
<!-- jar jarfile="${final.dir}/src/${Name}-src.jar"
basedir="${build.src}"/ -->
<copy todir="${final.dir}/src">
<fileset dir="${build.dir}/src" excludes="{Name}-src.jar"/>
</copy>
<copy todir="${final.dir}/build">
<fileset dir="${build.dir}/build"/>
</copy>
<chmod file="${final.dir}/build/build.sh" perm="755"/>
<copy todir="${final.dir}/docs">
<fileset dir="../docs"/>
</copy>
<copy todir="${final.dir}/lib">
<fileset dir="${build.checkout}/hopbuild/lib"/>
</copy>
<copy todir="${final.dir}">
<fileset dir="${build.checkout}/hopbuild/skeleton" excludes="**/CVS"/>
</copy>
<copy todir="${final.dir}/apps">
<fileset dir="${build.checkout}/apps" excludes="**/CVS,manage/**"/>
</copy>
<copy file="${build.dir}/${jar.name}-${DSTAMP}.jar" tofile="${final.dir}/lib/helma.jar"/>
<chmod file="${final.dir}/hop.sh" perm="755"/>
<mkdir dir="${final.dir}/apps/manage"/>
<zip zipfile="${final.dir}/apps/manage/manage.zip" basedir="${build.checkout}/apps/manage/" includes="**"/>
</target>
<!-- =================================================================== -->
<!-- Packages the distribution with ZIP -->
<!-- =================================================================== -->
<target name="package-zip" depends="package">
<zip zipfile="../${Name}-${version}.zip" basedir="../" includes="**/${final.name}/**"/>
</target>
<!-- =================================================================== -->
<!-- Packages the distribution with TAR-GZIP -->
<!-- =================================================================== -->
<target name="package-tgz" depends="package">
<tar tarfile="../${Name}-${version}.tar" basedir=".." excludes="**">
<tarfileset dir=".." mode="755">
<include name="${final.name}/hop.sh"/>
<include name="${final.name}/build/build.sh"/>
</tarfileset>
<tarfileset dir="..">
<include name="${final.name}/**"/>
<exclude name="${final.name}/hop.sh"/>
<exclude name="${final.name}/build/build.sh"/>
</tarfileset>
</tar>
<gzip zipfile="../${Name}-${version}.tar.gz" src="../${Name}-${version}.tar"/>
</target>
<!-- =================================================================== -->
<!-- Packages the distribution with ZIP and TAR-GZIP -->
<!-- =================================================================== -->
<target name="package-all" depends="package-zip, package-tgz">
</target>
<!-- =================================================================== -->
<!-- These are just some tests -->
<!-- =================================================================== -->
<target name="ftp-test" depends="">
<ftp server="piefke.helma.at"
userid="anonymous"
password="tobi@helma.at">
<fileset dir="${build.dir}">
<include name="${Name}-${version}.zip,${Name}-${version}.tar.gz"/>
</fileset>
</ftp>
</target>
<target name="test1" depends="init">
<mkdir dir="${build.checkout}"/>
<cvs cvsRoot="${cvs.root}" package="apps/manage" dest="${build.checkout}"/>
<zip zipfile="../manage.zip" basedir="${build.checkout}/apps/manage/" includes="**"/>
</target>
</project>

Binary file not shown.

Binary file not shown.

View file

@ -1,9 +0,0 @@
# List of apps to start.
base=self
manage=self
bloggerapi
himp
lillebror
hopblog

View file

@ -1,16 +0,0 @@
# This is where you specify relational data sources to
# map Helma types to relational databases.
#
# If you want to define a data source just for one
# application, simply copy the db.properties file to
# the application directory.
#
# The actual mapping of types is done in the
# type.properties file in the prototype directories.
#
# Properties of JDBC data sources
myDataSource.url = jdbc:mysql://db.domain.com/space
myDataSource.driver = org.gjt.mm.mysql.Driver
myDataSource.user = username
myDataSource.password = xyz

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,13 +0,0 @@
@echo off
rem Batch file for starting Hop with a JDK-like virtual machine.
set JARS=lib\helma.jar;lib\berkeley.jar;lib\village.jar;lib\jsdk.jar;lib\openxml.jar
set JARS=%JARS%;lib\sax.jar;lib\regexp.jar;lib\netcomponents.jar;lib\jimi.jar
set JARS=%JARS%;lib\mail.jar;lib\activation.jar;lib\mysql.jar;lib\jdom.jar;lib\minml.jar
set HOP_PORT=8080
echo Starting Web server on port %HOP_PORT%
java -classpath c:\winnt\java\packages\rmi.zip;%JARS% helma.main.Server -w %HOP_PORT%

View file

@ -1,11 +0,0 @@
#!/bin/sh
# Stupid shell script for starting Hop with a JDK-like virtual machine.
# Presumes that you have your classpath set.
export HOP_PORT=8080
export JARS=lib/helma.jar:lib/berkeley.jar:lib/village.jar:lib/jsdk.jar:lib/openxml.jar
export JARS=$JARS:lib/sax.jar:lib/regexp.jar:lib/netcomponents.jar:lib/jimi.jar
export JARS=$JARS:lib/mail.jar:lib/activation.jar:lib/mysql.jar:lib/jdom.jar:lib/minml.jar
java -classpath $CLASSPATH:$JARS helma.main.Server -w $HOP_PORT

View file

@ -1,50 +0,0 @@
Copyright (c) 1999-2001 Helma Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The end-user documentation included with the redistribution,
if any, must include the following acknowledgment:
"This product includes software developed by the Helma Project
for use in the Helma Object Publisher (http://www.helma.org/)."
Alternately, this acknowledgment may appear in the software itself,
if and wherever such third-party acknowledgments normally appear.
4. The names "Helma" and "Hop" must not be used to endorse or
promote products derived from this software without prior written
permission. For written permission, please contact
helma@helma.org.
5. Products derived from this software may not be called "Helma"
or "Hop", nor may "Helma" or "Hop" appear in their name, without
prior written permission of the Helma Project Group.
6. We ask you to give credit to the Helma Project for sites which build
upon Helma. This would normally consist of a text or graphic link
to http://helma.org/ with the line "Powered by Helma" somewhere on the
site. While it is not a breach of this license to omit this, it's a
great way for you to make help the Helma Project to continue
to flourish and grow.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE HELMA PROJECT OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,33 +0,0 @@
# The SMTP server to use for sending mails. Set and
# uncomment this line before trying to send mails from
# Helma applications.
#
# smtp=mail.yourdomain.com
# Some examples for server-wide locale settings
# (please refer to http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
# for country codes, resp. http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
# for language codes).
#
# country = AT
# language = de
#
# country = UK
# language = en
#
# country = FR
# language = fr
#
# country = CZ
# language = cs
# list ip addresses for admin-application here:
allowAdmin=127.0.0.1, 192.168.0.1
# md5-encrypted username and password for admin-app
# the default is test/test
adminUsername=098f6bcd4621d373cade4e832627b4f6
adminPassword=098f6bcd4621d373cade4e832627b4f6

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

View file

@ -1,16 +0,0 @@
# This is where you specify relational data sources to
# map Helma types to relational databases.
#
# If you want to define a data source just for one
# application, simply copy the db.properties file to
# the application directory.
#
# The actual mapping of types is done in the
# type.properties file in the prototype directories.
#
# Properties of JDBC data sources
myDataSource.url = jdbc:mysql://db.domain.com/space
myDataSource.driver = org.gjt.mm.mysql.Driver
myDataSource.user = username
myDataSource.password = xyz

13
hop.bat
View file

@ -1,13 +0,0 @@
@echo off
rem Batch file for starting Hop with a JDK-like virtual machine.
set JARS=lib\helma.jar;lib\berkeley.jar;lib\village.jar;lib\jsdk.jar;lib\openxml.jar
set JARS=%JARS%;lib\sax.jar;lib\regexp.jar;lib\netcomponents.jar;lib\jimi.jar
set JARS=%JARS%;lib\mail.jar;lib\activation.jar;lib\mysql.jar;lib\jdom.jar;lib\minml.jar
set HOP_PORT=8080
echo Starting Web server on port %HOP_PORT%
java -classpath c:\winnt\java\packages\rmi.zip;%JARS% helma.main.Server -w %HOP_PORT%

11
hop.sh
View file

@ -1,11 +0,0 @@
#!/bin/sh
# Stupid shell script for starting Hop with a JDK-like virtual machine.
# Presumes that you have your classpath set.
export HOP_PORT=8080
export JARS=lib/helma.jar:lib/berkeley.jar:lib/village.jar:lib/jsdk.jar:lib/openxml.jar
export JARS=$JARS:lib/sax.jar:lib/regexp.jar:lib/netcomponents.jar:lib/jimi.jar
export JARS=$JARS:lib/mail.jar:lib/activation.jar:lib/mysql.jar:lib/jdom.jar:lib/minml.jar
java -classpath $CLASSPATH:$JARS helma.main.Server -w $HOP_PORT

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,50 +0,0 @@
Copyright (c) 1999-2001 Helma Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The end-user documentation included with the redistribution,
if any, must include the following acknowledgment:
"This product includes software developed by the Helma Project
for use in the Helma Object Publisher (http://www.helma.org/)."
Alternately, this acknowledgment may appear in the software itself,
if and wherever such third-party acknowledgments normally appear.
4. The names "Helma" and "Hop" must not be used to endorse or
promote products derived from this software without prior written
permission. For written permission, please contact
helma@helma.org.
5. Products derived from this software may not be called "Helma"
or "Hop", nor may "Helma" or "Hop" appear in their name, without
prior written permission of the Helma Project Group.
6. We ask you to give credit to the Helma Project for sites which build
upon Helma. This would normally consist of a text or graphic link
to http://helma.org/ with the line "Powered by Helma" somewhere on the
site. While it is not a breach of this license to omit this, it's a
great way for you to make help the Helma Project to continue
to flourish and grow.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE HELMA PROJECT OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,33 +0,0 @@
# The SMTP server to use for sending mails. Set and
# uncomment this line before trying to send mails from
# Helma applications.
#
# smtp=mail.yourdomain.com
# Some examples for server-wide locale settings
# (please refer to http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
# for country codes, resp. http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
# for language codes).
#
# country = AT
# language = de
#
# country = UK
# language = en
#
# country = FR
# language = fr
#
# country = CZ
# language = cs
# list ip addresses for admin-application here:
allowAdmin=127.0.0.1, 192.168.0.1
# md5-encrypted username and password for admin-app
# the default is test/test
adminUsername=098f6bcd4621d373cade4e832627b4f6
adminPassword=098f6bcd4621d373cade4e832627b4f6

View file

@ -1,613 +0,0 @@
// Fmt - some simple single-arg sprintf-like routines
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
/// Some simple single-arg sprintf-like routines.
// <P>
// It is apparently impossible to declare a Java method that accepts
// variable numbers of any type of argument. You can declare it to take
// Objects, but numeric variables and constants are not in fact Objects.
// <P>
// However, using the built-in string concatenation, it's almost as
// convenient to make a series of single-argument formatting routines.
// <P>
// Fmt can format the following types:
// <BLOCKQUOTE><CODE>
// byte short int long float double char String Object
// </CODE></BLOCKQUOTE>
// For each type there is a set of overloaded methods, each returning
// a formatted String. There's the plain formatting version:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( x )
// </PRE></BLOCKQUOTE>
// There's a version specifying a minimum field width:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( x, minWidth )
// </PRE></BLOCKQUOTE>
// And there's a version that takes flags:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( x, minWidth, flags )
// </PRE></BLOCKQUOTE>
// Currently available flags are:
// <BLOCKQUOTE><PRE>
// Fmt.ZF - zero-fill
// Fmt.LJ - left justify
// Fmt.HX - hexadecimal
// Fmt.OC - octal
// </PRE></BLOCKQUOTE>
// The HX and OC flags imply unsigned output.
// <P>
// For doubles and floats, there's a significant-figures parameter before
// the flags:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( d )
// Fmt.fmt( d, minWidth )
// Fmt.fmt( d, minWidth, sigFigs )
// Fmt.fmt( d, minWidth, sigFigs, flags )
// </PRE></BLOCKQUOTE>
// <P>
// <A HREF="/resources/classes/Acme/Fmt.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <HR>
// Similar classes:
// <UL>
// <LI> Andrew Scherpbier's <A HREF="http://www.sdsu.edu/doc/java-SDSU/sdsu.FormatString.html">FormatString</A>
// Tries to allow variable numbers of arguments by
// supplying overloaded routines with different combinations of parameters,
// but doesn't actually supply that many. The floating point conversion
// is described as "very incomplete".
// <LI> Core Java's <A HREF="http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html">Format</A>.
// The design seems a little weird. They want you to create an instance,
// passing the format string to the constructor, and then call an instance
// method with your data to do the actual formatting. The extra steps are
// pointless; better to just use static methods.
// </UL>
public class Fmt
{
// Flags.
/// Zero-fill.
public static final int ZF = 1;
/// Left justify.
public static final int LJ = 2;
/// Hexadecimal.
public static final int HX = 4;
/// Octal.
public static final int OC = 8;
// Was a number - internal use.
private static final int WN = 16;
// byte
public static String fmt( byte b )
{
return fmt( b, 0, 0 );
}
public static String fmt( byte b, int minWidth )
{
return fmt( b, minWidth, 0 );
}
public static String fmt( byte b, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
return fmt( Integer.toString( b & 0xff, 16 ), minWidth, flags|WN );
else if ( octal )
return fmt( Integer.toString( b & 0xff, 8 ), minWidth, flags|WN );
else
return fmt( Integer.toString( b & 0xff ), minWidth, flags|WN );
}
// short
public static String fmt( short s )
{
return fmt( s, 0, 0 );
}
public static String fmt( short s, int minWidth )
{
return fmt( s, minWidth, 0 );
}
public static String fmt( short s, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
return fmt(
Integer.toString( s & 0xffff, 16 ), minWidth, flags|WN );
else if ( octal )
return fmt(
Integer.toString( s & 0xffff, 8 ), minWidth, flags|WN );
else
return fmt( Integer.toString( s ), minWidth, flags|WN );
}
// int
public static String fmt( int i )
{
return fmt( i, 0, 0 );
}
public static String fmt( int i, int minWidth )
{
return fmt( i, minWidth, 0 );
}
public static String fmt( int i, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
return fmt(
Long.toString( i & 0xffffffffL, 16 ), minWidth, flags|WN );
else if ( octal )
return fmt(
Long.toString( i & 0xffffffffL, 8 ), minWidth, flags|WN );
else
return fmt( Integer.toString( i ), minWidth, flags|WN );
}
// long
public static String fmt( long l )
{
return fmt( l, 0, 0 );
}
public static String fmt( long l, int minWidth )
{
return fmt( l, minWidth, 0 );
}
public static String fmt( long l, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
{
if ( ( l & 0xf000000000000000L ) != 0 )
return fmt(
Long.toString( l >>> 60, 16 ) +
fmt( l & 0x0fffffffffffffffL, 15, HX|ZF ),
minWidth, flags|WN );
else
return fmt( Long.toString( l, 16 ), minWidth, flags|WN );
}
else if ( octal )
{
if ( ( l & 0x8000000000000000L ) != 0 )
return fmt(
Long.toString( l >>> 63, 8 ) +
fmt( l & 0x7fffffffffffffffL, 21, OC|ZF ),
minWidth, flags|WN );
else
return fmt( Long.toString( l, 8 ), minWidth, flags|WN );
}
else
return fmt( Long.toString( l ), minWidth, flags|WN );
}
// float
public static String fmt( float f )
{
return fmt( f, 0, 0, 0 );
}
public static String fmt( float f, int minWidth )
{
return fmt( f, minWidth, 0, 0 );
}
public static String fmt( float f, int minWidth, int sigFigs )
{
return fmt( f, minWidth, sigFigs, 0 );
}
public static String fmt( float f, int minWidth, int sigFigs, int flags )
{
if ( sigFigs != 0 )
return fmt(
sigFigFix( Float.toString( f ), sigFigs ), minWidth,
flags|WN );
else
return fmt( Float.toString( f ), minWidth, flags|WN );
}
// double
public static String fmt( double d )
{
return fmt( d, 0, 0, 0 );
}
public static String fmt( double d, int minWidth )
{
return fmt( d, minWidth, 0, 0 );
}
public static String fmt( double d, int minWidth, int sigFigs )
{
return fmt( d, minWidth, sigFigs, 0 );
}
public static String fmt( double d, int minWidth, int sigFigs, int flags )
{
if ( sigFigs != 0 )
return fmt(
sigFigFix( doubleToString( d ), sigFigs ), minWidth,
flags|WN );
else
return fmt( doubleToString( d ), minWidth, flags|WN );
}
// char
public static String fmt( char c )
{
return fmt( c, 0, 0 );
}
public static String fmt( char c, int minWidth )
{
return fmt( c, minWidth, 0 );
}
public static String fmt( char c, int minWidth, int flags )
{
// return fmt( Character.toString( c ), minWidth, flags );
// Character currently lacks a static toString method. Workaround
// is to make a temporary instance and use the instance toString.
return fmt( new Character( c ).toString(), minWidth, flags );
}
// Object
public static String fmt( Object o )
{
return fmt( o, 0, 0 );
}
public static String fmt( Object o, int minWidth )
{
return fmt( o, minWidth, 0 );
}
public static String fmt( Object o, int minWidth, int flags )
{
return fmt( o.toString(), minWidth, flags );
}
// String
public static String fmt( String s )
{
return fmt( s, 0, 0 );
}
public static String fmt( String s, int minWidth )
{
return fmt( s, minWidth, 0 );
}
public static String fmt( String s, int minWidth, int flags )
{
int len = s.length();
boolean zeroFill = ( ( flags & ZF ) != 0 );
boolean leftJustify = ( ( flags & LJ ) != 0 );
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
boolean wasNumber = ( ( flags & WN ) != 0 );
if ( ( hexadecimal || octal || zeroFill ) && ! wasNumber )
throw new InternalError( "Acme.Fmt: number flag on a non-number" );
if ( zeroFill && leftJustify )
throw new InternalError( "Acme.Fmt: zero-fill left-justify is silly" );
if ( hexadecimal && octal )
throw new InternalError( "Acme.Fmt: can't do both hex and octal" );
if ( len >= minWidth )
return s;
int fillWidth = minWidth - len;
StringBuffer fill = new StringBuffer( fillWidth );
for ( int i = 0; i < fillWidth; ++i )
if ( zeroFill )
fill.append( '0' );
else
fill.append( ' ' );
if ( leftJustify )
return s + fill;
else if ( zeroFill && s.startsWith( "-" ) )
return "-" + fill + s.substring( 1 );
else
return fill + s;
}
// Internal routines.
private static String sigFigFix( String s, int sigFigs )
{
// First dissect the floating-point number string into sign,
// integer part, fraction part, and exponent.
String sign;
String unsigned;
if ( s.startsWith( "-" ) || s.startsWith( "+" ) )
{
sign = s.substring( 0, 1 );
unsigned = s.substring( 1 );
}
else
{
sign = "";
unsigned = s;
}
String mantissa;
String exponent;
int eInd = unsigned.indexOf( 'e' );
if ( eInd == -1 ) // it may be 'e' or 'E'
eInd = unsigned.indexOf( 'E' );
if ( eInd == -1 )
{
mantissa = unsigned;
exponent = "";
}
else
{
mantissa = unsigned.substring( 0, eInd );
exponent = unsigned.substring( eInd );
}
StringBuffer number, fraction;
int dotInd = mantissa.indexOf( '.' );
if ( dotInd == -1 )
{
number = new StringBuffer( mantissa );
fraction = new StringBuffer( "" );
}
else
{
number = new StringBuffer( mantissa.substring( 0, dotInd ) );
fraction = new StringBuffer( mantissa.substring( dotInd + 1 ) );
}
int numFigs = number.length();
int fracFigs = fraction.length();
if ( ( numFigs == 0 || number.equals( "0" ) ) && fracFigs > 0 )
{
// Don't count leading zeros in the fraction.
numFigs = 0;
for ( int i = 0; i < fraction.length(); ++i )
{
if ( fraction.charAt( i ) != '0' )
break;
--fracFigs;
}
}
int mantFigs = numFigs + fracFigs;
if ( sigFigs > mantFigs )
{
// We want more figures; just append zeros to the fraction.
for ( int i = mantFigs; i < sigFigs; ++i )
fraction.append( '0' );
}
else if ( sigFigs < mantFigs && sigFigs >= numFigs )
{
// Want fewer figures in the fraction; chop.
fraction.setLength(
fraction.length() - ( fracFigs - ( sigFigs - numFigs ) ) );
// Round?
}
else if ( sigFigs < numFigs )
{
// Want fewer figures in the number; turn them to zeros.
fraction.setLength( 0 ); // should already be zero, but make sure
for ( int i = sigFigs; i < numFigs; ++i )
number.setCharAt( i, '0' );
// Round?
}
// Else sigFigs == mantFigs, which is fine.
if ( fraction.length() == 0 )
return sign + number + exponent;
else
return sign + number + "." + fraction + exponent;
}
/// Improved version of Double.toString(), returns more decimal places.
// <P>
// The JDK 1.0.2 version of Double.toString() returns only six decimal
// places on some systems. In JDK 1.1 full precision is returned on
// all platforms.
// @deprecated
// @see java.lang.Double#toString
public static String doubleToString( double d )
{
// Handle special numbers first, to avoid complications.
if ( Double.isNaN( d ) )
return "NaN";
if ( d == Double.NEGATIVE_INFINITY )
return "-Inf";
if ( d == Double.POSITIVE_INFINITY )
return "Inf";
// Grab the sign, and then make the number positive for simplicity.
boolean negative = false;
if ( d < 0.0D )
{
negative = true;
d = -d;
}
// Get the native version of the unsigned value, as a template.
String unsStr = Double.toString( d );
// Dissect out the exponent.
String mantStr, expStr;
int exp;
int eInd = unsStr.indexOf( 'e' );
if ( eInd == -1 ) // it may be 'e' or 'E'
eInd = unsStr.indexOf( 'E' );
if ( eInd == -1 )
{
mantStr = unsStr;
expStr = "";
exp = 0;
}
else
{
mantStr = unsStr.substring( 0, eInd );
expStr = unsStr.substring( eInd + 1 );
if ( expStr.startsWith( "+" ) )
exp = Integer.parseInt( expStr.substring( 1 ) );
else
exp = Integer.parseInt( expStr );
}
// Dissect out the number part.
String numStr;
int dotInd = mantStr.indexOf( '.' );
if ( dotInd == -1 )
numStr = mantStr;
else
numStr = mantStr.substring( 0, dotInd );
long num;
if ( numStr.length() == 0 )
num = 0;
else
num = Integer.parseInt( numStr );
// Build the new mantissa.
StringBuffer newMantBuf = new StringBuffer( numStr + "." );
double p = Math.pow( 10, exp );
double frac = d - num * p;
String digits = "0123456789";
int nDigits = 16 - numStr.length(); // about 16 digits in a double
for ( int i = 0; i < nDigits; ++i )
{
p /= 10.0D;
int dig = (int) ( frac / p );
if ( dig < 0 ) dig = 0;
if ( dig > 9 ) dig = 9;
newMantBuf.append( digits.charAt( dig ) );
frac -= dig * p;
}
if ( (int) ( frac / p + 0.5D ) == 1 )
{
// Round up.
boolean roundMore = true;
for ( int i = newMantBuf.length() - 1; i >= 0; --i )
{
int dig = digits.indexOf( newMantBuf.charAt( i ) );
if ( dig == -1 )
continue;
++dig;
if ( dig == 10 )
{
newMantBuf.setCharAt( i, '0' );
continue;
}
newMantBuf.setCharAt( i, digits.charAt( dig ) );
roundMore = false;
break;
}
if ( roundMore )
{
// If this happens, we need to prepend a 1. But I haven't
// found a test case yet, so I'm leaving it out for now.
// But if you get this message, please let me know!
newMantBuf.append( "ROUNDMORE" );
}
}
// Chop any trailing zeros.
int len = newMantBuf.length();
while ( newMantBuf.charAt( len - 1 ) == '0' )
newMantBuf.setLength( --len );
// And chop a trailing dot, if any.
if ( newMantBuf.charAt( len - 1 ) == '.' )
newMantBuf.setLength( --len );
// Done.
return ( negative ? "-" : "" ) +
newMantBuf +
( expStr.length() != 0 ? ( "e" + expStr ) : "" );
}
/******************************************************************************
/// Test program.
public static void main( String[] args )
{
System.out.println( "Starting tests." );
show( Fmt.fmt( "Hello there." ) );
show( Fmt.fmt( 123 ) );
show( Fmt.fmt( 123, 10 ) );
show( Fmt.fmt( 123, 10, Fmt.ZF ) );
show( Fmt.fmt( 123, 10, Fmt.LJ ) );
show( Fmt.fmt( -123 ) );
show( Fmt.fmt( -123, 10 ) );
show( Fmt.fmt( -123, 10, Fmt.ZF ) );
show( Fmt.fmt( -123, 10, Fmt.LJ ) );
show( Fmt.fmt( (byte) 0xbe, 22, Fmt.OC ) );
show( Fmt.fmt( (short) 0xbabe, 22, Fmt.OC ) );
show( Fmt.fmt( 0xcafebabe, 22, Fmt.OC ) );
show( Fmt.fmt( 0xdeadbeefcafebabeL, 22, Fmt.OC ) );
show( Fmt.fmt( 0x8000000000000000L, 22, Fmt.OC ) );
show( Fmt.fmt( (byte) 0xbe, 16, Fmt.HX ) );
show( Fmt.fmt( (short) 0xbabe, 16, Fmt.HX ) );
show( Fmt.fmt( 0xcafebabe, 16, Fmt.HX ) );
show( Fmt.fmt( 0xdeadbeefcafebabeL, 16, Fmt.HX ) );
show( Fmt.fmt( 0x8000000000000000L, 16, Fmt.HX ) );
show( Fmt.fmt( 'c' ) );
show( Fmt.fmt( new java.util.Date() ) );
show( Fmt.fmt( 123.456F ) );
show( Fmt.fmt( 123456000000000000.0F ) );
show( Fmt.fmt( 123.456F, 0, 8 ) );
show( Fmt.fmt( 123.456F, 0, 7 ) );
show( Fmt.fmt( 123.456F, 0, 6 ) );
show( Fmt.fmt( 123.456F, 0, 5 ) );
show( Fmt.fmt( 123.456F, 0, 4 ) );
show( Fmt.fmt( 123.456F, 0, 3 ) );
show( Fmt.fmt( 123.456F, 0, 2 ) );
show( Fmt.fmt( 123.456F, 0, 1 ) );
show( Fmt.fmt( 123456000000000000.0F, 0, 4 ) );
show( Fmt.fmt( -123.456F, 0, 4 ) );
show( Fmt.fmt( -123456000000000000.0F, 0, 4 ) );
show( Fmt.fmt( 123.0F ) );
show( Fmt.fmt( 123.0D ) );
show( Fmt.fmt( 1.234567890123456789F ) );
show( Fmt.fmt( 1.234567890123456789D ) );
show( Fmt.fmt( 1234567890123456789F ) );
show( Fmt.fmt( 1234567890123456789D ) );
show( Fmt.fmt( 0.000000000000000000001234567890123456789F ) );
show( Fmt.fmt( 0.000000000000000000001234567890123456789D ) );
show( Fmt.fmt( 12300.0F ) );
show( Fmt.fmt( 12300.0D ) );
show( Fmt.fmt( 123000.0F ) );
show( Fmt.fmt( 123000.0D ) );
show( Fmt.fmt( 1230000.0F ) );
show( Fmt.fmt( 1230000.0D ) );
show( Fmt.fmt( 12300000.0F ) );
show( Fmt.fmt( 12300000.0D ) );
show( Fmt.fmt( Float.NaN ) );
show( Fmt.fmt( Float.POSITIVE_INFINITY ) );
show( Fmt.fmt( Float.NEGATIVE_INFINITY ) );
show( Fmt.fmt( Double.NaN ) );
show( Fmt.fmt( Double.POSITIVE_INFINITY ) );
show( Fmt.fmt( Double.NEGATIVE_INFINITY ) );
show( Fmt.fmt( 1.0F / 8.0F ) );
show( Fmt.fmt( 1.0D / 8.0D ) );
System.out.println( "Done with tests." );
}
private static void show( String str )
{
System.out.println( "#" + str + "#" );
}
******************************************************************************/
}

View file

@ -1,396 +0,0 @@
// IntHashtable - a Hashtable that uses ints as the keys
//
// This is 90% based on JavaSoft's java.util.Hashtable.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
import java.util.*;
/// A Hashtable that uses ints as the keys.
// <P>
// Use just like java.util.Hashtable, except that the keys must be ints.
// This is much faster than creating a new Integer for each access.
// <P>
// <A HREF="/resources/classes/Acme/IntHashtable.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see java.util.Hashtable
public class IntHashtable extends Dictionary implements Cloneable
{
/// The hash table data.
private IntHashtableEntry table[];
/// The total number of entries in the hash table.
private int count;
/// Rehashes the table when count exceeds this threshold.
private int threshold;
/// The load factor for the hashtable.
private float loadFactor;
/// Constructs a new, empty hashtable with the specified initial
// capacity and the specified load factor.
// @param initialCapacity the initial number of buckets
// @param loadFactor a number between 0.0 and 1.0, it defines
// the threshold for rehashing the hashtable into
// a bigger one.
// @exception IllegalArgumentException If the initial capacity
// is less than or equal to zero.
// @exception IllegalArgumentException If the load factor is
// less than or equal to zero.
public IntHashtable( int initialCapacity, float loadFactor )
{
if ( initialCapacity <= 0 || loadFactor <= 0.0 )
throw new IllegalArgumentException();
this.loadFactor = loadFactor;
table = new IntHashtableEntry[initialCapacity];
threshold = (int) ( initialCapacity * loadFactor );
}
/// Constructs a new, empty hashtable with the specified initial
// capacity.
// @param initialCapacity the initial number of buckets
public IntHashtable( int initialCapacity )
{
this( initialCapacity, 0.75f );
}
/// Constructs a new, empty hashtable. A default capacity and load factor
// is used. Note that the hashtable will automatically grow when it gets
// full.
public IntHashtable()
{
this( 101, 0.75f );
}
/// Returns the number of elements contained in the hashtable.
public int size()
{
return count;
}
/// Returns true if the hashtable contains no elements.
public boolean isEmpty()
{
return count == 0;
}
/// Returns an enumeration of the hashtable's keys.
// @see IntHashtable#elements
public synchronized Enumeration keys()
{
return new IntHashtableEnumerator( table, true );
}
/// Returns an enumeration of the elements. Use the Enumeration methods
// on the returned object to fetch the elements sequentially.
// @see IntHashtable#keys
public synchronized Enumeration elements()
{
return new IntHashtableEnumerator( table, false );
}
/// Returns true if the specified object is an element of the hashtable.
// This operation is more expensive than the containsKey() method.
// @param value the value that we are looking for
// @exception NullPointerException If the value being searched
// for is equal to null.
// @see IntHashtable#containsKey
public synchronized boolean contains( Object value )
{
if ( value == null )
throw new NullPointerException();
IntHashtableEntry tab[] = table;
for ( int i = tab.length ; i-- > 0 ; )
{
for ( IntHashtableEntry e = tab[i] ; e != null ; e = e.next )
{
if ( e.value.equals( value ) )
return true;
}
}
return false;
}
/// Returns true if the collection contains an element for the key.
// @param key the key that we are looking for
// @see IntHashtable#contains
public synchronized boolean containsKey( int key )
{
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next )
{
if ( e.hash == hash && e.key == key )
return true;
}
return false;
}
/// Gets the object associated with the specified key in the
// hashtable.
// @param key the specified key
// @returns the element for the key or null if the key
// is not defined in the hash table.
// @see IntHashtable#put
public synchronized Object get( int key )
{
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next )
{
if ( e.hash == hash && e.key == key )
return e.value;
}
return null;
}
/// A get method that takes an Object, for compatibility with
// java.util.Dictionary. The Object must be an Integer.
public Object get( Object okey )
{
if ( ! ( okey instanceof Integer ) )
throw new InternalError( "key is not an Integer" );
Integer ikey = (Integer) okey;
int key = ikey.intValue();
return get( key );
}
/// Rehashes the content of the table into a bigger table.
// This method is called automatically when the hashtable's
// size exceeds the threshold.
protected void rehash()
{
int oldCapacity = table.length;
IntHashtableEntry oldTable[] = table;
int newCapacity = oldCapacity * 2 + 1;
IntHashtableEntry newTable[] = new IntHashtableEntry[newCapacity];
threshold = (int) ( newCapacity * loadFactor );
table = newTable;
for ( int i = oldCapacity ; i-- > 0 ; )
{
for ( IntHashtableEntry old = oldTable[i] ; old != null ; )
{
IntHashtableEntry e = old;
old = old.next;
int index = ( e.hash & 0x7FFFFFFF ) % newCapacity;
e.next = newTable[index];
newTable[index] = e;
}
}
}
/// Puts the specified element into the hashtable, using the specified
// key. The element may be retrieved by doing a get() with the same key.
// The key and the element cannot be null.
// @param key the specified key in the hashtable
// @param value the specified element
// @exception NullPointerException If the value of the element
// is equal to null.
// @see IntHashtable#get
// @return the old value of the key, or null if it did not have one.
public synchronized Object put( int key, Object value )
{
// Make sure the value is not null.
if ( value == null )
throw new NullPointerException();
// Makes sure the key is not already in the hashtable.
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next )
{
if ( e.hash == hash && e.key == key )
{
Object old = e.value;
e.value = value;
return old;
}
}
if ( count >= threshold )
{
// Rehash the table if the threshold is exceeded.
rehash();
return put( key, value );
}
// Creates the new entry.
IntHashtableEntry e = new IntHashtableEntry();
e.hash = hash;
e.key = key;
e.value = value;
e.next = tab[index];
tab[index] = e;
++count;
return null;
}
/// A put method that takes an Object, for compatibility with
// java.util.Dictionary. The Object must be an Integer.
public Object put( Object okey, Object value )
{
if ( ! ( okey instanceof Integer ) )
throw new InternalError( "key is not an Integer" );
Integer ikey = (Integer) okey;
int key = ikey.intValue();
return put( key, value );
}
/// Removes the element corresponding to the key. Does nothing if the
// key is not present.
// @param key the key that needs to be removed
// @return the value of key, or null if the key was not found.
public synchronized Object remove( int key )
{
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next )
{
if ( e.hash == hash && e.key == key )
{
if ( prev != null )
prev.next = e.next;
else
tab[index] = e.next;
--count;
return e.value;
}
}
return null;
}
/// A remove method that takes an Object, for compatibility with
// java.util.Dictionary. The Object must be an Integer.
public Object remove( Object okey )
{
if ( ! ( okey instanceof Integer ) )
throw new InternalError( "key is not an Integer" );
Integer ikey = (Integer) okey;
int key = ikey.intValue();
return remove( key );
}
/// Clears the hash table so that it has no more elements in it.
public synchronized void clear()
{
IntHashtableEntry tab[] = table;
for ( int index = tab.length; --index >= 0; )
tab[index] = null;
count = 0;
}
/// Creates a clone of the hashtable. A shallow copy is made,
// the keys and elements themselves are NOT cloned. This is a
// relatively expensive operation.
public synchronized Object clone()
{
try
{
IntHashtable t = (IntHashtable) super.clone();
t.table = new IntHashtableEntry[table.length];
for ( int i = table.length ; i-- > 0 ; )
t.table[i] = ( table[i] != null ) ?
(IntHashtableEntry) table[i].clone() : null;
return t;
}
catch ( CloneNotSupportedException e)
{
// This shouldn't happen, since we are Cloneable.
throw new InternalError();
}
}
/// Converts to a rather lengthy String.
public synchronized String toString()
{
int max = size() - 1;
StringBuffer buf = new StringBuffer();
Enumeration k = keys();
Enumeration e = elements();
buf.append( "{" );
for ( int i = 0; i <= max; ++i )
{
String s1 = k.nextElement().toString();
String s2 = e.nextElement().toString();
buf.append( s1 + "=" + s2 );
if ( i < max )
buf.append( ", " );
}
buf.append( "}" );
return buf.toString();
}
}
class IntHashtableEntry
{
int hash;
int key;
Object value;
IntHashtableEntry next;
protected Object clone()
{
IntHashtableEntry entry = new IntHashtableEntry();
entry.hash = hash;
entry.key = key;
entry.value = value;
entry.next = ( next != null ) ? (IntHashtableEntry) next.clone() : null;
return entry;
}
}
class IntHashtableEnumerator implements Enumeration
{
boolean keys;
int index;
IntHashtableEntry table[];
IntHashtableEntry entry;
IntHashtableEnumerator( IntHashtableEntry table[], boolean keys )
{
this.table = table;
this.keys = keys;
this.index = table.length;
}
public boolean hasMoreElements()
{
if ( entry != null )
return true;
while ( index-- > 0 )
if ( ( entry = table[index] ) != null )
return true;
return false;
}
public Object nextElement()
{
if ( entry == null )
while ( ( index-- > 0 ) && ( ( entry = table[index] ) == null ) )
;
if ( entry != null )
{
IntHashtableEntry e = entry;
entry = e.next;
return keys ? new Integer( e.key ) : e.value;
}
throw new NoSuchElementException( "IntHashtableEnumerator" );
}
}

View file

@ -1,314 +0,0 @@
// ImageDecoder - abstract class for reading in an image
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Decoders;
import java.util.*;
import java.io.*;
import java.awt.image.*;
/// Abstract class for reading in an image.
// <P>
// A framework for classes that read in and decode an image in
// a particular file format.
// <P>
// This provides a very simplified rendition of the ImageProducer interface.
// It requires the decoder to read the image a row at a time. It requires
// use of the RGBdefault color model.
// If you want more flexibility you can always implement ImageProducer
// directly.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Decoders/ImageDecoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see PpmDecoder
// @see Acme.JPM.Encoders.ImageEncoder
public abstract class ImageDecoder implements ImageProducer
{
private InputStream in;
private int width, height;
private boolean[] rowsRead;
private int[][] rgbPixels;
private boolean startedRead = false;
private boolean gotSize = false;
private boolean err = false;
private boolean producing = false;
private Vector consumers = new Vector();
private static final ColorModel model = ColorModel.getRGBdefault();
/// Constructor.
// @param in The stream to read the bytes from.
public ImageDecoder( InputStream in )
{
this.in = in;
}
// Methods that subclasses implement.
/// Subclasses implement this to read in enough of the image stream
// to figure out the width and height.
abstract void readHeader( InputStream in ) throws IOException;
/// Subclasses implement this to return the width, or -1 if not known.
abstract int getWidth();
/// Subclasses implement this to return the height, or -1 if not known.
abstract int getHeight();
/// Subclasses implement this to read pixel data into the rgbRow
// array, an int[width]. One int per pixel, no offsets or padding,
// RGBdefault (AARRGGBB) color model.
abstract void readRow( InputStream in, int row, int[] rgbRow ) throws IOException;
// Our own methods.
void readImage()
{
try
{
readHeader( in );
width = getWidth();
height = getHeight();
if ( width == -1 || height == -1 )
err = true;
else
{
rowsRead = new boolean[height];
for ( int row = 0; row < height; ++row )
rowsRead[row] = false;
gotSize = true;
notifyThem();
rgbPixels = new int[height][width];
for ( int row = 0; row < height; ++row )
{
readRow( in, row, rgbPixels[row] );
rowsRead[row] = true;
notifyThem();
}
}
}
catch ( IOException e )
{
err = true;
width = -1;
height = -1;
rowsRead = null;
rgbPixels = null;
}
}
private synchronized void notifyThem()
{
notifyAll();
}
void sendImage()
{
// Grab the list of consumers, in case it changes while we're sending.
ImageConsumer[] c = new ImageConsumer[consumers.size()];
int i;
for ( i = 0; i < c.length; ++i )
c[i] = (ImageConsumer) consumers.elementAt( i );
// Try to be as parallel as possible.
waitForSize();
for ( i = 0; i < c.length; ++i )
sendHead( c[i] );
for ( int row = 0; row < height; ++row )
for ( i = 0; i < c.length; ++i )
sendPixelRow( c[i], row );
for ( i = 0; i < c.length; ++i )
sendTail( c[i] );
producing = false;
}
private synchronized void waitForSize()
{
while ( ( ! err ) && ( ! gotSize ))
{
try
{
wait();
}
catch ( InterruptedException ignore ) {}
}
}
private synchronized void waitForRow( int row )
{
while ( ( ! err ) && ( ! rowsRead[row] ) )
{
try
{
wait();
}
catch ( InterruptedException ignore ) {}
}
}
private void sendHead( ImageConsumer ic )
{
if ( err )
return;
ic.setDimensions( width, height );
ic.setColorModel( model );
ic.setHints(
ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME );
}
private void sendPixelRow( ImageConsumer ic, int row )
{
if ( err )
return;
waitForRow( row );
if ( err )
return;
ic.setPixels( 0, row, width, 1, model, rgbPixels[row], 0, width );
}
private void sendTail( ImageConsumer ic )
{
if ( err )
ic.imageComplete( ImageConsumer.IMAGEERROR );
else
ic.imageComplete( ImageConsumer.STATICIMAGEDONE );
}
// Methods from ImageProducer.
/// This method is used to register an ImageConsumer with the
// ImageProducer for access to the image data during a later
// reconstruction of the Image. The ImageProducer may, at its
// discretion, start delivering the image data to the consumer
// using the ImageConsumer interface immediately, or when the
// next available image reconstruction is triggered by a call
// to the startProduction method.
// @see #startProduction
public void addConsumer( ImageConsumer ic )
{
if ( ic != null && ! isConsumer( ic ) )
consumers.addElement( ic );
}
/// This method determines if a given ImageConsumer object
// is currently registered with this ImageProducer as one
// of its consumers.
public boolean isConsumer( ImageConsumer ic )
{
return consumers.contains( ic );
}
/// This method removes the given ImageConsumer object
// from the list of consumers currently registered to
// receive image data. It is not considered an error
// to remove a consumer that is not currently registered.
// The ImageProducer should stop sending data to this
// consumer as soon as is feasible.
public void removeConsumer( ImageConsumer ic )
{
consumers.removeElement( ic );
}
/// This method both registers the given ImageConsumer object
// as a consumer and starts an immediate reconstruction of
// the image data which will then be delivered to this
// consumer and any other consumer which may have already
// been registered with the producer. This method differs
// from the addConsumer method in that a reproduction of
// the image data should be triggered as soon as possible.
// @see #addConsumer
public void startProduction( ImageConsumer ic )
{
addConsumer( ic );
if ( ! startedRead )
{
startedRead = true;
new ImageDecoderRead( this );
}
if ( ! producing )
{
producing = true;
sendImage();
}
}
/// This method is used by an ImageConsumer to request that
// the ImageProducer attempt to resend the image data one
// more time in TOPDOWNLEFTRIGHT order so that higher
// quality conversion algorithms which depend on receiving
// pixels in order can be used to produce a better output
// version of the image. The ImageProducer is free to
// ignore this call if it cannot resend the data in that
// order. If the data can be resent, then the ImageProducer
// should respond by executing the following minimum set of
// ImageConsumer method calls:
// <PRE>
// ic.setHints( TOPDOWNLEFTRIGHT | [otherhints] );
// ic.setPixels( [...] ); // as many times as needed
// ic.imageComplete( [status] );
// </PRE>
// @see ImageConsumer#setHints
public void requestTopDownLeftRightResend( ImageConsumer ic )
{
addConsumer( ic );
waitForSize();
sendHead( ic );
for ( int row = 0; row < height; ++row )
sendPixelRow( ic, row );
sendTail( ic );
}
}
class ImageDecoderRead extends Thread
{
private ImageDecoder parent;
public ImageDecoderRead( ImageDecoder parent )
{
this.parent = parent;
start();
}
// Methods from Runnable.
public void run()
{
parent.readImage();
}
}

View file

@ -1,267 +0,0 @@
// PpmDecoder - read in a PPM image
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Decoders;
import java.io.*;
import java.awt.image.*;
/// Read in a PPM image.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Decoders/PpmDecoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Acme.JPM.Encoders.PpmEncoder
public class PpmDecoder extends ImageDecoder
{
/// Constructor.
// @param in The stream to read the bytes from.
public PpmDecoder( InputStream in )
{
super( in );
}
private int type;
private static final int PBM_ASCII = 1;
private static final int PGM_ASCII = 2;
private static final int PPM_ASCII = 3;
private static final int PBM_RAW = 4;
private static final int PGM_RAW = 5;
private static final int PPM_RAW = 6;
private int width = -1, height = -1;
private int maxval;
/// Subclasses implement this to read in enough of the image stream
// to figure out the width and height.
void readHeader( InputStream in ) throws IOException
{
char c1, c2;
c1 = (char) readByte( in );
c2 = (char) readByte( in );
if ( c1 != 'P' )
throw new IOException( "not a PBM/PGM/PPM file" );
switch ( c2 )
{
case '1':
type = PBM_ASCII;
break;
case '2':
type = PGM_ASCII;
break;
case '3':
type = PPM_ASCII;
break;
case '4':
type = PBM_RAW;
break;
case '5':
type = PGM_RAW;
break;
case '6':
type = PPM_RAW;
break;
default:
throw new IOException( "not a standard PBM/PGM/PPM file" );
}
width = readInt( in );
height = readInt( in );
if ( type != PBM_ASCII && type != PBM_RAW )
maxval = readInt( in );
}
/// Subclasses implement this to return the width, or -1 if not known.
int getWidth()
{
return width;
}
/// Subclasses implement this to return the height, or -1 if not known.
int getHeight()
{
return height;
}
/// Subclasses implement this to read pixel data into the rgbRow
// array, an int[width]. One int per pixel, no offsets or padding,
// RGBdefault (AARRGGBB) color model
void readRow( InputStream in, int row, int[] rgbRow ) throws IOException
{
int col, r, g, b;
int rgb = 0;
char c;
for ( col = 0; col < width; ++col )
{
switch ( type )
{
case PBM_ASCII:
c = readChar( in );
if ( c == '1' )
rgb = 0xff000000;
else if ( c == '0' )
rgb = 0xffffffff;
else
throw new IOException( "illegal PBM bit" );
break;
case PGM_ASCII:
g = readInt( in );
rgb = makeRgb( g, g, g );
break;
case PPM_ASCII:
r = readInt( in );
g = readInt( in );
b = readInt( in );
rgb = makeRgb( r, g, b );
break;
case PBM_RAW:
if ( readBit( in ) )
rgb = 0xff000000;
else
rgb = 0xffffffff;
break;
case PGM_RAW:
g = readByte( in );
if ( maxval != 255 )
g = fixDepth( g );
rgb = makeRgb( g, g, g );
break;
case PPM_RAW:
r = readByte( in );
g = readByte( in );
b = readByte( in );
if ( maxval != 255 )
{
r = fixDepth( r );
g = fixDepth( g );
b = fixDepth( b );
}
rgb = makeRgb( r, g, b );
break;
}
rgbRow[col] = rgb;
}
}
/// Utility routine to read a byte. Instead of returning -1 on
// EOF, it throws an exception.
private static int readByte( InputStream in ) throws IOException
{
int b = in.read();
if ( b == -1 )
throw new EOFException();
return b;
}
private int bitshift = -1;
private int bits;
/// Utility routine to read a bit, packed eight to a byte, big-endian.
private boolean readBit( InputStream in ) throws IOException
{
if ( bitshift == -1 )
{
bits = readByte( in );
bitshift = 7;
}
boolean bit = ( ( ( bits >> bitshift ) & 1 ) != 0 );
--bitshift;
return bit;
}
/// Utility routine to read a character, ignoring comments.
private static char readChar( InputStream in ) throws IOException
{
char c;
c = (char) readByte( in );
if ( c == '#' )
{
do
{
c = (char) readByte( in );
}
while ( c != '\n' && c != '\r' );
}
return c;
}
/// Utility routine to read the first non-whitespace character.
private static char readNonwhiteChar( InputStream in ) throws IOException
{
char c;
do
{
c = readChar( in );
}
while ( c == ' ' || c == '\t' || c == '\n' || c == '\r' );
return c;
}
/// Utility routine to read an ASCII integer, ignoring comments.
private static int readInt( InputStream in ) throws IOException
{
char c;
int i;
c = readNonwhiteChar( in );
if ( c < '0' || c > '9' )
throw new IOException( "junk in file where integer should be" );
i = 0;
do
{
i = i * 10 + c - '0';
c = readChar( in );
}
while ( c >= '0' && c <= '9' );
return i;
}
/// Utility routine to rescale a pixel value from a non-eight-bit maxval.
private int fixDepth( int p )
{
return ( p * 255 + maxval / 2 ) / maxval;
}
/// Utility routine make an RGBdefault pixel from three color values.
private static int makeRgb( int r, int g, int b )
{
return 0xff000000 | ( r << 16 ) | ( g << 8 ) | b;
}
}

View file

@ -1,691 +0,0 @@
// GifEncoder - write out an image as a GIF
//
// Transparency handling and variable bit size courtesy of Jack Palevich.
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Encoders;
import java.util.*;
import java.io.*;
import java.awt.Image;
import java.awt.image.*;
/// Write out an image as a GIF.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Encoders/GifEncoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see ToGif
public class GifEncoder extends ImageEncoder
{
private boolean interlace = false;
/// Constructor from Image.
// @param img The image to encode.
// @param out The stream to write the GIF to.
public GifEncoder( Image img, OutputStream out ) throws IOException
{
super( img, out );
}
/// Constructor from Image with interlace setting.
// @param img The image to encode.
// @param out The stream to write the GIF to.
// @param interlace Whether to interlace.
public GifEncoder( Image img, OutputStream out, boolean interlace ) throws IOException
{
super( img, out );
this.interlace = interlace;
}
/// Constructor from ImageProducer.
// @param prod The ImageProducer to encode.
// @param out The stream to write the GIF to.
public GifEncoder( ImageProducer prod, OutputStream out ) throws IOException
{
super( prod, out );
}
/// Constructor from ImageProducer with interlace setting.
// @param prod The ImageProducer to encode.
// @param out The stream to write the GIF to.
public GifEncoder( ImageProducer prod, OutputStream out, boolean interlace ) throws IOException
{
super( prod, out );
this.interlace = interlace;
}
int width, height;
int[][] rgbPixels;
void encodeStart( int width, int height ) throws IOException
{
this.width = width;
this.height = height;
rgbPixels = new int[height][width];
}
void encodePixels(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException
{
// Save the pixels.
for ( int row = 0; row < h; ++row )
System.arraycopy(
rgbPixels, row * scansize + off,
this.rgbPixels[y + row], x, w );
}
Acme.IntHashtable colorHash;
void encodeDone() throws IOException
{
int transparentIndex = -1;
int transparentRgb = -1;
// Put all the pixels into a hash table.
colorHash = new Acme.IntHashtable();
int index = 0;
for ( int row = 0; row < height; ++row )
{
int rowOffset = row * width;
for ( int col = 0; col < width; ++col )
{
int rgb = rgbPixels[row][col];
boolean isTransparent = ( ( rgb >>> 24 ) < 0x80 );
if ( isTransparent )
{
if ( transparentIndex < 0 )
{
// First transparent color; remember it.
transparentIndex = index;
transparentRgb = rgb;
}
else if ( rgb != transparentRgb )
{
// A second transparent color; replace it with
// the first one.
rgbPixels[row][col] = rgb = transparentRgb;
}
}
GifEncoderHashitem item =
(GifEncoderHashitem) colorHash.get( rgb );
if ( item == null )
{
if ( index >= 256 )
throw new IOException( "too many colors for a GIF" );
item = new GifEncoderHashitem(
rgb, 1, index, isTransparent );
++index;
colorHash.put( rgb, item );
}
else
++item.count;
}
}
// Figure out how many bits to use.
int logColors;
if ( index <= 2 )
logColors = 1;
else if ( index <= 4 )
logColors = 2;
else if ( index <= 16 )
logColors = 4;
else
logColors = 8;
// Turn colors into colormap entries.
int mapSize = 1 << logColors;
byte[] reds = new byte[mapSize];
byte[] grns = new byte[mapSize];
byte[] blus = new byte[mapSize];
for ( Enumeration e = colorHash.elements(); e.hasMoreElements(); )
{
GifEncoderHashitem item = (GifEncoderHashitem) e.nextElement();
reds[item.index] = (byte) ( ( item.rgb >> 16 ) & 0xff );
grns[item.index] = (byte) ( ( item.rgb >> 8 ) & 0xff );
blus[item.index] = (byte) ( item.rgb & 0xff );
}
GIFEncode(
out, width, height, interlace, (byte) 0, transparentIndex,
logColors, reds, grns, blus );
}
byte GetPixel( int x, int y ) throws IOException
{
GifEncoderHashitem item =
(GifEncoderHashitem) colorHash.get( rgbPixels[y][x] );
if ( item == null )
throw new IOException( "color not found" );
return (byte) item.index;
}
static void writeString( OutputStream out, String str ) throws IOException
{
byte[] buf = str.getBytes();
out.write( buf );
}
// Adapted from ppmtogif, which is based on GIFENCOD by David
// Rowley <mgardi@watdscu.waterloo.edu>. Lempel-Zim compression
// based on "compress".
int Width, Height;
boolean Interlace;
int curx, cury;
int CountDown;
int Pass = 0;
void GIFEncode(
OutputStream outs, int Width, int Height, boolean Interlace, byte Background, int Transparent, int BitsPerPixel, byte[] Red, byte[] Green, byte[] Blue )
throws IOException
{
byte B;
int LeftOfs, TopOfs;
int ColorMapSize;
int InitCodeSize;
int i;
this.Width = Width;
this.Height = Height;
this.Interlace = Interlace;
ColorMapSize = 1 << BitsPerPixel;
LeftOfs = TopOfs = 0;
// Calculate number of bits we are expecting
CountDown = Width * Height;
// Indicate which pass we are on (if interlace)
Pass = 0;
// The initial code size
if ( BitsPerPixel <= 1 )
InitCodeSize = 2;
else
InitCodeSize = BitsPerPixel;
// Set up the current x and y position
curx = 0;
cury = 0;
// Write the Magic header
writeString( outs, "GIF89a" );
// Write out the screen width and height
Putword( Width, outs );
Putword( Height, outs );
// Indicate that there is a global colour map
B = (byte) 0x80; // Yes, there is a color map
// OR in the resolution
B |= (byte) ( ( 8 - 1 ) << 4 );
// Not sorted
// OR in the Bits per Pixel
B |= (byte) ( ( BitsPerPixel - 1 ) );
// Write it out
Putbyte( B, outs );
// Write out the Background colour
Putbyte( Background, outs );
// Pixel aspect ratio - 1:1.
//Putbyte( (byte) 49, outs );
// Java's GIF reader currently has a bug, if the aspect ratio byte is
// not zero it throws an ImageFormatException. It doesn't know that
// 49 means a 1:1 aspect ratio. Well, whatever, zero works with all
// the other decoders I've tried so it probably doesn't hurt.
Putbyte( (byte) 0, outs );
// Write out the Global Colour Map
for ( i = 0; i < ColorMapSize; ++i )
{
Putbyte( Red[i], outs );
Putbyte( Green[i], outs );
Putbyte( Blue[i], outs );
}
// Write out extension for transparent colour index, if necessary.
if ( Transparent != -1 )
{
Putbyte( (byte) '!', outs );
Putbyte( (byte) 0xf9, outs );
Putbyte( (byte) 4, outs );
Putbyte( (byte) 1, outs );
Putbyte( (byte) 0, outs );
Putbyte( (byte) 0, outs );
Putbyte( (byte) Transparent, outs );
Putbyte( (byte) 0, outs );
}
// Write an Image separator
Putbyte( (byte) ',', outs );
// Write the Image header
Putword( LeftOfs, outs );
Putword( TopOfs, outs );
Putword( Width, outs );
Putword( Height, outs );
// Write out whether or not the image is interlaced
if ( Interlace )
Putbyte( (byte) 0x40, outs );
else
Putbyte( (byte) 0x00, outs );
// Write out the initial code size
Putbyte( (byte) InitCodeSize, outs );
// Go and actually compress the data
compress( InitCodeSize+1, outs );
// Write out a Zero-length packet (to end the series)
Putbyte( (byte) 0, outs );
// Write the GIF file terminator
Putbyte( (byte) ';', outs );
}
// Bump the 'curx' and 'cury' to point to the next pixel
void BumpPixel()
{
// Bump the current X position
++curx;
// If we are at the end of a scan line, set curx back to the beginning
// If we are interlaced, bump the cury to the appropriate spot,
// otherwise, just increment it.
if ( curx == Width )
{
curx = 0;
if ( ! Interlace )
++cury;
else
{
switch( Pass )
{
case 0:
cury += 8;
if ( cury >= Height )
{
++Pass;
cury = 4;
}
break;
case 1:
cury += 8;
if ( cury >= Height )
{
++Pass;
cury = 2;
}
break;
case 2:
cury += 4;
if ( cury >= Height )
{
++Pass;
cury = 1;
}
break;
case 3:
cury += 2;
break;
}
}
}
}
static final int EOF = -1;
// Return the next pixel from the image
int GIFNextPixel() throws IOException
{
byte r;
if ( CountDown == 0 )
return EOF;
--CountDown;
r = GetPixel( curx, cury );
BumpPixel();
return r & 0xff;
}
// Write out a word to the GIF file
void Putword( int w, OutputStream outs ) throws IOException
{
Putbyte( (byte) ( w & 0xff ), outs );
Putbyte( (byte) ( ( w >> 8 ) & 0xff ), outs );
}
// Write out a byte to the GIF file
void Putbyte( byte b, OutputStream outs ) throws IOException
{
outs.write( b );
}
// GIFCOMPR.C - GIF Image compression routines
//
// Lempel-Ziv compression based on 'compress'. GIF modifications by
// David Rowley (mgardi@watdcsu.waterloo.edu)
// General DEFINEs
static final int BITS = 12;
static final int HSIZE = 5003; // 80% occupancy
// GIF Image compression - modified 'compress'
//
// Based on: compress.c - File compression ala IEEE Computer, June 1984.
//
// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
// Jim McKie (decvax!mcvax!jim)
// Steve Davies (decvax!vax135!petsd!peora!srd)
// Ken Turkowski (decvax!decwrl!turtlevax!ken)
// James A. Woods (decvax!ihnp4!ames!jaw)
// Joe Orost (decvax!vax135!petsd!joe)
int n_bits; // number of bits/code
int maxbits = BITS; // user settable max # bits/code
int maxcode; // maximum code, given n_bits
int maxmaxcode = 1 << BITS; // should NEVER generate this code
final int MAXCODE( int n_bits )
{
return ( 1 << n_bits ) - 1;
}
int[] htab = new int[HSIZE];
int[] codetab = new int[HSIZE];
int hsize = HSIZE; // for dynamic table sizing
int free_ent = 0; // first unused entry
// block compression parameters -- after all codes are used up,
// and compression rate changes, start over.
boolean clear_flg = 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.
int g_init_bits;
int ClearCode;
int EOFCode;
void compress( int init_bits, OutputStream outs ) throws IOException
{
int fcode;
int i /* = 0 */;
int c;
int ent;
int disp;
int hsize_reg;
int hshift;
// Set up the globals: g_init_bits - initial number of bits
g_init_bits = init_bits;
// Set up the necessary values
clear_flg = false;
n_bits = g_init_bits;
maxcode = MAXCODE( n_bits );
ClearCode = 1 << ( init_bits - 1 );
EOFCode = ClearCode + 1;
free_ent = ClearCode + 2;
char_init();
ent = GIFNextPixel();
hshift = 0;
for ( fcode = hsize; fcode < 65536; fcode *= 2 )
++hshift;
hshift = 8 - hshift; // set hash code range bound
hsize_reg = hsize;
cl_hash( hsize_reg ); // clear hash table
output( ClearCode, outs );
outer_loop:
while ( (c = GIFNextPixel()) != EOF )
{
fcode = ( c << maxbits ) + ent;
i = ( c << hshift ) ^ ent; // xor hashing
if ( htab[i] == fcode )
{
ent = codetab[i];
continue;
}
else if ( htab[i] >= 0 ) // non-empty slot
{
disp = hsize_reg - i; // secondary hash (after G. Knott)
if ( i == 0 )
disp = 1;
do
{
if ( (i -= disp) < 0 )
i += hsize_reg;
if ( htab[i] == fcode )
{
ent = codetab[i];
continue outer_loop;
}
}
while ( htab[i] >= 0 );
}
output( ent, outs );
ent = c;
if ( free_ent < maxmaxcode )
{
codetab[i] = free_ent++; // code -> hashtable
htab[i] = fcode;
}
else
cl_block( outs );
}
// Put out the final code.
output( ent, outs );
output( EOFCode, outs );
}
// 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.
int cur_accum = 0;
int cur_bits = 0;
int masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF,
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
void output( int code, OutputStream outs ) throws IOException
{
cur_accum &= masks[cur_bits];
if ( cur_bits > 0 )
cur_accum |= ( code << cur_bits );
else
cur_accum = code;
cur_bits += n_bits;
while ( cur_bits >= 8 )
{
char_out( (byte) ( cur_accum & 0xff ), outs );
cur_accum >>= 8;
cur_bits -= 8;
}
// If the next entry is going to be too big for the code size,
// then increase it, if possible.
if ( free_ent > maxcode || clear_flg )
{
if ( clear_flg )
{
maxcode = MAXCODE(n_bits = g_init_bits);
clear_flg = false;
}
else
{
++n_bits;
if ( n_bits == maxbits )
maxcode = maxmaxcode;
else
maxcode = MAXCODE(n_bits);
}
}
if ( code == EOFCode )
{
// At EOF, write the rest of the buffer.
while ( cur_bits > 0 )
{
char_out( (byte) ( cur_accum & 0xff ), outs );
cur_accum >>= 8;
cur_bits -= 8;
}
flush_char( outs );
}
}
// Clear out the hash table
// table clear for block compress
void cl_block( OutputStream outs ) throws IOException
{
cl_hash( hsize );
free_ent = ClearCode + 2;
clear_flg = true;
output( ClearCode, outs );
}
// reset code table
void cl_hash( int hsize )
{
for ( int i = 0; i < hsize; ++i )
htab[i] = -1;
}
// GIF Specific routines
// Number of characters so far in this 'packet'
int a_count;
// Set up the 'byte output' routine
void char_init()
{
a_count = 0;
}
// Define the storage for the packet accumulator
byte[] accum = new byte[256];
// Add a character to the end of the current packet, and if it is 254
// characters, flush the packet to disk.
void char_out( byte c, OutputStream outs ) throws IOException
{
accum[a_count++] = c;
if ( a_count >= 254 )
flush_char( outs );
}
// Flush the packet to disk, and reset the accumulator
void flush_char( OutputStream outs ) throws IOException
{
if ( a_count > 0 )
{
outs.write( a_count );
outs.write( accum, 0, a_count );
a_count = 0;
}
}
}
class GifEncoderHashitem
{
public int rgb;
public int count;
public int index;
public boolean isTransparent;
public GifEncoderHashitem( int rgb, int count, int index, boolean isTransparent )
{
this.rgb = rgb;
this.count = count;
this.index = index;
this.isTransparent = isTransparent;
}
}

View file

@ -1,271 +0,0 @@
// ImageEncoder - abstract class for writing out an image
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Encoders;
import java.util.*;
import java.io.*;
import java.awt.Image;
import java.awt.image.*;
/// Abstract class for writing out an image.
// <P>
// A framework for classes that encode and write out an image in
// a particular file format.
// <P>
// This provides a simplified rendition of the ImageConsumer interface.
// It always delivers the pixels as ints in the RGBdefault color model.
// It always provides them in top-down left-right order.
// If you want more flexibility you can always implement ImageConsumer
// directly.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Encoders/ImageEncoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see GifEncoder
// @see PpmEncoder
// @see Acme.JPM.Decoders.ImageDecoder
public abstract class ImageEncoder implements ImageConsumer
{
protected OutputStream out;
private ImageProducer producer;
private int width = -1;
private int height = -1;
private int hintflags = 0;
private boolean started = false;
private boolean encoding;
private IOException iox;
private static final ColorModel rgbModel = ColorModel.getRGBdefault();
private Hashtable props = null;
/// Constructor.
// @param img The image to encode.
// @param out The stream to write the bytes to.
public ImageEncoder( Image img, OutputStream out ) throws IOException
{
this( img.getSource(), out );
}
/// Constructor.
// @param producer The ImageProducer to encode.
// @param out The stream to write the bytes to.
public ImageEncoder( ImageProducer producer, OutputStream out ) throws IOException
{
this.producer = producer;
this.out = out;
}
// Methods that subclasses implement.
/// Subclasses implement this to initialize an encoding.
abstract void encodeStart( int w, int h ) throws IOException;
/// Subclasses implement this to actually write out some bits. They
// are guaranteed to be delivered in top-down-left-right order.
// One int per pixel, index is row * scansize + off + col,
// RGBdefault (AARRGGBB) color model.
abstract void encodePixels(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException;
/// Subclasses implement this to finish an encoding.
abstract void encodeDone() throws IOException;
// Our own methods.
/// Call this after initialization to get things going.
public synchronized void encode() throws IOException
{
encoding = true;
iox = null;
producer.startProduction( this );
while ( encoding )
try
{
wait();
}
catch ( InterruptedException e ) {}
if ( iox != null )
throw iox;
}
private boolean accumulate = false;
private int[] accumulator;
private void encodePixelsWrapper(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException
{
if ( ! started )
{
started = true;
encodeStart( width, height );
if ( ( hintflags & TOPDOWNLEFTRIGHT ) == 0 )
{
accumulate = true;
accumulator = new int[width * height];
}
}
if ( accumulate )
for ( int row = 0; row < h; ++row )
System.arraycopy(
rgbPixels, row * scansize + off,
accumulator, ( y + row ) * width + x,
w );
else
encodePixels( x, y, w, h, rgbPixels, off, scansize );
}
private void encodeFinish() throws IOException
{
if ( accumulate )
{
encodePixels( 0, 0, width, height, accumulator, 0, width );
accumulator = null;
accumulate = false;
}
}
private synchronized void stop()
{
encoding = false;
notifyAll();
}
// Methods from ImageConsumer.
public void setDimensions( int width, int height )
{
this.width = width;
this.height = height;
}
public void setProperties( Hashtable props )
{
this.props = props;
}
public void setColorModel( ColorModel model )
{
// Ignore.
}
public void setHints( int hintflags )
{
this.hintflags = hintflags;
}
public void setPixels(
int x, int y, int w, int h, ColorModel model, byte[] pixels,
int off, int scansize )
{
int[] rgbPixels = new int[w];
for ( int row = 0; row < h; ++row )
{
int rowOff = off + row * scansize;
for ( int col = 0; col < w; ++col )
rgbPixels[col] = model.getRGB( pixels[rowOff + col] & 0xff );
try
{
encodePixelsWrapper( x, y + row, w, 1, rgbPixels, 0, w );
}
catch ( IOException e )
{
iox = e;
stop();
return;
}
}
}
public void setPixels(
int x, int y, int w, int h, ColorModel model, int[] pixels,
int off, int scansize )
{
if ( model == rgbModel )
{
try
{
encodePixelsWrapper( x, y, w, h, pixels, off, scansize );
}
catch ( IOException e )
{
iox = e;
stop();
return;
}
}
else
{
int[] rgbPixels = new int[w];
for ( int row = 0; row < h; ++row )
{
int rowOff = off + row * scansize;
for ( int col = 0; col < w; ++col )
rgbPixels[col] = model.getRGB( pixels[rowOff + col] );
try
{
encodePixelsWrapper( x, y + row, w, 1, rgbPixels, 0, w );
}
catch ( IOException e )
{
iox = e;
stop();
return;
}
}
}
}
public void imageComplete( int status )
{
producer.removeConsumer( this );
if ( status == ImageConsumer.IMAGEABORTED )
iox = new IOException( "image aborted" );
else
{
try
{
encodeFinish();
encodeDone();
}
catch ( IOException e )
{
iox = e;
}
}
stop();
}
}

View file

@ -1,448 +0,0 @@
// JpegEncoder - write out an image as a JPEG
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Encoders;
import java.util.*;
import java.io.*;
import java.awt.Image;
import java.awt.image.*;
/// Write out an image as a JPEG.
// DOESN'T WORK YET.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Encoders/JpegEncoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see ToJpeg
public class JpegEncoder extends ImageEncoder
{
/// Constructor.
// @param img The image to encode.
// @param out The stream to write the JPEG to.
public JpegEncoder( Image img, OutputStream out ) throws IOException
{
super( img, out );
}
/// Constructor.
// @param prod The ImageProducer to encode.
// @param out The stream to write the JPEG to.
public JpegEncoder( ImageProducer prod, OutputStream out ) throws IOException
{
super( prod, out );
}
int qfactor = 100;
/// Set the Q-factor.
public void setQfactor( int qfactor )
{
this.qfactor = qfactor;
}
int width, height;
int[][] rgbPixels;
void encodeStart( int width, int height ) throws IOException
{
this.width = width;
this.height = height;
rgbPixels = new int[height][width];
}
void encodePixels(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException
{
// Save the pixels.
for ( int row = 0; row < h; ++row )
System.arraycopy(
rgbPixels, row * scansize + off,
this.rgbPixels[y + row], x, w );
}
void encodeDone() throws IOException
{
writeJfifHuffHeader();
// !!!
}
// Some of the following code is derived from the Berkeley Continuous
// Media Toolkit (http://bmrc.berkeley.edu/projects/cmt/), which is
// Copyright (c) 1996 The Regents of the University of California.
// All rights reserved.
//
// IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
// OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
// UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
// ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
// This array represents the default JFIF header for quality = 100 and
// size = 640x480, with Huffman tables. The values are adjusted when a
// file is generated.
private static byte[] jfifHuff100Header = {
// SOI
(byte) 0xFF, (byte) 0xD8,
// JFIF header
(byte) 0xFF, (byte) 0xE0, // Marker
(byte) 0x00, (byte) 0x10, // Length = 16 bytes
(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46, // "JFIF"
(byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00,
(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
// Start of frame (section B.2.2)
(byte) 0xFF, (byte) 0xC0, // Baseline DCT
(byte) 0x00, (byte) 0x11, // Length = 17 bytes
(byte) 0x08, // Sample precision
(byte) 0x01, (byte) 0xE0, // Height
(byte) 0x02, (byte) 0x80, // Width
(byte) 0x03, // Number of components = 3
// Scan 1: 2:1 horiz, (byte) 1:1 vertical, (byte) use QT 0
(byte) 0x01, (byte) 0x21, (byte) 0x00,
// Scan 2: 1:1 horiz, (byte) 1:1 vertical, (byte) use QT 1
(byte) 0x02, (byte) 0x11, (byte) 0x01,
// Scan 3: 1:1 horiz, (byte) 1:1 vertical, (byte) use QT 1
(byte) 0x03, (byte) 0x11, (byte) 0x01,
// Define Quant table (section B.2.4.1)
(byte) 0xFF, (byte) 0xDB, // Marker
(byte) 0x00, (byte) 0x84, // Length (both tables)
(byte) 0x00, // 8 bit values, (byte) table 0
(byte) 0x10, (byte) 0x0B, (byte) 0x0C, (byte) 0x0E, (byte) 0x0C,
(byte) 0x0A, (byte) 0x10, (byte) 0x0E, (byte) 0x0D, (byte) 0x0E,
(byte) 0x12, (byte) 0x11, (byte) 0x10, (byte) 0x13, (byte) 0x18,
(byte) 0x28, (byte) 0x1A, (byte) 0x18, (byte) 0x16, (byte) 0x16,
(byte) 0x18, (byte) 0x31, (byte) 0x23, (byte) 0x25, (byte) 0x1D,
(byte) 0x28, (byte) 0x3A, (byte) 0x33, (byte) 0x3D, (byte) 0x3C,
(byte) 0x39, (byte) 0x33, (byte) 0x38, (byte) 0x37, (byte) 0x40,
(byte) 0x48, (byte) 0x5C, (byte) 0x4E, (byte) 0x40, (byte) 0x44,
(byte) 0x57, (byte) 0x45, (byte) 0x37, (byte) 0x38, (byte) 0x50,
(byte) 0x6D, (byte) 0x51, (byte) 0x57, (byte) 0x5F, (byte) 0x62,
(byte) 0x67, (byte) 0x68, (byte) 0x67, (byte) 0x3E, (byte) 0x4D,
(byte) 0x71, (byte) 0x79, (byte) 0x70, (byte) 0x64, (byte) 0x78,
(byte) 0x5C, (byte) 0x65, (byte) 0x67, (byte) 0x63,
(byte) 0x01, // 8 bit values, (byte) table 1
(byte) 0x11, (byte) 0x12, (byte) 0x12, (byte) 0x18, (byte) 0x15,
(byte) 0x18, (byte) 0x2F, (byte) 0x1A, (byte) 0x1A, (byte) 0x2F,
(byte) 0x63, (byte) 0x42, (byte) 0x38, (byte) 0x42, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
// Define huffman table (section B.2.4.1)
(byte) 0xFF, (byte) 0xC4, // Marker
(byte) 0x00, (byte) 0x1F, // Length (31 bytes)
(byte) 0x00, // DC, (byte) table 0
(byte) 0x00, (byte) 0x01, (byte) 0x05, (byte) 0x01, (byte) 0x01,
(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
(byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
(byte) 0x09, (byte) 0x0A, (byte) 0x0B,
// Define huffman table (section B.2.4.1)
(byte) 0xFF, (byte) 0xC4, // Marker
(byte) 0x00, (byte) 0xB5, // Length (181 bytes)
(byte) 0x10, // AC, (byte) table 0
(byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x03, (byte) 0x03,
(byte) 0x02, (byte) 0x04, (byte) 0x03, (byte) 0x05, (byte) 0x05,
(byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x01,
(byte) 0x7D, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x00,
(byte) 0x04, (byte) 0x11, (byte) 0x05, (byte) 0x12, (byte) 0x21,
(byte) 0x31, (byte) 0x41, (byte) 0x06, (byte) 0x13, (byte) 0x51,
(byte) 0x61, (byte) 0x07, (byte) 0x22, (byte) 0x71, (byte) 0x14,
(byte) 0x32, (byte) 0x81, (byte) 0x91, (byte) 0xA1, (byte) 0x08,
(byte) 0x23, (byte) 0x42, (byte) 0xB1, (byte) 0xC1, (byte) 0x15,
(byte) 0x52, (byte) 0xD1, (byte) 0xF0, (byte) 0x24, (byte) 0x33,
(byte) 0x62, (byte) 0x72, (byte) 0x82, (byte) 0x09, (byte) 0x0A,
(byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1A,
(byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29,
(byte) 0x2A, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37,
(byte) 0x38, (byte) 0x39, (byte) 0x3A, (byte) 0x43, (byte) 0x44,
(byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49,
(byte) 0x4A, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56,
(byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5A, (byte) 0x63,
(byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68,
(byte) 0x69, (byte) 0x6A, (byte) 0x73, (byte) 0x74, (byte) 0x75,
(byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7A,
(byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
(byte) 0x88, (byte) 0x89, (byte) 0x8A, (byte) 0x92, (byte) 0x93,
(byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98,
(byte) 0x99, (byte) 0x9A, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4,
(byte) 0xA5, (byte) 0xA6, (byte) 0xA7, (byte) 0xA8, (byte) 0xA9,
(byte) 0xAA, (byte) 0xB2, (byte) 0xB3, (byte) 0xB4, (byte) 0xB5,
(byte) 0xB6, (byte) 0xB7, (byte) 0xB8, (byte) 0xB9, (byte) 0xBA,
(byte) 0xC2, (byte) 0xC3, (byte) 0xC4, (byte) 0xC5, (byte) 0xC6,
(byte) 0xC7, (byte) 0xC8, (byte) 0xC9, (byte) 0xCA, (byte) 0xD2,
(byte) 0xD3, (byte) 0xD4, (byte) 0xD5, (byte) 0xD6, (byte) 0xD7,
(byte) 0xD8, (byte) 0xD9, (byte) 0xDA, (byte) 0xE1, (byte) 0xE2,
(byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6, (byte) 0xE7,
(byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xF1, (byte) 0xF2,
(byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7,
(byte) 0xF8, (byte) 0xF9, (byte) 0xFA,
// Define huffman table (section B.2.4.1)
(byte) 0xFF, (byte) 0xC4, // Marker
(byte) 0x00, (byte) 0x1F, // Length (31 bytes)
(byte) 0x01, // DC, (byte) table 1
(byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x01,
(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
(byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
(byte) 0x09, (byte) 0x0A, (byte) 0x0B,
// Define huffman table (section B.2.4.1)
(byte) 0xFF, (byte) 0xC4, // Marker
(byte) 0x00, (byte) 0xB5, // Length (181 bytes)
(byte) 0x11, // AC, (byte) table 1
(byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x04,
(byte) 0x04, (byte) 0x03, (byte) 0x04, (byte) 0x07, (byte) 0x05,
(byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x02,
(byte) 0x77, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
(byte) 0x11, (byte) 0x04, (byte) 0x05, (byte) 0x21, (byte) 0x31,
(byte) 0x06, (byte) 0x12, (byte) 0x41, (byte) 0x51, (byte) 0x07,
(byte) 0x61, (byte) 0x71, (byte) 0x13, (byte) 0x22, (byte) 0x32,
(byte) 0x81, (byte) 0x08, (byte) 0x14, (byte) 0x42, (byte) 0x91,
(byte) 0xA1, (byte) 0xB1, (byte) 0xC1, (byte) 0x09, (byte) 0x23,
(byte) 0x33, (byte) 0x52, (byte) 0xF0, (byte) 0x15, (byte) 0x62,
(byte) 0x72, (byte) 0xD1, (byte) 0x0A, (byte) 0x16, (byte) 0x24,
(byte) 0x34, (byte) 0xE1, (byte) 0x25, (byte) 0xF1, (byte) 0x17,
(byte) 0x18, (byte) 0x19, (byte) 0x1A, (byte) 0x26, (byte) 0x27,
(byte) 0x28, (byte) 0x29, (byte) 0x2A, (byte) 0x35, (byte) 0x36,
(byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3A, (byte) 0x43,
(byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48,
(byte) 0x49, (byte) 0x4A, (byte) 0x53, (byte) 0x54, (byte) 0x55,
(byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5A,
(byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67,
(byte) 0x68, (byte) 0x69, (byte) 0x6A, (byte) 0x73, (byte) 0x74,
(byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79,
(byte) 0x7A, (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85,
(byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8A,
(byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96,
(byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9A, (byte) 0xA2,
(byte) 0xA3, (byte) 0xA4, (byte) 0xA5, (byte) 0xA6, (byte) 0xA7,
(byte) 0xA8, (byte) 0xA9, (byte) 0xAA, (byte) 0xB2, (byte) 0xB3,
(byte) 0xB4, (byte) 0xB5, (byte) 0xB6, (byte) 0xB7, (byte) 0xB8,
(byte) 0xB9, (byte) 0xBA, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4,
(byte) 0xC5, (byte) 0xC6, (byte) 0xC7, (byte) 0xC8, (byte) 0xC9,
(byte) 0xCA, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4, (byte) 0xD5,
(byte) 0xD6, (byte) 0xD7, (byte) 0xD8, (byte) 0xD9, (byte) 0xDA,
(byte) 0xE2, (byte) 0xE3, (byte) 0xE4, (byte) 0xE5, (byte) 0xE6,
(byte) 0xE7, (byte) 0xE8, (byte) 0xE9, (byte) 0xEA, (byte) 0xF2,
(byte) 0xF3, (byte) 0xF4, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7,
(byte) 0xF8, (byte) 0xF9, (byte) 0xFA,
// Start of Scan (section B.2.3)
(byte) 0xFF, (byte) 0xDA, // Marker
(byte) 0x00, (byte) 0x0C, // Length of header
(byte) 0x03, // Number of image components
// Scan 1: use DC/AC huff tables 0/0
(byte) 0x01, (byte) 0x00,
// Scan 2: use DC/AC huff tables 1/1
(byte) 0x02, (byte) 0x11,
// Scan 3: use DC/AC huff tables 1/1
(byte) 0x03, (byte) 0x11,
(byte) 0x00, (byte) 0x3F, (byte) 0x00 // Not used
};
// This array represents the default JFIF header for quality = 100 and
// size = 640x480, without Huffman tables. The values are adjusted when a
// file is generated.
private static byte[] jfifNoHuff100Header = {
// SOI
(byte) 0xFF, (byte) 0xD8,
// JFIF header
(byte) 0xFF, (byte) 0xE0, // Marker
(byte) 0x00, (byte) 0x10, // Length = 16 bytes
(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46, // "JFIF"
(byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00,
(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
// Start of frame (section B.2.2)
(byte) 0xFF, (byte) 0xC0, // Baseline DCT
(byte) 0x00, (byte) 0x11, // Length = 17 bytes
(byte) 0x08, // Sample precision
(byte) 0x01, (byte) 0xE0, // Height
(byte) 0x02, (byte) 0x80, // Width
(byte) 0x03, // Number of components = 3
// Scan 1: 2:1 horiz, (byte) 1:1 vertical, (byte) use QT 0
(byte) 0x01, (byte) 0x21, (byte) 0x00,
// Scan 2: 1:1 horiz, (byte) 1:1 vertical, (byte) use QT 1
(byte) 0x02, (byte) 0x11, (byte) 0x01,
// Scan 3: 1:1 horiz, (byte) 1:1 vertical, (byte) use QT 1
(byte) 0x03, (byte) 0x11, (byte) 0x01,
// Define Quant table (section B.2.4.1)
(byte) 0xFF, (byte) 0xDB, // Marker
(byte) 0x00, (byte) 0x84, // Length (both tables)
(byte) 0x00, // 8 bit values, (byte) table 0
(byte) 0x10, (byte) 0x0B, (byte) 0x0C, (byte) 0x0E, (byte) 0x0C,
(byte) 0x0A, (byte) 0x10, (byte) 0x0E, (byte) 0x0D, (byte) 0x0E,
(byte) 0x12, (byte) 0x11, (byte) 0x10, (byte) 0x13, (byte) 0x18,
(byte) 0x28, (byte) 0x1A, (byte) 0x18, (byte) 0x16, (byte) 0x16,
(byte) 0x18, (byte) 0x31, (byte) 0x23, (byte) 0x25, (byte) 0x1D,
(byte) 0x28, (byte) 0x3A, (byte) 0x33, (byte) 0x3D, (byte) 0x3C,
(byte) 0x39, (byte) 0x33, (byte) 0x38, (byte) 0x37, (byte) 0x40,
(byte) 0x48, (byte) 0x5C, (byte) 0x4E, (byte) 0x40, (byte) 0x44,
(byte) 0x57, (byte) 0x45, (byte) 0x37, (byte) 0x38, (byte) 0x50,
(byte) 0x6D, (byte) 0x51, (byte) 0x57, (byte) 0x5F, (byte) 0x62,
(byte) 0x67, (byte) 0x68, (byte) 0x67, (byte) 0x3E, (byte) 0x4D,
(byte) 0x71, (byte) 0x79, (byte) 0x70, (byte) 0x64, (byte) 0x78,
(byte) 0x5C, (byte) 0x65, (byte) 0x67, (byte) 0x63,
(byte) 0x01, // 8 bit values, (byte) table 1
(byte) 0x11, (byte) 0x12, (byte) 0x12, (byte) 0x18, (byte) 0x15,
(byte) 0x18, (byte) 0x2F, (byte) 0x1A, (byte) 0x1A, (byte) 0x2F,
(byte) 0x63, (byte) 0x42, (byte) 0x38, (byte) 0x42, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
(byte) 0x63, (byte) 0x63, (byte) 0x63, (byte) 0x63,
// Start of Scan (section B.2.3)
(byte) 0xFF, (byte) 0xDA, // Marker
(byte) 0x00, (byte) 0x0C, // Length of header
(byte) 0x03, // Number of image components
// Scan 1: use DC/AC huff tables 0/0
(byte) 0x01, (byte) 0x00,
// Scan 2: use DC/AC huff tables 1/1
(byte) 0x02, (byte) 0x11,
// Scan 3: use DC/AC huff tables 1/1
(byte) 0x03, (byte) 0x11,
(byte) 0x00, (byte) 0x3F, (byte) 0x00 // Not used
};
private void writeJfifHuffHeader() throws IOException
{
byte[] newHeader = new byte[jfifHuff100Header.length];
System.arraycopy(
jfifHuff100Header, 0, newHeader, 0, jfifHuff100Header.length );
// Set image width in JFIF header.
newHeader[27] = (byte) ( ( width >>> 8 ) & 0xff );
newHeader[28] = (byte) ( width & 0xff );
// Set image height in JFIF header.
newHeader[25] = (byte) ( ( height >>> 8 ) & 0xff );
newHeader[26] = (byte) ( height & 0xff );
// Adjust the quality factor.
//
// The default quality factor is 100, therefore if
// our quality factor does not equal 100 we must
// scale the quantization matrices in the JFIF header.
// Note that values are clipped to a max of 255.
if ( qfactor != 100 )
{
for ( int i = 44; i < 108; ++i )
{
int t = ( newHeader[i] * qfactor ) / 100;
newHeader[i] = (byte) Math.max( t, 0xff );
}
for ( int i = 109; i < 173; ++i )
{
int t = ( newHeader[i] * qfactor ) / 100;
newHeader[i] = (byte) Math.max( t, 0xff );
}
}
// Write out buffer.
out.write( newHeader );
}
private void writeJfifNoHuffHeader() throws IOException
{
byte[] newHeader = new byte[jfifNoHuff100Header.length];
System.arraycopy(
jfifNoHuff100Header, 0, newHeader, 0, jfifNoHuff100Header.length );
// Set image width in JFIF header.
newHeader[27] = (byte) ( ( width >>> 8 ) & 0xff );
newHeader[28] = (byte) ( width & 0xff );
// Set image height in JFIF header.
newHeader[25] = (byte) ( ( height >>> 8 ) & 0xff );
newHeader[26] = (byte) ( height & 0xff );
// Adjust the quality factor.
//
// The default quality factor is 100, therefore if
// our quality factor does not equal 100 we must
// scale the quantization matrices in the JFIF header.
// Note that values are clipped to a max of 255.
if ( qfactor != 100 )
{
for ( int i = 44; i < 108; ++i )
{
int t = ( newHeader[i] * qfactor ) / 100;
newHeader[i] = (byte) Math.max( t, 0xff );
}
for ( int i = 109; i < 173; ++i )
{
int t = ( newHeader[i] * qfactor ) / 100;
newHeader[i] = (byte) Math.max( t, 0xff );
}
}
// Write out buffer.
out.write( newHeader );
}
}

View file

@ -1,103 +0,0 @@
// PpmEncoder - write out an image as a PPM
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Encoders;
import java.util.*;
import java.io.*;
import java.awt.Image;
import java.awt.image.*;
/// Write out an image as a PPM.
// <P>
// Writes an image onto a specified OutputStream in the PPM file format.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Encoders/PpmEncoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see ToPpm
public class PpmEncoder extends ImageEncoder
{
/// Constructor.
// @param img The image to encode.
// @param out The stream to write the PPM to.
public PpmEncoder( Image img, OutputStream out ) throws IOException
{
super( img, out );
}
/// Constructor.
// @param prod The ImageProducer to encode.
// @param out The stream to write the PPM to.
public PpmEncoder( ImageProducer prod, OutputStream out ) throws IOException
{
super( prod, out );
}
void encodeStart( int width, int height ) throws IOException
{
writeString( out, "P6\n" );
writeString( out, width + " " + height + "\n" );
writeString( out, "255\n" );
}
static void writeString( OutputStream out, String str ) throws IOException
{
byte[] buf = str.getBytes();
out.write( buf );
}
void encodePixels(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException
{
byte[] ppmPixels = new byte[w * 3];
for ( int row = 0; row < h; ++row )
{
int rowOff = off + row * scansize;
for ( int col = 0; col < w; ++col )
{
int i = rowOff + col;
int j = col * 3;
ppmPixels[j ] = (byte) ( ( rgbPixels[i] & 0xff0000 ) >> 16 );
ppmPixels[j + 1] = (byte) ( ( rgbPixels[i] & 0x00ff00 ) >> 8 );
ppmPixels[j + 2] = (byte) ( rgbPixels[i] & 0x0000ff );
}
out.write( ppmPixels );
}
}
void encodeDone() throws IOException
{
// Nothing.
}
}

View file

@ -1,106 +0,0 @@
// CompositeFilter - compose two filters into one
//
// Copyright (C) 1997 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
import java.util.*;
/// Compose two filters into one.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/CompositeFilter.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class CompositeFilter extends ImageFilterPlus
{
private ImageFilterPlus filterOne, filterTwo;
private ImageFilter instanceOne, instanceTwo;
/// Constructor. Builds a filter chain with a FilteredImageSource as
// the glue.
public CompositeFilter( ImageProducer producer, ImageFilterPlus filterOne, ImageFilterPlus filterTwo )
{
super( producer );
this.filterOne = filterOne;
this.filterTwo = filterTwo;
filterOne.setSource( producer );
ImageProducer producerOne =
new FilteredImageSource( producer, filterOne );
filterTwo.setSource( producerOne );
}
public ImageFilter getFilterInstance( ImageConsumer consumer )
{
CompositeFilter instance = (CompositeFilter) clone();
instance.instanceTwo = filterTwo.getFilterInstance( consumer );
instance.instanceOne = filterOne.getFilterInstance( instanceTwo );
return (ImageFilter) instance;
}
// The rest of the methods just delegate to instanceOne.
public void setColorModel( ColorModel model )
{
instanceOne.setColorModel( model );
}
public void setDimensions( int width, int height )
{
instanceOne.setDimensions( width, height );
}
public void setHints( int hintflags )
{
instanceOne.setHints( hintflags );
}
public void setProperties( Hashtable props )
{
instanceOne.setProperties( props );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
instanceOne.setPixels( x, y, w, h, model, pixels, off, scansize );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
instanceOne.setPixels( x, y, w, h, model, pixels, off, scansize );
}
public void imageComplete( int status )
{
//super.imageComplete( status );
instanceOne.imageComplete( status );
}
}

View file

@ -1,169 +0,0 @@
// EdgeDetect - edge-detection filter
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.io.*;
import java.awt.image.*;
import Acme.JPM.Decoders.*;
import Acme.JPM.Encoders.*;
/// Edge-detection filter.
// <IMG ALIGN=RIGHT WIDTH=202 HEIGHT=200 SRC="Earth-EdgeDetect.jpg">
// <IMG ALIGN=RIGHT WIDTH=202 HEIGHT=200 SRC="Earth.jpg">
// <P>
// Outlines the edges of an image.
// The edge detection technique used is to take the Pythagorean sum of
// two Sobel gradient operators at 90 degrees to each other, separately
// for each color component.
// For more details see "Digital Image Processing" by Gonzalez and Wintz,
// chapter 7.
// <P>
// This filter is slow.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/EdgeDetect.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class EdgeDetect extends RGBAllFilter
{
// Constructor.
public EdgeDetect( ImageProducer producer )
{
super( producer );
}
private static final double SCALE = 1.8D;
public void filterRGBAll( int width, int height, int[][] rgbPixels )
{
int[][] newPixels = new int[height][width];
long sum1, sum2;
double sum;
int r, g, b;
// First and last rows are black.
for ( int col = 0; col < width; ++col )
{
newPixels[0][col] = 0xff000000;
newPixels[height - 1][col] = 0xff000000;
}
for ( int row = 1; row < height - 1; ++row )
{
// First and last columns are black too.
newPixels[row][0] = 0xff000000;
newPixels[row][width - 1] = 0xff000000;
// The real pixels.
for ( int col = 1; col < width - 1; ++col )
{
sum1 =
rgbModel.getRed( rgbPixels[row - 1][col + 1] ) -
rgbModel.getRed( rgbPixels[row - 1][col - 1] ) +
2 * (
rgbModel.getRed( rgbPixels[row][col + 1] ) -
rgbModel.getRed( rgbPixels[row][col - 1] ) ) +
rgbModel.getRed( rgbPixels[row + 1][col + 1] ) -
rgbModel.getRed( rgbPixels[row + 1][col - 1] );
sum2 = (
rgbModel.getRed( rgbPixels[row + 1][col - 1] ) +
2 * rgbModel.getRed( rgbPixels[row + 1][col] ) +
rgbModel.getRed( rgbPixels[row + 1][col + 1] )
) - (
rgbModel.getRed( rgbPixels[row - 1][col - 1] ) +
2 * rgbModel.getRed( rgbPixels[row - 1][col] ) +
rgbModel.getRed( rgbPixels[row - 1][col + 1] )
);
sum = Math.sqrt( (double) ( sum1*sum1 + sum2*sum2 ) ) / SCALE;
r = Math.min( (int) sum, 255 );
sum1 =
rgbModel.getGreen( rgbPixels[row - 1][col + 1] ) -
rgbModel.getGreen( rgbPixels[row - 1][col - 1] ) +
2 * (
rgbModel.getGreen( rgbPixels[row][col + 1] ) -
rgbModel.getGreen( rgbPixels[row][col - 1] ) ) +
rgbModel.getGreen( rgbPixels[row + 1][col + 1] ) -
rgbModel.getGreen( rgbPixels[row + 1][col - 1] );
sum2 = (
rgbModel.getGreen( rgbPixels[row + 1][col - 1] ) +
2 * rgbModel.getGreen( rgbPixels[row + 1][col] ) +
rgbModel.getGreen( rgbPixels[row + 1][col + 1] )
) - (
rgbModel.getGreen( rgbPixels[row - 1][col - 1] ) +
2 * rgbModel.getGreen( rgbPixels[row - 1][col] ) +
rgbModel.getGreen( rgbPixels[row - 1][col + 1] )
);
sum = Math.sqrt( (double) ( sum1*sum1 + sum2*sum2 ) ) / SCALE;
g = Math.min( (int) sum, 255 );
sum1 =
rgbModel.getBlue( rgbPixels[row - 1][col + 1] ) -
rgbModel.getBlue( rgbPixels[row - 1][col - 1] ) +
2 * (
rgbModel.getBlue( rgbPixels[row][col + 1] ) -
rgbModel.getBlue( rgbPixels[row][col - 1] ) ) +
rgbModel.getBlue( rgbPixels[row + 1][col + 1] ) -
rgbModel.getBlue( rgbPixels[row + 1][col - 1] );
sum2 = (
rgbModel.getBlue( rgbPixels[row + 1][col - 1] ) +
2 * rgbModel.getBlue( rgbPixels[row + 1][col] ) +
rgbModel.getBlue( rgbPixels[row + 1][col + 1] )
) - (
rgbModel.getBlue( rgbPixels[row - 1][col - 1] ) +
2 * rgbModel.getBlue( rgbPixels[row - 1][col] ) +
rgbModel.getBlue( rgbPixels[row - 1][col + 1] )
);
sum = Math.sqrt( (double) ( sum1*sum1 + sum2*sum2 ) ) / SCALE;
b = Math.min( (int) sum, 255 );
newPixels[row][col] =
0xff000000 | ( r << 16 ) | ( g << 8 ) | b;
}
}
setPixels( width, height, newPixels );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 0 )
usage();
ImageFilterPlus filter = new EdgeDetect( null );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: EdgeDetect" );
System.exit( 1 );
}
}

View file

@ -1,140 +0,0 @@
// Enlarge - an ImageFilter that enlarges by pixel replication
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// An ImageFilter that enlarges by pixel replication.
// <P>
// Enlarges an image an integral factor by replicating pixels.
// The output uses the same color model as the input.
// This filter is very fast.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Enlarge.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Shrink
// @see ScaleCopy
public class Enlarge extends ImageFilterPlus
{
private int multiplier;
private int newWidth, newHeight;
/// Constructor.
public Enlarge( ImageProducer producer, int multiplier )
{
super( producer );
this.multiplier = multiplier;
}
public void setDimensions( int width, int height )
{
newWidth = width * multiplier;
newHeight = height * multiplier;
consumer.setDimensions( newWidth, newHeight );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
int newX = Math.min( x * multiplier, newWidth - 1 );
int newY = Math.min( y * multiplier, newHeight - 1 );
int newW = w * multiplier;
if ( newX + newW > newWidth )
newW = newWidth - newX;
int newH = h * multiplier;
if ( newY + newH > newHeight )
newH = newHeight - newY;
byte[] newPixels = new byte[newW * newH];
for ( int row = 0; row < h; ++row )
{
for ( int col = 0; col < w; ++col )
{
byte pixel = pixels[row * scansize + off + col];
for ( int i = 0; i < multiplier; ++i )
for ( int j = 0; j < multiplier; ++j )
{
int newRow = row * multiplier + i;
int newCol = col * multiplier + j;
newPixels[newRow * newW + newCol] = pixel;
}
}
}
consumer.setPixels( newX, newY, newW, newH, model, newPixels, 0, newW );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
int newX = Math.min( x * multiplier, newWidth - 1 );
int newY = Math.min( y * multiplier, newHeight - 1 );
int newW = w * multiplier;
if ( newX + newW > newWidth )
newW = newWidth - newX;
int newH = h * multiplier;
if ( newY + newH > newHeight )
newH = newHeight - newY;
int[] newPixels = new int[newW * newH];
for ( int row = 0; row < h; ++row )
{
for ( int col = 0; col < w; ++col )
{
int pixel = pixels[row * scansize + off + col];
for ( int i = 0; i < multiplier; ++i )
for ( int j = 0; j < multiplier; ++j )
{
int newRow = row * multiplier + i;
int newCol = col * multiplier + j;
newPixels[newRow * newW + newCol] = pixel;
}
}
}
consumer.setPixels( newX, newY, newW, newH, model, newPixels, 0, newW );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 1 )
usage();
ImageFilterPlus filter =
new Enlarge( null, Integer.parseInt( args[0] ) );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Enlarge <multiplier>" );
System.exit( 1 );
}
}

View file

@ -1,295 +0,0 @@
// Flip - an ImageFilter that flips or rotates the image
//
// Copyright (C) 1997 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// An ImageFilter that flips or rotates the image.
// <P>
// Flips the image left-right, top-bottom, rotates clockwise or
// counter-clockwise, or otherwise munges the image as specified.
// This filter is fast.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Flip.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Flip extends ImageFilterPlus
{
/// The null transformation.
public static final int FLIP_NULL = 0;
/// Flip left to right.
public static final int FLIP_LR = 1;
/// Flip top to bottom.
public static final int FLIP_TB = 2;
/// Transpose X and Y - reflection along a diagonal.
public static final int FLIP_XY = 3;
/// Rotate clockwise 90 degrees.
public static final int FLIP_CW = 4;
/// Rotate counter-clockwise 90 degrees.
public static final int FLIP_CCW = 5;
/// Rotate 180 degrees.
public static final int FLIP_R180 = 6;
private int flipType;
private int width, height;
private int newWidth, newHeight;
/// Constructor.
public Flip( ImageProducer producer, int flipType )
{
super( producer, true );
this.flipType = flipType;
}
public void setDimensions( int width, int height )
{
this.width = width;
this.height = height;
switch ( flipType )
{
case FLIP_NULL:
case FLIP_LR:
case FLIP_TB:
case FLIP_R180:
newWidth = width;
newHeight = height;
break;
case FLIP_XY:
case FLIP_CW:
case FLIP_CCW:
newWidth = height;
newHeight = width;
break;
}
consumer.setDimensions( newWidth, newHeight );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
int newX = x;
int newY = y;
int newW = w;
int newH = h;
switch ( flipType )
{
case FLIP_NULL:
break;
case FLIP_LR:
newX = width - ( x + w );
break;
case FLIP_TB:
newY = height - ( y + h );
break;
case FLIP_XY:
newW = h;
newH = w;
newX = y;
newY = x;
break;
case FLIP_CW:
newW = h;
newH = w;
newX = height - ( y + h );
newY = x;
break;
case FLIP_CCW:
newW = h;
newH = w;
newX = y;
newY = width - ( x + w );
break;
case FLIP_R180:
newX = width - ( x + w );
newY = height - ( y + h );
break;
}
byte[] newPixels = new byte[newW * newH];
for ( int row = 0; row < h; ++row )
{
for ( int col = 0; col < w; ++col )
{
int index = row * scansize + off + col;
int newRow = row;
int newCol = col;
switch ( flipType )
{
case FLIP_NULL:
break;
case FLIP_LR:
newCol = w - col - 1;
break;
case FLIP_TB:
newRow = h - row - 1;
break;
case FLIP_XY:
newRow = col;
newCol = row;
break;
case FLIP_CW:
newRow = col;
newCol = h - row - 1;;
break;
case FLIP_CCW:
newRow = w - col - 1;
newCol = row;
break;
case FLIP_R180:
newRow = h - row - 1;
newCol = w - col - 1;
break;
}
int newIndex = newRow * newW + newCol;
newPixels[newIndex] = pixels[index];
}
}
consumer.setPixels( newX, newY, newW, newH, model, newPixels, 0, newW );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
int newX = x;
int newY = y;
int newW = w;
int newH = h;
switch ( flipType )
{
case FLIP_NULL:
break;
case FLIP_LR:
newX = width - ( x + w );
break;
case FLIP_TB:
newY = height - ( y + h );
break;
case FLIP_XY:
newW = h;
newH = w;
newX = y;
newY = x;
break;
case FLIP_CW:
newW = h;
newH = w;
newX = height - ( y + h );
newY = x;
break;
case FLIP_CCW:
newW = h;
newH = w;
newX = y;
newY = width - ( x + w );
break;
case FLIP_R180:
newX = width - ( x + w );
newY = height - ( y + h );
break;
}
int[] newPixels = new int[newW * newH];
for ( int row = 0; row < h; ++row )
{
for ( int col = 0; col < w; ++col )
{
int index = row * scansize + off + col;
int newRow = row;
int newCol = col;
switch ( flipType )
{
case FLIP_NULL:
break;
case FLIP_LR:
newCol = w - col - 1;
break;
case FLIP_TB:
newRow = h - row - 1;
break;
case FLIP_XY:
newRow = col;
newCol = row;
break;
case FLIP_CW:
newRow = col;
newCol = h - row - 1;;
break;
case FLIP_CCW:
newRow = w - col - 1;
newCol = row;
break;
case FLIP_R180:
newRow = h - row - 1;
newCol = w - col - 1;
break;
}
int newIndex = newRow * newW + newCol;
newPixels[newIndex] = pixels[index];
}
}
consumer.setPixels( newX, newY, newW, newH, model, newPixels, 0, newW );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 1 )
usage();
int flipType = FLIP_NULL;
if ( args[0].equalsIgnoreCase( "-lr" ) )
flipType = FLIP_LR;
else if ( args[0].equalsIgnoreCase( "-tb" ) )
flipType = FLIP_TB;
else if ( args[0].equalsIgnoreCase( "-xy" ) )
flipType = FLIP_XY;
else if ( args[0].equalsIgnoreCase( "-cw" ) )
flipType = FLIP_CW;
else if ( args[0].equalsIgnoreCase( "-ccw" ) )
flipType = FLIP_CCW;
else if ( args[0].equalsIgnoreCase( "-r180" ) )
flipType = FLIP_R180;
else
usage();
ImageFilterPlus filter = new Flip( null, flipType );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Flip -lr|-tb|-xy|-cw|-ccw|-r180" );
System.exit( 1 );
}
}

View file

@ -1,148 +0,0 @@
// Gamma - gamma-correction filter
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// Gamma-correction filter.
// <P>
// Gamma correction fixes a form of color distortion common to many monitors.
// Values less than 1.0 darken the image, and greater than 1.0 lighten it.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Gamma.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Gamma extends RGBBlockFilter
{
private double rValue, gValue, bValue;
/// Constructor, single exponent.
public Gamma( ImageProducer producer, double value )
{
this( producer, value, value, value );
}
/// Constructor, different exponents for R G and B.
public Gamma( ImageProducer producer, double rValue, double gValue, double bValue )
{
super( producer );
this.rValue = rValue;
this.gValue = gValue;
this.bValue = bValue;
}
private int[] rTable, gTable, bTable;
public int[][] filterRGBBlock( int x, int y, int width, int height, int[][] rgbPixels )
{
initialize();
for ( int row = 0; row < height; ++row )
for ( int col = 0; col < width; ++col )
{
int rgb = rgbPixels[row][col];
int a = ( rgb >> 24 ) & 0xff;
int r = ( rgb >> 16 ) & 0xff;
int g = ( rgb >> 8 ) & 0xff;
int b = rgb & 0xff;
r = rTable[r];
g = gTable[g];
b = bTable[b];
rgbPixels[row][col] =
( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
}
return rgbPixels;
}
private boolean initialized = false;
private void initialize()
{
if ( initialized )
return;
initialized = true;
rTable = buildTable( rValue );
if ( gValue == rValue )
gTable = rTable;
else
gTable = buildTable( gValue );
if ( bValue == rValue )
bTable = rTable;
else if ( bValue == gValue )
bTable = gTable;
else
bTable = buildTable( bValue );
}
private int[] buildTable( double gamma )
{
int[] table = new int[256];
double oneOverGamma = 1.0D / gamma;
for ( int i = 0; i < 256; ++i )
{
int v = (int) (
( 255.0D * Math.pow( i / 255.0D, oneOverGamma ) ) + 0.5D );
if ( v > 255 )
v = 255;
table[i] = v;
}
return table;
}
// Main routine for command-line interface.
public static void main( String[] args )
{
ImageFilterPlus filter = null;
if ( args.length == 1 )
filter = new Gamma( null, Double.valueOf( args[0] ).doubleValue() );
else if ( args.length == 3 )
filter = new Gamma( null,
Double.valueOf( args[0] ).doubleValue(),
Double.valueOf( args[1] ).doubleValue(),
Double.valueOf( args[2] ).doubleValue() );
else
usage();
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Gamma <value>" );
System.err.println( "or: Gamma <rValue> <gValue> <bValue>" );
System.exit( 1 );
}
}

View file

@ -1,160 +0,0 @@
// ImageFilterPlus - an ImageFilter with some extra features and bug fixes
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
import java.io.*;
import Acme.JPM.Decoders.*;
import Acme.JPM.Encoders.*;
/// An ImageFilter with some extra features and bug fixes.
// <P>
// You can use an image filter to turn one Image into another via
// a FilteredImageSource, e.g.:
// <BLOCKQUOTE><CODE><PRE>
// Image newImage = comp.createImage( new FilteredImageSource(
// oldImage.getSource(), new SomeFilter( oldImage.getSource() ) ) );
// </PRE></CODE></BLOCKQUOTE>
// Or use the convenient utility JPMUtils.filterImage():
// <BLOCKQUOTE><CODE><PRE>
// Image newImage = JPMUtils.filterImage(
// comp, SomeFilter( oldImage.getSource() ) );
// </PRE></CODE></BLOCKQUOTE>
// <P>
// You can also use image filters from the command line, reading PPM
// from stdin and writing PPM to stdout, if you add code like the following
// to each filter:
// <BLOCKQUOTE><CODE><PRE>
// System.exit(
// ImageFilterPlus.filterStream(
// System.in, System.out,
// new SomeFilter( null ) ) );
// </PRE></CODE></BLOCKQUOTE>
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/ImageFilterPlus.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class ImageFilterPlus extends ImageFilter
{
private ImageProducer producer;
private boolean pixelOrderChanges;
/// Constructor.
// @param producer The ImageProducer is required, so that we can
// remove ourself from its consumers list when we're done.
// However, if you don't have the producer available when you want
// to create the filter, you can pass in null and set it later
// via setSource().
public ImageFilterPlus( ImageProducer producer )
{
this( producer, false );
}
/// Constructor, with pixel order change.
// @param producer The ImageProducer is required, so that we can
// remove ourself from its consumers list when we're done.
// However, if you don't have the producer available when you want
// to create the filter, you can pass in null and set it later
// via setSource().
// @param pixelOrderChanges If the filter may output pixels in a different
// order from the one they were delivered in, this flag must be set.
public ImageFilterPlus( ImageProducer producer, boolean pixelOrderChanges )
{
setSource( producer );
this.pixelOrderChanges = pixelOrderChanges;
}
/// The default color model - useful for comparisons.
public static final ColorModel rgbModel = ColorModel.getRGBdefault();
/// Return the ImageProducer for this filter.
public ImageProducer getSource()
{
return producer;
}
/// Set the ImageProducer for this filter, if it wasn't set by the
// constructor.
public void setSource( ImageProducer producer )
{
this.producer = producer;
}
/// Set the hint flags. If the pixel order may change, we have to
// turn off the TOPDOWNLEFTRIGHT flag; otherwise the flags are passed
// through unmodified.
public void setHints( int hintflags )
{
if ( pixelOrderChanges )
hintflags &= ~TOPDOWNLEFTRIGHT;
consumer.setHints( hintflags );
}
/// This routine fixes a bug in java.awt.image.ImageFilter. All
// ImageConsumers are required remove themselves from the producer's
// list when they're done reading. If they don't do this then some
// producers will generate an error. The standard ImageFilter class
// fails to do this, but this one does it.
public void imageComplete( int status )
{
if ( status != ImageConsumer.SINGLEFRAMEDONE )
producer.removeConsumer( this );
super.imageComplete( status );
}
/// Filter a PPM InputStream to a PPM OutputStream.
// <P>
// Create the filter with a null producer, and this routine will
// fill it in for you.
// @return a status code suitable for use with System.exit().
public static int filterStream( InputStream in, OutputStream out, ImageFilterPlus filter )
{
ImageDecoder producer = new PpmDecoder( in );
filter.setSource( producer );
try
{
ImageEncoder consumer = new PpmEncoder(
new FilteredImageSource( producer, filter ), out );
consumer.encode();
}
catch ( IOException e )
{
System.err.println( e.toString() );
return 1;
}
return 0;
}
}

View file

@ -1,83 +0,0 @@
// Invert - color-inversion filter
//
// Copyright (C) 1997 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// Color-inversion filter.
// <P>
// Switches black for white, and all the other colors too.
// This filter is very fast.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Invert.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Invert extends RGBBlockFilter
{
/// Constructor.
public Invert( ImageProducer producer )
{
super( producer );
}
public int[][] filterRGBBlock( int x, int y, int width, int height, int[][] rgbPixels )
{
for ( int row = 0; row < height; ++row )
for ( int col = 0; col < width; ++col )
{
int rgb = rgbPixels[row][col];
int alpha = rgb & 0xff000000;
int rest = ( ~ rgb ) & 0x00ffffff;
rgbPixels[row][col] = alpha | rest;
}
return rgbPixels;
}
// Main routine for command-line interface.
public static void main( String[] args )
{
ImageFilterPlus filter = null;
if ( args.length == 0 )
filter = new Invert( null );
else
usage();
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Invert" );
System.exit( 1 );
}
}

View file

@ -1,133 +0,0 @@
// Margin - an ImageFilter that adds a margin to an image
//
// Copyright (C) 1997 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.*;
import java.awt.image.*;
/// An ImageFilter that adds a margin to an image.
// <P>
// Adds a margin of a specified color and width around an image.
// The output uses the same color model as the input.
// This filter is very fast.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Margin.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Margin extends ImageFilterPlus
{
private Color color;
private int size;
private int width, height;
private int newWidth;
/// Constructor.
public Margin( ImageProducer producer, Color color, int size )
{
super( producer, true );
this.color = color;
this.size = size;
}
public void setDimensions( int width, int height )
{
this.width = width;
this.height = height;
newWidth = width + size * 2;
consumer.setDimensions( newWidth, height + size * 2 );
}
private boolean started = false;
private void start()
{
started = true;
int rgb = color.getRGB();
int[] fullRow = new int[newWidth];
for ( int col = 0; col < newWidth; ++col )
fullRow[col] = rgb;
for ( int row = 0; row < size; ++row )
{
consumer.setPixels(
0, row, newWidth, 1, rgbModel, fullRow, 0, newWidth );
consumer.setPixels(
0, size + height + row, newWidth, 1, rgbModel, fullRow, 0,
newWidth );
}
int[] sideRow = new int[size];
for ( int col = 0; col < size; ++col )
sideRow[col] = rgb;
for ( int row = 0; row < height; ++row )
{
consumer.setPixels(
0, size + row, size, 1, rgbModel, sideRow, 0, size );
consumer.setPixels(
size + width, size + row, size, 1, rgbModel, sideRow, 0, size );
}
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
if ( ! started )
start();
consumer.setPixels(
x + size, y + size, w, h, model, pixels, off, scansize );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
if ( ! started )
start();
consumer.setPixels(
x + size, y + size, w, h, model, pixels, off, scansize );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 1 )
usage();
ImageFilterPlus filter =
new Margin( null, Color.black, Integer.parseInt( args[0] ) );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Margin <size>" );
System.exit( 1 );
}
}

View file

@ -1,141 +0,0 @@
// Oil - oil-transfer filter
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// Oil-transfer filter.
// <IMG ALIGN=RIGHT WIDTH=202 HEIGHT=200 SRC="Earth-Oil.jpg">
// <IMG ALIGN=RIGHT WIDTH=202 HEIGHT=200 SRC="Earth.jpg">
// <P>
// The oil transfer is described in "Beyond Photography" by Holzmann,
// chapter 4, photo 7.
// It's a sort of localized smearing.
// The parameter controls the size of the smeared area, with a default of 3.
// <P>
// This filter is very slow.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Oil.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Oil extends RGBAllFilter
{
private int n;
/// Constructor.
public Oil( ImageProducer producer, int n )
{
super( producer );
this.n = n;
}
/// Constructor, default value.
public Oil( ImageProducer producer )
{
this( producer, 3 );
}
public void filterRGBAll( int width, int height, int[][] rgbPixels )
{
int[][] newPixels = new int[height][width];
int[] rHist = new int[256];
int[] gHist = new int[256];
int[] bHist = new int[256];
for ( int row = 0; row < height; ++row )
{
for ( int col = 0; col < width; ++col )
{
for ( int i = 0; i < 256; ++i )
rHist[i] = gHist[i] = bHist[i] =0;
for ( int drow = row - n; drow <= row + n; ++drow )
if ( drow >= 0 && drow < height )
for ( int dcol = col - n; dcol <= col + n; ++dcol )
if ( dcol >= 0 && dcol < width )
{
int rgb = rgbPixels[drow][dcol];
rHist[( rgb >> 16 ) & 0xff]++;
gHist[( rgb >> 8 ) & 0xff]++;
bHist[rgb & 0xff]++;
}
int r = 0, g = 0, b = 0;
for ( int i = 1; i < 256; ++i )
{
if ( rHist[i] > rHist[r] )
r = i;
if ( gHist[i] > gHist[g] )
g = i;
if ( bHist[i] > bHist[b] )
b = i;
}
newPixels[row][col] =
0xff000000 | ( r << 16 ) | ( g << 8 ) | b;
}
}
setPixels( width, height, newPixels );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
int n = -1;
int argc = args.length;
int argn;
for ( argn = 0; argn < argc && args[argn].charAt( 0 ) == '-'; ++argn )
{
if ( args[argn].equals( "-n" ) && argn + 1 < argc )
{
++argn;
n = Integer.parseInt( args[argn] );
}
else
usage();
}
if ( argn != argc )
usage();
ImageFilterPlus filter;
if ( n == -1 )
filter = new Oil( null );
else
filter = new Oil( null, n );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Oil [-n N]" );
System.exit( 1 );
}
}

View file

@ -1,170 +0,0 @@
// RGBAllFilter - an ImageFilter that grabs the whole image
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// An ImageFilter that grabs the whole image.
// <P>
// Many image filters need to work on the whole image at once.
// This class collects up the image and hands it to a single
// routine for processing.
// <P>
// Also, because Java's image classes allow each setPixels() call to
// use a different color model, we have to convert all pixels into
// the default RGB model.
// <P>
// Here's a sample RGBAllFilter that smooths an image by averaging
// nine adjacent pixels.
// <BLOCKQUOTE><CODE><PRE>
// class SmoothFilter extends RGBAllFilter
// {
// public void filterRGBAll( int width, int height, int[][] rgbPixels )
// {
// int[][] newPixels = new int[height][width];
// for ( int row = 0; row &lt; height; ++row )
// for ( int col = 0; col &lt; width; ++col )
// {
// int a = 0, r = 0, g = 0, b = 0, c = 0;
// for ( int subrow = row - 1; subrow &lt;= row + 1; ++subrow )
// if ( subrow &gt;= 0 && subrow &lt; height )
// for ( int subcol = col - 1; subcol &lt;= col + 1; ++subcol )
// if ( subcol &gt;= 0 && subcol &lt; width )
// {
// int pixel = rgbPixels[subrow][subcol];
// a += rgbModel.getAlpha( pixel );
// r += rgbModel.getRed( pixel );
// g += rgbModel.getGreen( pixel );
// b += rgbModel.getBlue( pixel );
// ++c;
// }
// a /= c;
// r /= c;
// g /= c;
// b /= c;
// newPixels[row][col] =
// ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
// }
// setPixels( width, height, newPixels );
// }
// }
// </PRE></CODE></BLOCKQUOTE>
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/RGBAllFilter.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public abstract class RGBAllFilter extends ImageFilterPlus
{
private int width = -1, height = -1;
private int[][] rgbPixels = null;
public RGBAllFilter( ImageProducer producer )
{
super( producer );
}
/// This is the routine that subclasses must implement.
// It gets the entire image as an int[height][width] in the default
// RGB color model. It should call setPixels() with a filtered array,
// same color model.
public abstract void filterRGBAll( int width, int height, int[][] rgbPixels );
/// The version of setPixels() that gets called by the subclass.
public void setPixels( int newWidth, int newHeight, int[][] newPixels )
{
// Send it on to the consumer.
consumer.setDimensions( newWidth, newHeight );
for ( int row = 0; row < newHeight; ++row )
consumer.setPixels(
0, row, newWidth, 1, rgbModel, newPixels[row], 0, newWidth );
}
public void setColorModel( ColorModel model )
{
consumer.setColorModel( rgbModel );
}
public void setDimensions( int width, int height )
{
if ( width == this.width && height == this.height )
return;
this.width = width;
this.height = height;
rgbPixels = new int[height][width];
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
for ( int row = 0; row < h; ++row )
{
int rowOffsetIn = row * scansize + off;
for ( int col = 0; col < w; ++col )
rgbPixels[y + row][x + col] =
model.getRGB( pixels[rowOffsetIn + col] & 0xff );
}
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
for ( int row = 0; row < h; ++row )
{
int rowOffsetIn = row * scansize + off;
if ( model == rgbModel )
System.arraycopy(
pixels, rowOffsetIn, rgbPixels[y + row], x, w );
else
for ( int col = 0; col < w; ++col )
rgbPixels[y + row][x + col] =
model.getRGB( pixels[rowOffsetIn + col] );
}
}
public void imageComplete( int status )
{
if ( status == ImageConsumer.IMAGEERROR ||
status == ImageConsumer.IMAGEABORTED )
{
super.imageComplete( status );
return;
}
// Do the actual work.
filterRGBAll( width, height, rgbPixels );
// And we're done.
super.imageComplete( status );
}
}

View file

@ -1,135 +0,0 @@
// RGBBlockFilter - more efficient RGB ImageFilter
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// More efficient RGB ImageFilter.
// <P>
// Similar in concept to java.awt.image.RGBImageFilter, but designed
// to run more efficiently when filtering large images.
// <P>
// As with RGBImageFilter, you only have to implement a single routine
// to use the filter. However, RGBImageFilter's routine filters a single
// pixel at a time. This means a lot of routine-calling overhead.
// RGBBlockFilter filters a block at a time.
// <P>
// Here's a sample RGBBlockFilter that makes an image translucent
// by setting all the alpha values to 0x80:
// <BLOCKQUOTE><CODE><PRE>
// class TranslucentFilter extends RGBBlockFilter
// {
// public int[] filterRGBBlock(
// int x, int y, int width, int height, int[][] rgbPixels )
// {
// for ( int row = 0; row &lt; height; ++row )
// for ( int col = 0; col &lt; width; ++col )
// rgbPixels[row][col] =
// ( rgbPixels[row][col] & 0x00ffffff ) | 0x80000000;
// return rgbPixels;
// }
// }
// </PRE></CODE></BLOCKQUOTE>
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/RGBBlockFilter.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public abstract class RGBBlockFilter extends ImageFilterPlus
{
public RGBBlockFilter( ImageProducer producer )
{
super( producer );
}
/// This is the routine that subclasses must implement.
// It gets a block of the image as an int[height][width] in the default
// RGB color model. It should return a filtered array, same size
// and same model.
public abstract int[][] filterRGBBlock(
int x, int y, int width, int height, int[][] rgbPixels );
public void setColorModel( ColorModel model )
{
consumer.setColorModel( rgbModel );
}
/// Byte version of setPixels reformats the pixels to RGB and the
// array to 2 dimensions.
public void setPixels(
int x, int y, int width, int height, ColorModel model,
byte[] pixels, int offset, int scansize )
{
int[][] rgbPixels = new int[height][width];
for ( int row = 0; row < height; ++row )
{
int rowOffsetIn = offset + row * scansize;
for ( int col = 0; col < width; ++col )
rgbPixels[row][col] =
model.getRGB( pixels[rowOffsetIn + col] & 0xff );
}
setPixels( x, y, width, height, rgbPixels );
}
/// Int version of setPixels reformats the array to 2 dimensions.
public void setPixels(
int x, int y, int width, int height, ColorModel model,
int[] pixels, int offset, int scansize )
{
int[][] rgbPixels = new int[height][width];
for ( int row = 0; row < height; ++row )
{
int rowOffsetIn = offset + row * scansize;
int rowOffsetOut = row * width;
// Convert color models if necessary.
if ( model == rgbModel )
System.arraycopy(
pixels, rowOffsetIn, rgbPixels[row], 0, width );
else
for ( int col = 0; col < width; ++col )
rgbPixels[row][col] =
model.getRGB( pixels[rowOffsetIn + col] );
}
setPixels( x, y, width, height, rgbPixels );
}
/// Call the filter routine, and send the results to the consumer.
private void setPixels( int x, int y, int width, int height, int[][] rgbPixels )
{
int[][] newPixels = filterRGBBlock( x, y, width, height, rgbPixels );
// And send it on to the consumer.
for ( int row = 0; row < height; ++row )
consumer.setPixels(
x, y + row, width, 1, rgbModel, newPixels[row], 0, width );
}
}

View file

@ -1,81 +0,0 @@
// Rotate - rotate an image by some angle
//
// Copyright (C) 1997 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// Rotate an image by some angle.
// <P>
// Rotates an image by the specified angle.
// The angle is in degrees measured counter-clockwise.
// It can be negative, but it should be between -90 and 90
// or the resulting image will be unreasonably large.
// Staying between -45 and 45 is best.
// <P>
// The rotation algorithm is Alan Paeth's three-shear method, described
// in "A Fast Algorithm for General Raster Rotation", Graphics Interface
// '86, pp. 77-81.
// <P>
// This filter is slow.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Rotate.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Rotate extends CompositeFilter
{
private double angle;
/// Constructor.
public Rotate( ImageProducer producer, double angle )
{
super( producer, new Shear( null, angle ), new Flip( null, Flip.FLIP_XY ) );
this.angle = angle * Math.PI / 180.0;
double xshearfac = Math.tan( angle / 2.0 );
double yshearfac = Math.sin( angle );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 1 )
usage();
ImageFilterPlus filter = new Rotate( null, Integer.parseInt( args[0] ) );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Rotate <angle>" );
System.exit( 1 );
}
}

View file

@ -1,159 +0,0 @@
// ScaleCopy - an ImageFilter that scales by pixel copying
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// An ImageFilter that scales by pixel copying.
// <P>
// Scales an image by copying pixels.
// If the image is being enlarged, pixels get replicated;
// if the image is being shrunk, pixels get dropped.
// The output uses the same color model as the input.
// For enlarging, this filter is slightly slower than Enlarge due
// to the floating-point arithmetic;
// for shrinking, it's much faster than Shrink, but
// the results aren't as nice.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/ScaleCopy.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Enlarge
// @see Shrink
public class ScaleCopy extends ImageFilterPlus
{
private double xScale, yScale;
private int newWidth, newHeight;
/// Constructor, same X and Y scale factor.
public ScaleCopy( ImageProducer producer, double scale )
{
this( producer, scale, scale );
}
/// Constructor, different X and Y scale factors.
public ScaleCopy( ImageProducer producer, double xScale, double yScale )
{
super( producer );
this.xScale = xScale;
this.yScale = yScale;
}
public void setDimensions( int width, int height )
{
newWidth = (int) ( width * xScale );
newHeight = (int) ( height * yScale );
consumer.setDimensions( newWidth, newHeight );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
int newX = Math.min( (int) ( x * xScale ), newWidth - 1 );
int newY = Math.min( (int) ( y * yScale ), newHeight - 1 );
int newW = Math.max( (int) ( w * xScale ), 1 );
if ( newX + newW > newWidth )
newW = newWidth - newX;
int newH = Math.max( (int) ( h * yScale ), 1 );
if ( newY + newH > newHeight )
newH = newHeight - newY;
byte[] newPixels = new byte[newW * newH];
for ( int newRow = 0; newRow < newH; ++newRow )
{
int row = (int) ( newRow / yScale );
if ( row >= h )
continue;
for ( int newCol = 0; newCol < newW; ++newCol )
{
int col = (int) ( newCol / xScale );
if ( col >= w )
continue;
newPixels[newRow * newW + newCol] =
pixels[row * scansize + off + col];
}
}
consumer.setPixels( newX, newY, newW, newH, model, newPixels, 0, newW );
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
int newX = Math.min( (int) ( x * xScale ), newWidth - 1 );
int newY = Math.min( (int) ( y * yScale ), newHeight - 1 );
int newW = Math.max( (int) ( w * xScale ), 1 );
if ( newX + newW > newWidth )
newW = newWidth - newX;
int newH = Math.max( (int) ( h * yScale ), 1 );
if ( newY + newH > newHeight )
newH = newHeight - newY;
int[] newPixels = new int[newW * newH];
for ( int newRow = 0; newRow < newH; ++newRow )
{
int row = (int) ( newRow / yScale );
if ( row >= h )
continue;
for ( int newCol = 0; newCol < newW; ++newCol )
{
int col = (int) ( newCol / xScale );
if ( col >= w )
continue;
newPixels[newRow * newW + newCol] =
pixels[row * scansize + off + col];
}
}
consumer.setPixels( newX, newY, newW, newH, model, newPixels, 0, newW );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
ImageFilterPlus filter = null;
if ( args.length == 1 )
filter = new ScaleCopy( null,
Double.valueOf( args[0] ).doubleValue() );
else if ( args.length == 2 )
filter = new ScaleCopy( null,
Double.valueOf( args[0] ).doubleValue(),
Double.valueOf( args[1] ).doubleValue() );
else
usage();
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: ScaleCopy scale" );
System.err.println( "or: ScaleCopy xScale yScale" );
System.exit( 1 );
}
}

View file

@ -1,144 +0,0 @@
// Shear - shear an image by some angle
//
// Copyright (C) 1997 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// Shear an image by some angle.
// <P>
// Shears an image by the specified angle.
// The angle is in degrees (floating point), and measures this:
// <BLOCKQUOTE><PRE><CODE>
// +-------+ +-------+
// | | |\ \
// | OLD | | \ NEW \
// | | |an\ \
// +-------+ |gle+-------+
// </CODE></PRE></BLOCKQUOTE>
// If the angle is negative, it shears the other way:
// <BLOCKQUOTE><PRE><CODE>
// +-------+ |-an+-------+
// | | |gl/ /
// | OLD | |e/ NEW /
// | | |/ /
// +-------+ +-------+
// </CODE></PRE></BLOCKQUOTE>
// The angle should not get too close to 90 or -90, or the resulting
// image will be unreasonably wide. Staying between -45 and 45 is best.
// <P>
// The shearing is implemented by looping over the source pixels and
// distributing fractions to each of the destination pixels.
// This has an "anti-aliasing" effect - it avoids jagged edges and similar
// artifacts.
// <P>
// This filter is fast.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Shear.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Shear extends RGBAllFilter
{
private double angle;
/// Constructor.
public Shear( ImageProducer producer, double angle )
{
super( producer );
this.angle = angle * Math.PI / 180.0;
}
public void filterRGBAll( int width, int height, int[][] rgbPixels )
{
double shearfac = Math.tan( angle );
if ( shearfac < 0.0 )
shearfac = -shearfac;
int newWidth = (int) ( height * shearfac + width + 0.999999 );
int[][] newPixels = new int[height][newWidth];
for ( int row = 0; row < height; ++row )
{
double new0;
if ( angle > 0.0 )
new0 = row * shearfac;
else
new0 = ( height - row ) * shearfac;
int intnew0 = (int) new0;
double fracnew0 = new0 - intnew0;
double omfracnew0 = 1.0 - fracnew0;
for ( int col = 0; col < newWidth; ++col )
newPixels[row][col] = 0x00000000;
int preva = 0;
int prevr = ( rgbPixels[row][0] >> 16 ) & 0xff;
int prevg = ( rgbPixels[row][0] >> 8 ) & 0xff;
int prevb = rgbPixels[row][0] & 0xff;
for ( int col = 0; col < width; ++col )
{
int rgb = rgbPixels[row][col];
int a = ( rgb >> 24 ) & 0xff;
int r = ( rgb >> 16 ) & 0xff;
int g = ( rgb >> 8 ) & 0xff;
int b = rgb & 0xff;
newPixels[row][intnew0 + col] =
( (int) ( fracnew0 * preva + omfracnew0 * a ) << 24 ) |
( (int) ( fracnew0 * prevr + omfracnew0 * r ) << 16 ) |
( (int) ( fracnew0 * prevg + omfracnew0 * g ) << 8 ) |
( (int) ( fracnew0 * prevb + omfracnew0 * b ) );
preva = a;
prevr = r;
prevg = g;
prevb = b;
}
newPixels[row][intnew0 + width] =
( (int) ( fracnew0 * preva ) << 24 ) |
( prevr << 16 ) | ( prevg << 8 ) | prevb;
}
setPixels( newWidth, height, newPixels );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 1 )
usage();
ImageFilterPlus filter = new Shear( null, Integer.parseInt( args[0] ) );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Shear <angle>" );
System.exit( 1 );
}
}

View file

@ -1,116 +0,0 @@
// Shrink - an ImageFilter that shrinks by pixel averaging
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// An ImageFilter that shrinks by pixel averaging.
// <P>
// Shrinks an image an integral factor by averaging pixels.
// Because the resulting pixels might not fit into the input's
// color model, the output is always in the default RGB color model.
// This filter is somewhat slow.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Shrink.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Enlarge
// @see ScaleCopy
public class Shrink extends RGBAllFilter
{
private int divisor;
/// Constructor.
public Shrink( ImageProducer producer, int divisor )
{
super( producer );
this.divisor = divisor;
}
public void filterRGBAll( int width, int height, int[][] rgbPixels )
{
int divisor2 = divisor * divisor;
int newWidth = Math.max( width / divisor, 1 );
int newHeight = Math.max( height / divisor, 1 );
int[][] newPixels = new int[newHeight][newWidth];
for ( int newRow = 0; newRow < newHeight; ++newRow )
{
for ( int newCol = 0; newCol < newWidth; ++newCol )
{
int a = 0, r = 0, g = 0, b = 0;
for ( int i = 0; i < divisor; ++i )
{
int row = newRow * divisor + i;
if ( row >= height )
continue;
for ( int j = 0; j < divisor; ++j )
{
int col = newCol * divisor + j;
if ( col >= width )
continue;
int rgb = rgbPixels[row][col];
a += ( rgb >> 24 ) & 0xff;
r += ( rgb >> 16 ) & 0xff;
g += ( rgb >> 8 ) & 0xff;
b += rgb & 0xff;
}
}
a /= divisor2;
r /= divisor2;
g /= divisor2;
b /= divisor2;
newPixels[newRow][newCol] =
( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
}
}
setPixels( newWidth, newHeight, newPixels );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 1 )
usage();
ImageFilterPlus filter = new Enlarge(
null, Integer.parseInt( args[0] ) );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Shrink <divisor>" );
System.exit( 1 );
}
}

View file

@ -1,123 +0,0 @@
// Smooth - smoothing filter
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// Smoothing filter.
// <P>
// Smooths an image by averaging adjacent pixels.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Smooth.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Smooth extends RGBAllFilter
{
private int n;
/// Constructor.
public Smooth( ImageProducer producer, int n )
{
super( producer );
this.n = n;
}
/// Constructor, default value.
public Smooth( ImageProducer producer )
{
this( producer, 1 );
}
public void filterRGBAll( int width, int height, int[][] rgbPixels )
{
int[][] newPixels = new int[height][width];
for ( int row = 0; row < height; ++row )
for ( int col = 0; col < width; ++col )
{
int a = 0, r = 0, g = 0, b = 0, c = 0;
for ( int subrow = row - n; subrow <= row + n; ++subrow )
if ( subrow >= 0 && subrow < height )
for ( int subcol = col - n; subcol <= col + n; ++subcol )
if ( subcol >= 0 && subcol < width )
{
int rgb = rgbPixels[subrow][subcol];
a += ( rgb >> 24 ) & 0xff;
r += ( rgb >> 16 ) & 0xff;
g += ( rgb >> 8 ) & 0xff;
b += rgb & 0xff;
++c;
}
a /= c;
r /= c;
g /= c;
b /= c;
newPixels[row][col] =
( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
}
setPixels( width, height, newPixels );
}
// Main routine for command-line interface.
public static void main( String[] args )
{
int n = -1;
int argc = args.length;
int argn;
for ( argn = 0; argn < argc && args[argn].charAt( 0 ) == '-'; ++argn )
{
if ( args[argn].equals( "-n" ) && argn + 1 < argc )
{
++argn;
n = Integer.parseInt( args[argn] );
}
else
usage();
}
if ( argn != argc )
usage();
ImageFilterPlus filter;
if ( n == -1 )
filter = new Smooth( null );
else
filter = new Smooth( null, n );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Smooth [-n N]" );
System.exit( 1 );
}
}

View file

@ -1,126 +0,0 @@
// Tile - an ImageFilter that replicates an image in a tiled pattern
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Filters;
import java.awt.image.*;
/// An ImageFilter that replicates an image in a tiled pattern.
// <P>
// Tiles the image onto an output image of a specified size.
// The output uses the same color model as the input.
// This filter is very fast.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Filters/Tile.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Tile extends ImageFilterPlus
{
private int width, height;
private int newWidth, newHeight;
private int nWide, nHigh;
/// Constructor.
public Tile( ImageProducer producer, int newWidth, int newHeight )
{
super( producer, true );
this.newWidth = newWidth;
this.newHeight = newHeight;
}
public void setDimensions( int width, int height )
{
this.width = width;
this.height = height;
consumer.setDimensions( newWidth, newHeight );
nWide = ( newWidth + width - 1 ) / width;
nHigh = ( newHeight + height - 1 ) / height;
}
public void setPixels( int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize )
{
for ( int r = 0; r < nHigh; ++r )
{
int ty = r * height + y;
int th = h;
if ( ty + th > newHeight )
th = newHeight - ty;
for ( int c = 0; c < nWide; ++c )
{
int tx = c * width + x;
int tw = w;
if ( tx + tw > newWidth )
tw = newWidth - tx;
consumer.setPixels(
tx, ty, tw, th, model, pixels, off, scansize );
}
}
}
public void setPixels( int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize )
{
for ( int r = 0; r < nHigh; ++r )
{
int ty = r * height + y;
int th = h;
if ( ty + th > newHeight )
th = newHeight - ty;
for ( int c = 0; c < nWide; ++c )
{
int tx = c * width + x;
int tw = w;
if ( tx + tw > newWidth )
tw = newWidth - tx;
consumer.setPixels(
tx, ty, tw, th, model, pixels, off, scansize );
}
}
}
// Main routine for command-line interface.
public static void main( String[] args )
{
if ( args.length != 2 )
usage();
ImageFilterPlus filter =
new Tile( null,
Integer.parseInt( args[0] ), Integer.parseInt( args[1] ) );
System.exit(
ImageFilterPlus.filterStream( System.in, System.out, filter ) );
}
private static void usage()
{
System.err.println( "usage: Tile <width> <height>" );
System.exit( 1 );
}
}

View file

@ -1,50 +0,0 @@
// JPMUtils - static utility routines for the JPM packages
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM;
import java.awt.*;
import java.awt.image.*;
import Acme.JPM.Filters.*;
/// Static utility routines for the JPM packages.
// <P>
// <A HREF="/resources/classes/Acme/JPM/JPMUtils.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class JPMUtils
{
/// Filter one image into another.
public static Image filterImage( Component comp, ImageFilterPlus filter )
{
return comp.createImage(
new FilteredImageSource( filter.getSource(), filter ) );
}
}

View file

@ -1,303 +0,0 @@
// LruHashtable - a Hashtable that expires least-recently-used objects
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
import java.util.*;
/// A Hashtable that expires least-recently-used objects.
// <P>
// Use just like java.util.Hashtable, except that the initial-capacity
// parameter is required. Instead of growing bigger than that size,
// it will throw out objects that haven't been looked at in a while.
// <P>
// <A HREF="/resources/classes/Acme/LruHashtable.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see java.util.Hashtable
public class LruHashtable extends Hashtable
{
// Number of buckets.
private static final int nBuckets = 2;
// Load factor.
private float loadFactor;
// When count exceeds this threshold, expires the old table.
private int threshold;
// Capacity of each bucket.
private int eachCapacity;
// The tables.
private Hashtable oldTable;
private Hashtable newTable;
/// Constructs a new, empty hashtable with the specified initial
// capacity and the specified load factor.
// Unlike a plain Hashtable, an LruHashtable will never grow or
// shrink from this initial capacity.
// @param initialCapacity the initial number of buckets
// @param loadFactor a number between 0.0 and 1.0, it defines
// the threshold for expiring old entries
// @exception IllegalArgumentException If the initial capacity
// is less than or equal to zero.
// @exception IllegalArgumentException If the load factor is
// less than or equal to zero.
public LruHashtable( int initialCapacity, float loadFactor )
{
// We have to call a superclass constructor, but we're not actually
// going to use it at all. The only reason we want to extend Hashtable
// is for type conformance. So, make a parent hash table of minimum
// size and then ignore it.
super( 1 );
if ( initialCapacity <= 0 || loadFactor <= 0.0 )
throw new IllegalArgumentException();
this.loadFactor = loadFactor;
threshold = (int) ( initialCapacity * loadFactor ) - 1;
eachCapacity = initialCapacity / nBuckets + 1;
oldTable = new Hashtable( eachCapacity, loadFactor );
newTable = new Hashtable( eachCapacity, loadFactor );
}
/// Constructs a new, empty hashtable with the specified initial
// capacity.
// Unlike a plain Hashtable, an LruHashtable will never grow or
// shrink from this initial capacity.
// @param initialCapacity the initial number of buckets
public LruHashtable( int initialCapacity )
{
this( initialCapacity, 0.75F );
}
/// Returns the number of elements contained in the hashtable.
public int size()
{
return newTable.size() + oldTable.size();
}
/// Returns true if the hashtable contains no elements.
public boolean isEmpty()
{
return size() == 0;
}
/// Returns an enumeration of the hashtable's keys.
// @see LruHashtable#elements
// @see Enumeration
public synchronized Enumeration keys()
{
return new LruHashtableEnumerator( oldTable, newTable, true );
}
/// Returns an enumeration of the elements. Use the Enumeration methods
// on the returned object to fetch the elements sequentially.
// @see LruHashtable#keys
// @see Enumeration
public synchronized Enumeration elements()
{
return new LruHashtableEnumerator( oldTable, newTable, false );
}
/// Returns true if the specified object is an element of the hashtable.
// This operation is more expensive than the containsKey() method.
// @param value the value that we are looking for
// @exception NullPointerException If the value being searched
// for is equal to null.
// @see LruHashtable#containsKey
public synchronized boolean contains( Object value )
{
if ( newTable.contains( value ) )
return true;
if ( oldTable.contains( value ) )
{
// We would like to move the object from the old table to the
// new table. However, we need keys to re-add the objects, and
// there's no good way to find all the keys for the given object.
// We'd have to enumerate through all the keys and check each
// one. Yuck. For now we just punt. Anyway, contains() is
// probably not a commonly-used operation.
return true;
}
return false;
}
/// Returns true if the collection contains an element for the key.
// @param key the key that we are looking for
// @see LruHashtable#contains
public synchronized boolean containsKey( Object key )
{
if ( newTable.containsKey( key ) )
return true;
if ( oldTable.containsKey( key ) )
{
// Move object from old table to new table.
Object value = oldTable.get( key );
newTable.put( key, value );
oldTable.remove( key );
return true;
}
return false;
}
/// Gets the object associated with the specified key in the
// hashtable.
// @param key the specified key
// @returns the element for the key or null if the key
// is not defined in the hash table.
// @see LruHashtable#put
public synchronized Object get( Object key )
{
Object value;
value = newTable.get( key );
if ( value != null )
return value;
value = oldTable.get( key );
if ( value != null )
{
// Move object from old table to new table.
newTable.put( key, value );
oldTable.remove( key );
return value;
}
return null;
}
/// Puts the specified element into the hashtable, using the specified
// key. The element may be retrieved by doing a get() with the same key.
// The key and the element cannot be null.
// @param key the specified key in the hashtable
// @param value the specified element
// @exception NullPointerException If the value of the element
// is equal to null.
// @see LruHashtable#get
// @return the old value of the key, or null if it did not have one.
public synchronized Object put( Object key, Object value )
{
Object oldValue = newTable.put( key, value );
if ( oldValue != null )
return oldValue;
oldValue = oldTable.get( key );
if ( oldValue != null )
oldTable.remove( key );
else
{
if ( size() >= threshold )
{
// Rotate the tables.
oldTable = newTable;
newTable = new Hashtable( eachCapacity, loadFactor );
}
}
return oldValue;
}
/// Removes the element corresponding to the key. Does nothing if the
// key is not present.
// @param key the key that needs to be removed
// @return the value of key, or null if the key was not found.
public synchronized Object remove( Object key )
{
Object oldValue = newTable.remove( key );
if ( oldValue == null )
oldValue = oldTable.remove( key );
return oldValue;
}
/// Clears the hash table so that it has no more elements in it.
public synchronized void clear()
{
newTable.clear();
oldTable.clear();
}
/// Creates a clone of the hashtable. A shallow copy is made,
// the keys and elements themselves are NOT cloned. This is a
// relatively expensive operation.
public synchronized Object clone()
{
LruHashtable n = (LruHashtable) super.clone();
n.newTable = (Hashtable) n.newTable.clone();
n.oldTable = (Hashtable) n.oldTable.clone();
return n;
}
// toString() can be inherited.
}
class LruHashtableEnumerator implements Enumeration
{
Enumeration oldEnum;
Enumeration newEnum;
boolean old;
LruHashtableEnumerator( Hashtable oldTable, Hashtable newTable, boolean keys )
{
if ( keys )
{
oldEnum = oldTable.keys();
newEnum = newTable.keys();
}
else
{
oldEnum = oldTable.elements();
newEnum = newTable.elements();
}
old = true;
}
public boolean hasMoreElements()
{
boolean r;
if ( old )
{
r = oldEnum.hasMoreElements();
if ( ! r )
{
old = false;
r = newEnum.hasMoreElements();
}
}
else
r = newEnum.hasMoreElements();
return r;
}
public Object nextElement()
{
if ( old )
return oldEnum.nextElement();
return newEnum.nextElement();
}
}

View file

@ -1,313 +0,0 @@
// CgiServlet - runs CGI programs
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
/// Runs CGI programs.
// <P>
// Note: although many implementations of CGI set the working directory of
// the subprocess to be the directory containing the executable file, the
// CGI spec actually says nothing about the working directory. Since
// Java has no method for setting the working directory, this implementation
// does not set it.
// <P>
// <A HREF="/resources/classes/Acme/Serve/CgiServlet.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Acme.Serve.Serve
public class CgiServlet extends HttpServlet
{
/// Returns a string containing information about the author, version, and
// copyright of the servlet.
public String getServletInfo()
{
return "runs CGI programs";
}
/// Services a single request from the client.
// @param req the servlet request
// @param req the servlet response
// @exception ServletException when an exception has occurred
public void service( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException
{
if ( ! ( req.getMethod().equalsIgnoreCase( "get" ) ||
req.getMethod().equalsIgnoreCase( "post" ) ) )
{
res.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED );
return;
}
String path = req.getServletPath();
if ( path == null || path.charAt( 0 ) != '/' )
{
res.sendError( HttpServletResponse.SC_BAD_REQUEST );
return;
}
if ( path.indexOf( "/../" ) != -1 || path.endsWith( "/.." ) )
{
res.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
// Make a version without the leading /.
String pathname = path.substring( 1 );
if ( pathname.length() == 0 )
pathname = "./";
dispatchPathname( req, res, path, pathname );
}
private void dispatchPathname( HttpServletRequest req, HttpServletResponse res, String path, String pathname ) throws IOException
{
String filename = pathname.replace( '/', File.separatorChar );
if ( filename.charAt( filename.length() - 1 ) == File.separatorChar )
filename = filename.substring( 0, filename.length() - 1 );
filename = getServletContext().getRealPath( filename );
File file = new File( filename );
if ( file.exists() )
serveFile( req, res, path, filename, file );
else
res.sendError( HttpServletResponse.SC_NOT_FOUND );
}
private void serveFile( HttpServletRequest req, HttpServletResponse res, String path, String filename, File file ) throws IOException
{
String queryString = req.getQueryString();
int contentLength = req.getContentLength();
int c;
log( "running " + path );
// Make argument list.
Vector argVec = new Vector();
argVec.addElement( filename );
if ( queryString != null && queryString.indexOf( "=" ) == -1 )
{
Enumeration enum = new StringTokenizer( queryString, "+" );
while ( enum.hasMoreElements() )
argVec.addElement( (String) enum.nextElement() );
}
String argList[] = makeList( argVec );
// Make environment list.
Vector envVec = new Vector();
envVec.addElement( makeEnv(
"PATH", "/usr/local/bin:/usr/ucb:/bin:/usr/bin" ) );
envVec.addElement( makeEnv( "GATEWAY_INTERFACE", "CGI/1.1" ) );
envVec.addElement( makeEnv(
"SERVER_SOFTWARE", getServletContext().getServerInfo() ) );
envVec.addElement( makeEnv( "SERVER_NAME", req.getServerName() ) );
envVec.addElement( makeEnv(
"SERVER_PORT", Integer.toString( req.getServerPort() ) ) );
envVec.addElement( makeEnv( "REMOTE_ADDR", req.getRemoteAddr() ) );
envVec.addElement( makeEnv( "REMOTE_HOST", req.getRemoteHost() ) );
envVec.addElement( makeEnv( "REQUEST_METHOD", req.getMethod() ) );
if ( contentLength != -1 )
envVec.addElement( makeEnv(
"CONTENT_LENGTH", Integer.toString( contentLength ) ) );
if ( req.getContentType() != null )
envVec.addElement( makeEnv(
"CONTENT_TYPE", req.getContentType() ) );
envVec.addElement( makeEnv( "SCRIPT_NAME", req.getServletPath() ) );
if ( req.getPathInfo() != null )
envVec.addElement( makeEnv( "PATH_INFO", req.getPathInfo() ) );
if ( req.getPathTranslated() != null )
envVec.addElement( makeEnv(
"PATH_TRANSLATED", req.getPathTranslated() ) );
if ( queryString != null )
envVec.addElement( makeEnv( "QUERY_STRING", queryString ) );
envVec.addElement( makeEnv( "SERVER_PROTOCOL", req.getProtocol() ) );
if ( req.getRemoteUser() != null )
envVec.addElement( makeEnv( "REMOTE_USER", req.getRemoteUser() ) );
if ( req.getAuthType() != null )
envVec.addElement( makeEnv( "AUTH_TYPE", req.getAuthType() ) );
Enumeration enum = req.getHeaderNames();
while ( enum.hasMoreElements() )
{
String name = (String) enum.nextElement();
String value = req.getHeader( name );
if ( value == null )
value = "";
envVec.addElement( makeEnv(
"HTTP_" + name.toUpperCase().replace( '-', '_' ), value ) );
}
String envList[] = makeList( envVec );
// Start the command.
Process proc = Runtime.getRuntime().exec( argList, envList );
try
{
// If it's a POST, copy the request data to the process.
if ( req.getMethod().equalsIgnoreCase( "post" ) )
{
InputStream reqIn = req.getInputStream();
OutputStream procOut = proc.getOutputStream();
for ( int i = 0; i < contentLength; ++i )
{
c = reqIn.read();
if ( c == -1 )
break;
procOut.write( c );
}
procOut.close();
}
// Now read the response from the process.
BufferedReader procIn = new BufferedReader( new InputStreamReader(
proc.getInputStream() ) );
OutputStream resOut = res.getOutputStream();
// Some of the headers have to be intercepted and handled.
boolean firstLine = true;
while ( true )
{
String line = procIn.readLine();
if ( line == null )
break;
line = line.trim();
if ( line.equals( "" ) )
break;
int colon = line.indexOf( ":" );
if ( colon == -1 )
{
// No colon. If it's the first line, parse it for status.
if ( firstLine )
{
StringTokenizer tok = new StringTokenizer( line, " " );
try
{
switch( tok.countTokens() )
{
case 2:
tok.nextToken();
res.setStatus(
Integer.parseInt( tok.nextToken() ) );
break;
case 3:
tok.nextToken();
res.setStatus(
Integer.parseInt( tok.nextToken() ),
tok.nextToken() );
break;
}
}
catch ( NumberFormatException ignore ) {}
}
else
{
// No colon and it's not the first line? Ignore.
}
}
else
{
// There's a colon. Check for certain special headers.
String name = line.substring( 0, colon );
String value = line.substring( colon + 1 ).trim();
if ( name.equalsIgnoreCase( "Status" ) )
{
StringTokenizer tok = new StringTokenizer( value, " " );
try
{
switch( tok.countTokens() )
{
case 1:
res.setStatus(
Integer.parseInt( tok.nextToken() ) );
break;
case 2:
res.setStatus(
Integer.parseInt( tok.nextToken() ),
tok.nextToken() );
break;
}
}
catch ( NumberFormatException ignore ) {}
}
else if ( name.equalsIgnoreCase( "Content-type" ) )
{
res.setContentType( value );
}
else if ( name.equalsIgnoreCase( "Content-length" ) )
{
try
{
res.setContentLength( Integer.parseInt( value ) );
}
catch ( NumberFormatException ignore ) {}
}
else if ( name.equalsIgnoreCase( "Location" ) )
{
res.setStatus(
HttpServletResponse.SC_MOVED_TEMPORARILY );
res.setHeader( name, value );
}
else
{
// Not a special header. Just set it.
res.setHeader( name, value );
}
}
}
// Copy the rest of the data uninterpreted.
Acme.Utils.copyStream( procIn, resOut );
procIn.close();
resOut.close();
}
catch ( IOException e )
{
//res.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
// There's some weird bug in Java, when reading from a Process
// you get a spurious IOException. We have to ignore it.
}
}
private static String makeEnv( String name, String value )
{
return name + "=" + value;
}
private static String[] makeList( Vector vec )
{
String list[] = new String[vec.size()];
for ( int i = 0; i < vec.size(); ++i )
list[i] = (String) vec.elementAt( i );
return list;
}
}

View file

@ -1,316 +0,0 @@
// FileServlet - servlet similar to a standard httpd
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;
/// Servlet similar to a standard httpd.
// <P>
// Implements the "GET" and "HEAD" methods for files and directories.
// Handles index.html.
// Redirects directory URLs that lack a trailing /.
// Handles If-Modified-Since and Range.
// <P>
// <A HREF="/resources/classes/Acme/Serve/FileServlet.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Acme.Serve.Serve
public class FileServlet extends HttpServlet
{
// We keep a single throttle table for all instances of the servlet.
// Normally there is only one instance; the exception is subclasses.
static Acme.WildcardDictionary throttleTab = null;
/// Constructor.
public FileServlet()
{
}
/// Constructor with throttling.
// @param throttles filename containing throttle settings
// @see ThrottledOutputStream
public FileServlet( String throttles ) throws IOException
{
this();
readThrottles( throttles );
}
private void readThrottles( String throttles ) throws IOException
{
Acme.WildcardDictionary newThrottleTab =
ThrottledOutputStream.parseThrottleFile( throttles );
if ( throttleTab == null )
throttleTab = newThrottleTab;
else
{
// Merge the new one into the old one.
Enumeration keys = newThrottleTab.keys();
Enumeration elements = newThrottleTab.elements();
while ( keys.hasMoreElements() )
{
Object key = keys.nextElement();
Object element = elements.nextElement();
throttleTab.put( key, element );
}
}
}
/// Returns a string containing information about the author, version, and
// copyright of the servlet.
public String getServletInfo()
{
return "servlet similar to a standard httpd";
}
/// Services a single request from the client.
// @param req the servlet request
// @param req the servlet response
// @exception ServletException when an exception has occurred
public void service( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException
{
boolean headOnly;
if ( req.getMethod().equalsIgnoreCase( "get" ) )
headOnly = false;
else if ( ! req.getMethod().equalsIgnoreCase( "head" ) )
headOnly = true;
else
{
res.sendError( HttpServletResponse.SC_NOT_IMPLEMENTED );
return;
}
String path = req.getServletPath();
if ( path == null || path.charAt( 0 ) != '/' )
{
res.sendError( HttpServletResponse.SC_BAD_REQUEST );
return;
}
if ( path.indexOf( "/../" ) != -1 || path.endsWith( "/.." ) )
{
res.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
// Make a version without the leading /.
String pathname = path.substring( 1 );
if ( pathname.length() == 0 )
pathname = "./";
dispatchPathname( req, res, headOnly, path, pathname );
}
private void dispatchPathname( HttpServletRequest req, HttpServletResponse res, boolean headOnly, String path, String pathname ) throws IOException
{
String filename = pathname.replace( '/', File.separatorChar );
if ( filename.charAt( filename.length() - 1 ) == File.separatorChar )
filename = filename.substring( 0, filename.length() - 1 );
filename = getServletContext().getRealPath( filename );
File file = new File( filename );
if ( file.exists() )
{
if ( ! file.isDirectory() )
serveFile( req, res, headOnly, path, filename, file );
else
{
if ( pathname.charAt( pathname.length() - 1 ) != '/' )
redirectDirectory( req, res, path, file );
else
{
String indexFilename =
filename + File.separatorChar + "index.html";
File indexFile = new File( indexFilename );
if ( indexFile.exists() )
serveFile(
req, res, headOnly, path, indexFilename,
indexFile );
else
serveDirectory(
req, res, headOnly, path, filename, file );
}
}
}
else
{
if ( pathname.endsWith( "/index.html" ) )
dispatchPathname(
req, res, headOnly, path,
pathname.substring( 0, pathname.length() - 10 ) );
else if ( pathname.equals( "index.html" ) )
dispatchPathname( req, res, headOnly, path, "./" );
else
res.sendError( HttpServletResponse.SC_NOT_FOUND );
}
}
protected void serveFile( HttpServletRequest req, HttpServletResponse res, boolean headOnly, String path, String filename, File file ) throws IOException
{
// log( "getting " + path );
if ( ! file.canRead() )
{
res.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
// Handle If-Modified-Since.
res.setStatus( HttpServletResponse.SC_OK );
long lastMod = file.lastModified();
String ifModSinceStr = req.getHeader( "If-Modified-Since" );
long ifModSince = -1;
if ( ifModSinceStr != null )
{
int semi = ifModSinceStr.indexOf( ';' );
if ( semi != -1 )
ifModSinceStr = ifModSinceStr.substring( 0, semi );
try
{
ifModSince =
DateFormat.getDateInstance().parse( ifModSinceStr ).getTime();
}
catch ( Exception ignore ) {}
}
if ( ifModSince != -1 && ifModSince >= lastMod )
{
res.setStatus( HttpServletResponse.SC_NOT_MODIFIED );
headOnly = true;
}
String rangeStr = req.getHeader( "Range" );
if ( rangeStr != null )
{
//!!!
}
res.setContentType( getServletContext().getMimeType( filename ) );
res.setContentLength( (int) file.length() );
res.setDateHeader( "Last-modified", lastMod );
OutputStream out = res.getOutputStream();
if ( ! headOnly )
{
// Check throttle.
if ( throttleTab != null )
{
ThrottleItem throttleItem =
(ThrottleItem) throttleTab.get( path );
if ( throttleItem != null )
{
// !!! Need to account for multiple simultaneous fetches.
out = new ThrottledOutputStream(
out, throttleItem.getMaxBps() );
}
}
InputStream in = new FileInputStream( file );
copyStream( in, out );
in.close();
}
out.close();
}
/// Copy a file from in to out.
// Sub-classes can override this in order to do filtering of some sort.
public void copyStream( InputStream in, OutputStream out ) throws IOException
{
Acme.Utils.copyStream( in, out );
}
private void serveDirectory( HttpServletRequest req, HttpServletResponse res, boolean headOnly, String path, String filename, File file ) throws IOException
{
log( "indexing " + path );
if ( ! file.canRead() )
{
res.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
res.setStatus( HttpServletResponse.SC_OK );
res.setContentType( "text/html" );
OutputStream out = res.getOutputStream();
if ( ! headOnly )
{
PrintStream p = new PrintStream( new BufferedOutputStream( out ) );
p.println( "<HTML><HEAD>" );
p.println( "<TITLE>Index of " + path + "</TITLE>" );
p.println( "</HEAD><BODY BGCOLOR=\"#ffffff\">" );
p.println( "<H2>Index of " + path + "</H2>" );
p.println( "<PRE>" );
p.println( "mode bytes last-changed name" );
p.println( "<HR>" );
String[] names = file.list();
Acme.Utils.sortStrings( names );
for ( int i = 0; i < names.length; ++i )
{
String aFilename = filename + File.separatorChar + names[i];
File aFile = new File( aFilename );
String aFileType;
if ( aFile.isDirectory() )
aFileType = "d";
else if ( aFile.isFile() )
aFileType = "-";
else
aFileType = "?";
String aFileRead = ( aFile.canRead() ? "r" : "-" );
String aFileWrite = ( aFile.canWrite() ? "w" : "-" );
String aFileExe = "-";
String aFileSize = Acme.Fmt.fmt( aFile.length(), 8 );
String aFileDate =
Acme.Utils.lsDateStr( new Date( aFile.lastModified() ) );
String aFileDirsuf = ( aFile.isDirectory() ? "/" : "" );
String aFileSuf = ( aFile.isDirectory() ? "/" : "" );
p.println(
aFileType + aFileRead + aFileWrite + aFileExe +
" " + aFileSize + " " + aFileDate + " " +
"<A HREF=\"" + names[i] + aFileDirsuf + "\">" +
names[i] + aFileSuf + "</A>" );
}
p.println( "</PRE>" );
p.println( "<HR>" );
ServeUtils.writeAddress( p );
p.println( "</BODY></HTML>" );
p.flush();
}
out.close();
}
protected void redirectDirectory( HttpServletRequest req, HttpServletResponse res, String path, File file ) throws IOException
{
log( "redirecting " + path );
res.sendRedirect( path + "/" );
}
}

View file

@ -1,70 +0,0 @@
// SampleServlet - trivial servlet
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/// Trivial servlet.
// <P>
// <A HREF="/resources/classes/Acme/Serve/SampleServlet.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class SampleServlet extends HttpServlet
{
/// Returns a string containing information about the author, version, and
// copyright of the servlet.
public String getServletInfo()
{
return "trivial servlet";
}
/// Services a single request from the client.
// @param req the servlet request
// @param req the servlet response
// @exception ServletException when an exception has occurred
public void service( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException
{
log( "called" );
res.setStatus( HttpServletResponse.SC_OK );
res.setContentType( "text/html" );
ServletOutputStream p = res.getOutputStream();
p.println( "<HTML><HEAD>" );
p.println( "<TITLE>Sample Servlet Output</TITLE>" );
p.println( "</HEAD><BODY>" );
p.println( "<H2>Sample Servlet Output</H2>" );
p.println( "<P>Output from a sample servlet." );
p.println( "</BODY></HTML>" );
p.flush();
p.close();
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,95 +0,0 @@
// ServeUtils - static utilities for minimal Java HTTP server
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
/// Static utilities for minimal Java HTTP server.
// <P>
// <A HREF="/resources/classes/Acme/Serve/ServeUtils.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class ServeUtils
{
// Server identification.
public static final String serverName = "Helma";
// we're using the server version from helma.main.Server class.
// public static final String serverVersion = "1.2 p1";
public static final String serverUrl = "http://helma.org/";
/// Write a standard-format HTML address for this server.
public static void writeAddress( OutputStream o ) throws IOException
{
PrintStream p = new PrintStream( o );
p.println(
"<ADDRESS><A HREF=\"" + serverUrl + "\">" +
serverName + " " + helma.main.Server.version + "</A></ADDRESS>" );
}
/// Get a cookie of a given name.
public static String getCookie( HttpServletRequest req, String name )
{
String h = req.getHeader( "Cookie" );
if ( h == null )
return null;
StringTokenizer st = new StringTokenizer( h, "; " );
while ( st.hasMoreTokens() )
{
String tk = st.nextToken();
int eq = tk.indexOf( '=' );
String n, v;
if ( eq == -1 )
{
n = tk;
v = "";
}
else
{
n = tk.substring( 0, eq );
v = tk.substring( eq + 1 );
}
if ( name.equals( n ) )
return v;
}
return null;
}
/// Set a cookie.
public static void setCookie( HttpServletResponse res, String name, String value )
{
res.setHeader( "Set-Cookie", name + "=" + value );
}
}

View file

@ -1,132 +0,0 @@
// TestServlet - simple servlet that tests the Servlet API
//
// Copyright (C) 1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
/// Simple servlet that tests the Servlet API.
// Sample output:
// <PRE>
// getContentLength(): -1
// getContentType(): null
// getProtocol(): HTTP/1.0
// getScheme(): http
// getServerName(): www.acme.com
// getServerPort(): 1234
// getRemoteAddr(): 192.100.66.1
// getRemoteHost(): acme.com
// getMethod(): GET
// getRequestURI(): http://www.acme.com:1234/TestServlet?foo=bar
// getServletPath(): /TestServlet
// getPathInfo(): null
// getPathTranslated(): null
// getQueryString(): foo=bar
// getRemoteUser(): null
// getAuthType(): null
//
// Parameters:
// foo = bar
//
// Header:
// accept: text/html, image/gif, image/jpeg, *; q=.2
// user-agent: Java1.0.2
// </PRE>
// <A HREF="/resources/classes/Acme/Serve/TestServlet.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class TestServlet extends HttpServlet
{
/// Returns a string containing information about the author, version, and
// copyright of the servlet.
public String getServletInfo()
{
return "simple servlet that tests the Servlet API";
}
/// Services a single request from the client.
// @param req the servlet request
// @param req the servlet response
// @exception ServletException when an exception has occurred
public void service( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException
{
Enumeration en;
log( "called" );
res.setStatus( HttpServletResponse.SC_OK );
res.setContentType( "text/html" );
ServletOutputStream p = res.getOutputStream();
p.println( "<HTML><HEAD>" );
p.println( "<TITLE>Test Servlet Output</TITLE>" );
p.println( "</HEAD><BODY>" );
p.println( "<H2>Test Servlet Output</H2>" );
p.println( "<HR>" );
p.println( "<PRE>" );
p.println( "getContentLength(): " + req.getContentLength() );
p.println( "getContentType(): " + req.getContentType() );
p.println( "getProtocol(): " + req.getProtocol() );
p.println( "getScheme(): " + req.getScheme() );
p.println( "getServerName(): " + req.getServerName() );
p.println( "getServerPort(): " + req.getServerPort() );
p.println( "getRemoteAddr(): " + req.getRemoteAddr() );
p.println( "getRemoteHost(): " + req.getRemoteHost() );
p.println( "getMethod(): " + req.getMethod() );
p.println( "getRequestURI(): " + req.getRequestURI() );
p.println( "getServletPath(): " + req.getServletPath() );
p.println( "getPathInfo(): " + req.getPathInfo() );
p.println( "getPathTranslated(): " + req.getPathTranslated() );
p.println( "getQueryString(): " + req.getQueryString() );
p.println( "getRemoteUser(): " + req.getRemoteUser() );
p.println( "getAuthType(): " + req.getAuthType() );
p.println( "" );
p.println( "Parameters:" );
en = req.getParameterNames();
while ( en.hasMoreElements() )
{
String name = (String) en.nextElement();
p.println( " " + name + " = " + req.getParameter( name ) );
}
p.println( "" );
p.println( "Headers:" );
en = req.getHeaderNames();
while ( en.hasMoreElements() )
{
String name = (String) en.nextElement();
p.println( " " + name + ": " + req.getHeader( name ) );
}
p.println( "</PRE>" );
p.println( "<HR>" );
p.println( "</BODY></HTML>" );
p.flush();
p.close();
}
}

View file

@ -1,55 +0,0 @@
// ThrottleItem - data item for ThrottledOutputStream
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import java.util.*;
/// Data item for ThrottledOutputStream.
// <P>
// <A HREF="/resources/classes/Acme/Serve/ThrottleItem.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class ThrottleItem
{
private long maxBps;
/// Constructor.
public ThrottleItem( long maxBps )
{
this.maxBps = maxBps;
}
public long getMaxBps()
{
return maxBps;
}
}

View file

@ -1,156 +0,0 @@
// ThrottledOutputStream - output stream with throttling
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.Serve;
import java.io.*;
import java.util.*;
/// Output stream with throttling.
// <P>
// Restricts output to a specified rate. Also includes a static utility
// routine for parsing a file of throttle settings.
// <P>
// <A HREF="/resources/classes/Acme/Serve/ThrottledOutputStream.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class ThrottledOutputStream extends FilterOutputStream
{
/// Parses a standard throttle file.
// <P>
// A throttle file lets you set maximum byte rates on filename patterns.
// The format of the throttle file is very simple. A # starts a
// comment, and the rest of the line is ignored. Blank lines are ignored.
// The rest of the lines should consist of a pattern, whitespace, and a
// number. The pattern is a simple shell-style filename pattern, using
// ? and *, or multiple such patterns separated by |.
// <P>
// The numbers in the file are byte rates, specified in units of bytes
// per second. For comparison, a v.32b/v.42b modem gives about
// 1500/2000 B/s depending on compression, a double-B-channel ISDN line
// about 12800 B/s, and a T1 line is about 150000 B/s.
// <P>
// Example:
// <BLOCKQUOTE><PRE>
// # throttle file for www.acme.com
// * 100000 # limit total web usage to 2/3 of our T1
// *.jpg|*.gif 50000 # limit images to 1/3 of our T1
// *.mpg 20000 # and movies to even less
// jef/* 20000 # jef's pages are too popular
// </PRE></BLOCKQUOTE>
// <P>
// The routine returns a WildcardDictionary. Do a lookup in this
// dictionary using a filename, and you'll get back a ThrottleItem
// containing the corresponding byte rate.
public static Acme.WildcardDictionary parseThrottleFile( String filename ) throws IOException
{
Acme.WildcardDictionary wcd = new Acme.WildcardDictionary();
BufferedReader br = new BufferedReader( new FileReader( filename ) );
while ( true )
{
String line = br.readLine();
if ( line == null )
break;
int i = line.indexOf( '#' );
if ( i != -1 )
line = line.substring( 0, i );
line = line.trim();
if ( line.length() == 0 )
continue;
String[] words = Acme.Utils.splitStr( line );
if ( words.length != 2 )
throw new IOException( "malformed throttle line: " + line );
try
{
wcd.put(
words[0], new ThrottleItem( Long.parseLong( words[1] ) ) );
}
catch ( NumberFormatException e )
{
throw new IOException(
"malformed number in throttle line: " + line );
}
}
br.close();
return wcd;
}
private long maxBps;
private long bytes;
private long start;
/// Constructor.
public ThrottledOutputStream( OutputStream out, long maxBps )
{
super( out );
this.maxBps = maxBps;
bytes = 0;
start = System.currentTimeMillis();
}
private byte[] oneByte = new byte[1];
/// Writes a byte. This method will block until the byte is actually
// written.
// @param b the byte to be written
// @exception IOException if an I/O error has occurred
public void write( int b ) throws IOException
{
oneByte[0] = (byte) b;
write( oneByte, 0, 1 );
}
/// Writes a subarray of bytes.
// @param b the data to be written
// @param off the start offset in the data
// @param len the number of bytes that are written
// @exception IOException if an I/O error has occurred
public void write( byte b[], int off, int len ) throws IOException
{
// Check the throttle.
bytes += len;
long elapsed = System.currentTimeMillis() - start;
long bps = bytes * 1000L / elapsed;
if ( bps > maxBps )
{
// Oops, sending too fast.
long wakeElapsed = bytes * 1000L / maxBps;
try
{
Thread.sleep( wakeElapsed - elapsed );
}
catch ( InterruptedException ignore ) {}
}
// Write the bytes.
out.write( b, off, len );
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,147 +0,0 @@
// WildcardDictionary - a dictionary with wildcard lookups
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
import java.util.*;
/// A dictionary with wildcard lookups.
// <P>
// The keys in this dictionary are wildcard patterns. When you do a get(),
// the string you pass in is matched against all the patterns, and the
// first match is returned.
// <P>
// The wildcard matcher is fairly simple, it implements * meaning any
// string, ? meaning any single character, and | separating multiple
// patterns. All other characters must match literally.
// <P>
// <A HREF="/resources/classes/Acme/WildcardDictionary.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see Acme.Utils#match
public class WildcardDictionary extends Dictionary
{
private Vector keys;
private Vector elements;
/// Constructor.
public WildcardDictionary()
{
keys = new Vector();
elements = new Vector();
}
/// Returns the number of elements contained within the dictionary.
public int size()
{
return elements.size();
}
/// Returns true if the dictionary contains no elements.
public boolean isEmpty()
{
return size() == 0;
}
/// Returns an enumeration of the dictionary's keys.
public Enumeration keys()
{
return keys.elements();
}
/// Returns an enumeration of the elements. Use the Enumeration methods
// on the returned object to fetch the elements sequentially.
public Enumeration elements()
{
return elements.elements();
}
/// Gets the object associated with the specified key in the dictionary.
// The key is assumed to be a String, which is matched against
// the wildcard-pattern keys in the dictionary.
// @param key the string to match
// @returns the element for the key, or null if there's no match
// @see Acme.Utils#match
public synchronized Object get( Object key )
{
String sKey = (String) key;
for ( int i = 0; i < keys.size(); ++i )
{
String thisKey = (String) keys.elementAt( i );
if ( Acme.Utils.match( thisKey, sKey ) )
return elements.elementAt( i );
}
return null;
}
/// Puts the specified element into the Dictionary, using the specified
// key. The element may be retrieved by doing a get() with the same
// key. The key and the element cannot be null.
// @param key the specified wildcard-pattern key
// @param value the specified element
// @return the old value of the key, or null if it did not have one.
// @exception NullPointerException If the value of the specified
// element is null.
public synchronized Object put( Object key, Object element )
{
int i = keys.indexOf( key );
if ( i != -1 )
{
Object oldElement = elements.elementAt( i );
elements.setElementAt( element, i );
return oldElement;
}
else
{
keys.addElement( key );
elements.addElement( element );
return null;
}
}
/// Removes the element corresponding to the key. Does nothing if the
// key is not present.
// @param key the key that needs to be removed
// @return the value of key, or null if the key was not found.
public synchronized Object remove( Object key )
{
int i = keys.indexOf( key );
if ( i != -1 )
{
Object oldElement = elements.elementAt( i );
keys.removeElementAt( i );
elements.removeElementAt( i );
return oldElement;
}
else
return null;
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTAllocationExpression.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTAllocationExpression extends SimpleNode {
public ASTAllocationExpression(int id) {
super(id);
}
public ASTAllocationExpression(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTAllocationExpression(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTAllocationExpression(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTAndExpressionSequence.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTAndExpressionSequence extends SimpleNode {
public ASTAndExpressionSequence(int id) {
super(id);
}
public ASTAndExpressionSequence(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTAndExpressionSequence(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTAndExpressionSequence(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTAssignmentExpression.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTAssignmentExpression extends SimpleNode {
public ASTAssignmentExpression(int id) {
super(id);
}
public ASTAssignmentExpression(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTAssignmentExpression(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTAssignmentExpression(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTBinaryExpressionSequence.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTBinaryExpressionSequence extends SimpleNode {
public ASTBinaryExpressionSequence(int id) {
super(id);
}
public ASTBinaryExpressionSequence(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTBinaryExpressionSequence(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTBinaryExpressionSequence(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTBreakStatement.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTBreakStatement extends SimpleNode {
public ASTBreakStatement(int id) {
super(id);
}
public ASTBreakStatement(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTBreakStatement(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTBreakStatement(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTCompositeReference.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTCompositeReference extends SimpleNode {
public ASTCompositeReference(int id) {
super(id);
}
public ASTCompositeReference(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTCompositeReference(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTCompositeReference(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTConditionalExpression.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTConditionalExpression extends SimpleNode {
public ASTConditionalExpression(int id) {
super(id);
}
public ASTConditionalExpression(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTConditionalExpression(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTConditionalExpression(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTContinueStatement.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTContinueStatement extends SimpleNode {
public ASTContinueStatement(int id) {
super(id);
}
public ASTContinueStatement(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTContinueStatement(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTContinueStatement(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTEmptyExpression.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTEmptyExpression extends SimpleNode {
public ASTEmptyExpression(int id) {
super(id);
}
public ASTEmptyExpression(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTEmptyExpression(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTEmptyExpression(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTExpressionList.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTExpressionList extends SimpleNode {
public ASTExpressionList(int id) {
super(id);
}
public ASTExpressionList(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTExpressionList(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTExpressionList(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTForInStatement.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTForInStatement extends SimpleNode {
public ASTForInStatement(int id) {
super(id);
}
public ASTForInStatement(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTForInStatement(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTForInStatement(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTForStatement.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTForStatement extends SimpleNode {
public ASTForStatement(int id) {
super(id);
}
public ASTForStatement(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTForStatement(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTForStatement(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTForVarInStatement.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTForVarInStatement extends SimpleNode {
public ASTForVarInStatement(int id) {
super(id);
}
public ASTForVarInStatement(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTForVarInStatement(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTForVarInStatement(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTForVarStatement.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTForVarStatement extends SimpleNode {
public ASTForVarStatement(int id) {
super(id);
}
public ASTForVarStatement(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTForVarStatement(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTForVarStatement(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,39 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTFormalParameterList.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTFormalParameterList extends SimpleNode {
public ASTFormalParameterList(int id) {
super(id);
}
public ASTFormalParameterList(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTFormalParameterList(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTFormalParameterList(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
// JMCL
public String [] getArguments() {
int n = jjtGetNumChildren();
String [] args = new String[n];
for (int i=0; i<n; i++) {
ASTIdentifier idNode = (ASTIdentifier) (jjtGetChild(i));
args[i]=idNode.getName();
}
return args;
}
}

View file

@ -1,28 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTFunctionCallParameters.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTFunctionCallParameters extends SimpleNode {
public ASTFunctionCallParameters(int id) {
super(id);
}
public ASTFunctionCallParameters(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTFunctionCallParameters(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTFunctionCallParameters(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View file

@ -1,38 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTFunctionDeclaration.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTFunctionDeclaration extends SimpleNode {
private String sourceString = null;
public ASTFunctionDeclaration(int id) {
super(id);
}
public ASTFunctionDeclaration(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTFunctionDeclaration(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTFunctionDeclaration(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public void setSourceString(String sourceString) {
this.sourceString = sourceString;
}
public String getSourceString() {
return sourceString;
}
}

View file

@ -1,50 +0,0 @@
/* Generated By:JJTree: Do not edit this line. ASTIdentifier.java */
package FESI.AST;
import FESI.Parser.*;
public class ASTIdentifier extends SimpleNode {
private String identifierName = null;
private int hash = 0;
public ASTIdentifier(int id) {
super(id);
}
public ASTIdentifier(EcmaScript p, int id) {
super(p, id);
}
public static Node jjtCreate(int id) {
return new ASTIdentifier(id);
}
public static Node jjtCreate(EcmaScript p, int id) {
return new ASTIdentifier(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(EcmaScriptVisitor visitor, Object data) {
return visitor.visit(this, data);
}
// JMCL
public void setName(String identifierName) {
this.identifierName = identifierName.intern(); // to lower number of strings
this.hash = identifierName.hashCode();
}
public int hashCode() {
return hash;
}
public String getName() {
return identifierName;
}
public String toString() {
return "<" + identifierName + ">";
}
}

Some files were not shown because too many files have changed in this diff Show more