libpixels-java-2.1.3+svn.orig/ 0000755 0001750 0001750 00000000000 11412236310 015527 5 ustar martin martin libpixels-java-2.1.3+svn.orig/filters.iml 0000644 0001750 0001750 00000000655 10565274750 017732 0 ustar martin martin
libpixels-java-2.1.3+svn.orig/lib/ 0000755 0001750 0001750 00000000000 11412236303 016277 5 ustar martin martin libpixels-java-2.1.3+svn.orig/patterns_to_put_into_svn_ignore.txt 0000644 0001750 0001750 00000000144 10565274750 025025 0 ustar martin martin target
profiles.xml
.settings
.classpath
.project
.wtpmodules
*.iml
*.ipr
*.iws
nbproject
local
libpixels-java-2.1.3+svn.orig/www/ 0000755 0001750 0001750 00000000000 11412236303 016355 5 ustar martin martin libpixels-java-2.1.3+svn.orig/www/index.html 0000644 0001750 0001750 00000004676 10562646447 020412 0 ustar martin martin
Project Home Page
Default project home page
Congratulations on your new java.net project!
This page is the home page for your new project. This content is appearing
because you have selected the option Use project index.html. To edit
the information displayed on this page, just use CVS to check out your project's
CVS repository and edit index.html in directory www. You can get more information
on how to set-up your local CVS client, click on Version Control on the
left nav bar.
If you don't want to use CVS to manage your home page, click on the Edit
project link on this page and unclick the option Use project index.html.
Your project home page contents will be generated from the Edit project
field Description. Edit the text on that field to change your home page
contents. Click on Submit changes to save your edits.
Remember that you will attract more new members and your project team will
work more effectively if you, as the project owner, supply sufficient information
about your project for visitors to your project space. Good luck with your new
project!
libpixels-java-2.1.3+svn.orig/www/alm-process/ 0000755 0001750 0001750 00000000000 11412236303 020602 5 ustar martin martin libpixels-java-2.1.3+svn.orig/www/alm-process/snippets/ 0000755 0001750 0001750 00000000000 11412236303 022447 5 ustar martin martin libpixels-java-2.1.3+svn.orig/www/alm-process/snippets/page.xml 0000644 0001750 0001750 00000000674 11265044432 024122 0 ustar martin martin
HtmlSnippet1.htmlSubprojects
libpixels-java-2.1.3+svn.orig/www/alm-process/snippets/HtmlSnippet1.html 0000644 0001750 0001750 00000001153 11265044420 025670 0 ustar martin martin This project is a home for a set of image processing filters for use with Java2D. The focus is mainly on visual effects rather than scientific uses or machine vision. To that end, the filters are designed to work mainly with ARGB BufferedImages. They are intended to be used where JAI would be overkill, such as in applets. Also included are a set of custom Composites which implement commonly-used blending modes.
Pending the writing of documentation, descriptions of the filters can be found here. libpixels-java-2.1.3+svn.orig/filters.iws 0000644 0001750 0001750 00000122031 10565274750 017744 0 ustar martin martin
C:\Documents and Settings\ge0ffrey\Application Data\Subversionhttps://svn.sourceforge.net/svnroot/networktools
libpixels-java-2.1.3+svn.orig/LICENSE.txt 0000644 0001750 0001750 00000026135 10565274750 017403 0 ustar martin martin Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
libpixels-java-2.1.3+svn.orig/filters.ipr 0000644 0001750 0001750 00000053257 10565274750 017751 0 ustar martin martin
libpixels-java-2.1.3+svn.orig/src/ 0000755 0001750 0001750 00000000000 11412236304 016321 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/ 0000755 0001750 0001750 00000000000 11412236310 017242 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/ 0000755 0001750 0001750 00000000000 11412236304 020166 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/ 0000755 0001750 0001750 00000000000 11412236304 020744 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/ 0000755 0001750 0001750 00000000000 11412236310 022204 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/ 0000755 0001750 0001750 00000000000 11412236310 023633 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Tuple4f.java 0000644 0001750 0001750 00000005615 10562652111 026036 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Tuple4f {
public float x, y, z, w;
public Tuple4f() {
this( 0, 0, 0, 0 );
}
public Tuple4f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[2];
}
public Tuple4f( float x, float y, float z, float w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Tuple4f( Tuple4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public void absolute() {
x = Math.abs(x);
y = Math.abs(y);
z = Math.abs(z);
w = Math.abs(w);
}
public void absolute( Tuple4f t ) {
x = Math.abs(t.x);
y = Math.abs(t.y);
z = Math.abs(t.z);
w = Math.abs(t.w);
}
public void clamp( float min, float max ) {
if ( x < min )
x = min;
else if ( x > max )
x = max;
if ( y < min )
y = min;
else if ( y > max )
y = max;
if ( z < min )
z = min;
else if ( z > max )
z = max;
if ( w < min )
w = min;
else if ( w > max )
w = max;
}
public void set( float x, float y, float z, float w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public void set( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[2];
}
public void set( Tuple4f t ) {
x = t.x;
y = t.y;
z = t.z;
w = t.w;
}
public void get( Tuple4f t ) {
t.x = x;
t.y = y;
t.z = z;
t.w = w;
}
public void get( float[] t ) {
t[0] = x;
t[1] = y;
t[2] = z;
t[3] = w;
}
public void negate() {
x = -x;
y = -y;
z = -z;
w = -w;
}
public void negate( Tuple4f t ) {
x = -t.x;
y = -t.y;
z = -t.z;
w = -t.w;
}
public void interpolate( Tuple4f t, float alpha ) {
float a = 1-alpha;
x = a*x + alpha*t.x;
y = a*y + alpha*t.y;
z = a*z + alpha*t.z;
w = a*w + alpha*t.w;
}
public void scale( float s ) {
x *= s;
y *= s;
z *= s;
w *= s;
}
public void add( Tuple4f t ) {
x += t.x;
y += t.y;
z += t.z;
w += t.w;
}
public void add( Tuple4f t1, Tuple4f t2 ) {
x = t1.x+t2.x;
y = t1.y+t2.y;
z = t1.z+t2.z;
w = t1.w+t2.w;
}
public void sub( Tuple4f t ) {
x -= t.x;
y -= t.y;
z -= t.z;
w -= t.w;
}
public void sub( Tuple4f t1, Tuple4f t2 ) {
x = t1.x-t2.x;
y = t1.y-t2.y;
z = t1.z-t2.z;
w = t1.w-t2.w;
}
public String toString() {
return "["+x+", "+y+", "+z+", "+w+"]";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Matrix4f.java 0000644 0001750 0001750 00000014702 10562652111 026206 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Matrix4f {
public float m00, m01, m02, m03;
public float m10, m11, m12, m13;
public float m20, m21, m22, m23;
public float m30, m31, m32, m33;
public Matrix4f() {
setIdentity();
}
public Matrix4f( Matrix4f m ) {
set( m );
}
public Matrix4f(float[] m) {
set( m );
}
public void set( Matrix4f m) {
m00 = m.m00;
m01 = m.m01;
m02 = m.m02;
m03 = m.m03;
m10 = m.m10;
m11 = m.m11;
m12 = m.m12;
m13 = m.m13;
m20 = m.m20;
m21 = m.m21;
m22 = m.m22;
m23 = m.m23;
m30 = m.m30;
m31 = m.m31;
m32 = m.m32;
m33 = m.m33;
}
public void set(float[] m) {
m00 = m[0];
m01 = m[1];
m02 = m[2];
m03 = m[3];
m10 = m[4];
m11 = m[5];
m12 = m[6];
m13 = m[7];
m20 = m[8];
m21 = m[9];
m22 = m[10];
m23 = m[11];
m30 = m[12];
m31 = m[13];
m32 = m[14];
m33 = m[15];
}
public void get( Matrix4f m) {
m.m00 = m00;
m.m01 = m01;
m.m02 = m02;
m.m03 = m03;
m.m10 = m10;
m.m11 = m11;
m.m12 = m12;
m.m13 = m13;
m.m20 = m20;
m.m21 = m21;
m.m22 = m22;
m.m23 = m23;
m.m30 = m30;
m.m31 = m31;
m.m32 = m32;
m.m33 = m33;
}
public void get(float[] m) {
m[0] = m00;
m[1] = m01;
m[2] = m02;
m[3] = m03;
m[4] = m10;
m[5] = m11;
m[6] = m12;
m[7] = m13;
m[8] = m20;
m[9] = m21;
m[10] = m22;
m[11] = m23;
m[12] = m30;
m[13] = m31;
m[14] = m32;
m[15] = m33;
}
public void setIdentity() {
m00 = 1.0f;
m01 = 0.0f;
m02 = 0.0f;
m03 = 0.0f;
m10 = 0.0f;
m11 = 1.0f;
m12 = 0.0f;
m13 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = 1.0f;
m23 = 0.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 1.0f;
}
public void mul( Matrix4f m ) {
float tm00 = m00;
float tm01 = m01;
float tm02 = m02;
float tm03 = m03;
float tm10 = m10;
float tm11 = m11;
float tm12 = m12;
float tm13 = m13;
float tm20 = m20;
float tm21 = m21;
float tm22 = m22;
float tm23 = m23;
float tm30 = m30;
float tm31 = m31;
float tm32 = m32;
float tm33 = m33;
m00 = tm00*m.m00 + tm10*m.m01 + tm20*m.m02 + tm30*m.m03;
m01 = tm01*m.m00 + tm11*m.m01 + tm21*m.m02 + tm31*m.m03;
m02 = tm02*m.m00 + tm12*m.m01 + tm22*m.m02 + tm32*m.m03;
m03 = tm03*m.m00 + tm13*m.m01 + tm23*m.m02 + tm33*m.m03;
m10 = tm00*m.m10 + tm10*m.m11 + tm20*m.m12 + tm30*m.m13;
m11 = tm01*m.m10 + tm11*m.m11 + tm21*m.m12 + tm31*m.m13;
m12 = tm02*m.m10 + tm12*m.m11 + tm22*m.m12 + tm32*m.m13;
m13 = tm03*m.m10 + tm13*m.m11 + tm23*m.m12 + tm33*m.m13;
m20 = tm00*m.m20 + tm10*m.m21 + tm20*m.m22 + tm30*m.m23;
m21 = tm01*m.m20 + tm11*m.m21 + tm21*m.m22 + tm31*m.m23;
m22 = tm02*m.m20 + tm12*m.m21 + tm22*m.m22 + tm32*m.m23;
m23 = tm03*m.m20 + tm13*m.m21 + tm23*m.m22 + tm33*m.m23;
m30 = tm00*m.m30 + tm10*m.m31 + tm20*m.m32 + tm30*m.m33;
m31 = tm01*m.m30 + tm11*m.m31 + tm21*m.m32 + tm31*m.m33;
m32 = tm02*m.m30 + tm12*m.m31 + tm22*m.m32 + tm32*m.m33;
m33 = tm03*m.m30 + tm13*m.m31 + tm23*m.m32 + tm33*m.m33;
}
public void invert() {
Matrix4f t = new Matrix4f( this );
invert( t );
}
public void invert( Matrix4f t ) {
m00 = t.m00;
m01 = t.m10;
m02 = t.m20;
m03 = t.m03;
m10 = t.m01;
m11 = t.m11;
m12 = t.m21;
m13 = t.m13;
m20 = t.m02;
m21 = t.m12;
m22 = t.m22;
m23 = t.m23;
m30 *= -1.0f;
m31 *= -1.0f;
m32 *= -1.0f;
m33 = t.m33;
}
public void set( AxisAngle4f a ) {
float halfTheta = a.angle * 0.5f;
float cosHalfTheta = (float)Math.cos(halfTheta);
float sinHalfTheta = (float)Math.sin(halfTheta);
set( new Quat4f( a.x * sinHalfTheta, a.y * sinHalfTheta, a.z * sinHalfTheta, cosHalfTheta ) );
}
public void set( Quat4f q ) {
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
x2 = q.x + q.x;
y2 = q.y + q.y;
z2 = q.z + q.z;
xx = q.x * x2;
xy = q.x * y2;
xz = q.x * z2;
yy = q.y * y2;
yz = q.y * z2;
zz = q.z * z2;
wx = q.w * x2;
wy = q.w * y2;
wz = q.w * z2;
m00 = 1.0f - (yy + zz);
m01 = xy - wz;
m02 = xz + wy;
m03 = 0.0f;
m10 = xy + wz;
m11 = 1.0f - (xx + zz);
m12 = yz - wx;
m13 = 0.0f;
m20 = xz - wy;
m21 = yz + wx;
m22 = 1.0f - (xx + yy);
m23 = 0.0f;
m30 = 0;
m31 = 0;
m32 = 0;
m33 = 1;
}
public void transform( Point3f v ) {
float x = v.x * m00 + v.y * m10 + v.z * m20 + m30;
float y = v.x * m01 + v.y * m11 + v.z * m21 + m31;
float z = v.x * m02 + v.y * m12 + v.z * m22 + m32;
v.x = x;
v.y = y;
v.z = z;
}
public void transform( Vector3f v ) {
float x = v.x * m00 + v.y * m10 + v.z * m20;
float y = v.x * m01 + v.y * m11 + v.z * m21;
float z = v.x * m02 + v.y * m12 + v.z * m22;
v.x = x;
v.y = y;
v.z = z;
}
public void setTranslation( Vector3f v ) {
m30 = v.x;
m31 = v.y;
m32 = v.z;
}
public void set( float scale ) {
m00 = scale;
m11 = scale;
m22 = scale;
}
public void rotX( float angle ) {
float s = (float)Math.sin( angle );
float c = (float)Math.cos( angle );
m00 = 1.0f;
m01 = 0.0f;
m02 = 0.0f;
m03 = 0.0f;
m10 = 0.0f;
m11 = c;
m12 = s;
m13 = 0.0f;
m20 = 0.0f;
m21 = -s;
m22 = c;
m23 = 0.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 1.0f;
}
public void rotY( float angle ) {
float s = (float)Math.sin( angle );
float c = (float)Math.cos( angle );
m00 = c;
m01 = 0.0f;
m02 = -s;
m03 = 0.0f;
m10 = 0.0f;
m11 = 1.0f;
m12 = 0.0f;
m13 = 0.0f;
m20 = s;
m21 = 0.0f;
m22 = c;
m23 = 0.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 1.0f;
}
public void rotZ( float angle ) {
float s = (float)Math.sin( angle );
float c = (float)Math.cos( angle );
m00 = c;
m01 = s;
m02 = 0.0f;
m03 = 0.0f;
m10 = -s;
m11 = c;
m12 = 0.0f;
m13 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = 1.0f;
m23 = 0.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = 0.0f;
m33 = 1.0f;
}
/*
void rotate(float angle, float x, float y, float z) {
Matrix4f m = new Matrix4f();//FIXME
m.MatrixFromAxisAngle(Vector3f(x, y, z), angle);
Multiply(m);
}
*/
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Point3f.java 0000644 0001750 0001750 00000002722 10562652111 026031 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Point3f extends Tuple3f {
public Point3f() {
this( 0, 0, 0 );
}
public Point3f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
}
public Point3f( float x, float y, float z ) {
this.x = x;
this.y = y;
this.z = z;
}
public Point3f( Point3f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
}
public Point3f( Tuple3f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
}
public float distanceL1( Point3f p ) {
return Math.abs(x-p.x) + Math.abs(y-p.y) + Math.abs(z-p.z);
}
public float distanceSquared( Point3f p ) {
float dx = x-p.x;
float dy = y-p.y;
float dz = z-p.z;
return dx*dx+dy*dy+dz*dz;
}
public float distance( Point3f p ) {
float dx = x-p.x;
float dy = y-p.y;
float dz = z-p.z;
return (float)Math.sqrt( dx*dx+dy*dy+dz*dz );
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Point4f.java 0000644 0001750 0001750 00000003143 10562652111 026030 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Point4f extends Tuple4f {
public Point4f() {
this( 0, 0, 0, 0 );
}
public Point4f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[3];
}
public Point4f( float x, float y, float z, float w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Point4f( Point4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public Point4f( Tuple4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public float distanceL1( Point4f p ) {
return Math.abs(x-p.x) + Math.abs(y-p.y) + Math.abs(z-p.z) + Math.abs(w-p.w);
}
public float distanceSquared( Point4f p ) {
float dx = x-p.x;
float dy = y-p.y;
float dz = z-p.z;
float dw = w-p.w;
return dx*dx+dy*dy+dz*dz+dw*dw;
}
public float distance( Point4f p ) {
float dx = x-p.x;
float dy = y-p.y;
float dz = z-p.z;
float dw = w-p.w;
return (float)Math.sqrt( dx*dx+dy*dy+dz*dz+dw*dw );
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Quat4f.java 0000644 0001750 0001750 00000007245 10562652111 025660 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Quat4f extends Tuple4f {
public Quat4f() {
this( 0, 0, 0, 0 );
}
public Quat4f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[3];
}
public Quat4f( float x, float y, float z, float w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Quat4f( Quat4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public Quat4f( Tuple4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public void set( AxisAngle4f a ) {
float halfTheta = a.angle * 0.5f;
float cosHalfTheta = (float)Math.cos(halfTheta);
float sinHalfTheta = (float)Math.sin(halfTheta);
x = a.x * sinHalfTheta;
y = a.y * sinHalfTheta;
z = a.z * sinHalfTheta;
w = cosHalfTheta;
}
/*
public void EulerToQuaternion(float roll, float pitch, float yaw)
{
float cr, cp, cy, sr, sp, sy, cpcy, spsy;
cr = cos(roll/2);
cp = cos(pitch/2);
cy = cos(yaw/2);
sr = sin(roll/2);
sp = sin(pitch/2);
sy = sin(yaw/2);
cpcy = cp * cy;
spsy = sp * sy;
w = cr * cpcy + sr * spsy;
x = sr * cpcy - cr * spsy;
y = cr * sp * cy + sr * cp * sy;
z = cr * cp * sy - sr * sp * cy;
}
*/
public void normalize() {
float d = 1.0f/( x*x+y*y+z*z+w*w );
x *= d;
y *= d;
z *= d;
w *= d;
}
/*
public void mul( Quat4f q ) {
Quat4f q3 = new Quat4f();
Vector3f vectorq1 = new Vector3f( x, y, z );
Vector3f vectorq2 = new Vector3f( q.x, q.y, q.z );
Vector3f tempvec1 = new Vector3f( vectorq1 );
Vector3f tempvec2;
Vector3f tempvec3;
q3.w = (w*q.w) - tempvec1.dot(vectorq2);
tempvec1.cross(vectorq2);
tempvec2.x = w * q.x;
tempvec2.y = w * q.y;
tempvec2.z = w * q.z;
tempvec3.x = q.w * x;
tempvec3.y = q.w * y;
tempvec3.z = q.w * z;
q3.x = tempvec1.x + tempvec2.x + tempvec3.x;
q3.y = tempvec1.y + tempvec2.y + tempvec3.y;
q3.z = tempvec1.z + tempvec2.z + tempvec3.z;
set(q3);
}
*/
public void set( Matrix4f m ) {
float s;
int i;
float tr = m.m00 + m.m11 + m.m22;
if (tr > 0.0) {
s = (float)Math.sqrt(tr + 1.0f);
w = s / 2.0f;
s = 0.5f / s;
x = (m.m12 - m.m21) * s;
y = (m.m20 - m.m02) * s;
z = (m.m01 - m.m10) * s;
} else {
i = 0;
if ( m.m11 > m.m00 ) {
i = 1;
if ( m.m22 > m.m11 ) {
i = 2;
} else {
}
} else {
if ( m.m22 > m.m00 ) {
i = 2;
} else {
}
}
switch ( i ) {
case 0:
s = (float)Math.sqrt ((m.m00 - (m.m11 + m.m22)) + 1.0f);
x = s * 0.5f;
if (s != 0.0)
s = 0.5f / s;
w = (m.m12 - m.m21) * s;
y = (m.m01 + m.m10) * s;
z = (m.m02 + m.m20) * s;
break;
case 1:
s = (float)Math.sqrt ((m.m11 - (m.m22 + m.m00)) + 1.0f);
y = s * 0.5f;
if (s != 0.0)
s = 0.5f / s;
w = (m.m20 - m.m02) * s;
z = (m.m12 + m.m21) * s;
x = (m.m10 + m.m01) * s;
break;
case 2:
s = (float)Math.sqrt ((m.m00 - (m.m11 + m.m22)) + 1.0f);
z = s * 0.5f;
if (s != 0.0)
s = 0.5f / s;
w = (m.m01 - m.m10) * s;
x = (m.m20 + m.m02) * s;
y = (m.m21 + m.m12) * s;
break;
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Vector3f.java 0000644 0001750 0001750 00000003117 10562652111 026201 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Vector3f extends Tuple3f {
public Vector3f() {
this( 0, 0, 0 );
}
public Vector3f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
}
public Vector3f( float x, float y, float z ) {
this.x = x;
this.y = y;
this.z = z;
}
public Vector3f( Vector3f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
}
public Vector3f( Tuple3f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
}
public float angle( Vector3f v ) {
return (float)Math.acos( dot(v) / (length()*v.length()) );
}
public float dot( Vector3f v ) {
return v.x * x + v.y * y + v.z * z;
}
public void cross( Vector3f v1, Vector3f v2 ) {
x = v1.y * v2.z - v1.z * v2.y;
y = v1.z * v2.x - v1.x * v2.z;
z = v1.x * v2.y - v1.y * v2.x;
}
public float length() {
return (float)Math.sqrt( x*x+y*y+z*z );
}
public void normalize() {
float d = 1.0f/(float)Math.sqrt( x*x+y*y+z*z );
x *= d;
y *= d;
z *= d;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Tuple3f.java 0000644 0001750 0001750 00000005402 10562652111 026027 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Tuple3f {
public float x, y, z;
public Tuple3f() {
this( 0, 0, 0 );
}
public Tuple3f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
}
public Tuple3f( float x, float y, float z ) {
this.x = x;
this.y = y;
this.z = z;
}
public Tuple3f( Tuple3f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
}
public void absolute() {
x = Math.abs(x);
y = Math.abs(y);
z = Math.abs(z);
}
public void absolute( Tuple3f t ) {
x = Math.abs(t.x);
y = Math.abs(t.y);
z = Math.abs(t.z);
}
public void clamp( float min, float max ) {
if ( x < min )
x = min;
else if ( x > max )
x = max;
if ( y < min )
y = min;
else if ( y > max )
y = max;
if ( z < min )
z = min;
else if ( z > max )
z = max;
}
public void set( float x, float y, float z ) {
this.x = x;
this.y = y;
this.z = z;
}
public void set( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
}
public void set( Tuple3f t ) {
x = t.x;
y = t.y;
z = t.z;
}
public void get( Tuple3f t ) {
t.x = x;
t.y = y;
t.z = z;
}
public void get( float[] t ) {
t[0] = x;
t[1] = y;
t[2] = z;
}
public void negate() {
x = -x;
y = -y;
z = -z;
}
public void negate( Tuple3f t ) {
x = -t.x;
y = -t.y;
z = -t.z;
}
public void interpolate( Tuple3f t, float alpha ) {
float a = 1-alpha;
x = a*x + alpha*t.x;
y = a*y + alpha*t.y;
z = a*z + alpha*t.z;
}
public void scale( float s ) {
x *= s;
y *= s;
z *= s;
}
public void add( Tuple3f t ) {
x += t.x;
y += t.y;
z += t.z;
}
public void add( Tuple3f t1, Tuple3f t2 ) {
x = t1.x+t2.x;
y = t1.y+t2.y;
z = t1.z+t2.z;
}
public void sub( Tuple3f t ) {
x -= t.x;
y -= t.y;
z -= t.z;
}
public void sub( Tuple3f t1, Tuple3f t2 ) {
x = t1.x-t2.x;
y = t1.y-t2.y;
z = t1.z-t2.z;
}
public void scaleAdd( float s, Tuple3f t ) {
x += s*t.x;
y += s*t.y;
z += s*t.z;
}
public void scaleAdd( float s, Tuple3f t1, Tuple3f t2 ) {
x = s*t1.x + t2.x;
y = s*t1.y + t2.y;
z = s*t1.z + t2.z;
}
public String toString() {
return "["+x+", "+y+", "+z+"]";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/AxisAngle4f.java 0000644 0001750 0001750 00000003311 10562652111 026607 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class AxisAngle4f {
public float x, y, z, angle;
public AxisAngle4f() {
this( 0, 0, 0, 0 );
}
public AxisAngle4f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.angle = x[2];
}
public AxisAngle4f( float x, float y, float z, float angle ) {
this.x = x;
this.y = y;
this.z = z;
this.angle = angle;
}
public AxisAngle4f( AxisAngle4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.angle = t.angle;
}
public AxisAngle4f( Vector3f v, float angle ) {
this.x = v.x;
this.y = v.y;
this.z = v.z;
this.angle = angle;
}
public void set( float x, float y, float z, float angle ) {
this.x = x;
this.y = y;
this.z = z;
this.angle = angle;
}
public void set( AxisAngle4f t ) {
x = t.x;
y = t.y;
z = t.z;
angle = t.angle;
}
public void get( AxisAngle4f t ) {
t.x = x;
t.y = y;
t.z = z;
t.angle = angle;
}
public void get( float[] t ) {
t[0] = x;
t[1] = y;
t[2] = z;
t[3] = angle;
}
public String toString() {
return "["+x+", "+y+", "+z+", "+angle+"]";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Vector4f.java 0000644 0001750 0001750 00000002601 10562652111 026177 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Vector4f extends Tuple4f {
public Vector4f() {
this( 0, 0, 0, 0 );
}
public Vector4f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[2];
}
public Vector4f( float x, float y, float z, float w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Vector4f( Vector4f t ) {
x = t.x;
y = t.y;
z = t.z;
w = t.w;
}
public Vector4f( Tuple4f t ) {
x = t.x;
y = t.y;
z = t.z;
w = t.w;
}
public float dot( Vector4f v ) {
return v.x * x + v.y * y + v.z * z + v.w * w;
}
public float length() {
return (float)Math.sqrt( x*x+y*y+z*z+w*w );
}
public void normalize() {
float d = 1.0f/( x*x+y*y+z*z+w*w );
x *= d;
y *= d;
z *= d;
w *= d;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/vecmath/Color4f.java 0000644 0001750 0001750 00000002527 10562652111 026022 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.vecmath;
import java.awt.*;
/**
* Vector math package, converted to look similar to javax.vecmath.
*/
public class Color4f extends Tuple4f {
public Color4f() {
this( 0, 0, 0, 0 );
}
public Color4f( float[] x ) {
this.x = x[0];
this.y = x[1];
this.z = x[2];
this.w = x[3];
}
public Color4f( float x, float y, float z, float w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Color4f( Color4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public Color4f( Tuple4f t ) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public Color4f( Color c ) {
set( c );
}
public void set( Color c ) {
set( c.getRGBComponents( null ) );
}
public Color get() {
return new Color( x, y, z, w );
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/ 0000755 0001750 0001750 00000000000 11412236310 023135 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/MarbleFunction.java 0000644 0001750 0001750 00000001631 10562652111 026717 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class MarbleFunction extends CompoundFunction2D {
public MarbleFunction() {
super(new TurbulenceFunction(new Noise(), 6));
}
public MarbleFunction(Function2D basis) {
super(basis);
}
public float evaluate(float x, float y) {
return (float)Math.pow(0.5 * (Math.sin(8. * basis.evaluate(x, y)) + 1), 0.77);
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/RidgedFBM.java 0000644 0001750 0001750 00000001325 10562652111 025532 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class RidgedFBM implements Function2D {
public float evaluate(float x, float y) {
return 1-Math.abs(Noise.noise2(x, y));
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/CompositeFunction1D.java 0000644 0001750 0001750 00000001522 10562652111 027643 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class CompositeFunction1D implements Function1D {
private Function1D f1, f2;
public CompositeFunction1D(Function1D f1, Function1D f2) {
this.f1 = f1;
this.f2 = f2;
}
public float evaluate(float v) {
return f1.evaluate(f2.evaluate(v));
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/Noise.java 0000644 0001750 0001750 00000016364 10562652111 025075 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
import java.util.*;
/**
* Perlin Noise functions
*/
public class Noise implements Function1D, Function2D, Function3D {
private static Random randomGenerator = new Random();
public float evaluate(float x) {
return noise1(x);
}
public float evaluate(float x, float y) {
return noise2(x, y);
}
public float evaluate(float x, float y, float z) {
return noise3(x, y, z);
}
/**
* Compute turbulence using Perlin noise.
* @param x the x value
* @param y the y value
* @param octaves number of octaves of turbulence
* @return turbulence value at (x,y)
*/
public static float turbulence2(float x, float y, float octaves) {
float t = 0.0f;
for (float f = 1.0f; f <= octaves; f *= 2)
t += Math.abs(noise2(f * x, f * y)) / f;
return t;
}
/**
* Compute turbulence using Perlin noise.
* @param x the x value
* @param y the y value
* @param octaves number of octaves of turbulence
* @return turbulence value at (x,y)
*/
public static float turbulence3(float x, float y, float z, float octaves) {
float t = 0.0f;
for (float f = 1.0f; f <= octaves; f *= 2)
t += Math.abs(noise3(f * x, f * y, f * z)) / f;
return t;
}
private final static int B = 0x100;
private final static int BM = 0xff;
private final static int N = 0x1000;
static int[] p = new int[B + B + 2];
static float[][] g3 = new float[B + B + 2][3];
static float[][] g2 = new float[B + B + 2][2];
static float[] g1 = new float[B + B + 2];
static boolean start = true;
private static float sCurve(float t) {
return t * t * (3.0f - 2.0f * t);
}
/**
* Compute 1-dimensional Perlin noise.
* @param x the x value
* @return noise value at x in the range -1..1
*/
public static float noise1(float x) {
int bx0, bx1;
float rx0, rx1, sx, t, u, v;
if (start) {
start = false;
init();
}
t = x + N;
bx0 = ((int)t) & BM;
bx1 = (bx0+1) & BM;
rx0 = t - (int)t;
rx1 = rx0 - 1.0f;
sx = sCurve(rx0);
u = rx0 * g1[p[bx0]];
v = rx1 * g1[p[bx1]];
return 2.3f*lerp(sx, u, v);
}
/**
* Compute 2-dimensional Perlin noise.
* @param x the x coordinate
* @param y the y coordinate
* @return noise value at (x,y)
*/
public static float noise2(float x, float y) {
int bx0, bx1, by0, by1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, q[], sx, sy, a, b, t, u, v;
int i, j;
if (start) {
start = false;
init();
}
t = x + N;
bx0 = ((int)t) & BM;
bx1 = (bx0+1) & BM;
rx0 = t - (int)t;
rx1 = rx0 - 1.0f;
t = y + N;
by0 = ((int)t) & BM;
by1 = (by0+1) & BM;
ry0 = t - (int)t;
ry1 = ry0 - 1.0f;
i = p[bx0];
j = p[bx1];
b00 = p[i + by0];
b10 = p[j + by0];
b01 = p[i + by1];
b11 = p[j + by1];
sx = sCurve(rx0);
sy = sCurve(ry0);
q = g2[b00]; u = rx0 * q[0] + ry0 * q[1];
q = g2[b10]; v = rx1 * q[0] + ry0 * q[1];
a = lerp(sx, u, v);
q = g2[b01]; u = rx0 * q[0] + ry1 * q[1];
q = g2[b11]; v = rx1 * q[0] + ry1 * q[1];
b = lerp(sx, u, v);
return 1.5f*lerp(sy, a, b);
}
/**
* Compute 3-dimensional Perlin noise.
* @param x the x coordinate
* @param y the y coordinate
* @param y the y coordinate
* @return noise value at (x,y,z)
*/
public static float noise3(float x, float y, float z) {
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, rz0, rz1, q[], sy, sz, a, b, c, d, t, u, v;
int i, j;
if (start) {
start = false;
init();
}
t = x + N;
bx0 = ((int)t) & BM;
bx1 = (bx0+1) & BM;
rx0 = t - (int)t;
rx1 = rx0 - 1.0f;
t = y + N;
by0 = ((int)t) & BM;
by1 = (by0+1) & BM;
ry0 = t - (int)t;
ry1 = ry0 - 1.0f;
t = z + N;
bz0 = ((int)t) & BM;
bz1 = (bz0+1) & BM;
rz0 = t - (int)t;
rz1 = rz0 - 1.0f;
i = p[bx0];
j = p[bx1];
b00 = p[i + by0];
b10 = p[j + by0];
b01 = p[i + by1];
b11 = p[j + by1];
t = sCurve(rx0);
sy = sCurve(ry0);
sz = sCurve(rz0);
q = g3[b00 + bz0]; u = rx0 * q[0] + ry0 * q[1] + rz0 * q[2];
q = g3[b10 + bz0]; v = rx1 * q[0] + ry0 * q[1] + rz0 * q[2];
a = lerp(t, u, v);
q = g3[b01 + bz0]; u = rx0 * q[0] + ry1 * q[1] + rz0 * q[2];
q = g3[b11 + bz0]; v = rx1 * q[0] + ry1 * q[1] + rz0 * q[2];
b = lerp(t, u, v);
c = lerp(sy, a, b);
q = g3[b00 + bz1]; u = rx0 * q[0] + ry0 * q[1] + rz1 * q[2];
q = g3[b10 + bz1]; v = rx1 * q[0] + ry0 * q[1] + rz1 * q[2];
a = lerp(t, u, v);
q = g3[b01 + bz1]; u = rx0 * q[0] + ry1 * q[1] + rz1 * q[2];
q = g3[b11 + bz1]; v = rx1 * q[0] + ry1 * q[1] + rz1 * q[2];
b = lerp(t, u, v);
d = lerp(sy, a, b);
return 1.5f*lerp(sz, c, d);
}
public static float lerp(float t, float a, float b) {
return a + t * (b - a);
}
private static void normalize2(float v[]) {
float s = (float)Math.sqrt(v[0] * v[0] + v[1] * v[1]);
v[0] = v[0] / s;
v[1] = v[1] / s;
}
static void normalize3(float v[]) {
float s = (float)Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] = v[0] / s;
v[1] = v[1] / s;
v[2] = v[2] / s;
}
private static int random() {
return randomGenerator.nextInt() & 0x7fffffff;
}
private static void init() {
int i, j, k;
for (i = 0; i < B; i++) {
p[i] = i;
g1[i] = (float)((random() % (B + B)) - B) / B;
for (j = 0; j < 2; j++)
g2[i][j] = (float)((random() % (B + B)) - B) / B;
normalize2(g2[i]);
for (j = 0; j < 3; j++)
g3[i][j] = (float)((random() % (B + B)) - B) / B;
normalize3(g3[i]);
}
for (i = B-1; i >= 0; i--) {
k = p[i];
p[i] = p[j = random() % B];
p[j] = k;
}
for (i = 0; i < B + 2; i++) {
p[B + i] = p[i];
g1[B + i] = g1[i];
for (j = 0; j < 2; j++)
g2[B + i][j] = g2[i][j];
for (j = 0; j < 3; j++)
g3[B + i][j] = g3[i][j];
}
}
/**
* Returns the minimum and maximum of a number of random values
* of the given function. This is useful for making some stab at
* normalising the function.
*/
public static float[] findRange(Function1D f, float[] minmax) {
if (minmax == null)
minmax = new float[2];
float min = 0, max = 0;
// Some random numbers here...
for (float x = -100; x < 100; x += 1.27139) {
float n = f.evaluate(x);
min = Math.min(min, n);
max = Math.max(max, n);
}
minmax[0] = min;
minmax[1] = max;
return minmax;
}
/**
* Returns the minimum and maximum of a number of random values
* of the given function. This is useful for making some stab at
* normalising the function.
*/
public static float[] findRange(Function2D f, float[] minmax) {
if (minmax == null)
minmax = new float[2];
float min = 0, max = 0;
// Some random numbers here...
for (float y = -100; y < 100; y += 10.35173) {
for (float x = -100; x < 100; x += 10.77139) {
float n = f.evaluate(x, y);
min = Math.min(min, n);
max = Math.max(max, n);
}
}
minmax[0] = min;
minmax[1] = max;
return minmax;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/FBM.java 0000644 0001750 0001750 00000003404 10562652111 024413 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class FBM implements Function2D {
protected float[] exponents;
protected float H;
protected float lacunarity;
protected float octaves;
protected Function2D basis;
public FBM(float H, float lacunarity, float octaves) {
this(H, lacunarity, octaves, new Noise());
}
public FBM(float H, float lacunarity, float octaves, Function2D basis) {
this.H = H;
this.lacunarity = lacunarity;
this.octaves = octaves;
this.basis = basis;
exponents = new float[(int)octaves+1];
float frequency = 1.0f;
for (int i = 0; i <= (int)octaves; i++) {
exponents[i] = (float)Math.pow(frequency, -H);
frequency *= lacunarity;
}
}
public void setBasis(Function2D basis) {
this.basis = basis;
}
public Function2D getBasisType() {
return basis;
}
public float evaluate(float x, float y) {
float value = 0.0f;
float remainder;
int i;
// to prevent "cascading" effects
x += 371;
y += 529;
for (i = 0; i < (int)octaves; i++) {
value += basis.evaluate(x, y) * exponents[i];
x *= lacunarity;
y *= lacunarity;
}
remainder = octaves - (int)octaves;
if (remainder != 0)
value += remainder * basis.evaluate(x, y) * exponents[i];
return value;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/MathFunction1D.java 0000644 0001750 0001750 00000002626 10562652111 026600 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class MathFunction1D implements Function1D {
public final static int SIN = 1;
public final static int COS = 2;
public final static int TAN = 3;
public final static int SQRT = 4;
public final static int ASIN = -1;
public final static int ACOS = -2;
public final static int ATAN = -3;
public final static int SQR = -4;
private int operation;
public MathFunction1D(int operation) {
this.operation = operation;
}
public float evaluate(float v) {
switch (operation) {
case SIN:
return (float)Math.sin(v);
case COS:
return (float)Math.cos(v);
case TAN:
return (float)Math.tan(v);
case SQRT:
return (float)Math.sqrt(v);
case ASIN:
return (float)Math.asin(v);
case ACOS:
return (float)Math.acos(v);
case ATAN:
return (float)Math.atan(v);
case SQR:
return v*v;
}
return v;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/CellularFunction2D.java 0000644 0001750 0001750 00000006517 10562652111 027456 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
import java.awt.image.*;
import java.util.*;
public class CellularFunction2D implements Function2D {
public float distancePower = 2;
public boolean cells = false;
public boolean angular = false;
private float[] coefficients = { 1, 0, 0, 0 };
private Random random = new Random();
private Point[] results = null;
public CellularFunction2D() {
results = new Point[2];
for (int j = 0; j < results.length; j++)
results[j] = new Point();
}
public void setCoefficient(int c, float v) {
coefficients[c] = v;
}
public float getCoefficient(int c) {
return coefficients[c];
}
class Point {
int index;
float x, y;
float distance;
}
private float checkCube(float x, float y, int cubeX, int cubeY, Point[] results) {
random.setSeed(571*cubeX + 23*cubeY);
int numPoints = 3 + random.nextInt() % 4;
numPoints = 4;
for (int i = 0; i < numPoints; i++) {
float px = random.nextFloat();
float py = random.nextFloat();
float dx = Math.abs(x-px);
float dy = Math.abs(y-py);
float d;
if (distancePower == 1.0f)
d = dx + dy;
else if (distancePower == 2.0f)
d = (float)Math.sqrt(dx*dx + dy*dy);
else
d = (float)Math.pow(Math.pow(dx, distancePower) + Math.pow(dy, distancePower), 1/distancePower);
// Insertion sort
for (int j = 0; j < results.length; j++) {
if (results[j].distance == Double.POSITIVE_INFINITY) {
Point last = results[j];
last.distance = d;
last.x = px;
last.y = py;
results[j] = last;
break;
} else if (d < results[j].distance) {
Point last = results[results.length-1];
for (int k = results.length-1; k > j; k--)
results[k] = results[k-1];
last.distance = d;
last.x = px;
last.y = py;
results[j] = last;
break;
}
}
}
return results[1].distance;
}
public float evaluate(float x, float y) {
for (int j = 0; j < results.length; j++)
results[j].distance = Float.POSITIVE_INFINITY;
int ix = (int)x;
int iy = (int)y;
float fx = x-ix;
float fy = y-iy;
float d = checkCube(fx, fy, ix, iy, results);
if (d > fy)
d = checkCube(fx, fy+1, ix, iy-1, results);
if (d > 1-fy)
d = checkCube(fx, fy-1, ix, iy+1, results);
if (d > fx) {
checkCube(fx+1, fy, ix-1, iy, results);
if (d > fy)
d = checkCube(fx+1, fy+1, ix-1, iy-1, results);
if (d > 1-fy)
d = checkCube(fx+1, fy-1, ix-1, iy+1, results);
}
if (d > 1-fx) {
d = checkCube(fx-1, fy, ix+1, iy, results);
if (d > fy)
d = checkCube(fx-1, fy+1, ix+1, iy-1, results);
if (d > 1-fy)
d = checkCube(fx-1, fy-1, ix+1, iy+1, results);
}
float t = 0;
for (int i = 0; i < 2; i++)
t += coefficients[i] * results[i].distance;
if (angular)
t += Math.atan2(fy-results[0].y, fx-results[0].x) / (2*Math.PI) + 0.5;
return t;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/FractalSumFunction.java 0000644 0001750 0001750 00000001626 10562652111 027562 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class FractalSumFunction extends CompoundFunction2D {
private float octaves = 1.0f;
public FractalSumFunction(Function2D basis) {
super(basis);
}
public float evaluate(float x, float y) {
float t = 0.0f;
for (float f = 1.0f; f <= octaves; f *= 2)
t += basis.evaluate(f * x, f * y) / f;
return t;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/BinaryFunction.java 0000644 0001750 0001750 00000001222 10562652111 026735 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public interface BinaryFunction {
public boolean isBlack(int rgb);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/SCNoise.java 0000644 0001750 0001750 00000011711 10562652111 025312 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
import java.util.*;
/**
* Sparse Convolution Noise. This is computationally very expensive, but worth it.
*/
public class SCNoise implements Function1D, Function2D, Function3D {
private static Random randomGenerator = new Random();
public float evaluate(float x) {
return evaluate(x, .1f);
}
public float evaluate(float x, float y) {
int i, j, k, h, n;
int ix, iy;
float sum = 0;
float fx, fy, dx, dy, distsq;
if (impulseTab == null)
impulseTab = impulseTabInit(665);
ix = floor(x); fx = x - ix;
iy = floor(y); fy = y - iy;
/* Perform the sparse convolution. */
int m = 2;
for (i = -m; i <= m; i++) {
for (j = -m; j <= m; j++) {
/* Compute voxel hash code. */
h = perm[(ix+i + perm[(iy+j)&TABMASK])&TABMASK];
for (n = NIMPULSES; n > 0; n--, h = (h+1) & TABMASK) {
/* Convolve filter and impulse. */
int h4 = h*4;
dx = fx - (i + impulseTab[h4++]);
dy = fy - (j + impulseTab[h4++]);
distsq = dx*dx + dy*dy;
sum += catrom2(distsq) * impulseTab[h4];
}
}
}
return sum / NIMPULSES;
}
public float evaluate(float x, float y, float z) {
int i, j, k, h, n;
int ix, iy, iz;
float sum = 0;
float fx, fy, fz, dx, dy, dz, distsq;
if (impulseTab == null)
impulseTab = impulseTabInit(665);
ix = floor(x); fx = x - ix;
iy = floor(y); fy = y - iy;
iz = floor(z); fz = z - iz;
/* Perform the sparse convolution. */
int m = 2;
for (i = -m; i <= m; i++) {
for (j = -m; j <= m; j++) {
for (k = -m; k <= m; k++) {
/* Compute voxel hash code. */
h = perm[(ix+i + perm[(iy+j + perm[(iz+k)&TABMASK])&TABMASK])&TABMASK];
for (n = NIMPULSES; n > 0; n--, h = (h+1) & TABMASK) {
/* Convolve filter and impulse. */
int h4 = h*4;
dx = fx - (i + impulseTab[h4++]);
dy = fy - (j + impulseTab[h4++]);
dz = fz - (k + impulseTab[h4++]);
distsq = dx*dx + dy*dy + dz*dz;
sum += catrom2(distsq) * impulseTab[h4];
}
}
}
}
return sum / NIMPULSES;
}
public short[] perm = {
225,155,210,108,175,199,221,144,203,116, 70,213, 69,158, 33,252,
5, 82,173,133,222,139,174, 27, 9, 71, 90,246, 75,130, 91,191,
169,138, 2,151,194,235, 81, 7, 25,113,228,159,205,253,134,142,
248, 65,224,217, 22,121,229, 63, 89,103, 96,104,156, 17,201,129,
36, 8,165,110,237,117,231, 56,132,211,152, 20,181,111,239,218,
170,163, 51,172,157, 47, 80,212,176,250, 87, 49, 99,242,136,189,
162,115, 44, 43,124, 94,150, 16,141,247, 32, 10,198,223,255, 72,
53,131, 84, 57,220,197, 58, 50,208, 11,241, 28, 3,192, 62,202,
18,215,153, 24, 76, 41, 15,179, 39, 46, 55, 6,128,167, 23,188,
106, 34,187,140,164, 73,112,182,244,195,227, 13, 35, 77,196,185,
26,200,226,119, 31,123,168,125,249, 68,183,230,177,135,160,180,
12, 1,243,148,102,166, 38,238,251, 37,240,126, 64, 74,161, 40,
184,149,171,178,101, 66, 29, 59,146, 61,254,107, 42, 86,154, 4,
236,232,120, 21,233,209, 45, 98,193,114, 78, 19,206, 14,118,127,
48, 79,147, 85, 30,207,219, 54, 88,234,190,122, 95, 67,143,109,
137,214,145, 93, 92,100,245, 0,216,186, 60, 83,105, 97,204, 52
};
private final static int TABSIZE = 256;
private final static int TABMASK = (TABSIZE-1);
private final static int NIMPULSES = 3;
private static float[] impulseTab;
public static int floor(float x) {
int ix = (int)x;
if (x < 0 && x != ix)
return ix-1;
return ix;
}
private final static int SAMPRATE = 100; /* table entries per unit distance */
private final static int NENTRIES = (4*SAMPRATE+1);
private static float[] table;
public float catrom2(float d) {
float x;
int i;
if (d >= 4)
return 0;
if (table == null) {
table = new float[NENTRIES];
for (i = 0; i < NENTRIES; i++) {
x = i/(float)SAMPRATE;
x = (float)Math.sqrt(x);
if (x < 1)
table[i] = 0.5f * (2+x*x*(-5+x*3));
else
table[i] = 0.5f * (4+x*(-8+x*(5-x)));
}
}
d = d*SAMPRATE + 0.5f;
i = floor(d);
if (i >= NENTRIES)
return 0;
return table[i];
}
static float[] impulseTabInit(int seed) {
float[] impulseTab = new float[TABSIZE*4];
randomGenerator = new Random(seed); /* Set random number generator seed. */
for (int i = 0; i < TABSIZE; i++) {
impulseTab[i++] = randomGenerator.nextFloat();
impulseTab[i++] = randomGenerator.nextFloat();
impulseTab[i++] = randomGenerator.nextFloat();
impulseTab[i++] = 1.0f - 2.0f*randomGenerator.nextFloat();
}
return impulseTab;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/Function3D.java 0000644 0001750 0001750 00000001237 10562652111 025765 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public interface Function3D {
public float evaluate(float x, float y, float z);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/CompoundFunction2D.java 0000644 0001750 0001750 00000001561 10562652111 027471 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public abstract class CompoundFunction2D implements Function2D {
protected Function2D basis;
public CompoundFunction2D(Function2D basis) {
this.basis = basis;
}
public void setBasis(Function2D basis) {
this.basis = basis;
}
public Function2D getBasis() {
return basis;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/Function2D.java 0000644 0001750 0001750 00000001226 10562652111 025762 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public interface Function2D {
public float evaluate(float x, float y);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/TurbulenceFunction.java 0000644 0001750 0001750 00000002072 10562652111 027625 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class TurbulenceFunction extends CompoundFunction2D {
private float octaves;
public TurbulenceFunction(Function2D basis, float octaves) {
super(basis);
this.octaves = octaves;
}
public void setOctaves(float octaves) {
this.octaves = octaves;
}
public float getOctaves() {
return octaves;
}
public float evaluate(float x, float y) {
float t = 0.0f;
for (float f = 1.0f; f <= octaves; f *= 2)
t += Math.abs(basis.evaluate(f * x, f * y)) / f;
return t;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/FFT.java 0000644 0001750 0001750 00000011112 10562652111 024421 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class FFT {
// Weighting factors
protected float[] w1;
protected float[] w2;
protected float[] w3;
public FFT( int logN ) {
// Prepare the weighting factors
w1 = new float[logN];
w2 = new float[logN];
w3 = new float[logN];
int N = 1;
for ( int k = 0; k < logN; k++ ) {
N <<= 1;
double angle = -2.0 * Math.PI / N;
w1[k] = (float)Math.sin(0.5 * angle);
w2[k] = -2.0f * w1[k] * w1[k];
w3[k] = (float)Math.sin(angle);
}
}
private void scramble( int n, float[] real, float[] imag ) {
int j = 0;
for ( int i = 0; i < n; i++ ) {
if ( i > j ) {
float t;
t = real[j];
real[j] = real[i];
real[i] = t;
t = imag[j];
imag[j] = imag[i];
imag[i] = t;
}
int m = n >> 1;
while (j >= m && m >= 2) {
j -= m;
m >>= 1;
}
j += m;
}
}
private void butterflies( int n, int logN, int direction, float[] real, float[] imag ) {
int N = 1;
for ( int k = 0; k < logN; k++ ) {
float w_re, w_im, wp_re, wp_im, temp_re, temp_im, wt;
int half_N = N;
N <<= 1;
wt = direction * w1[k];
wp_re = w2[k];
wp_im = direction * w3[k];
w_re = 1.0f;
w_im = 0.0f;
for ( int offset = 0; offset < half_N; offset++ ) {
for( int i = offset; i < n; i += N ) {
int j = i + half_N;
float re = real[j];
float im = imag[j];
temp_re = (w_re * re) - (w_im * im);
temp_im = (w_im * re) + (w_re * im);
real[j] = real[i] - temp_re;
real[i] += temp_re;
imag[j] = imag[i] - temp_im;
imag[i] += temp_im;
}
wt = w_re;
w_re = wt * wp_re - w_im * wp_im + w_re;
w_im = w_im * wp_re + wt * wp_im + w_im;
}
}
if ( direction == -1 ) {
float nr = 1.0f / n;
for ( int i = 0; i < n; i++ ) {
real[i] *= nr;
imag[i] *= nr;
}
}
}
public void transform1D( float[] real, float[] imag, int logN, int n, boolean forward ) {
scramble( n, real, imag );
butterflies( n, logN, forward ? 1 : -1, real, imag );
}
public void transform2D( float[] real, float[] imag, int cols, int rows, boolean forward ) {
int log2cols = log2(cols);
int log2rows = log2(rows);
int n = Math.max(rows, cols);
float[] rtemp = new float[n];
float[] itemp = new float[n];
// FFT the rows
for ( int y = 0; y < rows; y++ ) {
int offset = y*cols;
System.arraycopy( real, offset, rtemp, 0, cols );
System.arraycopy( imag, offset, itemp, 0, cols );
transform1D(rtemp, itemp, log2cols, cols, forward);
System.arraycopy( rtemp, 0, real, offset, cols );
System.arraycopy( itemp, 0, imag, offset, cols );
}
// FFT the columns
for ( int x = 0; x < cols; x++ ) {
int index = x;
for ( int y = 0; y < rows; y++ ) {
rtemp[y] = real[index];
itemp[y] = imag[index];
index += cols;
}
transform1D(rtemp, itemp, log2rows, rows, forward);
index = x;
for ( int y = 0; y < rows; y++ ) {
real[index] = rtemp[y];
imag[index] = itemp[y];
index += cols;
}
}
}
private int log2( int n ) {
int m = 1;
int log2n = 0;
while (m < n) {
m *= 2;
log2n++;
}
return m == n ? log2n : -1;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/Function1D.java 0000644 0001750 0001750 00000001215 10562652111 025757 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public interface Function1D {
public float evaluate(float v);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/VLNoise.java 0000644 0001750 0001750 00000001743 10562652111 025332 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class VLNoise implements Function2D {
private float distortion = 10.0f;
public void setDistortion(float distortion) {
this.distortion = distortion;
}
public float getDistortion() {
return distortion;
}
public float evaluate(float x, float y) {
float ox = Noise.noise2(x+0.5f, y) * distortion;
float oy = Noise.noise2(x, y+0.5f) * distortion;
return Noise.noise2(x+ox, y+oy);
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/ImageFunction2D.java 0000644 0001750 0001750 00000007655 10566572034 026752 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.image.*;
public class ImageFunction2D implements Function2D {
public final static int ZERO = 0;
public final static int CLAMP = 1;
public final static int WRAP = 2;
protected int[] pixels;
protected int width;
protected int height;
protected int edgeAction = ZERO;
protected boolean alpha = false;
public ImageFunction2D(BufferedImage image) {
this(image, false);
}
public ImageFunction2D(BufferedImage image, boolean alpha) {
this(image, ZERO, alpha);
}
public ImageFunction2D(BufferedImage image, int edgeAction, boolean alpha) {
init( getRGB( image, 0, 0, image.getWidth(), image.getHeight(), null), image.getWidth(), image.getHeight(), edgeAction, alpha);
}
public ImageFunction2D(int[] pixels, int width, int height, int edgeAction, boolean alpha) {
init(pixels, width, height, edgeAction, alpha);
}
public ImageFunction2D(Image image) {
this( image, ZERO, false );
}
public ImageFunction2D(Image image, int edgeAction, boolean alpha) {
PixelGrabber pg = new PixelGrabber(image, 0, 0, -1, -1, null, 0, -1);
try {
pg.grabPixels();
} catch (InterruptedException e) {
throw new RuntimeException("interrupted waiting for pixels!");
}
if ((pg.status() & ImageObserver.ABORT) != 0) {
throw new RuntimeException("image fetch aborted");
}
init((int[])pg.getPixels(), pg.getWidth(), pg.getHeight(), edgeAction, alpha);
}
/**
* A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
* penalty of BufferedImage.getRGB unmanaging the image.
* @param image a BufferedImage object
* @param x the left edge of the pixel block
* @param y the right edge of the pixel block
* @param width the width of the pixel arry
* @param height the height of the pixel arry
* @param pixels the array to hold the returned pixels. May be null.
* @return the pixels
* @see #setRGB
*/
public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
int type = image.getType();
if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
return image.getRGB( x, y, width, height, pixels, 0, width );
}
public void init(int[] pixels, int width, int height, int edgeAction, boolean alpha) {
this.pixels = pixels;
this.width = width;
this.height = height;
this.edgeAction = edgeAction;
this.alpha = alpha;
}
public float evaluate(float x, float y) {
int ix = (int)x;
int iy = (int)y;
if (edgeAction == WRAP) {
ix = ImageMath.mod(ix, width);
iy = ImageMath.mod(iy, height);
} else if (ix < 0 || iy < 0 || ix >= width || iy >= height) {
if (edgeAction == ZERO)
return 0;
if (ix < 0)
ix = 0;
else if (ix >= width)
ix = width-1;
if (iy < 0)
iy = 0;
else if (iy >= height)
iy = height-1;
}
return alpha ? ((pixels[iy*width+ix] >> 24) & 0xff) / 255.0f : PixelUtils.brightness(pixels[iy*width+ix]) / 255.0f;
}
public void setEdgeAction(int edgeAction) {
this.edgeAction = edgeAction;
}
public int getEdgeAction() {
return edgeAction;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int[] getPixels() {
return pixels;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/math/BlackFunction.java 0000644 0001750 0001750 00000001307 10562652111 026531 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.math;
public class BlackFunction implements BinaryFunction {
public boolean isBlack(int rgb) {
return rgb == 0xff000000;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ 0000755 0001750 0001750 00000000000 11412236310 024206 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/DarkenComposite.java 0000644 0001750 0001750 00000004030 10562652111 030143 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class DarkenComposite extends RGBComposite {
public DarkenComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = dir < sr ? dir : sr;
dog = dig < sg ? dig : sg;
dob = dib < sb ? dib : sb;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/SubtractComposite.java 0000644 0001750 0001750 00000004257 10562652111 030541 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class SubtractComposite extends RGBComposite {
public SubtractComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = dir - sr;
if ( dor < 0 )
dor = 0;
dog = dig - sg;
if ( dog < 0 )
dog = 0;
dob = dib - sb;
if ( dob < 0 )
dob = 0;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ColorComposite.java 0000644 0001750 0001750 00000004551 10562652111 030025 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class ColorComposite extends RGBComposite {
public ColorComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
private float[] sHSB = new float[3];
private float[] dHSB = new float[3];
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
Color.RGBtoHSB( sr, sg, sb, sHSB );
Color.RGBtoHSB( dir, dig, dib, dHSB );
dHSB[0] = sHSB[0];
dHSB[1] = sHSB[1];
int doRGB = Color.HSBtoRGB( dHSB[0], dHSB[1], dHSB[2] );
dor = (doRGB & 0xff0000) >> 16;
dog = (doRGB & 0xff00) >> 8;
dob = (doRGB & 0xff);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ColorDodgeComposite.java 0000644 0001750 0001750 00000004525 10562652111 030771 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class ColorDodgeComposite extends RGBComposite {
public ColorDodgeComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
if (sr != 255)
dor = Math.min((dir << 8) / (255-sr), 255);
else
dor = sr;
if (sg != 255)
dog = Math.min((dig << 8) / (255-sg), 255);
else
dog = sg;
if (sb != 255)
dob = Math.min((dib << 8) / (255-sb), 255);
else
dob = sb;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/HardLightComposite.java 0000644 0001750 0001750 00000004630 10562652111 030613 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class HardLightComposite extends RGBComposite {
public HardLightComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
if (sr > 127)
dor = 255 - 2*multiply255(255 - sr, 255 - dir);
else
dor = 2*multiply255(sr, dir);
if (sg > 127)
dog = 255 - 2*multiply255(255 - sg, 255 - dig);
else
dog = 2*multiply255(sg, dig);
if (sb > 127)
dob = 255 - 2*multiply255(255 - sb, 255 - dib);
else
dob = 2*multiply255(sb, dib);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/BurnComposite.java 0000644 0001750 0001750 00000004541 10562652111 027654 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class BurnComposite extends RGBComposite {
public BurnComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
if (dir != 255)
dor = clamp(255-(((int)(255-sr) << 8) / (dir+1)));
else
dor = sr;
if (dig != 255)
dog = clamp(255-(((int)(255-sg) << 8) / (dig+1)));
else
dog = sg;
if (dib != 255)
dob = clamp(255-(((int)(255-sb) << 8) / (dib+1)));
else
dob = sb;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ContourComposite.java 0000644 0001750 0001750 00000005665 10562652111 030407 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
import java.awt.color.*;
/**
* A special Composite used for drawing "marching ants". It draws the ants at the 127 contour of the alpha channel of the source.
* This can only be used on TYPE_INT_RGBA images.
*/
public final class ContourComposite implements Composite {
private int offset;
public ContourComposite( int offset ) {
this.offset = offset;
}
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
return new ContourCompositeContext( offset, srcColorModel, dstColorModel );
}
public int hashCode() {
return 0;
}
public boolean equals(Object o) {
if (!(o instanceof ContourComposite))
return false;
return true;
}
}
class ContourCompositeContext implements CompositeContext {
private int offset;
public ContourCompositeContext( int offset, ColorModel srcColorModel, ColorModel dstColorModel ) {
this.offset = offset;
}
public void dispose() {
}
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
int x = src.getMinX();
int y = src.getMinY();
int w = src.getWidth();
int h = src.getHeight();
int[] srcPix = null;
int[] srcPix2 = null;
int[] dstInPix = null;
int[] dstOutPix = new int[w*4];
for ( int i = 0; i < h; i++ ) {
srcPix = src.getPixels(x, y, w, 1, srcPix);
dstInPix = dstIn.getPixels(x, y, w, 1, dstInPix);
int lastAlpha = 0;
int k = 0;
for ( int j = 0; j < w; j++ ) {
int alpha = srcPix[k+3];
int alphaAbove = i != 0 ? srcPix2[k+3] : alpha;
if ( i != 0 && j != 0 && ((alpha ^ lastAlpha) & 0x80) != 0 || ((alpha ^ alphaAbove) & 0x80) != 0 ) {
if ((offset+i+j)%10 > 4) {
dstOutPix[k] = 0x00;
dstOutPix[k+1] = 0x00;
dstOutPix[k+2] = 0x00;
} else {
dstOutPix[k] = 0xff;
dstOutPix[k+1] = 0xff;
dstOutPix[k+2] = 0x7f;
}
dstOutPix[k+3] = 0xff;
} else {
dstOutPix[k] = dstInPix[k];
dstOutPix[k+1] = dstInPix[k+1];
dstOutPix[k+2] = dstInPix[k+2];
// if ( dstOut == dstIn )
dstOutPix[k] = 0xff;
dstOutPix[k+1] = 0;
dstOutPix[k+2] = 0;
dstOutPix[k+3] = 0;
// else
// dstOutPix[k+3] = dstInPix[k+3];
}
lastAlpha = alpha;
k += 4;
}
dstOut.setPixels(x, y, w, 1, dstOutPix);
int[] t = srcPix;
srcPix = srcPix2;
srcPix2 = t;
y++;
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/DodgeComposite.java 0000644 0001750 0001750 00000004061 10562652111 027765 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class DodgeComposite extends RGBComposite {
public DodgeComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = clamp((sr << 8) / (256-dir));
dog = clamp((sg << 8) / (256-dig));
dob = clamp((sb << 8) / (256-dib));
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/DifferenceComposite.java 0000644 0001750 0001750 00000004274 10562652111 031003 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class DifferenceComposite extends RGBComposite {
public DifferenceComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = dir - sr;
if ( dor < 0 )
dor = -dor;
dog = dig - sg;
if ( dog < 0 )
dog = -dog;
dob = dib - sb;
if ( dob < 0 )
dob = -dob;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/AddComposite.java 0000644 0001750 0001750 00000004261 10562652111 027435 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class AddComposite extends RGBComposite {
public AddComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = dir + sr;
if ( dor > 255 )
dor = 255;
dog = dig + sg;
if ( dog > 255 )
dog = 255;
dob = dib + sb;
if ( dob > 255 )
dob = 255;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/SoftLightComposite.java 0000644 0001750 0001750 00000004450 10562652111 030650 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class SoftLightComposite extends RGBComposite {
public SoftLightComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
int d;
d = multiply255(sr, dir);
dor = d + multiply255(dir, 255 - multiply255(255-dir, 255-sr)-d);
d = multiply255(sg, dig);
dog = d + multiply255(dig, 255 - multiply255(255-dig, 255-sg)-d);
d = multiply255(sb, dib);
dob = d + multiply255(dib, 255 - multiply255(255-dib, 255-sb)-d);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ColorBurnComposite.java 0000644 0001750 0001750 00000004556 10562652111 030661 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class ColorBurnComposite extends RGBComposite {
public ColorBurnComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
if (sr != 0)
dor = Math.max(255 - (((int)(255-dir) << 8) / sr), 0);
else
dor = sr;
if (sg != 0)
dog = Math.max(255 - (((int)(255-dig) << 8) / sg), 0);
else
dog = sg;
if (sb != 0)
dob = Math.max(255 - (((int)(255-dib) << 8) / sb), 0);
else
dob = sb;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/SaturationComposite.java 0000644 0001750 0001750 00000004520 10562652111 031074 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class SaturationComposite extends RGBComposite {
public SaturationComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
private float[] sHSB = new float[3];
private float[] dHSB = new float[3];
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
Color.RGBtoHSB( sr, sg, sb, sHSB );
Color.RGBtoHSB( dir, dig, dib, dHSB );
dHSB[1] = sHSB[1];
int doRGB = Color.HSBtoRGB( dHSB[0], dHSB[1], dHSB[2] );
dor = (doRGB & 0xff0000) >> 16;
dog = (doRGB & 0xff00) >> 8;
dob = (doRGB & 0xff);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ValueComposite.java 0000644 0001750 0001750 00000004506 10562652111 030023 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class ValueComposite extends RGBComposite {
public ValueComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
private float[] sHSB = new float[3];
private float[] dHSB = new float[3];
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
Color.RGBtoHSB( sr, sg, sb, sHSB );
Color.RGBtoHSB( dir, dig, dib, dHSB );
dHSB[2] = sHSB[2];
int doRGB = Color.HSBtoRGB( dHSB[0], dHSB[1], dHSB[2] );
dor = (doRGB & 0xff0000) >> 16;
dog = (doRGB & 0xff00) >> 8;
dob = (doRGB & 0xff);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/PinLightComposite.java 0000644 0001750 0001750 00000004163 10562652111 030464 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class PinLightComposite extends RGBComposite {
public PinLightComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = sr > 127 ? Math.max(sr, dir) : Math.min(sr, dir);
dog = sg > 127 ? Math.max(sg, dig) : Math.min(sg, dig);
dob = sb > 127 ? Math.max(sb, dib) : Math.min(sb, dib);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/AverageComposite.java 0000644 0001750 0001750 00000004013 10562652111 030312 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class AverageComposite extends RGBComposite {
public AverageComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = (dir + sr) / 2;
dog = (dig + sg) / 2;
dob = (dib + sb) / 2;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/MiscCompositeContext.java 0000644 0001750 0001750 00000021176 10562652111 031211 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.color.*;
import java.net.*;
import java.io.*;
public class MiscCompositeContext implements CompositeContext {
private int rule;
private float alpha;
private ColorModel srcColorModel;
private ColorModel dstColorModel;
private ColorSpace srcColorSpace;
private ColorSpace dstColorSpace;
private boolean srcNeedsConverting;
private boolean dstNeedsConverting;
public MiscCompositeContext(int rule,
float alpha,
ColorModel srcColorModel,
ColorModel dstColorModel) {
this.rule = rule;
this.alpha = alpha;
this.srcColorModel = srcColorModel;
this.dstColorModel = dstColorModel;
this.srcColorSpace = srcColorModel.getColorSpace();
this.dstColorSpace = dstColorModel.getColorSpace();
ColorModel srgbCM = ColorModel.getRGBdefault();
// srcNeedsConverting = !srcColorModel.equals(srgbCM);
// dstNeedsConverting = !dstColorModel.equals(srgbCM);
}
public void dispose() {
}
// Multiply two numbers in the range 0..255 such that 255*255=255
static int multiply255( int a, int b ) {
int t = a * b + 0x80;
return ((t >> 8) + t) >> 8;
}
static int clamp( int a ) {
return a < 0 ? 0 : a > 255 ? 255 : a;
}
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
float a=0, ac=0;
float alpha = this.alpha;
int t;
float[] sHsv = null, diHsv = null, doHsv = null;
switch ( rule ) {
case MiscComposite.HUE:
case MiscComposite.SATURATION:
case MiscComposite.VALUE:
case MiscComposite.COLOR:
sHsv = new float[3];
diHsv = new float[3];
doHsv = new float[3];
break;
}
int[] srcPix = null;
int[] dstPix = null;
int x = dstOut.getMinX();
int w = dstOut.getWidth();
int y0 = dstOut.getMinY();
int y1 = y0 + dstOut.getHeight();
for ( int y = y0; y < y1; y++ ) {
srcPix = src.getPixels(x, y, w, 1, srcPix);
dstPix = dstIn.getPixels(x, y, w, 1, dstPix);
int i = 0;
int end = w*4;
while ( i < end ) {
int sr = srcPix[i];
int dir = dstPix[i];
int sg = srcPix[i+1];
int dig = dstPix[i+1];
int sb = srcPix[i+2];
int dib = dstPix[i+2];
int sa = srcPix[i+3];
int dia = dstPix[i+3];
int dor, dog, dob, doa;
switch ( rule ) {
case MiscComposite.ADD:
default:
dor = dir + sr;
if ( dor > 255 )
dor = 255;
dog = dig + sg;
if ( dog > 255 )
dog = 255;
dob = dib + sb;
if ( dob > 255 )
dob = 255;
break;
case MiscComposite.SUBTRACT:
dor = dir - sr;
if ( dor < 0 )
dor = 0;
dog = dig - sg;
if ( dog < 0 )
dog = 0;
dob = dib - sb;
if ( dob < 0 )
dob = 0;
break;
case MiscComposite.DIFFERENCE:
dor = dir - sr;
if ( dor < 0 )
dor = -dor;
dog = dig - sg;
if ( dog < 0 )
dog = -dog;
dob = dib - sb;
if ( dob < 0 )
dob = -dob;
break;
case MiscComposite.MULTIPLY:
t = dir * sr + 0x80;
dor = ((t >> 8) + t) >> 8;
t = dig * sg + 0x80;
dog = ((t >> 8) + t) >> 8;
t = dib * sb + 0x80;
dob = ((t >> 8) + t) >> 8;
break;
case MiscComposite.SCREEN:
t = (255-dir) * (255-sr) + 0x80;
dor = 255 - ( ((t >> 8) + t) >> 8 );
t = (255-dig) * (255-sg) + 0x80;
dog = 255 - ( ((t >> 8) + t) >> 8 );
t = (255-dib) * (255-sb) + 0x80;
dob = 255 - ( ((t >> 8) + t) >> 8 );
break;
case MiscComposite.OVERLAY:
if ( dir < 128 ) {
t = dir * sr + 0x80;
dor = 2 * (((t >> 8) + t) >> 8);
} else {
t = (255-dir) * (255-sr) + 0x80;
dor = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
}
if ( dig < 128 ) {
t = dig * sg + 0x80;
dog = 2 * (((t >> 8) + t) >> 8);
} else {
t = (255-dig) * (255-sg) + 0x80;
dog = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
}
if ( dib < 128 ) {
t = dib * sb + 0x80;
dob = 2 * (((t >> 8) + t) >> 8);
} else {
t = (255-dib) * (255-sb) + 0x80;
dob = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
}
break;
case MiscComposite.DARKEN:
dor = dir < sr ? dir : sr;
dog = dig < sg ? dig : sg;
dob = dib < sb ? dib : sb;
break;
case MiscComposite.LIGHTEN:
dor = dir > sr ? dir : sr;
dog = dig > sg ? dig : sg;
dob = dib > sb ? dib : sb;
break;
case MiscComposite.AVERAGE:
dor = (dir + sr) / 2;
dog = (dig + sg) / 2;
dob = (dib + sb) / 2;
break;
case MiscComposite.HUE:
case MiscComposite.SATURATION:
case MiscComposite.VALUE:
case MiscComposite.COLOR:
Color.RGBtoHSB(sr, sg, sb, sHsv);
Color.RGBtoHSB(dir, dig, dib, diHsv);
switch(rule) {
case MiscComposite.HUE:
doHsv[0] = sHsv[0];
doHsv[1] = diHsv[1];
doHsv[2] = diHsv[2];
break;
case MiscComposite.SATURATION:
doHsv[0] = diHsv[0];
doHsv[1] = sHsv[1];
doHsv[2] = diHsv[2];
break;
case MiscComposite.VALUE:
doHsv[0] = diHsv[0];
doHsv[1] = diHsv[1];
doHsv[2] = sHsv[2];
break;
case MiscComposite.COLOR:
doHsv[0] = sHsv[0];
doHsv[1] = sHsv[1];
doHsv[2] = diHsv[2];
break;
}
int doRGB = Color.HSBtoRGB(doHsv[0], doHsv[1], doHsv[2]);
dor = (doRGB&0xff0000)>>16;
dog = (doRGB&0xff00)>>8;
dob = (doRGB&0xff);
break;
case MiscComposite.BURN:
if (dir != 255)
dor = clamp(255-(((int)(255-sr) << 8) / (dir+1)));
else
dor = sr;
if (dig != 255)
dog = clamp(255-(((int)(255-sg) << 8) / (dig+1)));
else
dog = sg;
if (dib != 255)
dob = clamp(255-(((int)(255-sb) << 8) / (dib+1)));
else
dob = sb;
break;
case MiscComposite.COLOR_BURN:
if (sr != 0)
dor = Math.max(255 - (((int)(255-dir) << 8) / sr), 0);
else
dor = sr;
if (sg != 0)
dog = Math.max(255 - (((int)(255-dig) << 8) / sg), 0);
else
dog = sg;
if (sb != 0)
dob = Math.max(255 - (((int)(255-dib) << 8) / sb), 0);
else
dob = sb;
break;
case MiscComposite.DODGE:
dor = clamp((sr << 8) / (256-dir));
dog = clamp((sg << 8) / (256-dig));
dob = clamp((sb << 8) / (256-dib));
break;
case MiscComposite.COLOR_DODGE:
if (sr != 255)
dor = Math.min((dir << 8) / (255-sr), 255);
else
dor = sr;
if (sg != 255)
dog = Math.min((dig << 8) / (255-sg), 255);
else
dog = sg;
if (sb != 255)
dob = Math.min((dib << 8) / (255-sb), 255);
else
dob = sb;
break;
case MiscComposite.SOFT_LIGHT:
int d;
d = multiply255(sr, dir);
dor = d + multiply255(dir, 255 - multiply255(255-dir, 255-sr)-d);
d = multiply255(sg, dig);
dog = d + multiply255(dig, 255 - multiply255(255-dig, 255-sg)-d);
d = multiply255(sb, dib);
dob = d + multiply255(dib, 255 - multiply255(255-dib, 255-sb)-d);
break;
case MiscComposite.HARD_LIGHT:
if (sr > 127)
dor = 255 - 2*multiply255(255 - sr, 255 - dir);
else
dor = 2*multiply255(sr, dir);
if (sg > 127)
dog = 255 - 2*multiply255(255 - sg, 255 - dig);
else
dog = 2*multiply255(sg, dig);
if (sb > 127)
dob = 255 - 2*multiply255(255 - sb, 255 - dib);
else
dob = 2*multiply255(sb, dib);
break;
case MiscComposite.PIN_LIGHT:
dor = sr > 127 ? Math.max(sr, dir) : Math.min(sr, dir);
dog = sg > 127 ? Math.max(sg, dig) : Math.min(sg, dig);
dob = sb > 127 ? Math.max(sb, dib) : Math.min(sb, dib);
break;
case MiscComposite.EXCLUSION:
dor = dir+multiply255(sr, (255-dir-dir));
dog = dig+multiply255(sg, (255-dig-dig));
dob = dib+multiply255(sb, (255-dib-dib));
break;
case MiscComposite.NEGATION:
dor = 255 - Math.abs(255-sr-dir);
dog = 255 - Math.abs(255-sg-dig);
dob = 255 - Math.abs(255-sb-dib);
break;
}
a = alpha*sa/255f;
ac = 1-a;
dstPix[i] = (int)(a*dor + ac*dir);
dstPix[i+1] = (int)(a*dog + ac*dig);
dstPix[i+2] = (int)(a*dob + ac*dib);
dstPix[i+3] = (int)(sa*alpha + dia*ac);
i += 4;
}
dstOut.setPixels(x, y, w, 1, dstPix);
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/RGBComposite.java 0000644 0001750 0001750 00000005422 10562652111 027357 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public abstract class RGBComposite implements Composite {
protected float extraAlpha;
public RGBComposite() {
this( 1.0f );
}
public RGBComposite( float alpha ) {
if ( alpha < 0.0f || alpha > 1.0f )
throw new IllegalArgumentException("RGBComposite: alpha must be between 0 and 1");
this.extraAlpha = alpha;
}
public float getAlpha() {
return extraAlpha;
}
public int hashCode() {
return Float.floatToIntBits(extraAlpha);
}
public boolean equals(Object o) {
if (!(o instanceof RGBComposite))
return false;
RGBComposite c = (RGBComposite)o;
if ( extraAlpha != c.extraAlpha )
return false;
return true;
}
public abstract static class RGBCompositeContext implements CompositeContext {
private float alpha;
private ColorModel srcColorModel;
private ColorModel dstColorModel;
public RGBCompositeContext( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
this.alpha = alpha;
this.srcColorModel = srcColorModel;
this.dstColorModel = dstColorModel;
}
public void dispose() {
}
// Multiply two numbers in the range 0..255 such that 255*255=255
static int multiply255( int a, int b ) {
int t = a * b + 0x80;
return ((t >> 8) + t) >> 8;
}
static int clamp( int a ) {
return a < 0 ? 0 : a > 255 ? 255 : a;
}
public abstract void composeRGB( int[] src, int[] dst, float alpha );
public void compose( Raster src, Raster dstIn, WritableRaster dstOut ) {
float alpha = this.alpha;
int[] srcPix = null;
int[] dstPix = null;
int x = dstOut.getMinX();
int w = dstOut.getWidth();
int y0 = dstOut.getMinY();
int y1 = y0 + dstOut.getHeight();
for ( int y = y0; y < y1; y++ ) {
srcPix = src.getPixels( x, y, w, 1, srcPix );
dstPix = dstIn.getPixels( x, y, w, 1, dstPix );
composeRGB( srcPix, dstPix, alpha );
dstOut.setPixels( x, y, w, 1, dstPix );
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/LightenComposite.java 0000644 0001750 0001750 00000004032 10562652111 030333 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class LightenComposite extends RGBComposite {
public LightenComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = dir > sr ? dir : sr;
dog = dig > sg ? dig : sg;
dob = dib > sb ? dib : sb;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/NegationComposite.java 0000644 0001750 0001750 00000004061 10562652111 030507 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class NegationComposite extends RGBComposite {
public NegationComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = 255 - Math.abs(255-sr-dir);
dog = 255 - Math.abs(255-sg-dig);
dob = 255 - Math.abs(255-sb-dib);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/MiscComposite.java 0000644 0001750 0001750 00000012135 10562652111 027637 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class MiscComposite implements Composite {
public final static int BLEND = 0;
public final static int ADD = 1;
public final static int SUBTRACT = 2;
public final static int DIFFERENCE = 3;
public final static int MULTIPLY = 4;
public final static int DARKEN = 5;
public final static int BURN = 6;
public final static int COLOR_BURN = 7;
public final static int SCREEN = 8;
public final static int LIGHTEN = 9;
public final static int DODGE = 10;
public final static int COLOR_DODGE = 11;
public final static int HUE = 12;
public final static int SATURATION = 13;
public final static int VALUE = 14;
public final static int COLOR = 15;
public final static int OVERLAY = 16;
public final static int SOFT_LIGHT = 17;
public final static int HARD_LIGHT = 18;
public final static int PIN_LIGHT = 19;
public final static int EXCLUSION = 20;
public final static int NEGATION = 21;
public final static int AVERAGE = 22;
public final static int STENCIL = 23;
public final static int SILHOUETTE = 24;
private static final int MIN_RULE = BLEND;
private static final int MAX_RULE = SILHOUETTE;
public static String[] RULE_NAMES = {
"Normal",
"Add",
"Subtract",
"Difference",
"Multiply",
"Darken",
"Burn",
"Color Burn",
"Screen",
"Lighten",
"Dodge",
"Color Dodge",
"Hue",
"Saturation",
"Brightness",
"Color",
"Overlay",
"Soft Light",
"Hard Light",
"Pin Light",
"Exclusion",
"Negation",
"Average",
"Stencil",
"Silhouette",
};
protected float extraAlpha;
protected int rule;
private MiscComposite(int rule) {
this(rule, 1.0f);
}
private MiscComposite(int rule, float alpha) {
if (alpha < 0.0f || alpha > 1.0f)
throw new IllegalArgumentException("alpha value out of range");
if (rule < MIN_RULE || rule > MAX_RULE)
throw new IllegalArgumentException("unknown composite rule");
this.rule = rule;
this.extraAlpha = alpha;
}
public static Composite getInstance(int rule, float alpha) {
switch ( rule ) {
case MiscComposite.BLEND:
return AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha );
case MiscComposite.ADD:
return new AddComposite( alpha );
case MiscComposite.SUBTRACT:
return new SubtractComposite( alpha );
case MiscComposite.DIFFERENCE:
return new DifferenceComposite( alpha );
case MiscComposite.MULTIPLY:
return new MultiplyComposite( alpha );
case MiscComposite.DARKEN:
return new DarkenComposite( alpha );
case MiscComposite.BURN:
return new BurnComposite( alpha );
case MiscComposite.COLOR_BURN:
return new ColorBurnComposite( alpha );
case MiscComposite.SCREEN:
return new ScreenComposite( alpha );
case MiscComposite.LIGHTEN:
return new LightenComposite( alpha );
case MiscComposite.DODGE:
return new DodgeComposite( alpha );
case MiscComposite.COLOR_DODGE:
return new ColorDodgeComposite( alpha );
case MiscComposite.HUE:
return new HueComposite( alpha );
case MiscComposite.SATURATION:
return new SaturationComposite( alpha );
case MiscComposite.VALUE:
return new ValueComposite( alpha );
case MiscComposite.COLOR:
return new ColorComposite( alpha );
case MiscComposite.OVERLAY:
return new OverlayComposite( alpha );
case MiscComposite.SOFT_LIGHT:
return new SoftLightComposite( alpha );
case MiscComposite.HARD_LIGHT:
return new HardLightComposite( alpha );
case MiscComposite.PIN_LIGHT:
return new PinLightComposite( alpha );
case MiscComposite.EXCLUSION:
return new ExclusionComposite( alpha );
case MiscComposite.NEGATION:
return new NegationComposite( alpha );
case MiscComposite.AVERAGE:
return new AverageComposite( alpha );
case MiscComposite.STENCIL:
return AlphaComposite.getInstance( AlphaComposite.DST_IN, alpha );
case MiscComposite.SILHOUETTE:
return AlphaComposite.getInstance( AlphaComposite.DST_OUT, alpha );
}
return new MiscComposite(rule, alpha);
}
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
return new MiscCompositeContext( rule, extraAlpha, srcColorModel, dstColorModel );
}
public float getAlpha() {
return extraAlpha;
}
public int getRule() {
return rule;
}
public int hashCode() {
return (Float.floatToIntBits(extraAlpha) * 31 + rule);
}
public boolean equals(Object o) {
if (!(o instanceof MiscComposite))
return false;
MiscComposite c = (MiscComposite)o;
if (rule != c.rule)
return false;
if (extraAlpha != c.extraAlpha)
return false;
return true;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ExclusionComposite.java 0000644 0001750 0001750 00000004113 10562652111 030712 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class ExclusionComposite extends RGBComposite {
public ExclusionComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
dor = dir+multiply255(sr, (255-dir-dir));
dog = dig+multiply255(sg, (255-dig-dig));
dob = dib+multiply255(sb, (255-dib-dib));
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/ScreenComposite.java 0000644 0001750 0001750 00000004315 10562652111 030164 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class ScreenComposite extends RGBComposite {
public ScreenComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
int t = (255-dir) * (255-sr) + 0x80;
dor = 255 - ( ((t >> 8) + t) >> 8 );
t = (255-dig) * (255-sg) + 0x80;
dog = 255 - ( ((t >> 8) + t) >> 8 );
t = (255-dib) * (255-sb) + 0x80;
dob = 255 - ( ((t >> 8) + t) >> 8 );
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/OverlayComposite.java 0000644 0001750 0001750 00000005420 10562652111 030364 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class OverlayComposite extends RGBComposite {
public OverlayComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
int t;
if ( dir < 128 ) {
t = dir * sr + 0x80;
dor = 2 * (((t >> 8) + t) >> 8);
} else {
t = (255-dir) * (255-sr) + 0x80;
dor = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
}
if ( dig < 128 ) {
t = dig * sg + 0x80;
dog = 2 * (((t >> 8) + t) >> 8);
} else {
t = (255-dig) * (255-sg) + 0x80;
dog = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
}
if ( dib < 128 ) {
t = dib * sb + 0x80;
dob = 2 * (((t >> 8) + t) >> 8);
} else {
t = (255-dib) * (255-sb) + 0x80;
dob = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
}
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/MultiplyComposite.java 0000644 0001750 0001750 00000004217 10562652111 030565 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class MultiplyComposite extends RGBComposite {
public MultiplyComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
int t = dir * sr + 0x80;
dor = ((t >> 8) + t) >> 8;
t = dig * sg + 0x80;
dog = ((t >> 8) + t) >> 8;
t = dib * sb + 0x80;
dob = ((t >> 8) + t) >> 8;
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/composite/HueComposite.java 0000644 0001750 0001750 00000004502 10562652111 027464 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.composite;
import java.awt.*;
import java.awt.image.*;
public final class HueComposite extends RGBComposite {
public HueComposite( float alpha ) {
super( alpha );
}
public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
return new Context( extraAlpha, srcColorModel, dstColorModel );
}
static class Context extends RGBCompositeContext {
private float[] sHSB = new float[3];
private float[] dHSB = new float[3];
public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
super( alpha, srcColorModel, dstColorModel );
}
public void composeRGB( int[] src, int[] dst, float alpha ) {
int w = src.length;
for ( int i = 0; i < w; i += 4 ) {
int sr = src[i];
int dir = dst[i];
int sg = src[i+1];
int dig = dst[i+1];
int sb = src[i+2];
int dib = dst[i+2];
int sa = src[i+3];
int dia = dst[i+3];
int dor, dog, dob;
Color.RGBtoHSB( sr, sg, sb, sHSB );
Color.RGBtoHSB( dir, dig, dib, dHSB );
dHSB[0] = sHSB[0];
int doRGB = Color.HSBtoRGB( dHSB[0], dHSB[1], dHSB[2] );
dor = (doRGB & 0xff0000) >> 16;
dog = (doRGB & 0xff00) >> 8;
dob = (doRGB & 0xff);
float a = alpha*sa/255f;
float ac = 1-a;
dst[i] = (int)(a*dor + ac*dir);
dst[i+1] = (int)(a*dog + ac*dig);
dst[i+2] = (int)(a*dob + ac*dib);
dst[i+3] = (int)(sa*alpha + dia*ac);
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ 0000755 0001750 0001750 00000000000 11412236307 023274 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LookupFilter.java 0000644 0001750 0001750 00000003415 10566356614 026576 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which uses the brightness of each pixel to lookup a color from a colormap.
*/
public class LookupFilter extends PointFilter {
private Colormap colormap = new Gradient();
/**
* Construct a LookupFilter.
*/
public LookupFilter() {
canFilterIndexColorModel = true;
}
/**
* Construct a LookupFilter.
* @param colormap the color map
*/
public LookupFilter(Colormap colormap) {
canFilterIndexColorModel = true;
this.colormap = colormap;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public int filterRGB(int x, int y, int rgb) {
// int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
rgb = (r + g + b) / 3;
return colormap.getColor(rgb/255.0f);
}
public String toString() {
return "Colors/Lookup...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GaussianFilter.java 0000644 0001750 0001750 00000012574 10606647276 027107 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which applies Gaussian blur to an image. This is a subclass of ConvolveFilter
* which simply creates a kernel with a Gaussian distribution for blurring.
* @author Jerry Huxtable
*/
public class GaussianFilter extends ConvolveFilter {
/**
* The blur radius.
*/
protected float radius;
/**
* The convolution kernel.
*/
protected Kernel kernel;
/**
* Construct a Gaussian filter.
*/
public GaussianFilter() {
this(2);
}
/**
* Construct a Gaussian filter.
* @param radius blur radius in pixels
*/
public GaussianFilter(float radius) {
setRadius(radius);
}
/**
* Set the radius of the kernel, and hence the amount of blur. The bigger the radius, the longer this filter will take.
* @param radius the radius of the blur in pixels.
* @min-value 0
* @max-value 100+
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
kernel = makeKernel(radius);
}
/**
* Get the radius of the kernel.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
src.getRGB( 0, 0, width, height, inPixels, 0, width );
if ( radius > 0 ) {
convolveAndTranspose(kernel, inPixels, outPixels, width, height, alpha, alpha && premultiplyAlpha, false, CLAMP_EDGES);
convolveAndTranspose(kernel, outPixels, inPixels, height, width, alpha, false, alpha && premultiplyAlpha, CLAMP_EDGES);
}
dst.setRGB( 0, 0, width, height, inPixels, 0, width );
return dst;
}
/**
* Blur and transpose a block of ARGB pixels.
* @param kernel the blur kernel
* @param inPixels the input pixels
* @param outPixels the output pixels
* @param width the width of the pixel array
* @param height the height of the pixel array
* @param alpha whether to blur the alpha channel
* @param edgeAction what to do at the edges
*/
public static void convolveAndTranspose(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, boolean premultiply, boolean unpremultiply, int edgeAction) {
float[] matrix = kernel.getKernelData( null );
int cols = kernel.getWidth();
int cols2 = cols/2;
for (int y = 0; y < height; y++) {
int index = y;
int ioffset = y*width;
for (int x = 0; x < width; x++) {
float r = 0, g = 0, b = 0, a = 0;
int moffset = cols2;
for (int col = -cols2; col <= cols2; col++) {
float f = matrix[moffset+col];
if (f != 0) {
int ix = x+col;
if ( ix < 0 ) {
if ( edgeAction == CLAMP_EDGES )
ix = 0;
else if ( edgeAction == WRAP_EDGES )
ix = (x+width) % width;
} else if ( ix >= width) {
if ( edgeAction == CLAMP_EDGES )
ix = width-1;
else if ( edgeAction == WRAP_EDGES )
ix = (x+width) % width;
}
int rgb = inPixels[ioffset+ix];
int pa = (rgb >> 24) & 0xff;
int pr = (rgb >> 16) & 0xff;
int pg = (rgb >> 8) & 0xff;
int pb = rgb & 0xff;
if ( premultiply ) {
float a255 = pa * (1.0f / 255.0f);
pr *= a255;
pg *= a255;
pb *= a255;
}
a += f * pa;
r += f * pr;
g += f * pg;
b += f * pb;
}
}
if ( unpremultiply && a != 0 && a != 255 ) {
float f = 255.0f / a;
r *= f;
g *= f;
b *= f;
}
int ia = alpha ? PixelUtils.clamp((int)(a+0.5)) : 0xff;
int ir = PixelUtils.clamp((int)(r+0.5));
int ig = PixelUtils.clamp((int)(g+0.5));
int ib = PixelUtils.clamp((int)(b+0.5));
outPixels[index] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
index += height;
}
}
}
/**
* Make a Gaussian blur kernel.
* @param radius the blur radius
* @return the kernel
*/
public static Kernel makeKernel(float radius) {
int r = (int)Math.ceil(radius);
int rows = r*2+1;
float[] matrix = new float[rows];
float sigma = radius/3;
float sigma22 = 2*sigma*sigma;
float sigmaPi2 = 2*ImageMath.PI*sigma;
float sqrtSigmaPi2 = (float)Math.sqrt(sigmaPi2);
float radius2 = radius*radius;
float total = 0;
int index = 0;
for (int row = -r; row <= r; row++) {
float distance = row*row;
if (distance > radius2)
matrix[index] = 0;
else
matrix[index] = (float)Math.exp(-(distance)/sigma22) / sqrtSigmaPi2;
total += matrix[index];
index++;
}
for (int i = 0; i < rows; i++)
matrix[i] /= total;
return new Kernel(rows, 1, matrix);
}
public String toString() {
return "Blur/Gaussian Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PerspectiveFilter.java 0000644 0001750 0001750 00000021755 10626010640 027604 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
/**
* A filter which performs a perspective distortion on an image.
* Coordinates are treated as if the image was a unit square, i.e. the bottom-right corner of the image is at (1, 1).
* The filter maps the unit square onto an arbitrary convex quadrilateral or vice versa.
*/
public class PerspectiveFilter extends TransformFilter {
private float x0, y0, x1, y1, x2, y2, x3, y3;
private float dx1, dy1, dx2, dy2, dx3, dy3;
private float A, B, C, D, E, F, G, H, I;
private float a11, a12, a13, a21, a22, a23, a31, a32, a33;
private boolean scaled;
private boolean clip = false;
/**
* Construct a PerspectiveFilter.
*/
public PerspectiveFilter() {
this( 0, 0, 1, 0, 1, 1, 0, 1);
}
/**
* Construct a PerspectiveFilter.
* @param x0 the new position of the top left corner
* @param y0 the new position of the top left corner
* @param x1 the new position of the top right corner
* @param y1 the new position of the top right corner
* @param x2 the new position of the bottom right corner
* @param y2 the new position of the bottom right corner
* @param x3 the new position of the bottom left corner
* @param y3 the new position of the bottom left corner
*/
public PerspectiveFilter(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) {
unitSquareToQuad(x0, y0, x1, y1, x2, y2, x3, y3);
}
public void setClip( boolean clip ) {
this.clip = clip;
}
public boolean getClip() {
return clip;
}
/**
* Set the new positions of the image corners.
* This is the same as unitSquareToQuad, but the coordinates are in image pixels, not relative to the unit square.
* This method is provided as a convenience.
* @param x0 the new position of the top left corner
* @param y0 the new position of the top left corner
* @param x1 the new position of the top right corner
* @param y1 the new position of the top right corner
* @param x2 the new position of the bottom right corner
* @param y2 the new position of the bottom right corner
* @param x3 the new position of the bottom left corner
* @param y3 the new position of the bottom left corner
*/
public void setCorners(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) {
unitSquareToQuad( x0, y0, x1, y1, x2, y2, x3, y3 );
scaled = true;
}
/**
* Set the transform to map the unit square onto a quadrilateral. When filtering, all coordinates will be scaled
* by the size of the image.
* @param x0 the new position of the top left corner
* @param y0 the new position of the top left corner
* @param x1 the new position of the top right corner
* @param y1 the new position of the top right corner
* @param x2 the new position of the bottom right corner
* @param y2 the new position of the bottom right corner
* @param x3 the new position of the bottom left corner
* @param y3 the new position of the bottom left corner
*/
public void unitSquareToQuad( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3 ) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
dx1 = x1-x2;
dy1 = y1-y2;
dx2 = x3-x2;
dy2 = y3-y2;
dx3 = x0-x1+x2-x3;
dy3 = y0-y1+y2-y3;
if (dx3 == 0 && dy3 == 0) {
a11 = x1-x0;
a21 = x2-x1;
a31 = x0;
a12 = y1-y0;
a22 = y2-y1;
a32 = y0;
a13 = a23 = 0;
} else {
a13 = (dx3*dy2-dx2*dy3)/(dx1*dy2-dy1*dx2);
a23 = (dx1*dy3-dy1*dx3)/(dx1*dy2-dy1*dx2);
a11 = x1-x0+a13*x1;
a21 = x3-x0+a23*x3;
a31 = x0;
a12 = y1-y0+a13*y1;
a22 = y3-y0+a23*y3;
a32 = y0;
}
a33 = 1;
scaled = false;
}
/**
* Set the transform to map a quadrilateral onto the unit square. When filtering, all coordinates will be scaled
* by the size of the image.
* @param x0 the old position of the top left corner
* @param y0 the old position of the top left corner
* @param x1 the old position of the top right corner
* @param y1 the old position of the top right corner
* @param x2 the old position of the bottom right corner
* @param y2 the old position of the bottom right corner
* @param x3 the old position of the bottom left corner
* @param y3 the old position of the bottom left corner
*/
public void quadToUnitSquare( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3 ) {
unitSquareToQuad( x0, y0, x1, y1, x2, y2, x3, y3 );
// Invert the transformation
float ta11 = a22*a33 - a32*a23;
float ta21 = a32*a13 - a12*a33;
float ta31 = a12*a23 - a22*a13;
float ta12 = a31*a23 - a21*a33;
float ta22 = a11*a33 - a31*a13;
float ta32 = a21*a13 - a11*a23;
float ta13 = a21*a32 - a31*a22;
float ta23 = a31*a12 - a11*a32;
float ta33 = a11*a22 - a21*a12;
float f = 1.0f/ta33;
a11 = ta11*f;
a21 = ta12*f;
a31 = ta13*f;
a12 = ta21*f;
a22 = ta22*f;
a32 = ta23*f;
a13 = ta31*f;
a23 = ta32*f;
a33 = 1.0f;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
A = a22*a33 - a32*a23;
B = a31*a23 - a21*a33;
C = a21*a32 - a31*a22;
D = a32*a13 - a12*a33;
E = a11*a33 - a31*a13;
F = a31*a12 - a11*a32;
G = a12*a23 - a22*a13;
H = a21*a13 - a11*a23;
I = a11*a22 - a21*a12;
if ( !scaled ) {
int width = src.getWidth();
int height = src.getHeight();
float invWidth = 1.0f/width;
float invHeight = 1.0f/height;
A *= invWidth;
D *= invWidth;
G *= invWidth;
B *= invHeight;
E *= invHeight;
H *= invHeight;
}
return super.filter( src, dst );
}
protected void transformSpace( Rectangle rect ) {
if ( scaled ) {
rect.x = (int)Math.min( Math.min( x0, x1 ), Math.min( x2, x3 ) );
rect.y = (int)Math.min( Math.min( y0, y1 ), Math.min( y2, y3 ) );
rect.width = (int)Math.max( Math.max( x0, x1 ), Math.max( x2, x3 ) ) - rect.x;
rect.height = (int)Math.max( Math.max( y0, y1 ), Math.max( y2, y3 ) ) - rect.y;
return;
}
if ( !clip ) {
float w = (float)rect.getWidth(), h = (float)rect.getHeight();
Rectangle r = new Rectangle();
r.add( getPoint2D( new Point2D.Float(0, 0), null ) );
r.add( getPoint2D( new Point2D.Float(w, 0), null ) );
r.add( getPoint2D( new Point2D.Float(0, h), null ) );
r.add( getPoint2D( new Point2D.Float(w, h), null ) );
rect.setRect( r );
}
}
/**
* Get the origin of the output image. Use this for working out where to draw your new image.
* @return the X origin.
*/
public float getOriginX() {
return x0 - (int)Math.min( Math.min( x0, x1 ), Math.min( x2, x3 ) );
}
/**
* Get the origin of the output image. Use this for working out where to draw your new image.
* @return the Y origin.
*/
public float getOriginY() {
return y0 - (int)Math.min( Math.min( y0, y1 ), Math.min( y2, y3 ) );
}
public Rectangle2D getBounds2D( BufferedImage src ) {
if ( clip )
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
float w = src.getWidth(), h = src.getHeight();
Rectangle2D r = new Rectangle2D.Float();
r.add( getPoint2D( new Point2D.Float(0, 0), null ) );
r.add( getPoint2D( new Point2D.Float(w, 0), null ) );
r.add( getPoint2D( new Point2D.Float(0, h), null ) );
r.add( getPoint2D( new Point2D.Float(w, h), null ) );
return r;
}
public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
if ( dstPt == null )
dstPt = new Point2D.Float();
float x = (float)srcPt.getX();
float y = (float)srcPt.getY();
float f = 1.0f/(x*a13 + y*a23 + a33);
dstPt.setLocation( (x*a11 + y*a21 + a31)*f, (x*a12 + y*a22 + a32)*f );
return dstPt;
}
protected void transformInverse( int x, int y, float[] out ) {
out[0] = originalSpace.width * (A*x+B*y+C)/(G*x+H*y+I);
out[1] = originalSpace.height * (D*x+E*y+F)/(G*x+H*y+I);
}
public String toString() {
return "Distort/Perspective...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/InvertFilter.java 0000644 0001750 0001750 00000001704 10562652111 026556 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which inverts the RGB channels of an image.
*/
public class InvertFilter extends PointFilter {
public InvertFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
return a | (~rgb & 0x00ffffff);
}
public String toString() {
return "Colors/Invert";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MinimumFilter.java 0000644 0001750 0001750 00000003033 10566356614 026734 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which replcaes each pixel by the mimimum of itself and its eight neightbours.
*/
public class MinimumFilter extends WholeImageFilter {
public MinimumFilter() {
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = 0xffffffff;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (0 <= ix && ix < width) {
pixel = PixelUtils.combinePixels(pixel, inPixels[ioffset+ix], PixelUtils.MIN);
}
}
}
}
outPixels[index++] = pixel;
}
}
return outPixels;
}
public String toString() {
return "Blur/Minimum";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/WaterFilter.java 0000644 0001750 0001750 00000011112 10566572034 026374 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* A filter which produces a water ripple distortion.
*/
public class WaterFilter extends TransformFilter {
private float wavelength = 16;
private float amplitude = 10;
private float phase = 0;
private float centreX = 0.5f;
private float centreY = 0.5f;
private float radius = 50;
private float radius2 = 0;
private float icentreX;
private float icentreY;
public WaterFilter() {
setEdgeAction( CLAMP );
}
/**
* Set the wavelength of the ripples.
* @param wavelength the wavelength
* @see #getWavelength
*/
public void setWavelength(float wavelength) {
this.wavelength = wavelength;
}
/**
* Get the wavelength of the ripples.
* @return the wavelength
* @see #setWavelength
*/
public float getWavelength() {
return wavelength;
}
/**
* Set the amplitude of the ripples.
* @param amplitude the amplitude
* @see #getAmplitude
*/
public void setAmplitude(float amplitude) {
this.amplitude = amplitude;
}
/**
* Get the amplitude of the ripples.
* @return the amplitude
* @see #setAmplitude
*/
public float getAmplitude() {
return amplitude;
}
/**
* Set the phase of the ripples.
* @param phase the phase
* @see #getPhase
*/
public void setPhase(float phase) {
this.phase = phase;
}
/**
* Get the phase of the ripples.
* @return the phase
* @see #setPhase
*/
public float getPhase() {
return phase;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
private boolean inside(int v, int a, int b) {
return a <= v && v <= b;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
icentreX = src.getWidth() * centreX;
icentreY = src.getHeight() * centreY;
if ( radius == 0 )
radius = Math.min(icentreX, icentreY);
radius2 = radius*radius;
return super.filter( src, dst );
}
protected void transformInverse(int x, int y, float[] out) {
float dx = x-icentreX;
float dy = y-icentreY;
float distance2 = dx*dx + dy*dy;
if (distance2 > radius2) {
out[0] = x;
out[1] = y;
} else {
float distance = (float)Math.sqrt(distance2);
float amount = amplitude * (float)Math.sin(distance / wavelength * ImageMath.TWO_PI - phase);
amount *= (radius-distance)/radius;
if ( distance != 0 )
amount *= wavelength/distance;
out[0] = x + dx*amount;
out[1] = y + dy*amount;
}
}
public String toString() {
return "Distort/Water Ripples...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TransferFilter.java 0000644 0001750 0001750 00000003430 10562652111 027071 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public abstract class TransferFilter extends PointFilter {
protected int[] rTable, gTable, bTable;
protected boolean initialized = false;
public TransferFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = rTable[r];
g = gTable[g];
b = bTable[b];
return a | (r << 16) | (g << 8) | b;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if (!initialized)
initialize();
return super.filter( src, dst );
}
protected void initialize() {
initialized = true;
rTable = gTable = bTable = makeTable();
}
protected int[] makeTable() {
int[] table = new int[256];
for (int i = 0; i < 256; i++)
table[i] = PixelUtils.clamp( (int)( 255 * transferFunction( i / 255.0f ) ) );
return table;
}
protected float transferFunction( float v ) {
return 0;
}
public int[] getLUT() {
if (!initialized)
initialize();
int[] lut = new int[256];
for ( int i = 0; i < 256; i++ ) {
lut[i] = filterRGB( 0, 0, (i << 24) | (i << 16) | (i << 8) | i );
}
return lut;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/RaysFilter.java 0000644 0001750 0001750 00000011354 10566572034 026240 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import com.jhlabs.composite.*;
/**
* A filter which produces the effect of light rays shining out of an image.
*/
public class RaysFilter extends MotionBlurOp {
private float opacity = 1.0f;
private float threshold = 0.0f;
private float strength = 0.5f;
private boolean raysOnly = false;
private Colormap colormap;
public RaysFilter() {
}
/**
* Set the opacity of the rays.
* @param opacity the opacity.
* @see #getOpacity
*/
public void setOpacity(float opacity) {
this.opacity = opacity;
}
/**
* Get the opacity of the rays.
* @return the opacity.
* @see #setOpacity
*/
public float getOpacity() {
return opacity;
}
/**
* Set the threshold value.
* @param threshold the threshold value
* @see #getThreshold
*/
public void setThreshold( float threshold ) {
this.threshold = threshold;
}
/**
* Get the threshold value.
* @return the threshold value
* @see #setThreshold
*/
public float getThreshold() {
return threshold;
}
/**
* Set the strength of the rays.
* @param strength the strength.
* @see #getStrength
*/
public void setStrength( float strength ) {
this.strength = strength;
}
/**
* Get the strength of the rays.
* @return the strength.
* @see #setStrength
*/
public float getStrength() {
return strength;
}
/**
* Set whether to render only the rays.
* @param raysOnly true to render rays only.
* @see #getRaysOnly
*/
public void setRaysOnly(boolean raysOnly) {
this.raysOnly = raysOnly;
}
/**
* Get whether to render only the rays.
* @return true to render rays only.
* @see #setRaysOnly
*/
public boolean getRaysOnly() {
return raysOnly;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int[] pixels = new int[width];
int[] srcPixels = new int[width];
BufferedImage rays = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int threshold3 = (int)(threshold*3*255);
for ( int y = 0; y < height; y++ ) {
getRGB( src, 0, y, width, 1, pixels );
for ( int x = 0; x < width; x++ ) {
int rgb = pixels[x];
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int l = r + g + b;
if (l < threshold3)
pixels[x] = 0xff000000;
else {
l /= 3;
pixels[x] = a | (l << 16) | (l << 8) | l;
}
}
setRGB( rays, 0, y, width, 1, pixels );
}
rays = super.filter( rays, null );
for ( int y = 0; y < height; y++ ) {
getRGB( rays, 0, y, width, 1, pixels );
getRGB( src, 0, y, width, 1, srcPixels );
for ( int x = 0; x < width; x++ ) {
int rgb = pixels[x];
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if ( colormap != null ) {
int l = r + g + b;
rgb = colormap.getColor( l * strength * (1/3f) );
} else {
r = PixelUtils.clamp((int)(r * strength));
g = PixelUtils.clamp((int)(g * strength));
b = PixelUtils.clamp((int)(b * strength));
rgb = a | (r << 16) | (g << 8) | b;
}
pixels[x] = rgb;
}
setRGB( rays, 0, y, width, 1, pixels );
}
if ( dst == null )
dst = createCompatibleDestImage( src, null );
Graphics2D g = dst.createGraphics();
if ( !raysOnly ) {
g.setComposite( AlphaComposite.SrcOver );
g.drawRenderedImage( src, null );
}
g.setComposite( MiscComposite.getInstance( MiscComposite.ADD, opacity ) );
g.drawRenderedImage( rays, null );
g.dispose();
return dst;
}
public String toString() {
return "Stylize/Rays...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/QuiltFilter.java 0000644 0001750 0001750 00000010357 10566572034 026422 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
public class QuiltFilter extends WholeImageFilter {
private Random randomGenerator;
private long seed = 567;
private int iterations = 25000;
private float a = -0.59f;
private float b = 0.2f;
private float c = 0.1f;
private float d = 0;
private int k = 0;
private Colormap colormap = new LinearColormap();
public QuiltFilter() {
randomGenerator = new Random();
}
public void randomize() {
seed = new Date().getTime();
randomGenerator.setSeed(seed);
a = randomGenerator.nextFloat();
b = randomGenerator.nextFloat();
c = randomGenerator.nextFloat();
d = randomGenerator.nextFloat();
k = randomGenerator.nextInt() % 20 - 10;
}
/**
* Set the number of iterations the effect is performed.
* @param iterations the number of iterations
* @min-value 0
* @see #getIterations
*/
public void setIterations(int iterations) {
this.iterations = iterations;
}
/**
* Get the number of iterations the effect is performed.
* @return the number of iterations
* @see #setIterations
*/
public int getIterations() {
return iterations;
}
public void setA(float a) {
this.a = a;
}
public float getA() {
return a;
}
public void setB(float b) {
this.b = b;
}
public float getB() {
return b;
}
public void setC(float c) {
this.c = c;
}
public float getC() {
return c;
}
public void setD(float d) {
this.d = d;
}
public float getD() {
return d;
}
public void setK(int k) {
this.k = k;
}
public int getK() {
return k;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
int i = 0;
int max = 0;
float x = 0.1f;
float y = 0.3f;
for (int n = 0; n < 20; n++) {
float mx = ImageMath.PI*x;
float my = ImageMath.PI*y;
float smx2 = (float)Math.sin(2*mx);
float smy2 = (float)Math.sin(2*my);
float x1 = (float)(a*smx2 + b*smx2*Math.cos(2*my) +
c*Math.sin(4*mx) + d*Math.sin(6*mx)*Math.cos(4*my) + k*x);
x1 = x1 >= 0 ? x1 - (int)x1 : x1 - (int)x1 + 1;
float y1 = (float)(a*smy2 + b*smy2*Math.cos(2*mx) +
c*Math.sin(4*my) + d*Math.sin(6*my)*Math.cos(4*mx) + k*y);
y1 = y1 >= 0 ? y1 - (int)y1 : y1 - (int)y1 + 1;
x = x1;
y = y1;
}
for (int n = 0; n < iterations; n++) {
float mx = ImageMath.PI*x;
float my = ImageMath.PI*y;
float x1 = (float)(a*Math.sin(2*mx) + b*Math.sin(2*mx)*Math.cos(2*my) +
c*Math.sin(4*mx) + d*Math.sin(6*mx)*Math.cos(4*my) + k*x);
x1 = x1 >= 0 ? x1 - (int)x1 : x1 - (int)x1 + 1;
float y1 = (float)(a*Math.sin(2*my) + b*Math.sin(2*my)*Math.cos(2*mx) +
c*Math.sin(4*my) + d*Math.sin(6*my)*Math.cos(4*mx) + k*y);
y1 = y1 >= 0 ? y1 - (int)y1 : y1 - (int)y1 + 1;
x = x1;
y = y1;
int ix = (int)(width*x);
int iy = (int)(height*y);
if (ix >= 0 && ix < width && iy >= 0 && iy < height) {
int t = outPixels[width*iy+ix]++;
if (t > max)
max = t;
}
}
if (colormap != null) {
int index = 0;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
outPixels[index] = colormap.getColor(outPixels[index] / (float)max);
index++;
}
}
}
return outPixels;
}
public String toString() {
return "Texture/Chaotic Quilt...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ContourFilter.java 0000644 0001750 0001750 00000007055 10566356614 026762 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which draws contours on an image at given brightness levels.
*/
public class ContourFilter extends WholeImageFilter {
private float levels = 5;
private float scale = 1;
private float offset = 0;
private int contourColor = 0xff000000;
public ContourFilter() {
}
public void setLevels( float levels ) {
this.levels = levels;
}
public float getLevels() {
return levels;
}
/**
* Specifies the scale of the contours.
* @param scale the scale of the contours.
* @min-value 0
* @max-value 1
* @see #getScale
*/
public void setScale( float scale ) {
this.scale = scale;
}
/**
* Returns the scale of the contours.
* @return the scale of the contours.
* @see #setScale
*/
public float getScale() {
return scale;
}
public void setOffset( float offset ) {
this.offset = offset;
}
public float getOffset() {
return offset;
}
public void setContourColor( int contourColor ) {
this.contourColor = contourColor;
}
public int getContourColor() {
return contourColor;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
short[][] r = new short[3][width];
int[] outPixels = new int[width * height];
short[] table = new short[256];
int offsetl = (int)(offset * 256 / levels);
for ( int i = 0; i < 256; i++ )
table[i] = (short)PixelUtils.clamp( (int)(255 * Math.floor(levels*(i+offsetl) / 256) / (levels-1) - offsetl) );
for (int x = 0; x < width; x++) {
int rgb = inPixels[x];
r[1][x] = (short)PixelUtils.brightness( rgb );
}
for (int y = 0; y < height; y++) {
boolean yIn = y > 0 && y < height-1;
int nextRowIndex = index+width;
if ( y < height-1) {
for (int x = 0; x < width; x++) {
int rgb = inPixels[nextRowIndex++];
r[2][x] = (short)PixelUtils.brightness( rgb );
}
}
for (int x = 0; x < width; x++) {
boolean xIn = x > 0 && x < width-1;
int w = x-1;
int e = x+1;
int v = 0;
if ( yIn && xIn ) {
short nwb = r[0][w];
short neb = r[0][x];
short swb = r[1][w];
short seb = r[1][x];
short nw = table[nwb];
short ne = table[neb];
short sw = table[swb];
short se = table[seb];
if (nw != ne || nw != sw || ne != se || sw != se) {
v = (int)(scale * (Math.abs(nwb - neb) + Math.abs(nwb - swb) + Math.abs(neb - seb) + Math.abs(swb - seb)));
// v /= 255;
if (v > 255)
v = 255;
}
}
if ( v != 0 )
outPixels[index] = PixelUtils.combinePixels( inPixels[index], contourColor, PixelUtils.NORMAL, v );
// outPixels[index] = PixelUtils.combinePixels( (contourColor & 0xff)|(v << 24), inPixels[index], PixelUtils.NORMAL );
else
outPixels[index] = inPixels[index];
index++;
}
short[] t;
t = r[0];
r[0] = r[1];
r[1] = r[2];
r[2] = t;
}
return outPixels;
}
public String toString() {
return "Stylize/Contour...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DiffusionFilter.java 0000644 0001750 0001750 00000011003 11201001401 027203 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which uses Floyd-Steinberg error diffusion dithering to halftone an image.
*/
public class DiffusionFilter extends WholeImageFilter {
private final static int[] diffusionMatrix = {
0, 0, 0,
0, 0, 7,
3, 5, 1,
};
private int[] matrix;
private int sum = 3+5+7+1;
private boolean serpentine = true;
private boolean colorDither = true;
private int levels = 6;
/**
* Construct a DiffusionFilter.
*/
public DiffusionFilter() {
setMatrix(diffusionMatrix);
}
/**
* Set whether to use a serpentine pattern for return or not. This can reduce 'avalanche' artifacts in the output.
* @param serpentine true to use serpentine pattern
* @see #getSerpentine
*/
public void setSerpentine(boolean serpentine) {
this.serpentine = serpentine;
}
/**
* Return the serpentine setting.
* @return the current setting
* @see #setSerpentine
*/
public boolean getSerpentine() {
return serpentine;
}
/**
* Set whether to use a color dither.
* @param colorDither true to use a color dither
* @see #getColorDither
*/
public void setColorDither(boolean colorDither) {
this.colorDither = colorDither;
}
/**
* Get whether to use a color dither.
* @return true to use a color dither
* @see #setColorDither
*/
public boolean getColorDither() {
return colorDither;
}
/**
* Set the dither matrix.
* @param matrix the dither matrix
* @see #getMatrix
*/
public void setMatrix(int[] matrix) {
this.matrix = matrix;
sum = 0;
for (int i = 0; i < matrix.length; i++)
sum += matrix[i];
}
/**
* Get the dither matrix.
* @return the dither matrix
* @see #setMatrix
*/
public int[] getMatrix() {
return matrix;
}
/**
* Set the number of dither levels.
* @param levels the number of levels
* @see #getLevels
*/
public void setLevels(int levels) {
this.levels = levels;
}
/**
* Get the number of dither levels.
* @return the number of levels
* @see #setLevels
*/
public int getLevels() {
return levels;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
int index = 0;
int[] map = new int[levels];
for (int i = 0; i < levels; i++) {
int v = 255 * i / (levels-1);
map[i] = v;
}
int[] div = new int[256];
for (int i = 0; i < 256; i++)
div[i] = levels*i / 256;
for (int y = 0; y < height; y++) {
boolean reverse = serpentine && (y & 1) == 1;
int direction;
if (reverse) {
index = y*width+width-1;
direction = -1;
} else {
index = y*width;
direction = 1;
}
for (int x = 0; x < width; x++) {
int rgb1 = inPixels[index];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
if (!colorDither)
r1 = g1 = b1 = (r1+g1+b1) / 3;
int r2 = map[div[r1]];
int g2 = map[div[g1]];
int b2 = map[div[b1]];
outPixels[index] = (rgb1 & 0xff000000) | (r2 << 16) | (g2 << 8) | b2;
int er = r1-r2;
int eg = g1-g2;
int eb = b1-b2;
for (int i = -1; i <= 1; i++) {
int iy = i+y;
if (0 <= iy && iy < height) {
for (int j = -1; j <= 1; j++) {
int jx = j+x;
if (0 <= jx && jx < width) {
int w;
if (reverse)
w = matrix[(i+1)*3-j+1];
else
w = matrix[(i+1)*3+j+1];
if (w != 0) {
int k = reverse ? index - j : index + j;
rgb1 = inPixels[k];
r1 = (rgb1 >> 16) & 0xff;
g1 = (rgb1 >> 8) & 0xff;
b1 = rgb1 & 0xff;
r1 += er * w/sum;
g1 += eg * w/sum;
b1 += eb * w/sum;
inPixels[k] = (inPixels[k] & 0xff000000) | (PixelUtils.clamp(r1) << 16) | (PixelUtils.clamp(g1) << 8) | PixelUtils.clamp(b1);
}
}
}
}
}
index += direction;
}
}
return outPixels;
}
public String toString() {
return "Colors/Diffusion Dither...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Quantizer.java 0000644 0001750 0001750 00000003326 10566572034 026136 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* The interface for an image quantizer. The addColor method is called (repeatedly
* if necessary) with all the image pixels. A color table can then be returned by
* calling the buildColorTable method.
*/
public interface Quantizer {
/**
* Initialize the quantizer. This should be called before adding any pixels.
* @param numColors the number of colors we're quantizing to.
*/
public void setup(int numColors);
/**
* Add pixels to the quantizer.
* @param pixels the array of ARGB pixels
* @param offset the offset into the array
* @param count the count of pixels
*/
public void addPixels(int[] pixels, int offset, int count);
/**
* Build a color table from the added pixels.
* @return an array of ARGB pixels representing a color table
*/
public int[] buildColorTable();
/**
* Using the previously-built color table, return the index into that table for a pixel.
* This is guaranteed to return a valid index - returning the index of a color closer
* to that requested if necessary.
* @param rgb the pixel to find
* @return the pixel's index in the color table
*/
public int getIndexForColor(int rgb);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MirrorFilter.java 0000644 0001750 0001750 00000006034 10566572034 026573 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
public class MirrorFilter extends AbstractBufferedImageOp {
private float opacity = 1.0f;
private float centreY = 0.5f;
private float distance;
private float angle;
private float rotation;
private float gap;
public MirrorFilter() {
}
/**
* Specifies the angle of the mirror.
* @param angle the angle of the mirror.
* @angle
* @see #getAngle
*/
public void setAngle( float angle ) {
this.angle = angle;
}
/**
* Returns the angle of the mirror.
* @return the angle of the mirror.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
public void setDistance( float distance ) {
this.distance = distance;
}
public float getDistance() {
return distance;
}
public void setRotation( float rotation ) {
this.rotation = rotation;
}
public float getRotation() {
return rotation;
}
public void setGap( float gap ) {
this.gap = gap;
}
public float getGap() {
return gap;
}
/**
* Set the opacity of the reflection.
* @param opacity the opacity.
* @see #getOpacity
*/
public void setOpacity( float opacity ) {
this.opacity = opacity;
}
/**
* Get the opacity of the reflection.
* @return the opacity.
* @see #setOpacity
*/
public float getOpacity() {
return opacity;
}
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
public float getCentreY() {
return centreY;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
BufferedImage tsrc = src;
Shape clip;
int width = src.getWidth();
int height = src.getHeight();
int h = (int)(centreY * height);
int d = (int)(gap * height);
Graphics2D g = dst.createGraphics();
clip = g.getClip();
g.clipRect( 0, 0, width, h );
g.drawRenderedImage( src, null );
g.setClip( clip );
g.clipRect( 0, h+d, width, height-h-d );
g.translate( 0, 2*h+d );
g.scale( 1, -1 );
g.drawRenderedImage( src, null );
g.setPaint( new GradientPaint( 0, 0, new Color( 1.0f, 0.0f, 0.0f, 0.0f ), 0, h, new Color( 0.0f, 1.0f, 0.0f, opacity ) ) );
g.setComposite( AlphaComposite.getInstance( AlphaComposite.DST_IN ) );
g.fillRect( 0, 0, width, h );
g.setClip( clip );
g.dispose();
return dst;
}
public String toString() {
return "Effects/Mirror...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Histogram.java 0000644 0001750 0001750 00000010300 10562652111 026066 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* An image histogram.
*/
public class Histogram {
public static final int RED = 0;
public static final int GREEN = 1;
public static final int BLUE = 2;
public static final int GRAY = 3;
protected int[][] histogram;
protected int numSamples;
protected int[] minValue;
protected int[] maxValue;
protected int[] minFrequency;
protected int[] maxFrequency;
protected float[] mean;
protected boolean isGray;
public Histogram() {
histogram = null;
numSamples = 0;
isGray = true;
minValue = null;
maxValue = null;
minFrequency = null;
maxFrequency = null;
mean = null;
}
public Histogram(int[] pixels, int w, int h, int offset, int stride) {
histogram = new int[3][256];
minValue = new int[4];
maxValue = new int[4];
minFrequency = new int[3];
maxFrequency = new int[3];
mean = new float[3];
numSamples = w*h;
isGray = true;
int index = 0;
for (int y = 0; y < h; y++) {
index = offset+y*stride;
for (int x = 0; x < w; x++) {
int rgb = pixels[index++];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
histogram[RED][r]++;
histogram[GREEN][g]++;
histogram[BLUE][b]++;
}
}
for (int i = 0; i < 256; i++) {
if (histogram[RED][i] != histogram[GREEN][i] || histogram[GREEN][i] != histogram[BLUE][i]) {
isGray = false;
break;
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 256; j++) {
if (histogram[i][j] > 0) {
minValue[i] = j;
break;
}
}
for (int j = 255; j >= 0; j--) {
if (histogram[i][j] > 0) {
maxValue[i] = j;
break;
}
}
minFrequency[i] = Integer.MAX_VALUE;
maxFrequency[i] = 0;
for (int j = 0; j < 256; j++) {
minFrequency[i] = Math.min(minFrequency[i], histogram[i][j]);
maxFrequency[i] = Math.max(maxFrequency[i], histogram[i][j]);
mean[i] += (float)(j*histogram[i][j]);
}
mean[i] /= (float)numSamples;
}
minValue[GRAY] = Math.min(Math.min(minValue[RED], minValue[GREEN]), minValue[BLUE]);
maxValue[GRAY] = Math.max(Math.max(maxValue[RED], maxValue[GREEN]), maxValue[BLUE]);
}
public boolean isGray() {
return isGray;
}
public int getNumSamples() {
return numSamples;
}
public int getFrequency(int value) {
if (numSamples > 0 && isGray && value >= 0 && value <= 255)
return histogram[0][value];
return -1;
}
public int getFrequency(int channel, int value) {
if (numSamples < 1 || channel < 0 || channel > 2 ||
value < 0 || value > 255)
return -1;
return histogram[channel][value];
}
public int getMinFrequency() {
if (numSamples > 0 && isGray)
return minFrequency[0];
return -1;
}
public int getMinFrequency(int channel) {
if (numSamples < 1 || channel < 0 || channel > 2)
return -1;
return minFrequency[channel];
}
public int getMaxFrequency() {
if (numSamples > 0 && isGray)
return maxFrequency[0];
return -1;
}
public int getMaxFrequency(int channel) {
if (numSamples < 1 || channel < 0 || channel > 2)
return -1;
return maxFrequency[channel];
}
public int getMinValue() {
if (numSamples > 0 && isGray)
return minValue[0];
return -1;
}
public int getMinValue(int channel) {
return minValue[channel];
}
public int getMaxValue() {
if (numSamples > 0 && isGray)
return maxValue[0];
return -1;
}
public int getMaxValue(int channel) {
return maxValue[channel];
}
public float getMeanValue() {
if (numSamples > 0 && isGray)
return mean[0];
return -1.0F;
}
public float getMeanValue(int channel) {
if (numSamples > 0 && RED <= channel && channel <= BLUE)
return mean[channel];
return -1.0F;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SmartBlurFilter.java 0000644 0001750 0001750 00000013107 11331370607 027224 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
/**
* A filter which performs a "smart blur". i.e. a blur which blurs smotth parts of the image while preserving edges.
*/
public class SmartBlurFilter extends AbstractBufferedImageOp {
private int hRadius = 5;
private int vRadius = 5;
private int threshold = 10;
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
getRGB( src, 0, 0, width, height, inPixels );
Kernel kernel = GaussianFilter.makeKernel(hRadius);
thresholdBlur( kernel, inPixels, outPixels, width, height, true );
thresholdBlur( kernel, outPixels, inPixels, height, width, true );
setRGB( dst, 0, 0, width, height, inPixels );
return dst;
}
/**
* Convolve with a kernel consisting of one row
*/
private void thresholdBlur(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha) {
// int index = 0;
float[] matrix = kernel.getKernelData( null );
int cols = kernel.getWidth();
int cols2 = cols/2;
for (int y = 0; y < height; y++) {
int ioffset = y*width;
int outIndex = y;
for (int x = 0; x < width; x++) {
float r = 0, g = 0, b = 0, a = 0;
int moffset = cols2;
int rgb1 = inPixels[ioffset+x];
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
float af = 0, rf = 0, gf = 0, bf = 0;
for (int col = -cols2; col <= cols2; col++) {
float f = matrix[moffset+col];
if (f != 0) {
int ix = x+col;
if (!(0 <= ix && ix < width))
ix = x;
int rgb2 = inPixels[ioffset+ix];
int a2 = (rgb2 >> 24) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
int d;
d = a1-a2;
if ( d >= -threshold && d <= threshold ) {
a += f * a2;
af += f;
}
d = r1-r2;
if ( d >= -threshold && d <= threshold ) {
r += f * r2;
rf += f;
}
d = g1-g2;
if ( d >= -threshold && d <= threshold ) {
g += f * g2;
gf += f;
}
d = b1-b2;
if ( d >= -threshold && d <= threshold ) {
b += f * b2;
bf += f;
}
}
}
a = af == 0 ? a1 : a/af;
r = rf == 0 ? r1 : r/rf;
g = gf == 0 ? g1 : g/gf;
b = bf == 0 ? b1 : b/bf;
int ia = alpha ? PixelUtils.clamp((int)(a+0.5)) : 0xff;
int ir = PixelUtils.clamp((int)(r+0.5));
int ig = PixelUtils.clamp((int)(g+0.5));
int ib = PixelUtils.clamp((int)(b+0.5));
outPixels[outIndex] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
outIndex += height;
}
}
}
/**
* Set the horizontal size of the blur.
* @param hRadius the radius of the blur in the horizontal direction
* @min-value 0
* @see #getHRadius
*/
public void setHRadius(int hRadius) {
this.hRadius = hRadius;
}
/**
* Get the horizontal size of the blur.
* @return the radius of the blur in the horizontal direction
* @see #setHRadius
*/
public int getHRadius() {
return hRadius;
}
/**
* Set the vertical size of the blur.
* @param vRadius the radius of the blur in the vertical direction
* @min-value 0
* @see #getVRadius
*/
public void setVRadius(int vRadius) {
this.vRadius = vRadius;
}
/**
* Get the vertical size of the blur.
* @return the radius of the blur in the vertical direction
* @see #setVRadius
*/
public int getVRadius() {
return vRadius;
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(int radius) {
this.hRadius = this.vRadius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public int getRadius() {
return hRadius;
}
/**
* Set the threshold value.
* @param threshold the threshold value
* @see #getThreshold
*/
public void setThreshold(int threshold) {
this.threshold = threshold;
}
/**
* Get the threshold value.
* @return the threshold value
* @see #setThreshold
*/
public int getThreshold() {
return threshold;
}
public String toString() {
return "Blur/Smart Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PremultiplyFilter.java 0000755 0001750 0001750 00000001251 10626011515 027633 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which premultiplies an image's alpha.
* Note: this does not change the image type of the BufferedImage
*/
public class PremultiplyFilter extends PointFilter {
public PremultiplyFilter() {
}
public int filterRGB(int x, int y, int rgb) {
int a = (rgb >> 24) & 0xff;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
float f = a * (1.0f / 255.0f);
r *= f;
g *= f;
b *= f;
return (a << 24) | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Alpha/Premultiply";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ScaleFilter.java 0000644 0001750 0001750 00000003273 11201001401 026316 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* Scales an image using the area-averaging algorithm, which can't be done with AffineTransformOp.
*/
public class ScaleFilter extends AbstractBufferedImageOp {
private int width;
private int height;
/**
* Construct a ScaleFilter.
*/
public ScaleFilter() {
this(32, 32);
}
/**
* Construct a ScaleFilter.
* @param width the width to scale to
* @param height the height to scale to
*/
public ScaleFilter( int width, int height ) {
this.width = width;
this.height = height;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster( width, height ), dstCM.isAlphaPremultiplied(), null);
}
Image scaleImage = src.getScaledInstance( width, height, Image.SCALE_AREA_AVERAGING );
Graphics2D g = dst.createGraphics();
g.drawImage( scaleImage, 0, 0, width, height, null );
g.dispose();
return dst;
}
public String toString() {
return "Distort/Scale";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FeedbackFilter.java 0000644 0001750 0001750 00000016365 11331366650 027011 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which priduces a video feedback effect by repeated transformations.
*/
public class FeedbackFilter extends AbstractBufferedImageOp {
private float centreX = 0.5f, centreY = 0.5f;
private float distance;
private float angle;
private float rotation;
private float zoom;
private float startAlpha = 1;
private float endAlpha = 1;
private int iterations;
/**
* Construct a FeedbackFilter.
*/
public FeedbackFilter() {
}
/**
* Construct a FeedbackFilter.
* @param distance the distance to move on each iteration
* @param angle the angle to move on each iteration
* @param rotation the amount to rotate on each iteration
* @param zoom the amount to scale on each iteration
*/
public FeedbackFilter( float distance, float angle, float rotation, float zoom ) {
this.distance = distance;
this.angle = angle;
this.rotation = rotation;
this.zoom = zoom;
}
/**
* Specifies the angle of each iteration.
* @param angle the angle of each iteration.
* @angle
* @see #getAngle
*/
public void setAngle( float angle ) {
this.angle = angle;
}
/**
* Returns the angle of each iteration.
* @return the angle of each iteration.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Specifies the distance to move on each iteration.
* @param distance the distance
* @see #getDistance
*/
public void setDistance( float distance ) {
this.distance = distance;
}
/**
* Get the distance to move on each iteration.
* @return the distance
* @see #setDistance
*/
public float getDistance() {
return distance;
}
/**
* Specifies the amount of rotation on each iteration.
* @param rotation the angle of rotation
* @angle
* @see #getRotation
*/
public void setRotation( float rotation ) {
this.rotation = rotation;
}
/**
* Returns the amount of rotation on each iteration.
* @return the angle of rotation
* @angle
* @see #setRotation
*/
public float getRotation() {
return rotation;
}
/**
* Specifies the amount to scale on each iteration.
* @param zoom the zoom factor
* @see #getZoom
*/
public void setZoom( float zoom ) {
this.zoom = zoom;
}
/**
* Returns the amount to scale on each iteration.
* @return the zoom factor
* @see #setZoom
*/
public float getZoom() {
return zoom;
}
/**
* Set the alpha value at the first iteration.
* @param startAlpha the alpha value
* @min-value 0
* @max-value 1
* @see #getStartAlpha
*/
public void setStartAlpha( float startAlpha ) {
this.startAlpha = startAlpha;
}
/**
* Get the alpha value at the first iteration.
* @return the alpha value
* @see #setStartAlpha
*/
public float getStartAlpha() {
return startAlpha;
}
/**
* Set the alpha value at the last iteration.
* @param endAlpha the alpha value
* @min-value 0
* @max-value 1
* @see #getEndAlpha
*/
public void setEndAlpha( float endAlpha ) {
this.endAlpha = endAlpha;
}
/**
* Get the alpha value at the last iteration.
* @return the alpha value
* @see #setEndAlpha
*/
public float getEndAlpha() {
return endAlpha;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Set the number of iterations.
* @param iterations the number of iterations
* @min-value 0
* @see #getIterations
*/
public void setIterations( int iterations ) {
this.iterations = iterations;
}
/**
* Get the number of iterations.
* @return the number of iterations
* @see #setIterations
*/
public int getIterations() {
return iterations;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
float cx = (float)src.getWidth() * centreX;
float cy = (float)src.getHeight() * centreY;
// float imageRadius = (float)Math.sqrt( cx*cx + cy*cy );
float translateX = (float)(distance * Math.cos( angle ));
float translateY = (float)(distance * -Math.sin( angle ));
float scale = (float)Math.exp(zoom);
float rotate = rotation;
if ( iterations == 0 ) {
Graphics2D g = dst.createGraphics();
g.drawRenderedImage( src, null );
g.dispose();
return dst;
}
Graphics2D g = dst.createGraphics();
g.drawImage( src, null, null );
for ( int i = 0; i < iterations; i++ ) {
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
g.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, ImageMath.lerp( (float)i/(iterations-1), startAlpha, endAlpha ) ) );
g.translate( cx+translateX, cy+translateY );
g.scale( scale, scale ); // The .0001 works round a bug on Windows where drawImage throws an ArrayIndexOutofBoundException
if ( rotation != 0 )
g.rotate( rotate );
g.translate( -cx, -cy );
g.drawImage( src, null, null );
}
g.dispose();
return dst;
}
public String toString() {
return "Effects/Feedback...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SpectrumColormap.java 0000644 0001750 0001750 00000001770 10566356614 027460 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* A colormap with the colors of the spectrum.
*/
public class SpectrumColormap implements Colormap {
/**
* Construct a spcetrum color map.
*/
public SpectrumColormap() {
}
/**
* Convert a value in the range 0..1 to an RGB color.
* @param v a value in the range 0..1
* @return an RGB color
*/
public int getColor(float v) {
return Spectrum.wavelengthToRGB(380+400*ImageMath.clamp(v, 0, 1.0f));
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SharpenFilter.java 0000644 0001750 0001750 00000001705 10566356614 026725 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which performs a simple 3x3 sharpening operation.
*/
public class SharpenFilter extends ConvolveFilter {
private static float[] sharpenMatrix = {
0.0f, -0.2f, 0.0f,
-0.2f, 1.8f, -0.2f,
0.0f, -0.2f, 0.0f
};
public SharpenFilter() {
super(sharpenMatrix);
}
public String toString() {
return "Blur/Sharpen";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SkeletonFilter.java 0000644 0001750 0001750 00000007001 10566356614 027104 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which reduces a binary image to a skeleton.
*
* Based on an algorithm by Zhang and Suen (CACM, March 1984, 236-239).
*/
public class SkeletonFilter extends BinaryFilter {
private final static byte[] skeletonTable = {
0, 0, 0, 1, 0, 0, 1, 3, 0, 0, 3, 1, 1, 0, 1, 3,
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 3, 0, 3, 3,
0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 2, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0,
3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 2, 0,
0, 1, 3, 1, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 3, 1, 3, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
3, 3, 0, 1, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0, 0
};
public SkeletonFilter() {
newColor = 0xffffffff;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
int count = 0;
int black = 0xff000000;
int white = 0xffffffff;
for (int i = 0; i < iterations; i++) {
count = 0;
for (int pass = 0; pass < 2; pass++) {
for (int y = 1; y < height-1; y++) {
int offset = y*width+1;
for (int x = 1; x < width-1; x++) {
int pixel = inPixels[offset];
if (pixel == black) {
int tableIndex = 0;
if (inPixels[offset-width-1] == black)
tableIndex |= 1;
if (inPixels[offset-width] == black)
tableIndex |= 2;
if (inPixels[offset-width+1] == black)
tableIndex |= 4;
if (inPixels[offset+1] == black)
tableIndex |= 8;
if (inPixels[offset+width+1] == black)
tableIndex |= 16;
if (inPixels[offset+width] == black)
tableIndex |= 32;
if (inPixels[offset+width-1] == black)
tableIndex |= 64;
if (inPixels[offset-1] == black)
tableIndex |= 128;
int code = skeletonTable[tableIndex];
if (pass == 1) {
if (code == 2 || code == 3) {
if (colormap != null)
pixel = colormap.getColor((float)i/iterations);
else
pixel = newColor;
count++;
}
} else {
if (code == 1 || code == 3) {
if (colormap != null)
pixel = colormap.getColor((float)i/iterations);
else
pixel = newColor;
count++;
}
}
}
outPixels[offset++] = pixel;
}
}
if (pass == 0) {
inPixels = outPixels;
outPixels = new int[width * height];
}
}
if (count == 0)
break;
}
return outPixels;
}
public String toString() {
return "Binary/Skeletonize...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Colormap.java 0000644 0001750 0001750 00000001706 10562652111 025717 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* An interface for color maps. These are passed to filters which convert gray values to
* colors. This is similar to the ColorModel class but works with floating point values.
*/
public interface Colormap {
/**
* Convert a value in the range 0..1 to an RGB color.
* @param v a value in the range 0..1
* @return an RGB color
*/
public int getColor(float v);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/InterpolateFilter.java 0000644 0001750 0001750 00000006334 10566356614 027616 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* A filter which interpolates betwen two images. You can set the interpolation factor outside the range 0 to 1
* to extrapolate images.
*/
public class InterpolateFilter extends AbstractBufferedImageOp {
private BufferedImage destination;
private float interpolation;
public InterpolateFilter() {
}
/**
* Set the destination image.
* @param destination the destination image
* @see #getDestination
*/
public void setDestination( BufferedImage destination ) {
this.destination = destination;
}
/**
* Get the destination image.
* @return the destination image
* @see #setDestination
*/
public BufferedImage getDestination() {
return destination;
}
/**
* Set the interpolation factor.
* @param interpolation the interpolation factor
* @see #getInterpolation
*/
public void setInterpolation( float interpolation ) {
this.interpolation = interpolation;
}
/**
* Get the interpolation factor.
* @return the interpolation factor
* @see #setInterpolation
*/
public float getInterpolation() {
return interpolation;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
WritableRaster dstRaster = dst.getRaster();
if ( destination != null ) {
width = Math.min( width, destination.getWidth() );
height = Math.min( height, destination.getWidth() );
int[] pixels1 = null;
int[] pixels2 = null;
for (int y = 0; y < height; y++) {
pixels1 = getRGB( src, 0, y, width, 1, pixels1 );
pixels2 = getRGB( destination, 0, y, width, 1, pixels2 );
for (int x = 0; x < width; x++) {
int rgb1 = pixels1[x];
int rgb2 = pixels2[x];
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int a2 = (rgb2 >> 24) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
r1 = PixelUtils.clamp( ImageMath.lerp( interpolation, r1, r2 ) );
g1 = PixelUtils.clamp( ImageMath.lerp( interpolation, g1, g2 ) );
b1 = PixelUtils.clamp( ImageMath.lerp( interpolation, b1, b2 ) );
pixels1[x] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
}
setRGB( dst, 0, y, width, 1, pixels1 );
}
}
return dst;
}
public String toString() {
return "Effects/Interpolate...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SmearFilter.java 0000644 0001750 0001750 00000015053 10566356614 026375 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
public class SmearFilter extends WholeImageFilter {
public final static int CROSSES = 0;
public final static int LINES = 1;
public final static int CIRCLES = 2;
public final static int SQUARES = 3;
private Colormap colormap = new LinearColormap();
private float angle = 0;
private float density = 0.5f;
private float scatter = 0.0f;
private int distance = 8;
private Random randomGenerator;
private long seed = 567;
private int shape = LINES;
private float mix = 0.5f;
private int fadeout = 0;
private boolean background = false;
public SmearFilter() {
randomGenerator = new Random();
}
public void setShape(int shape) {
this.shape = shape;
}
public int getShape() {
return shape;
}
public void setDistance(int distance) {
this.distance = distance;
}
public int getDistance() {
return distance;
}
public void setDensity(float density) {
this.density = density;
}
public float getDensity() {
return density;
}
public void setScatter(float scatter) {
this.scatter = scatter;
}
public float getScatter() {
return scatter;
}
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
public void setMix(float mix) {
this.mix = mix;
}
public float getMix() {
return mix;
}
public void setFadeout(int fadeout) {
this.fadeout = fadeout;
}
public int getFadeout() {
return fadeout;
}
public void setBackground(boolean background) {
this.background = background;
}
public boolean getBackground() {
return background;
}
public void randomize() {
seed = new Date().getTime();
}
private float random(float low, float high) {
return low+(high-low) * randomGenerator.nextFloat();
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
randomGenerator.setSeed(seed);
float sinAngle = (float)Math.sin(angle);
float cosAngle = (float)Math.cos(angle);
int i = 0;
int numShapes;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
outPixels[i] = background ? 0xffffffff : inPixels[i];
i++;
}
switch (shape) {
case CROSSES:
//Crosses
numShapes = (int)(2*density*width * height / (distance + 1));
for (i = 0; i < numShapes; i++) {
int x = (randomGenerator.nextInt() & 0x7fffffff) % width;
int y = (randomGenerator.nextInt() & 0x7fffffff) % height;
int length = randomGenerator.nextInt() % distance + 1;
int rgb = inPixels[y*width+x];
for (int x1 = x - length; x1 < x + length + 1; x1++) {
if (x1 >= 0 && x1 < width) {
int rgb2 = background ? 0xffffffff : outPixels[y*width+x1];
outPixels[y*width+x1] = ImageMath.mixColors(mix, rgb2, rgb);
}
}
for (int y1 = y - length; y1 < y + length + 1; y1++) {
if (y1 >= 0 && y1 < height) {
int rgb2 = background ? 0xffffffff : outPixels[y1*width+x];
outPixels[y1*width+x] = ImageMath.mixColors(mix, rgb2, rgb);
}
}
}
break;
case LINES:
numShapes = (int)(2*density*width * height / 2);
for (i = 0; i < numShapes; i++) {
int sx = (randomGenerator.nextInt() & 0x7fffffff) % width;
int sy = (randomGenerator.nextInt() & 0x7fffffff) % height;
int rgb = inPixels[sy*width+sx];
int length = (randomGenerator.nextInt() & 0x7fffffff) % distance;
int dx = (int)(length*cosAngle);
int dy = (int)(length*sinAngle);
int x0 = sx-dx;
int y0 = sy-dy;
int x1 = sx+dx;
int y1 = sy+dy;
int x, y, d, incrE, incrNE, ddx, ddy;
if (x1 < x0)
ddx = -1;
else
ddx = 1;
if (y1 < y0)
ddy = -1;
else
ddy = 1;
dx = x1-x0;
dy = y1-y0;
dx = Math.abs(dx);
dy = Math.abs(dy);
x = x0;
y = y0;
if (x < width && x >= 0 && y < height && y >= 0) {
int rgb2 = background ? 0xffffffff : outPixels[y*width+x];
outPixels[y*width+x] = ImageMath.mixColors(mix, rgb2, rgb);
}
if (Math.abs(dx) > Math.abs(dy)) {
d = 2*dy-dx;
incrE = 2*dy;
incrNE = 2*(dy-dx);
while (x != x1) {
if (d <= 0)
d += incrE;
else {
d += incrNE;
y += ddy;
}
x += ddx;
if (x < width && x >= 0 && y < height && y >= 0) {
int rgb2 = background ? 0xffffffff : outPixels[y*width+x];
outPixels[y*width+x] = ImageMath.mixColors(mix, rgb2, rgb);
}
}
} else {
d = 2*dx-dy;
incrE = 2*dx;
incrNE = 2*(dx-dy);
while (y != y1) {
if (d <= 0)
d += incrE;
else {
d += incrNE;
x += ddx;
}
y += ddy;
if (x < width && x >= 0 && y < height && y >= 0) {
int rgb2 = background ? 0xffffffff : outPixels[y*width+x];
outPixels[y*width+x] = ImageMath.mixColors(mix, rgb2, rgb);
}
}
}
}
break;
case SQUARES:
case CIRCLES:
int radius = distance+1;
int radius2 = radius * radius;
numShapes = (int)(2*density*width * height / radius);
for (i = 0; i < numShapes; i++) {
int sx = (randomGenerator.nextInt() & 0x7fffffff) % width;
int sy = (randomGenerator.nextInt() & 0x7fffffff) % height;
int rgb = inPixels[sy*width+sx];
for (int x = sx - radius; x < sx + radius + 1; x++) {
for (int y = sy - radius; y < sy + radius + 1; y++) {
int f;
if (shape == CIRCLES)
f = (x - sx) * (x - sx) + (y - sy) * (y - sy);
else
f = 0;
if (x >= 0 && x < width && y >= 0 && y < height && f <= radius2) {
int rgb2 = background ? 0xffffffff : outPixels[y*width+x];
outPixels[y*width+x] = ImageMath.mixColors(mix, rgb2, rgb);
}
}
}
}
}
return outPixels;
}
public String toString() {
return "Effects/Smear...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ThresholdFilter.java 0000644 0001750 0001750 00000005706 10626010061 027242 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which performs a threshold operation on an image.
*/
public class ThresholdFilter extends PointFilter {
private int lowerThreshold;
private int upperThreshold;
private int white = 0xffffff;
private int black = 0x000000;
/**
* Construct a ThresholdFilter.
*/
public ThresholdFilter() {
this(127);
}
/**
* Construct a ThresholdFilter.
* @param t the threshold value
*/
public ThresholdFilter(int t) {
setLowerThreshold(t);
setUpperThreshold(t);
}
/**
* Set the lower threshold value.
* @param lowerThreshold the threshold value
* @see #getLowerThreshold
*/
public void setLowerThreshold(int lowerThreshold) {
this.lowerThreshold = lowerThreshold;
}
/**
* Get the lower threshold value.
* @return the threshold value
* @see #setLowerThreshold
*/
public int getLowerThreshold() {
return lowerThreshold;
}
/**
* Set the upper threshold value.
* @param upperThreshold the threshold value
* @see #getUpperThreshold
*/
public void setUpperThreshold(int upperThreshold) {
this.upperThreshold = upperThreshold;
}
/**
* Get the upper threshold value.
* @return the threshold value
* @see #setUpperThreshold
*/
public int getUpperThreshold() {
return upperThreshold;
}
/**
* Set the color to be used for pixels above the upper threshold.
* @param white the color
* @see #getWhite
*/
public void setWhite(int white) {
this.white = white;
}
/**
* Get the color to be used for pixels above the upper threshold.
* @return the color
* @see #setWhite
*/
public int getWhite() {
return white;
}
/**
* Set the color to be used for pixels below the lower threshold.
* @param black the color
* @see #getBlack
*/
public void setBlack(int black) {
this.black = black;
}
/**
* Set the color to be used for pixels below the lower threshold.
* @return the color
* @see #setBlack
*/
public int getBlack() {
return black;
}
public int filterRGB(int x, int y, int rgb) {
int v = PixelUtils.brightness( rgb );
float f = ImageMath.smoothStep( lowerThreshold, upperThreshold, v );
return (rgb & 0xff000000) | (ImageMath.mixColors( f, black, white ) & 0xffffff);
}
public String toString() {
return "Stylize/Threshold...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TwirlFilter.java 0000644 0001750 0001750 00000007767 10566356614 026444 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A Filter which distorts an image by twisting it from the centre out.
* The twisting is centred at the centre of the image and extends out to the smallest of
* the width and height. Pixels outside this radius are unaffected.
*/
public class TwirlFilter extends TransformFilter {
private float angle = 0;
private float centreX = 0.5f;
private float centreY = 0.5f;
private float radius = 100;
private float radius2 = 0;
private float icentreX;
private float icentreY;
/**
* Construct a TwirlFilter with no distortion.
*/
public TwirlFilter() {
setEdgeAction( CLAMP );
}
/**
* Set the angle of twirl in radians. 0 means no distortion.
* @param angle the angle of twirl. This is the angle by which pixels at the nearest edge of the image will move.
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
}
/**
* Get the angle of twist.
* @return the angle in radians.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
icentreX = src.getWidth() * centreX;
icentreY = src.getHeight() * centreY;
if ( radius == 0 )
radius = Math.min(icentreX, icentreY);
radius2 = radius*radius;
return super.filter( src, dst );
}
protected void transformInverse(int x, int y, float[] out) {
float dx = x-icentreX;
float dy = y-icentreY;
float distance = dx*dx + dy*dy;
if (distance > radius2) {
out[0] = x;
out[1] = y;
} else {
distance = (float)Math.sqrt(distance);
float a = (float)Math.atan2(dy, dx) + angle * (radius-distance) / radius;
out[0] = icentreX + distance*(float)Math.cos(a);
out[1] = icentreY + distance*(float)Math.sin(a);
}
}
public String toString() {
return "Distort/Twirl...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CompositeFilter.java 0000644 0001750 0001750 00000005325 10566356614 027271 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which composites two images together with an optional transform.
*/
public class CompositeFilter extends AbstractBufferedImageOp {
private Composite composite;
private AffineTransform transform;
/**
* Construct a CompositeFilter.
*/
public CompositeFilter() {
}
/**
* Construct a CompositeFilter.
* @param composite the composite to use
*/
public CompositeFilter( Composite composite ) {
this.composite = composite;
}
/**
* Construct a CompositeFilter.
* @param composite the composite to use
* @param transform a transform for the composited image
*/
public CompositeFilter( Composite composite, AffineTransform transform ) {
this.composite = composite;
this.transform = transform;
}
/**
* Set the composite.
* @param composite the composite to use
* @see #getComposite
*/
public void setComposite( Composite composite ) {
this.composite = composite;
}
/**
* Get the composite.
* @return the composite to use
* @see #setComposite
*/
public Composite getComposite() {
return composite;
}
/**
* Set the transform.
* @param transform the transform to use
* @see #getTransform
*/
public void setTransform( AffineTransform transform ) {
this.transform = transform;
}
/**
* Get the transform.
* @return the transform to use
* @see #setTransform
*/
public AffineTransform getTransform() {
return transform;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
Graphics2D g = dst.createGraphics();
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
g.setComposite( composite );
g.drawRenderedImage( src, transform );
g.dispose();
return dst;
}
public String toString() {
return "Composite";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/EmbossFilter.java 0000644 0001750 0001750 00000006673 10562652111 026551 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A class to emboss an image.
*/
public class EmbossFilter extends WholeImageFilter {
private final static float pixelScale = 255.9f;
private float azimuth = 135.0f * ImageMath.PI / 180.0f, elevation = 30.0f * ImageMath.PI / 180f;
private boolean emboss = false;
private float width45 = 3.0f;
public EmbossFilter() {
}
public void setAzimuth(float azimuth) {
this.azimuth = azimuth;
}
public float getAzimuth() {
return azimuth;
}
public void setElevation(float elevation) {
this.elevation = elevation;
}
public float getElevation() {
return elevation;
}
public void setBumpHeight(float bumpHeight) {
this.width45 = 3 * bumpHeight;
}
public float getBumpHeight() {
return width45 / 3;
}
public void setEmboss(boolean emboss) {
this.emboss = emboss;
}
public boolean getEmboss() {
return emboss;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
int[] bumpPixels;
int bumpMapWidth, bumpMapHeight;
bumpMapWidth = width;
bumpMapHeight = height;
bumpPixels = new int[bumpMapWidth * bumpMapHeight];
for (int i = 0; i < inPixels.length; i++)
bumpPixels[i] = PixelUtils.brightness(inPixels[i]);
int Nx, Ny, Nz, Lx, Ly, Lz, Nz2, NzLz, NdotL;
int shade, background;
Lx = (int)(Math.cos(azimuth) * Math.cos(elevation) * pixelScale);
Ly = (int)(Math.sin(azimuth) * Math.cos(elevation) * pixelScale);
Lz = (int)(Math.sin(elevation) * pixelScale);
Nz = (int)(6 * 255 / width45);
Nz2 = Nz * Nz;
NzLz = Nz * Lz;
background = Lz;
int bumpIndex = 0;
for (int y = 0; y < height; y++, bumpIndex += bumpMapWidth) {
int s1 = bumpIndex;
int s2 = s1 + bumpMapWidth;
int s3 = s2 + bumpMapWidth;
for (int x = 0; x < width; x++, s1++, s2++, s3++) {
if (y != 0 && y < height-2 && x != 0 && x < width-2) {
Nx = bumpPixels[s1-1] + bumpPixels[s2-1] + bumpPixels[s3-1] - bumpPixels[s1+1] - bumpPixels[s2+1] - bumpPixels[s3+1];
Ny = bumpPixels[s3-1] + bumpPixels[s3] + bumpPixels[s3+1] - bumpPixels[s1-1] - bumpPixels[s1] - bumpPixels[s1+1];
if (Nx == 0 && Ny == 0)
shade = background;
else if ((NdotL = Nx*Lx + Ny*Ly + NzLz) < 0)
shade = 0;
else
shade = (int)(NdotL / Math.sqrt(Nx*Nx + Ny*Ny + Nz2));
} else
shade = background;
if (emboss) {
int rgb = inPixels[index];
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = (r*shade) >> 8;
g = (g*shade) >> 8;
b = (b*shade) >> 8;
outPixels[index++] = a | (r << 16) | (g << 8) | b;
} else
outPixels[index++] = 0xff000000 | (shade << 16) | (shade << 8) | shade;
}
}
return outPixels;
}
public String toString() {
return "Stylize/Emboss...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/OffsetFilter.java 0000644 0001750 0001750 00000005366 11331370225 026543 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class OffsetFilter extends TransformFilter {
private int width, height;
private int xOffset, yOffset;
private boolean wrap;
private float relativeX;
private float relativeY;
private boolean useRelative = false;
public OffsetFilter() {
this(0, 0, true);
}
public OffsetFilter(int xOffset, int yOffset, boolean wrap) {
this.xOffset = xOffset;
this.yOffset = yOffset;
this.wrap = wrap;
setEdgeAction( ZERO );
}
public void setRelativeX(float relativeX) {
this.relativeX = relativeX;
}
public void setRelativeY(float relativeY) {
this.relativeY = relativeY;
}
public float getRelativeX() {
return relativeX;
}
public float getRelativeY() {
return relativeY;
}
public boolean isUseRelative() {
return useRelative;
}
/**
* When useRelative is set, the relative settings overwrite the absolute settings
* @param useRelative
*/
public void setUseRelative(boolean useRelative) {
this.useRelative = useRelative;
}
public void setXOffset(int xOffset) {
this.xOffset = xOffset;
}
public int getXOffset() {
return xOffset;
}
public void setYOffset(int yOffset) {
this.yOffset = yOffset;
}
public int getYOffset() {
return yOffset;
}
public void setWrap(boolean wrap) {
this.wrap = wrap;
}
public boolean getWrap() {
return wrap;
}
protected void transformInverse(int x, int y, float[] out) {
if ( wrap ) {
out[0] = (x+width-xOffset) % width;
out[1] = (y+height-yOffset) % height;
} else {
out[0] = x-xOffset;
out[1] = y-yOffset;
}
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
this.width = src.getWidth();
this.height = src.getHeight();
if(useRelative) {
xOffset = (int) (width * relativeX);
yOffset = (int) (height * relativeY);
}
if ( wrap ) {
while (xOffset < 0)
xOffset += width;
while (yOffset < 0)
yOffset += height;
xOffset %= width;
yOffset %= height;
}
return super.filter( src, dst );
}
public String toString() {
return "Distort/Offset...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/KaleidoscopeFilter.java 0000644 0001750 0001750 00000011103 10566356614 027720 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A Filter which produces the effect of looking into a kaleidoscope.
*/
public class KaleidoscopeFilter extends TransformFilter {
private float angle = 0;
private float angle2 = 0;
private float centreX = 0.5f;
private float centreY = 0.5f;
private int sides = 3;
private float radius = 0;
private float icentreX;
private float icentreY;
/**
* Construct a KaleidoscopeFilter with no distortion.
*/
public KaleidoscopeFilter() {
setEdgeAction( CLAMP );
}
/**
* Set the number of sides of the kaleidoscope.
* @param sides the number of sides
* @min-value 2
* @see #getSides
*/
public void setSides(int sides) {
this.sides = sides;
}
/**
* Get the number of sides of the kaleidoscope.
* @return the number of sides
* @see #setSides
*/
public int getSides() {
return sides;
}
/**
* Set the angle of the kaleidoscope.
* @param angle the angle of the kaleidoscope.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
}
/**
* Get the angle of the kaleidoscope.
* @return the angle of the kaleidoscope.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the secondary angle of the kaleidoscope.
* @param angle2 the angle
* @angle
* @see #getAngle2
*/
public void setAngle2(float angle2) {
this.angle2 = angle2;
}
/**
* Get the secondary angle of the kaleidoscope.
* @return the angle
* @see #setAngle2
*/
public float getAngle2() {
return angle2;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius( float radius ) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
icentreX = src.getWidth() * centreX;
icentreY = src.getHeight() * centreY;
return super.filter( src, dst );
}
protected void transformInverse(int x, int y, float[] out) {
double dx = x-icentreX;
double dy = y-icentreY;
double r = Math.sqrt( dx*dx + dy*dy );
double theta = Math.atan2( dy, dx ) - angle - angle2;
theta = ImageMath.triangle( (float)( theta/Math.PI*sides*.5 ) );
if ( radius != 0 ) {
double c = Math.cos(theta);
double radiusc = radius/c;
r = radiusc * ImageMath.triangle( (float)(r/radiusc) );
}
theta += angle;
out[0] = (float)(icentreX + r*Math.cos(theta));
out[1] = (float)(icentreY + r*Math.sin(theta));
}
public String toString() {
return "Distort/Kaleidoscope...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CompoundFilter.java 0000644 0001750 0001750 00000002407 10566356614 027111 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A BufferedImageOp which combines two other BufferedImageOps, one after the other.
*/
public class CompoundFilter extends AbstractBufferedImageOp {
private BufferedImageOp filter1;
private BufferedImageOp filter2;
/**
* Construct a CompoundFilter.
* @param filter1 the first filter
* @param filter2 the second filter
*/
public CompoundFilter( BufferedImageOp filter1, BufferedImageOp filter2 ) {
this.filter1 = filter1;
this.filter2 = filter2;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
BufferedImage image = filter1.filter( src, dst );
image = filter2.filter( image, dst );
return image;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FourColorFilter.java 0000644 0001750 0001750 00000005212 10562652111 027217 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* A filter which draws a gradient interpolated between four colors defined at the corners of the image.
*/
public class FourColorFilter extends PointFilter {
private int width;
private int height;
private int colorNW;
private int colorNE;
private int colorSW;
private int colorSE;
private int rNW, gNW, bNW;
private int rNE, gNE, bNE;
private int rSW, gSW, bSW;
private int rSE, gSE, bSE;
public FourColorFilter() {
setColorNW( 0xffff0000 );
setColorNE( 0xffff00ff );
setColorSW( 0xff0000ff );
setColorSE( 0xff00ffff );
}
public void setColorNW( int color ) {
this.colorNW = color;
rNW = (color >> 16) & 0xff;
gNW = (color >> 8) & 0xff;
bNW = color & 0xff;
}
public int getColorNW() {
return colorNW;
}
public void setColorNE( int color ) {
this.colorNE = color;
rNE = (color >> 16) & 0xff;
gNE = (color >> 8) & 0xff;
bNE = color & 0xff;
}
public int getColorNE() {
return colorNE;
}
public void setColorSW( int color ) {
this.colorSW = color;
rSW = (color >> 16) & 0xff;
gSW = (color >> 8) & 0xff;
bSW = color & 0xff;
}
public int getColorSW() {
return colorSW;
}
public void setColorSE( int color ) {
this.colorSE = color;
rSE = (color >> 16) & 0xff;
gSE = (color >> 8) & 0xff;
bSE = color & 0xff;
}
public int getColorSE() {
return colorSE;
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
super.setDimensions(width, height);
}
public int filterRGB(int x, int y, int rgb) {
float fx = (float)x / width;
float fy = (float)y / height;
float p, q;
p = rNW + (rNE - rNW) * fx;
q = rSW + (rSE - rSW) * fx;
int r = (int)( p + (q - p) * fy + 0.5f );
p = gNW + (gNE - gNW) * fx;
q = gSW + (gSE - gSW) * fx;
int g = (int)( p + (q - p) * fy + 0.5f );
p = bNW + (bNE - bNW) * fx;
q = bSW + (bSE - bSW) * fx;
int b = (int)( p + (q - p) * fy + 0.5f );
return 0xff000000 | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Texture/Four Color Fill...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DespeckleFilter.java 0000644 0001750 0001750 00000005735 10566356614 027233 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which removes noise from an image using a "pepper and salt" algorithm.
*/
public class DespeckleFilter extends WholeImageFilter {
public DespeckleFilter() {
}
private short pepperAndSalt( short c, short v1, short v2 ) {
if ( c < v1 )
c++;
if ( c < v2 )
c++;
if ( c > v1 )
c--;
if ( c > v2 )
c--;
return c;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
short[][] r = new short[3][width];
short[][] g = new short[3][width];
short[][] b = new short[3][width];
int[] outPixels = new int[width * height];
for (int x = 0; x < width; x++) {
int rgb = inPixels[x];
r[1][x] = (short)((rgb >> 16) & 0xff);
g[1][x] = (short)((rgb >> 8) & 0xff);
b[1][x] = (short)(rgb & 0xff);
}
for (int y = 0; y < height; y++) {
boolean yIn = y > 0 && y < height-1;
int nextRowIndex = index+width;
if ( y < height-1) {
for (int x = 0; x < width; x++) {
int rgb = inPixels[nextRowIndex++];
r[2][x] = (short)((rgb >> 16) & 0xff);
g[2][x] = (short)((rgb >> 8) & 0xff);
b[2][x] = (short)(rgb & 0xff);
}
}
for (int x = 0; x < width; x++) {
boolean xIn = x > 0 && x < width-1;
short or = r[1][x];
short og = g[1][x];
short ob = b[1][x];
int w = x-1;
int e = x+1;
if ( yIn ) {
or = pepperAndSalt( or, r[0][x], r[2][x] );
og = pepperAndSalt( og, g[0][x], g[2][x] );
ob = pepperAndSalt( ob, b[0][x], b[2][x] );
}
if ( xIn ) {
or = pepperAndSalt( or, r[1][w], r[1][e] );
og = pepperAndSalt( og, g[1][w], g[1][e] );
ob = pepperAndSalt( ob, b[1][w], b[1][e] );
}
if ( yIn && xIn ) {
or = pepperAndSalt( or, r[0][w], r[2][e] );
og = pepperAndSalt( og, g[0][w], g[2][e] );
ob = pepperAndSalt( ob, b[0][w], b[2][e] );
or = pepperAndSalt( or, r[2][w], r[0][e] );
og = pepperAndSalt( og, g[2][w], g[0][e] );
ob = pepperAndSalt( ob, b[2][w], b[0][e] );
}
outPixels[index] = (inPixels[index] & 0xff000000) | (or << 16) | (og << 8) | ob;
index++;
}
short[] t;
t = r[0];
r[0] = r[1];
r[1] = r[2];
r[2] = t;
t = g[0];
g[0] = g[1];
g[1] = g[2];
g[2] = t;
t = b[0];
b[0] = b[1];
b[1] = b[2];
b[2] = t;
}
return outPixels;
}
public String toString() {
return "Blur/Despeckle...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FlareFilter.java 0000644 0001750 0001750 00000007276 10566356614 026367 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import com.jhlabs.math.*;
/**
* An experimental filter for rendering lens flares.
*/
public class FlareFilter extends PointFilter {
private int rays = 50;
private float radius;
private float baseAmount = 1.0f;
private float ringAmount = 0.2f;
private float rayAmount = 0.1f;
private int color = 0xffffffff;
private int width, height;
private float centreX = 0.5f, centreY = 0.5f;
private float ringWidth = 1.6f;
private float linear = 0.03f;
private float gauss = 0.006f;
private float mix = 0.50f;
private float falloff = 6.0f;
private float sigma;
private float icentreX, icentreY;
public FlareFilter() {
setRadius(50.0f);
}
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
public void setRingWidth(float ringWidth) {
this.ringWidth = ringWidth;
}
public float getRingWidth() {
return ringWidth;
}
public void setBaseAmount(float baseAmount) {
this.baseAmount = baseAmount;
}
public float getBaseAmount() {
return baseAmount;
}
public void setRingAmount(float ringAmount) {
this.ringAmount = ringAmount;
}
public float getRingAmount() {
return ringAmount;
}
public void setRayAmount(float rayAmount) {
this.rayAmount = rayAmount;
}
public float getRayAmount() {
return rayAmount;
}
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
sigma = radius/3;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
icentreX = centreX*width;
icentreY = centreY*height;
super.setDimensions(width, height);
}
public int filterRGB(int x, int y, int rgb) {
float dx = x-icentreX;
float dy = y-icentreY;
float distance = (float)Math.sqrt(dx*dx+dy*dy);
float a = (float)Math.exp(-distance*distance*gauss)*mix + (float)Math.exp(-distance*linear)*(1-mix);
float ring;
a *= baseAmount;
if (distance > radius + ringWidth)
a = ImageMath.lerp((distance - (radius + ringWidth))/falloff, a, 0);
if (distance < radius - ringWidth || distance > radius + ringWidth)
ring = 0;
else {
ring = Math.abs(distance-radius)/ringWidth;
ring = 1 - ring*ring*(3 - 2*ring);
ring *= ringAmount;
}
a += ring;
float angle = (float)Math.atan2(dx, dy)+ImageMath.PI;
angle = (ImageMath.mod(angle/ImageMath.PI*17 + 1.0f + Noise.noise1(angle*10), 1.0f) - 0.5f)*2;
angle = Math.abs(angle);
angle = (float)Math.pow(angle, 5.0);
float b = rayAmount * angle / (1 + distance*0.1f);
a += b;
a = ImageMath.clamp(a, 0, 1);
return ImageMath.mixColors(a, rgb, color);
}
public String toString() {
return "Stylize/Flare...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SwimFilter.java 0000644 0001750 0001750 00000010020 10566356614 026232 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* A filter which distorts an image as if it were underwater.
*/
public class SwimFilter extends TransformFilter {
private float scale = 32;
private float stretch = 1.0f;
private float angle = 0.0f;
private float amount = 1.0f;
private float turbulence = 1.0f;
private float time = 0.0f;
private float m00 = 1.0f;
private float m01 = 0.0f;
private float m10 = 0.0f;
private float m11 = 1.0f;
public SwimFilter() {
}
/**
* Set the amount of swim.
* @param amount the amount of swim
* @min-value 0
* @max-value 100+
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of swim.
* @return the amount swim
* @see #setAmount
*/
public float getAmount() {
return amount;
}
/**
* Specifies the scale of the distortion.
* @param scale the scale of the distortion.
* @min-value 1
* @max-value 300+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the distortion.
* @return the scale of the distortion.
* @see #setScale
*/
public float getScale() {
return scale;
}
/**
* Specifies the stretch factor of the distortion.
* @param stretch the stretch factor of the distortion.
* @min-value 1
* @max-value 50+
* @see #getStretch
*/
public void setStretch(float stretch) {
this.stretch = stretch;
}
/**
* Returns the stretch factor of the distortion.
* @return the stretch factor of the distortion.
* @see #setStretch
*/
public float getStretch() {
return stretch;
}
/**
* Specifies the angle of the effect.
* @param angle the angle of the effect.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(angle);
float sin = (float)Math.sin(angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Returns the angle of the effect.
* @return the angle of the effect.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Specifies the turbulence of the texture.
* @param turbulence the turbulence of the texture.
* @min-value 0
* @max-value 1
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the effect.
* @return the turbulence of the effect.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
/**
* Specifies the time. Use this to animate the effect.
* @param time the time.
* @angle
* @see #getTime
*/
public void setTime(float time) {
this.time = time;
}
/**
* Returns the time.
* @return the time.
* @see #setTime
*/
public float getTime() {
return time;
}
protected void transformInverse(int x, int y, float[] out) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
if ( turbulence == 1.0f ) {
out[0] = x + amount * Noise.noise3(nx+0.5f, ny, time);
out[1] = y + amount * Noise.noise3(nx, ny+0.5f, time);
} else {
out[0] = x + amount * Noise.turbulence3(nx+0.5f, ny, turbulence, time);
out[1] = y + amount * Noise.turbulence3(nx, ny+0.5f, turbulence, time);
}
}
public String toString() {
return "Distort/Swim...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ShearFilter.java 0000644 0001750 0001750 00000006241 10562652111 026352 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class ShearFilter extends TransformFilter {
private float xangle = 0.0f;
private float yangle = 0.0f;
private float shx = 0.0f;
private float shy = 0.0f;
private float xoffset = 0.0f;
private float yoffset = 0.0f;
private boolean resize = true;
public ShearFilter() {
}
public void setResize(boolean resize) {
this.resize = resize;
}
public boolean isResize() {
return resize;
}
public void setXAngle(float xangle) {
this.xangle = xangle;
initialize();
}
public float getXAngle() {
return xangle;
}
public void setYAngle(float yangle) {
this.yangle = yangle;
initialize();
}
public float getYAngle() {
return yangle;
}
private void initialize() {
shx = (float)Math.sin(xangle);
shy = (float)Math.sin(yangle);
}
protected void transformSpace(Rectangle r) {
float tangent = (float)Math.tan(xangle);
xoffset = -r.height * tangent;
if (tangent < 0.0)
tangent = -tangent;
r.width = (int)(r.height * tangent + r.width + 0.999999f);
tangent = (float)Math.tan(yangle);
yoffset = -r.width * tangent;
if (tangent < 0.0)
tangent = -tangent;
r.height = (int)(r.width * tangent + r.height + 0.999999f);
}
/*
public void imageComplete(int status) {
try {
if (status == IMAGEERROR || status == IMAGEABORTED) {
consumer.imageComplete(status);
return;
}
int width = originalSpace.width;
int height = originalSpace.height;
float tangent = Math.tan(angle);
if (tangent < 0.0)
tangent = -tangent;
int newWidth = (int)(height * tangent + width + 0.999999);
int[] outPixels = new int[height*newWidth];
int inIndex = 0;
int yOffset = 0;
for (int y = 0; y < height; y++) {
float newCol;
if (angle >= 0.0)
newCol = y * tangent;
else
newCol = (height-y) * tangent;
int iNewCol = (int)newCol;
float f = newCol - iNewCol;
f = 1.0 - f;
int outIndex = yOffset+iNewCol;
int lastRGB = inPixels[inIndex];
for (int x = 0; x < width; x++) {
int rgb = inPixels[inIndex];
outPixels[outIndex] = ImageMath.mixColors(f, lastRGB, rgb);
lastRGB = rgb;
inIndex++;
outIndex++;
}
outPixels[outIndex] = ImageMath.mixColors(f, lastRGB, 0);
yOffset += newWidth;
}
consumer.setPixels(0, 0, newWidth, height, defaultRGBModel, outPixels, 0, newWidth);
consumer.imageComplete(status);
inPixels = null;
}
catch (Exception e) {
e.printStackTrace();
}
}
*/
protected void transformInverse(int x, int y, float[] out) {
out[0] = x + xoffset + (y * shx);
out[1] = y + yoffset + (x * shy);
}
public String toString() {
return "Distort/Shear...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LinearColormap.java 0000644 0001750 0001750 00000004002 10566572034 027053 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* A colormap which interpolates linearly between two colors.
*/
public class LinearColormap implements Colormap {
private int color1;
private int color2;
/**
* Construct a color map with a grayscale ramp from black to white.
*/
public LinearColormap() {
this(0xff000000, 0xffffffff);
}
/**
* Construct a linear color map.
* @param color1 the color corresponding to value 0 in the colormap
* @param color2 the color corresponding to value 1 in the colormap
*/
public LinearColormap(int color1, int color2) {
this.color1 = color1;
this.color2 = color2;
}
/**
* Set the first color.
* @param color1 the color corresponding to value 0 in the colormap
*/
public void setColor1(int color1) {
this.color1 = color1;
}
/**
* Get the first color.
* @return the color corresponding to value 0 in the colormap
*/
public int getColor1() {
return color1;
}
/**
* Set the second color.
* @param color2 the color corresponding to value 1 in the colormap
*/
public void setColor2(int color2) {
this.color2 = color2;
}
/**
* Get the second color.
* @return the color corresponding to value 1 in the colormap
*/
public int getColor2() {
return color2;
}
/**
* Convert a value in the range 0..1 to an RGB color.
* @param v a value in the range 0..1
* @return an RGB color
*/
public int getColor(float v) {
return ImageMath.mixColors(ImageMath.clamp(v, 0, 1.0f), color1, color2);
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MapFilter.java 0000644 0001750 0001750 00000002651 10562652111 026026 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
public class MapFilter extends TransformFilter {
private Function2D xMapFunction;
private Function2D yMapFunction;
public MapFilter() {
}
public void setXMapFunction(Function2D xMapFunction) {
this.xMapFunction = xMapFunction;
}
public Function2D getXMapFunction() {
return xMapFunction;
}
public void setYMapFunction(Function2D yMapFunction) {
this.yMapFunction = yMapFunction;
}
public Function2D getYMapFunction() {
return yMapFunction;
}
protected void transformInverse(int x, int y, float[] out) {
float xMap, yMap;
xMap = xMapFunction.evaluate(x, y);
yMap = yMapFunction.evaluate(x, y);
out[0] = xMap * transformedSpace.width;
out[1] = yMap * transformedSpace.height;
}
public String toString() {
return "Distort/Map Coordinates...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/WoodFilter.java 0000644 0001750 0001750 00000012354 10566356614 026237 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* A filter which produces a simulated wood texture. This is a bit of a hack, but might be usefult to some people.
*/
public class WoodFilter extends PointFilter {
private float scale = 200;
private float stretch = 10.0f;
private float angle = (float)Math.PI/2;
private float rings = 0.5f;
private float turbulence = 0.0f;
private float fibres = 0.5f;
private float gain = 0.8f;
private float m00 = 1.0f;
private float m01 = 0.0f;
private float m10 = 0.0f;
private float m11 = 1.0f;
private Colormap colormap = new LinearColormap( 0xffe5c494, 0xff987b51 );
/**
* Construct a WoodFilter.
*/
public WoodFilter() {
}
/**
* Specifies the rings value.
* @param rings the rings value.
* @min-value 0
* @max-value 1
* @see #getRings
*/
public void setRings(float rings) {
this.rings = rings;
}
/**
* Returns the rings value.
* @return the rings value.
* @see #setRings
*/
public float getRings() {
return rings;
}
/**
* Specifies the scale of the texture.
* @param scale the scale of the texture.
* @min-value 1
* @max-value 300+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the texture.
* @return the scale of the texture.
* @see #setScale
*/
public float getScale() {
return scale;
}
/**
* Specifies the stretch factor of the texture.
* @param stretch the stretch factor of the texture.
* @min-value 1
* @max-value 50+
* @see #getStretch
*/
public void setStretch(float stretch) {
this.stretch = stretch;
}
/**
* Returns the stretch factor of the texture.
* @return the stretch factor of the texture.
* @see #setStretch
*/
public float getStretch() {
return stretch;
}
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(angle);
float sin = (float)Math.sin(angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Specifies the turbulence of the texture.
* @param turbulence the turbulence of the texture.
* @min-value 0
* @max-value 1
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the texture.
* @return the turbulence of the texture.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
/**
* Specifies the amount of fibres in the texture.
* @param fibres the amount of fibres in the texture.
* @min-value 0
* @max-value 1
* @see #getFibres
*/
public void setFibres(float fibres) {
this.fibres = fibres;
}
/**
* Returns the amount of fibres in the texture.
* @return the amount of fibres in the texture.
* @see #setFibres
*/
public float getFibres() {
return fibres;
}
/**
* Specifies the gain of the texture.
* @param gain the gain of the texture.
* @min-value 0
* @max-value 1
* @see #getGain
*/
public void setGain(float gain) {
this.gain = gain;
}
/**
* Returns the gain of the texture.
* @return the gain of the texture.
* @see #setGain
*/
public float getGain() {
return gain;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public int filterRGB(int x, int y, int rgb) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
float f = Noise.noise2(nx, ny);
f += 0.1f*turbulence * Noise.noise2(nx*0.05f, ny*20);
f = (f * 0.5f) + 0.5f;
f *= rings*50;
f = f-(int)f;
f *= 1-ImageMath.smoothStep(gain, 1.0f, f);
f += fibres*Noise.noise2(nx*scale, ny*50);
int a = rgb & 0xff000000;
int v;
if (colormap != null)
v = colormap.getColor(f);
else {
v = PixelUtils.clamp((int)(f*255));
int r = v << 16;
int g = v << 8;
int b = v;
v = a|r|g|b;
}
return v;
}
public String toString() {
return "Texture/Wood...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DeinterlaceFilter.java 0000755 0001750 0001750 00000006062 10626011515 027531 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter for de-interlacing video frames.
*/
public class DeinterlaceFilter extends AbstractBufferedImageOp {
public final static int EVEN = 0;
public final static int ODD = 1;
public final static int AVERAGE = 2;
private int mode = EVEN;
public void setMode(int mode) {
this.mode = mode;
}
public int getMode() {
return mode;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] pixels = null;
if ( mode == EVEN ) {
for ( int y = 0; y < height-1; y += 2 ) {
pixels = getRGB( src, 0, y, width, 1, pixels );
if ( src != dst )
setRGB( dst, 0, y, width, 1, pixels );
setRGB( dst, 0, y+1, width, 1, pixels );
}
} else if ( mode == ODD ) {
for ( int y = 1; y < height; y += 2 ) {
pixels = getRGB( src, 0, y, width, 1, pixels );
if ( src != dst )
setRGB( dst, 0, y, width, 1, pixels );
setRGB( dst, 0, y-1, width, 1, pixels );
}
} else if ( mode == AVERAGE ) {
int[] pixels2 = null;
for ( int y = 0; y < height-1; y += 2 ) {
pixels = getRGB( src, 0, y, width, 1, pixels );
pixels2 = getRGB( src, 0, y+1, width, 1, pixels2 );
for ( int x = 0; x < width; x++ ) {
int rgb1 = pixels[x];
int rgb2 = pixels2[x];
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int a2 = (rgb2 >> 24) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
a1 = (a1+a2)/2;
r1 = (r1+r2)/2;
g1 = (g1+g2)/2;
b1 = (b1+b2)/2;
pixels[x] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
}
setRGB( dst, 0, y, width, 1, pixels );
setRGB( dst, 0, y+1, width, 1, pixels );
}
}
return dst;
}
public String toString() {
return "Video/De-Interlace";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MarbleFilter.java 0000644 0001750 0001750 00000006251 10606647276 026532 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* This filter applies a marbling effect to an image, displacing pixels by random amounts.
*/
public class MarbleFilter extends TransformFilter {
private float[] sinTable, cosTable;
private float xScale = 4;
private float yScale = 4;
private float amount = 1;
private float turbulence = 1;
public MarbleFilter() {
setEdgeAction(CLAMP);
}
/**
* Set the X scale of the effect.
* @param xScale the scale.
* @see #getXScale
*/
public void setXScale(float xScale) {
this.xScale = xScale;
}
/**
* Get the X scale of the effect.
* @return the scale.
* @see #setXScale
*/
public float getXScale() {
return xScale;
}
/**
* Set the Y scale of the effect.
* @param yScale the scale.
* @see #getYScale
*/
public void setYScale(float yScale) {
this.yScale = yScale;
}
/**
* Get the Y scale of the effect.
* @return the scale.
* @see #setYScale
*/
public float getYScale() {
return yScale;
}
/**
* Set the amount of effect.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of effect.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
/**
* Specifies the turbulence of the effect.
* @param turbulence the turbulence of the effect.
* @min-value 0
* @max-value 1
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the effect.
* @return the turbulence of the effect.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
private void initialize() {
sinTable = new float[256];
cosTable = new float[256];
for (int i = 0; i < 256; i++) {
float angle = ImageMath.TWO_PI*i/256f*turbulence;
sinTable[i] = (float)(-yScale*Math.sin(angle));
cosTable[i] = (float)(yScale*Math.cos(angle));
}
}
private int displacementMap(int x, int y) {
return PixelUtils.clamp((int)(127 * (1+Noise.noise2(x / xScale, y / xScale))));
}
protected void transformInverse(int x, int y, float[] out) {
int displacement = displacementMap(x, y);
out[0] = x + sinTable[displacement];
out[1] = y + cosTable[displacement];
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
initialize();
return super.filter( src, dst );
}
public String toString() {
return "Distort/Marble...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/UnpremultiplyFilter.java 0000755 0001750 0001750 00000001452 10626011515 030201 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which unpremultiplies an image's alpha.
* Note: this does not change the image type of the BufferedImage
*/
public class UnpremultiplyFilter extends PointFilter {
public UnpremultiplyFilter() {
}
public int filterRGB(int x, int y, int rgb) {
int a = (rgb >> 24) & 0xff;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if ( a == 0 || a == 255 )
return rgb;
float f = 255.0f / a;
r *= f;
g *= f;
b *= f;
if ( r > 255 )
r = 255;
if ( g > 255 )
g = 255;
if ( b > 255 )
b = 255;
return (a << 24) | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Alpha/Unpremultiply";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PlasmaFilter.java 0000644 0001750 0001750 00000014562 10566356614 026547 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
public class PlasmaFilter extends WholeImageFilter {
public float turbulence = 1.0f;
private float scaling = 0.0f;
private Colormap colormap = new LinearColormap();
private Random randomGenerator;
private long seed = 567;
private boolean useColormap = false;
private boolean useImageColors = false;
public PlasmaFilter() {
randomGenerator = new Random();
}
/**
* Specifies the turbulence of the texture.
* @param turbulence the turbulence of the texture.
* @min-value 0
* @max-value 10
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the effect.
* @return the turbulence of the effect.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
public void setScaling(float scaling) {
this.scaling = scaling;
}
public float getScaling() {
return scaling;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public void setUseColormap(boolean useColormap) {
this.useColormap = useColormap;
}
public boolean getUseColormap() {
return useColormap;
}
public void setUseImageColors(boolean useImageColors) {
this.useImageColors = useImageColors;
}
public boolean getUseImageColors() {
return useImageColors;
}
public void setSeed(int seed) {
this.seed = seed;
}
public int getSeed() {
return (int)seed;
}
public void randomize() {
seed = new Date().getTime();
}
private int randomRGB(int[] inPixels, int x, int y) {
if (useImageColors) {
return inPixels[y*originalSpace.width+x];
} else {
int r = (int)(255 * randomGenerator.nextFloat());
int g = (int)(255 * randomGenerator.nextFloat());
int b = (int)(255 * randomGenerator.nextFloat());
return 0xff000000 | (r << 16) | (g << 8) | b;
}
}
private int displace(int rgb, float amount) {
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = PixelUtils.clamp(r + (int)(amount * (randomGenerator.nextFloat()-0.5)));
g = PixelUtils.clamp(g + (int)(amount * (randomGenerator.nextFloat()-0.5)));
b = PixelUtils.clamp(b + (int)(amount * (randomGenerator.nextFloat()-0.5)));
return 0xff000000 | (r << 16) | (g << 8) | b;
}
private int average(int rgb1, int rgb2) {
return PixelUtils.combinePixels(rgb1, rgb2, PixelUtils.AVERAGE);
}
private int getPixel(int x, int y, int[] pixels, int stride) {
return pixels[y*stride+x];
}
private void putPixel(int x, int y, int rgb, int[] pixels, int stride) {
pixels[y*stride+x] = rgb;
}
private boolean doPixel(int x1, int y1, int x2, int y2, int[] pixels, int stride, int depth, int scale) {
int mx, my;
if (depth == 0) {
int ml, mr, mt, mb, mm, t;
int tl = getPixel(x1, y1, pixels, stride);
int bl = getPixel(x1, y2, pixels, stride);
int tr = getPixel(x2, y1, pixels, stride);
int br = getPixel(x2, y2, pixels, stride);
float amount = (256.0f / (2.0f * scale)) * turbulence;
mx = (x1 + x2) / 2;
my = (y1 + y2) / 2;
if (mx == x1 && mx == x2 && my == y1 && my == y2)
return true;
if (mx != x1 || mx != x2) {
ml = average(tl, bl);
ml = displace(ml, amount);
putPixel(x1, my, ml, pixels, stride);
if (x1 != x2){
mr = average(tr, br);
mr = displace(mr, amount);
putPixel(x2, my, mr, pixels, stride);
}
}
if (my != y1 || my != y2){
if (x1 != mx || my != y2){
mb = average(bl, br);
mb = displace(mb, amount);
putPixel(mx, y2, mb, pixels, stride);
}
if (y1 != y2){
mt = average(tl, tr);
mt = displace(mt, amount);
putPixel(mx, y1, mt, pixels, stride);
}
}
if (y1 != y2 || x1 != x2) {
mm = average(tl, br);
t = average(bl, tr);
mm = average(mm, t);
mm = displace(mm, amount);
putPixel(mx, my, mm, pixels, stride);
}
if (x2-x1 < 3 && y2-y1 < 3)
return false;
return true;
}
mx = (x1 + x2) / 2;
my = (y1 + y2) / 2;
doPixel(x1, y1, mx, my, pixels, stride, depth-1, scale+1);
doPixel(x1, my, mx ,y2, pixels, stride, depth-1, scale+1);
doPixel(mx, y1, x2 , my, pixels, stride, depth-1, scale+1);
return doPixel(mx, my, x2, y2, pixels, stride, depth-1, scale+1);
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
randomGenerator.setSeed(seed);
int w1 = width-1;
int h1 = height-1;
putPixel(0, 0, randomRGB(inPixels, 0, 0), outPixels, width);
putPixel(w1, 0, randomRGB(inPixels, w1, 0), outPixels, width);
putPixel(0, h1, randomRGB(inPixels, 0, h1), outPixels, width);
putPixel(w1, h1, randomRGB(inPixels, w1, h1), outPixels, width);
putPixel(w1/2, h1/2, randomRGB(inPixels, w1/2, h1/2), outPixels, width);
putPixel(0, h1/2, randomRGB(inPixels, 0, h1/2), outPixels, width);
putPixel(w1, h1/2, randomRGB(inPixels, w1, h1/2), outPixels, width);
putPixel(w1/2, 0, randomRGB(inPixels, w1/2, 0), outPixels, width);
putPixel(w1/2, h1, randomRGB(inPixels, w1/2, h1), outPixels, width);
int depth = 1;
while (doPixel(0, 0, width-1, height-1, outPixels, width, depth, 0))
depth++;
if (useColormap && colormap != null) {
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
outPixels[index] = colormap.getColor((outPixels[index] & 0xff)/255.0f);
index++;
}
}
}
return outPixels;
}
public String toString() {
return "Texture/Plasma...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ReduceNoiseFilter.java 0000644 0001750 0001750 00000005037 10562652111 027517 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which performs reduces noise by looking at each pixel's 8 neighbours, and if it's a minimum or maximum,
* replacing it by the next minimum or maximum of the neighbours.
*/
public class ReduceNoiseFilter extends WholeImageFilter {
public ReduceNoiseFilter() {
}
private int smooth(int[] v) {
int minindex = 0, maxindex = 0, min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int i = 0; i < 9; i++) {
if ( i != 4 ) {
if (v[i] < min) {
min = v[i];
minindex = i;
}
if (v[i] > max) {
max = v[i];
maxindex = i;
}
}
}
if ( v[4] < min )
return v[minindex];
if ( v[4] > max )
return v[maxindex];
return v[4];
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] r = new int[9];
int[] g = new int[9];
int[] b = new int[9];
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int k = 0;
int irgb = inPixels[index];
int ir = (irgb >> 16) & 0xff;
int ig = (irgb >> 8) & 0xff;
int ib = irgb & 0xff;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
if (0 <= iy && iy < height) {
int ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
r[k] = (rgb >> 16) & 0xff;
g[k] = (rgb >> 8) & 0xff;
b[k] = rgb & 0xff;
} else {
r[k] = ir;
g[k] = ig;
b[k] = ib;
}
k++;
}
} else {
for (int dx = -1; dx <= 1; dx++) {
r[k] = ir;
g[k] = ig;
b[k] = ib;
k++;
}
}
}
outPixels[index] = (inPixels[index] & 0xff000000) | (smooth(r) << 16) | (smooth(g) << 8) | smooth(b);
index++;
}
}
return outPixels;
}
public String toString() {
return "Blur/Smooth";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Curve.java 0000755 0001750 0001750 00000004062 10626011515 025226 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class Curve {
public float[] x;
public float[] y;
public Curve() {
x = new float[] { 0, 1 };
y = new float[] { 0, 1 };
}
public Curve( Curve curve ) {
x = (float[])curve.x.clone();
y = (float[])curve.y.clone();
}
public int addKnot( float kx, float ky ) {
int pos = -1;
int numKnots = x.length;
float[] nx = new float[numKnots+1];
float[] ny = new float[numKnots+1];
int j = 0;
for ( int i = 0; i < numKnots; i++ ) {
if ( pos == -1 && x[i] > kx ) {
pos = j;
nx[j] = kx;
ny[j] = ky;
j++;
}
nx[j] = x[i];
ny[j] = y[i];
j++;
}
if ( pos == -1 ) {
pos = j;
nx[j] = kx;
ny[j] = ky;
}
x = nx;
y = ny;
return pos;
}
public void removeKnot( int n ) {
int numKnots = x.length;
if ( numKnots <= 2 )
return;
float[] nx = new float[numKnots-1];
float[] ny = new float[numKnots-1];
int j = 0;
for ( int i = 0; i < numKnots-1; i++ ) {
if ( i == n )
j++;
nx[i] = x[j];
ny[i] = y[j];
j++;
}
x = nx;
y = ny;
}
private void sortKnots() {
int numKnots = x.length;
for (int i = 1; i < numKnots-1; i++) {
for (int j = 1; j < i; j++) {
if (x[i] < x[j]) {
float t = x[i];
x[i] = x[j];
x[j] = t;
t = y[i];
y[i] = y[j];
y[j] = t;
}
}
}
}
protected int[] makeTable() {
int numKnots = x.length;
float[] nx = new float[numKnots+2];
float[] ny = new float[numKnots+2];
System.arraycopy( x, 0, nx, 1, numKnots);
System.arraycopy( y, 0, ny, 1, numKnots);
nx[0] = nx[1];
ny[0] = ny[1];
nx[numKnots+1] = nx[numKnots];
ny[numKnots+1] = ny[numKnots];
int[] table = new int[256];
for (int i = 0; i < 1024; i++) {
float f = i/1024.0f;
int x = (int)(255 * ImageMath.spline( f, nx.length, nx ) + 0.5f);
int y = (int)(255 * ImageMath.spline( f, nx.length, ny ) + 0.5f);
x = ImageMath.clamp( x, 0, 255 );
y = ImageMath.clamp( y, 0, 255 );
table[x] = y;
}
return table;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DisplaceFilter.java 0000644 0001750 0001750 00000006664 10566356614 027062 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* A filter which simulates the appearance of looking through glass. A separate grayscale displacement image is provided and
* pixels in the source image are displaced according to the gradient of the displacement map.
*/
public class DisplaceFilter extends TransformFilter {
private float amount = 1;
private BufferedImage displacementMap = null;
private int[] xmap, ymap;
private int dw, dh;
public DisplaceFilter() {
}
/**
* Set the displacement map.
* @param displacementMap an image representing the displacment at each point
* @see #getDisplacementMap
*/
public void setDisplacementMap(BufferedImage displacementMap) {
this.displacementMap = displacementMap;
}
/**
* Get the displacement map.
* @return an image representing the displacment at each point
* @see #setDisplacementMap
*/
public BufferedImage getDisplacementMap() {
return displacementMap;
}
/**
* Set the amount of distortion.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of distortion.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int w = src.getWidth();
int h = src.getHeight();
BufferedImage dm = displacementMap != null ? displacementMap : src;
dw = dm.getWidth();
dh = dm.getHeight();
int[] mapPixels = new int[dw*dh];
getRGB( dm, 0, 0, dw, dh, mapPixels );
xmap = new int[dw*dh];
ymap = new int[dw*dh];
int i = 0;
for ( int y = 0; y < dh; y++ ) {
for ( int x = 0; x < dw; x++ ) {
int rgb = mapPixels[i];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
mapPixels[i] = (r+g+b) / 8; // An arbitrary scaling factor which gives a good range for "amount"
i++;
}
}
i = 0;
for ( int y = 0; y < dh; y++ ) {
int j1 = ((y+dh-1) % dh) * dw;
int j2 = y*dw;
int j3 = ((y+1) % dh) * dw;
for ( int x = 0; x < dw; x++ ) {
int k1 = (x+dw-1) % dw;
int k2 = x;
int k3 = (x+1) % dw;
xmap[i] = mapPixels[k1+j1] + mapPixels[k1+j2] + mapPixels[k1+j3] - mapPixels[k3+j1] - mapPixels[k3+j2] - mapPixels[k3+j3];
ymap[i] = mapPixels[k1+j3] + mapPixels[k2+j3] + mapPixels[k3+j3] - mapPixels[k1+j1] - mapPixels[k2+j1] - mapPixels[k3+j1];
i++;
}
}
mapPixels = null;
dst = super.filter( src, dst );
xmap = ymap = null;
return dst;
}
protected void transformInverse(int x, int y, float[] out) {
float xDisplacement, yDisplacement;
float nx = x;
float ny = y;
int i = (y % dh)*dw + x % dw;
out[0] = x + amount * xmap[i];
out[1] = y + amount * ymap[i];
}
public String toString() {
return "Distort/Displace...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/VariableBlurFilter.java 0000644 0001750 0001750 00000017451 10606647276 027706 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
/**
* A filter which performs a box blur with a different blur radius at each pixel. The radius can either be specified by
* providing a blur mask image or by overriding the blurRadiusAt method.
*/
public class VariableBlurFilter extends AbstractBufferedImageOp {
private int hRadius = 1;
private int vRadius = 1;
private int iterations = 1;
private BufferedImage blurMask;
private boolean premultiplyAlpha = true;
/**
* Set whether to premultiply the alpha channel.
* @param premultiplyAlpha true to premultiply the alpha
* @see #getPremultiplyAlpha
*/
public void setPremultiplyAlpha( boolean premultiplyAlpha ) {
this.premultiplyAlpha = premultiplyAlpha;
}
/**
* Get whether to premultiply the alpha channel.
* @return true to premultiply the alpha
* @see #setPremultiplyAlpha
*/
public boolean getPremultiplyAlpha() {
return premultiplyAlpha;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
getRGB( src, 0, 0, width, height, inPixels );
if ( premultiplyAlpha )
ImageMath.premultiply( inPixels, 0, inPixels.length );
for (int i = 0; i < iterations; i++ ) {
blur( inPixels, outPixels, width, height, hRadius, 1 );
blur( outPixels, inPixels, height, width, vRadius, 2 );
}
if ( premultiplyAlpha )
ImageMath.unpremultiply( inPixels, 0, inPixels.length );
setRGB( dst, 0, 0, width, height, inPixels );
return dst;
}
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
if ( dstCM == null )
dstCM = src.getColorModel();
return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
}
public Rectangle2D getBounds2D( BufferedImage src ) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
if ( dstPt == null )
dstPt = new Point2D.Double();
dstPt.setLocation( srcPt.getX(), srcPt.getY() );
return dstPt;
}
public RenderingHints getRenderingHints() {
return null;
}
public void blur( int[] in, int[] out, int width, int height, int radius, int pass ) {
int widthMinus1 = width-1;
int[] r = new int[width];
int[] g = new int[width];
int[] b = new int[width];
int[] a = new int[width];
int[] mask = new int[width];
int inIndex = 0;
for ( int y = 0; y < height; y++ ) {
int outIndex = y;
if ( blurMask != null ) {
if ( pass == 1 )
getRGB( blurMask, 0, y, width, 1, mask );
else
getRGB( blurMask, y, 0, 1, width, mask );
}
for ( int x = 0; x < width; x++ ) {
int argb = in[inIndex+x];
a[x] = (argb >> 24) & 0xff;
r[x] = (argb >> 16) & 0xff;
g[x] = (argb >> 8) & 0xff;
b[x] = argb & 0xff;
if ( x != 0 ) {
a[x] += a[x-1];
r[x] += r[x-1];
g[x] += g[x-1];
b[x] += b[x-1];
}
}
for ( int x = 0; x < width; x++ ) {
// Get the blur radius at x, y
int ra;
if ( blurMask != null ) {
if ( pass == 1 )
ra = (int)((mask[x] & 0xff)*hRadius/255f);
else
ra = (int)((mask[x] & 0xff)*vRadius/255f);
} else {
if ( pass == 1 )
ra = (int)(blurRadiusAt( x, y, width, height ) * hRadius);
else
ra = (int)(blurRadiusAt( y, x, height, width ) * vRadius);
}
int divisor = 2*ra+1;
int ta = 0, tr = 0, tg = 0, tb = 0;
int i1 = x+ra;
if ( i1 > widthMinus1 ) {
int f = i1-widthMinus1;
int l = widthMinus1;
ta += (a[l]-a[l-1]) * f;
tr += (r[l]-r[l-1]) * f;
tg += (g[l]-g[l-1]) * f;
tb += (b[l]-b[l-1]) * f;
i1 = widthMinus1;
}
int i2 = x-ra-1;
if ( i2 < 0 ) {
ta -= a[0] * i2;
tr -= r[0] * i2;
tg -= g[0] * i2;
tb -= b[0] * i2;
i2 = 0;
}
ta += a[i1] - a[i2];
tr += r[i1] - r[i2];
tg += g[i1] - g[i2];
tb += b[i1] - b[i2];
out[ outIndex ] = ((ta/divisor) << 24) | ((tr/divisor) << 16) | ((tg/divisor) << 8) | (tb/divisor);
outIndex += height;
}
inIndex += width;
}
}
/**
* Override this to get a different blur radius at eahc point.
* @param x the x coordinate
* @param y the y coordinate
* @param width the width of the image
* @param height the height of the image
* @return the blur radius
*/
protected float blurRadiusAt( int x, int y, int width, int height ) {
return (float)x/width;
}
/**
* Set the horizontal size of the blur.
* @param hRadius the radius of the blur in the horizontal direction
* @min-value 0
* @see #getHRadius
*/
public void setHRadius(int hRadius) {
this.hRadius = hRadius;
}
/**
* Get the horizontal size of the blur.
* @return the radius of the blur in the horizontal direction
* @see #setHRadius
*/
public int getHRadius() {
return hRadius;
}
/**
* Set the vertical size of the blur.
* @param vRadius the radius of the blur in the vertical direction
* @min-value 0
* @see #getVRadius
*/
public void setVRadius(int vRadius) {
this.vRadius = vRadius;
}
/**
* Get the vertical size of the blur.
* @return the radius of the blur in the vertical direction
* @see #setVRadius
*/
public int getVRadius() {
return vRadius;
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(int radius) {
this.hRadius = this.vRadius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public int getRadius() {
return hRadius;
}
/**
* Set the number of iterations the blur is performed.
* @param iterations the number of iterations
* @min-value 0
* @see #getIterations
*/
public void setIterations(int iterations) {
this.iterations = iterations;
}
/**
* Get the number of iterations the blur is performed.
* @return the number of iterations
* @see #setIterations
*/
public int getIterations() {
return iterations;
}
/**
* Set the mask used to give the amount of blur at each point.
* @param blurMask the mask
* @see #getBlurMask
*/
public void setBlurMask(BufferedImage blurMask) {
this.blurMask = blurMask;
}
/**
* Get the mask used to give the amount of blur at each point.
* @return the mask
* @see #setBlurMask
*/
public BufferedImage getBlurMask() {
return blurMask;
}
public String toString() {
return "Blur/Variable Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ContrastFilter.java 0000644 0001750 0001750 00000003573 10566356614 027127 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter to change the brightness and contrast of an image.
*/
public class ContrastFilter extends TransferFilter {
private float brightness = 1.0f;
private float contrast = 1.0f;
protected float transferFunction( float f ) {
f = f*brightness;
f = (f-0.5f)*contrast+0.5f;
return f;
}
/**
* Set the filter brightness.
* @param brightness the brightness in the range 0 to 1
* @min-value 0
* @max-value 0
* @see #getBrightness
*/
public void setBrightness(float brightness) {
this.brightness = brightness;
initialized = false;
}
/**
* Get the filter brightness.
* @return the brightness in the range 0 to 1
* @see #setBrightness
*/
public float getBrightness() {
return brightness;
}
/**
* Set the filter contrast.
* @param contrast the contrast in the range 0 to 1
* @min-value 0
* @max-value 0
* @see #getContrast
*/
public void setContrast(float contrast) {
this.contrast = contrast;
initialized = false;
}
/**
* Get the filter contrast.
* @return the contrast in the range 0 to 1
* @see #setContrast
*/
public float getContrast() {
return contrast;
}
public String toString() {
return "Colors/Contrast...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ArrayColormap.java 0000644 0001750 0001750 00000007711 10566356614 026735 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* A colormap implemented with an array of colors. This corresponds to the IndexColorModel class.
*/
public class ArrayColormap implements Colormap, Cloneable {
/**
* The array of colors.
*/
protected int[] map;
/**
* Construct an all-black colormap.
*/
public ArrayColormap() {
this.map = new int[256];
}
/**
* Construct a colormap with the given map.
* @param map the array of ARGB colors
*/
public ArrayColormap(int[] map) {
this.map = map;
}
public Object clone() {
try {
ArrayColormap g = (ArrayColormap)super.clone();
g.map = (int[])map.clone();
return g;
}
catch (CloneNotSupportedException e) {
}
return null;
}
/**
* Set the array of colors for the colormap.
* @param map the colors
* @see #getMap
*/
public void setMap(int[] map) {
this.map = map;
}
/**
* Get the array of colors for the colormap.
* @return the colors
* @see #setMap
*/
public int[] getMap() {
return map;
}
/**
* Convert a value in the range 0..1 to an RGB color.
* @param v a value in the range 0..1
* @return an RGB color
* @see #setColor
*/
public int getColor(float v) {
/*
v *= 255;
int n = (int)v;
float f = v-n;
if (n < 0)
return map[0];
else if (n >= 255)
return map[255];
return ImageMath.mixColors(f, map[n], map[n+1]);
*/
int n = (int)(v*255);
if (n < 0)
n = 0;
else if (n > 255)
n = 255;
return map[n];
}
/**
* Set the color at "index" to "color". Entries are interpolated linearly from
* the existing entries at "firstIndex" and "lastIndex" to the new entry.
* firstIndex < index < lastIndex must hold.
* @param index the position to set
* @param firstIndex the position of the first color from which to interpolate
* @param lastIndex the position of the second color from which to interpolate
* @param color the color to set
*/
public void setColorInterpolated(int index, int firstIndex, int lastIndex, int color) {
int firstColor = map[firstIndex];
int lastColor = map[lastIndex];
for (int i = firstIndex; i <= index; i++)
map[i] = ImageMath.mixColors((float)(i-firstIndex)/(index-firstIndex), firstColor, color);
for (int i = index; i < lastIndex; i++)
map[i] = ImageMath.mixColors((float)(i-index)/(lastIndex-index), color, lastColor);
}
/**
* Set a range of the colormap, interpolating between two colors.
* @param firstIndex the position of the first color
* @param lastIndex the position of the second color
* @param color1 the first color
* @param color2 the second color
*/
public void setColorRange(int firstIndex, int lastIndex, int color1, int color2) {
for (int i = firstIndex; i <= lastIndex; i++)
map[i] = ImageMath.mixColors((float)(i-firstIndex)/(lastIndex-firstIndex), color1, color2);
}
/**
* Set a range of the colormap to a single color.
* @param firstIndex the position of the first color
* @param lastIndex the position of the second color
* @param color the color
*/
public void setColorRange(int firstIndex, int lastIndex, int color) {
for (int i = firstIndex; i <= lastIndex; i++)
map[i] = color;
}
/**
* Set one element of the colormap to a given color.
* @param index the position of the color
* @param color the color
* @see #getColor
*/
public void setColor(int index, int color) {
map[index] = color;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/QuantizeFilter.java 0000644 0001750 0001750 00000011415 10562652111 027107 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which quantizes an image to a set number of colors - useful for producing
* images which are to be encoded using an index color model. The filter can perform
* Floyd-Steinberg error-diffusion dithering if required. At present, the quantization
* is done using an octtree algorithm but I eventually hope to add more quantization
* methods such as median cut. Note: at present, the filter produces an image which
* uses the RGB color model (because the application it was written for required it).
* I hope to extend it to produce an IndexColorModel by request.
*/
public class QuantizeFilter extends WholeImageFilter {
/**
* Floyd-Steinberg dithering matrix.
*/
protected final static int[] matrix = {
0, 0, 0,
0, 0, 7,
3, 5, 1,
};
private int sum = 3+5+7+1;
private boolean dither;
private int numColors = 256;
private boolean serpentine = true;
/**
* Set the number of colors to quantize to.
* @param numColors the number of colors. The default is 256.
*/
public void setNumColors(int numColors) {
this.numColors = Math.min(Math.max(numColors, 8), 256);
}
/**
* Get the number of colors to quantize to.
* @return the number of colors.
*/
public int getNumColors() {
return numColors;
}
/**
* Set whether to use dithering or not. If not, the image is posterized.
* @param dither true to use dithering
*/
public void setDither(boolean dither) {
this.dither = dither;
}
/**
* Return the dithering setting
* @return the current setting
*/
public boolean getDither() {
return dither;
}
/**
* Set whether to use a serpentine pattern for return or not. This can reduce 'avalanche' artifacts in the output.
* @param serpentine true to use serpentine pattern
*/
public void setSerpentine(boolean serpentine) {
this.serpentine = serpentine;
}
/**
* Return the serpentine setting
* @return the current setting
*/
public boolean getSerpentine() {
return serpentine;
}
public void quantize(int[] inPixels, int[] outPixels, int width, int height, int numColors, boolean dither, boolean serpentine) {
int count = width*height;
Quantizer quantizer = new OctTreeQuantizer();
quantizer.setup(numColors);
quantizer.addPixels(inPixels, 0, count);
int[] table = quantizer.buildColorTable();
if (!dither) {
for (int i = 0; i < count; i++)
outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])];
} else {
int index = 0;
for (int y = 0; y < height; y++) {
boolean reverse = serpentine && (y & 1) == 1;
int direction;
if (reverse) {
index = y*width+width-1;
direction = -1;
} else {
index = y*width;
direction = 1;
}
for (int x = 0; x < width; x++) {
int rgb1 = inPixels[index];
int rgb2 = table[quantizer.getIndexForColor(rgb1)];
outPixels[index] = rgb2;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
int er = r1-r2;
int eg = g1-g2;
int eb = b1-b2;
for (int i = -1; i <= 1; i++) {
int iy = i+y;
if (0 <= iy && iy < height) {
for (int j = -1; j <= 1; j++) {
int jx = j+x;
if (0 <= jx && jx < width) {
int w;
if (reverse)
w = matrix[(i+1)*3-j+1];
else
w = matrix[(i+1)*3+j+1];
if (w != 0) {
int k = reverse ? index - j : index + j;
rgb1 = inPixels[k];
r1 = (rgb1 >> 16) & 0xff;
g1 = (rgb1 >> 8) & 0xff;
b1 = rgb1 & 0xff;
r1 += er * w/sum;
g1 += eg * w/sum;
b1 += eb * w/sum;
inPixels[k] = (PixelUtils.clamp(r1) << 16) | (PixelUtils.clamp(g1) << 8) | PixelUtils.clamp(b1);
}
}
}
}
}
index += direction;
}
}
}
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width*height];
quantize(inPixels, outPixels, width, height, numColors, dither, serpentine);
return outPixels;
}
public String toString() {
return "Colors/Quantize...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/OpacityFilter.java 0000644 0001750 0001750 00000003206 10566356614 026733 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* Sets the opacity (alpha) of every pixel in an image to a constant value.
*/
public class OpacityFilter extends PointFilter {
private int opacity;
private int opacity24;
/**
* Construct an OpacityFilter with 50% opacity.
*/
public OpacityFilter() {
this(0x88);
}
/**
* Construct an OpacityFilter with the given opacity (alpha).
* @param opacity the opacity (alpha) in the range 0..255
*/
public OpacityFilter(int opacity) {
setOpacity(opacity);
}
/**
* Set the opacity.
* @param opacity the opacity (alpha) in the range 0..255
* @see #getOpacity
*/
public void setOpacity(int opacity) {
this.opacity = opacity;
opacity24 = opacity << 24;
}
/**
* Get the opacity setting.
* @return the opacity
* @see #setOpacity
*/
public int getOpacity() {
return opacity;
}
public int filterRGB(int x, int y, int rgb) {
if ((rgb & 0xff000000) != 0)
return (rgb & 0xffffff) | opacity24;
return rgb;
}
public String toString() {
return "Colors/Transparency...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/StampFilter.java 0000644 0001750 0001750 00000007170 10566572034 026407 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which produces a rubber-stamp type of effect by performing a thresholded blur.
*/
public class StampFilter extends PointFilter {
private float threshold;
private float softness = 0;
private float radius = 5;
private float lowerThreshold3;
private float upperThreshold3;
private int white = 0xffffffff;
private int black = 0xff000000;
/**
* Construct a StampFilter.
*/
public StampFilter() {
this(0.5f);
}
/**
* Construct a StampFilter.
* @param threshold the threshold value
*/
public StampFilter( float threshold ) {
setThreshold( threshold );
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
/**
* Set the threshold value.
* @param threshold the threshold value
* @see #getThreshold
*/
public void setThreshold(float threshold) {
this.threshold = threshold;
}
/**
* Get the threshold value.
* @return the threshold value
* @see #setThreshold
*/
public float getThreshold() {
return threshold;
}
/**
* Set the softness of the effect in the range 0..1.
* @param softness the softness
* @min-value 0
* @max-value 1
* @see #getSoftness
*/
public void setSoftness(float softness) {
this.softness = softness;
}
/**
* Get the softness of the effect.
* @return the softness
* @see #setSoftness
*/
public float getSoftness() {
return softness;
}
/**
* Set the color to be used for pixels above the upper threshold.
* @param white the color
* @see #getWhite
*/
public void setWhite(int white) {
this.white = white;
}
/**
* Get the color to be used for pixels above the upper threshold.
* @return the color
* @see #setWhite
*/
public int getWhite() {
return white;
}
/**
* Set the color to be used for pixels below the lower threshold.
* @param black the color
* @see #getBlack
*/
public void setBlack(int black) {
this.black = black;
}
/**
* Set the color to be used for pixels below the lower threshold.
* @return the color
* @see #setBlack
*/
public int getBlack() {
return black;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
dst = new GaussianFilter( (int)radius ).filter( src, null );
lowerThreshold3 = 255*3*(threshold - softness*0.5f);
upperThreshold3 = 255*3*(threshold + softness*0.5f);
return super.filter(dst, dst);
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int l = r + g + b;
float f = ImageMath.smoothStep(lowerThreshold3, upperThreshold3, l);
return ImageMath.mixColors(f, black, white);
}
public String toString() {
return "Stylize/Stamp...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FBMFilter.java 0000644 0001750 0001750 00000013640 10566356614 025732 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.util.*;
import com.jhlabs.math.*;
/**
* A filter which produces textures from fractal Brownian motion.
*/
public class FBMFilter extends PointFilter implements Cloneable {
public final static int NOISE = 0;
public final static int RIDGED = 1;
public final static int VLNOISE = 2;
public final static int SCNOISE = 3;
public final static int CELLULAR = 4;
private float scale = 32;
private float stretch = 1.0f;
private float angle = 0.0f;
private float amount = 1.0f;
private float H = 1.0f;
private float octaves = 4.0f;
private float lacunarity = 2.0f;
private float gain = 0.5f;
private float bias = 0.5f;
private int operation;
private float m00 = 1.0f;
private float m01 = 0.0f;
private float m10 = 0.0f;
private float m11 = 1.0f;
private float min;
private float max;
private Colormap colormap = new Gradient();
private boolean ridged;
private FBM fBm;
protected Random random = new Random();
private int basisType = NOISE;
private Function2D basis;
public FBMFilter() {
setBasisType(NOISE);
}
/**
* Set the amount of effect.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of texture.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public void setOperation(int operation) {
this.operation = operation;
}
public int getOperation() {
return operation;
}
/**
* Specifies the scale of the texture.
* @param scale the scale of the texture.
* @min-value 1
* @max-value 300+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the texture.
* @return the scale of the texture.
* @see #setScale
*/
public float getScale() {
return scale;
}
/**
* Specifies the stretch factor of the texture.
* @param stretch the stretch factor of the texture.
* @min-value 1
* @max-value 50+
* @see #getStretch
*/
public void setStretch(float stretch) {
this.stretch = stretch;
}
/**
* Returns the stretch factor of the texture.
* @return the stretch factor of the texture.
* @see #setStretch
*/
public float getStretch() {
return stretch;
}
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(this.angle);
float sin = (float)Math.sin(this.angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
public void setOctaves(float octaves) {
this.octaves = octaves;
}
public float getOctaves() {
return octaves;
}
public void setH(float H) {
this.H = H;
}
public float getH() {
return H;
}
public void setLacunarity(float lacunarity) {
this.lacunarity = lacunarity;
}
public float getLacunarity() {
return lacunarity;
}
public void setGain(float gain) {
this.gain = gain;
}
public float getGain() {
return gain;
}
public void setBias(float bias) {
this.bias = bias;
}
public float getBias() {
return bias;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public void setBasisType(int basisType) {
this.basisType = basisType;
switch (basisType) {
default:
case NOISE:
basis = new Noise();
break;
case RIDGED:
basis = new RidgedFBM();
break;
case VLNOISE:
basis = new VLNoise();
break;
case SCNOISE:
basis = new SCNoise();
break;
case CELLULAR:
basis = new CellularFunction2D();
break;
}
}
public int getBasisType() {
return basisType;
}
public void setBasis(Function2D basis) {
this.basis = basis;
}
public Function2D getBasis() {
return basis;
}
protected FBM makeFBM(float H, float lacunarity, float octaves) {
FBM fbm = new FBM(H, lacunarity, octaves, basis);
float[] minmax = Noise.findRange(fbm, null);
min = minmax[0];
max = minmax[1];
return fbm;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
fBm = makeFBM(H, lacunarity, octaves);
return super.filter( src, dst );
}
public int filterRGB(int x, int y, int rgb) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
float f = fBm.evaluate(nx, ny);
// Normalize to 0..1
f = (f-min)/(max-min);
f = ImageMath.gain(f, gain);
f = ImageMath.bias(f, bias);
f *= amount;
int a = rgb & 0xff000000;
int v;
if (colormap != null)
v = colormap.getColor(f);
else {
v = PixelUtils.clamp((int)(f*255));
int r = v << 16;
int g = v << 8;
int b = v;
v = a|r|g|b;
}
if (operation != PixelUtils.REPLACE)
v = PixelUtils.combinePixels(rgb, v, operation);
return v;
}
public String toString() {
return "Texture/Fractal Brownian Motion...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GrayFilter.java 0000644 0001750 0001750 00000002163 10562652111 026211 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which 'grays out' an image by averaging each pixel with white.
*/
public class GrayFilter extends PointFilter {
public GrayFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = (r+255)/2;
g = (g+255)/2;
b = (b+255)/2;
return a | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Colors/Gray Out";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/NoiseFilter.java 0000644 0001750 0001750 00000006543 10566572034 026403 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.util.*;
/**
* A filter which adds random noise into an image.
*/
public class NoiseFilter extends PointFilter {
/**
* Gaussian distribution for the noise.
*/
public final static int GAUSSIAN = 0;
/**
* Uniform distribution for the noise.
*/
public final static int UNIFORM = 1;
private int amount = 25;
private int distribution = UNIFORM;
private boolean monochrome = false;
private float density = 1;
private Random randomNumbers = new Random();
public NoiseFilter() {
}
/**
* Set the amount of effect.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(int amount) {
this.amount = amount;
}
/**
* Get the amount of noise.
* @return the amount
* @see #setAmount
*/
public int getAmount() {
return amount;
}
/**
* Set the distribution of the noise.
* @param distribution the distribution
* @see #getDistribution
*/
public void setDistribution( int distribution ) {
this.distribution = distribution;
}
/**
* Get the distribution of the noise.
* @return the distribution
* @see #setDistribution
*/
public int getDistribution() {
return distribution;
}
/**
* Set whether to use monochrome noise.
* @param monochrome true for monochrome noise
* @see #getMonochrome
*/
public void setMonochrome(boolean monochrome) {
this.monochrome = monochrome;
}
/**
* Get whether to use monochrome noise.
* @return true for monochrome noise
* @see #setMonochrome
*/
public boolean getMonochrome() {
return monochrome;
}
/**
* Set the density of the noise.
* @param density the density
* @see #getDensity
*/
public void setDensity( float density ) {
this.density = density;
}
/**
* Get the density of the noise.
* @return the density
* @see #setDensity
*/
public float getDensity() {
return density;
}
private int random(int x) {
x += (int)(((distribution == GAUSSIAN ? randomNumbers.nextGaussian() : 2*randomNumbers.nextFloat() - 1)) * amount);
if (x < 0)
x = 0;
else if (x > 0xff)
x = 0xff;
return x;
}
public int filterRGB(int x, int y, int rgb) {
if ( randomNumbers.nextFloat() <= density ) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if (monochrome) {
int n = (int)(((distribution == GAUSSIAN ? randomNumbers.nextGaussian() : 2*randomNumbers.nextFloat() - 1)) * amount);
r = PixelUtils.clamp(r+n);
g = PixelUtils.clamp(g+n);
b = PixelUtils.clamp(b+n);
} else {
r = random(r);
g = random(g);
b = random(b);
}
return a | (r << 16) | (g << 8) | b;
}
return rgb;
}
public String toString() {
return "Stylize/Add Noise...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CircleFilter.java 0000644 0001750 0001750 00000010661 10566356614 026527 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which wraps an image around a circular arc.
*/
public class CircleFilter extends TransformFilter {
private float radius = 10;
private float height = 20;
private float angle = 0;
private float spreadAngle = (float)Math.PI;
private float centreX = 0.5f;
private float centreY = 0.5f;
private float icentreX;
private float icentreY;
private float iWidth;
private float iHeight;
/**
* Construct a CircleFilter.
*/
public CircleFilter() {
setEdgeAction( ZERO );
}
/**
* Set the height of the arc.
* @param height the height
* @see #getHeight
*/
public void setHeight(float height) {
this.height = height;
}
/**
* Get the height of the arc.
* @return the height
* @see #setHeight
*/
public float getHeight() {
return height;
}
/**
* Set the angle of the arc.
* @param angle the angle of the arc.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
}
/**
* Returns the angle of the arc.
* @return the angle of the arc.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the spread angle of the arc.
* @param spreadAngle the angle
* @angle
* @see #getSpreadAngle
*/
public void setSpreadAngle(float spreadAngle) {
this.spreadAngle = spreadAngle;
}
/**
* Get the spread angle of the arc.
* @return the angle
* @angle
* @see #setSpreadAngle
*/
public float getSpreadAngle() {
return spreadAngle;
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
iWidth = src.getWidth();
iHeight = src.getHeight();
icentreX = iWidth * centreX;
icentreY = iHeight * centreY;
iWidth--;
return super.filter( src, dst );
}
protected void transformInverse(int x, int y, float[] out) {
float dx = x-icentreX;
float dy = y-icentreY;
float theta = (float)Math.atan2( -dy, -dx ) + angle;
float r = (float)Math.sqrt( dx*dx + dy*dy );
theta = ImageMath.mod( theta, 2*(float)Math.PI );
out[0] = iWidth * theta/(spreadAngle+0.00001f);
out[1] = iHeight * (1-(r-radius)/(height+0.00001f));
}
public String toString() {
return "Distort/Circle...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GlintFilter.java 0000644 0001750 0001750 00000017361 11331367037 026377 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import com.jhlabs.composite.*;
/**
* A filter which renders "glints" on bright parts of the image.
*/
public class GlintFilter extends AbstractBufferedImageOp {
private float threshold = 1.0f;
private int length = 5;
private float blur = 0.0f;
private float amount = 0.1f;
private boolean glintOnly = false;
private Colormap colormap = new LinearColormap( 0xffffffff, 0xff000000 );
private float coverage = 1.0f; // probability in percentage
public GlintFilter() {
}
public float getCoverage() {
return coverage;
}
public void setCoverage(float coverage) {
this.coverage = coverage;
}
/**
* Set the threshold value.
* @param threshold the threshold value
* @see #getThreshold
*/
public void setThreshold( float threshold ) {
this.threshold = threshold;
}
/**
* Get the threshold value.
* @return the threshold value
* @see #setThreshold
*/
public float getThreshold() {
return threshold;
}
/**
* Set the amount of glint.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount( float amount ) {
this.amount = amount;
}
/**
* Get the amount of glint.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
/**
* Set the length of the stars.
* @param length the length
* @see #getLength
*/
public void setLength( int length ) {
this.length = length;
}
/**
* Get the length of the stars.
* @return the length
* @see #setLength
*/
public int getLength() {
return length;
}
/**
* Set the blur that is applied before thresholding.
* @param blur the blur radius
* @see #getBlur
*/
public void setBlur(float blur) {
this.blur = blur;
}
/**
* Set the blur that is applied before thresholding.
* @return the blur radius
* @see #setBlur
*/
public float getBlur() {
return blur;
}
/**
* Set whether to render the stars and the image or only the stars.
* @param glintOnly true to render only stars
* @see #getGlintOnly
*/
public void setGlintOnly(boolean glintOnly) {
this.glintOnly = glintOnly;
}
/**
* Get whether to render the stars and the image or only the stars.
* @return true to render only stars
* @see #setGlintOnly
*/
public boolean getGlintOnly() {
return glintOnly;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int[] pixels = new int[width];
int length2 = (int)(length / 1.414f);
int[] colors = new int[length+1];
int[] colors2 = new int[length2+1];
if ( colormap != null ) {
for (int i = 0; i <= length; i++) {
int argb = colormap.getColor( (float)i/length );
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = argb & 0xff;
argb = (argb & 0xff000000) | ((int)(amount*r) << 16) | ((int)(amount*g) << 8) | (int)(amount*b);
colors[i] = argb;
}
for (int i = 0; i <= length2; i++) {
int argb = colormap.getColor( (float)i/length2 );
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = argb & 0xff;
argb = (argb & 0xff000000) | ((int)(amount*r) << 16) | ((int)(amount*g) << 8) | (int)(amount*b);
colors2[i] = argb;
}
}
BufferedImage mask = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int threshold3 = (int)(threshold*3*255);
for ( int y = 0; y < height; y++ ) {
getRGB( src, 0, y, width, 1, pixels );
for ( int x = 0; x < width; x++ ) {
int rgb = pixels[x];
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int l = r + g + b;
if (l < threshold3)
pixels[x] = 0xff000000;
else {
l /= 3;
pixels[x] = a | (l << 16) | (l << 8) | l;
}
}
setRGB( mask, 0, y, width, 1, pixels );
}
if ( blur != 0 )
mask = new GaussianFilter(blur).filter( mask, null );
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] dstPixels;
if ( glintOnly )
dstPixels = new int[width*height];
else
dstPixels = getRGB( src, 0, 0, width, height, null );//FIXME - only need 2*length
for ( int y = 0; y < height; y++ ) {
int index = y*width;
getRGB( mask, 0, y, width, 1, pixels );
int ymin = Math.max( y-length, 0 )-y;
int ymax = Math.min( y+length, height-1 )-y;
int ymin2 = Math.max( y-length2, 0 )-y;
int ymax2 = Math.min( y+length2, height-1 )-y;
for ( int x = 0; x < width; x++ ) {
boolean createGlint = (coverage > Math.random());
if (createGlint && (pixels[x] & 0xff) > threshold*255 ) {
int xmin = Math.max( x-length, 0 )-x;
int xmax = Math.min( x+length, width-1 )-x;
int xmin2 = Math.max( x-length2, 0 )-x;
int xmax2 = Math.min( x+length2, width-1 )-x;
// Horizontal
for ( int i = 0, k = 0; i <= xmax; i++, k++ )
dstPixels[index+i] = PixelUtils.combinePixels( dstPixels[index+i], colors[k], PixelUtils.ADD );
for ( int i = -1, k = 1; i >= xmin; i--, k++ )
dstPixels[index+i] = PixelUtils.combinePixels( dstPixels[index+i], colors[k], PixelUtils.ADD );
// Vertical
for ( int i = 1, j = index+width, k = 0; i <= ymax; i++, j += width, k++ )
dstPixels[j] = PixelUtils.combinePixels( dstPixels[j], colors[k], PixelUtils.ADD );
for ( int i = -1, j = index-width, k = 0; i >= ymin; i--, j -= width, k++ )
dstPixels[j] = PixelUtils.combinePixels( dstPixels[j], colors[k], PixelUtils.ADD );
// Diagonals
// int xymin = Math.max( xmin2, ymin2 );
// int xymax = Math.min( xmax2, ymax2 );
// SE
int count = Math.min( xmax2, ymax2 );
for ( int i = 1, j = index+width+1, k = 0; i <= count; i++, j += width+1, k++ )
dstPixels[j] = PixelUtils.combinePixels( dstPixels[j], colors2[k], PixelUtils.ADD );
// NW
count = Math.min( -xmin2, -ymin2 );
for ( int i = 1, j = index-width-1, k = 0; i <= count; i++, j -= width+1, k++ )
dstPixels[j] = PixelUtils.combinePixels( dstPixels[j], colors2[k], PixelUtils.ADD );
// NE
count = Math.min( xmax2, -ymin2 );
for ( int i = 1, j = index-width+1, k = 0; i <= count; i++, j += -width+1, k++ )
dstPixels[j] = PixelUtils.combinePixels( dstPixels[j], colors2[k], PixelUtils.ADD );
// SW
count = Math.min( -xmin2, ymax2 );
for ( int i = 1, j = index+width-1, k = 0; i <= count; i++, j += width-1, k++ )
dstPixels[j] = PixelUtils.combinePixels( dstPixels[j], colors2[k], PixelUtils.ADD );
}
index++;
}
}
setRGB( dst, 0, 0, width, height, dstPixels );
return dst;
}
public String toString() {
return "Effects/Glint...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Spectrum.java 0000644 0001750 0001750 00000004254 10566356614 025763 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* A class for calulating the colors of the spectrum.
*/
public class Spectrum {
private static int adjust(float color, float factor, float gamma) {
if (color == 0.0)
return 0;
return (int)Math.round(255 * Math.pow(color * factor, gamma));
}
/**
* Convert a wavelength to an RGB value.
* @param wavelength wavelength in nanometres
* @return the RGB value
*/
public static int wavelengthToRGB(float wavelength) {
float gamma = 0.80f;
float r, g, b, factor;
int w = (int)wavelength;
if (w < 380) {
r = 0.0f;
g = 0.0f;
b = 0.0f;
} else if (w < 440) {
r = -(wavelength - 440) / (440 - 380);
g = 0.0f;
b = 1.0f;
} else if (w < 490) {
r = 0.0f;
g = (wavelength - 440) / (490 - 440);
b = 1.0f;
} else if (w < 510) {
r = 0.0f;
g = 1.0f;
b = -(wavelength - 510) / (510 - 490);
} else if (w < 580) {
r = (wavelength - 510) / (580 - 510);
g = 1.0f;
b = 0.0f;
} else if (w < 645) {
r = 1.0f;
g = -(wavelength - 645) / (645 - 580);
b = 0.0f;
} else if (w <= 780) {
r = 1.0f;
g = 0.0f;
b = 0.0f;
} else {
r = 0.0f;
g = 0.0f;
b = 0.0f;
}
// Let the intensity fall off near the vision limits
if (380 <= w && w <= 419)
factor = 0.3f + 0.7f*(wavelength - 380) / (420 - 380);
else if (420 <= w && w <= 700)
factor = 1.0f;
else if (701 <= w && w <= 780)
factor = 0.3f + 0.7f*(780 - wavelength) / (780 - 700);
else
factor = 0.0f;
int ir = adjust(r, factor, gamma);
int ig = adjust(g, factor, gamma);
int ib = adjust(b, factor, gamma);
return 0xff000000 | (ir << 16) | (ig << 8) | ib;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/RenderTextFilter.java 0000644 0001750 0001750 00000007717 10566572034 027416 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which renders text onto an image.
*/
public class RenderTextFilter extends AbstractBufferedImageOp {
private String text;
private Font font;
private Paint paint;
private Composite composite;
private AffineTransform transform;
/**
* Construct a RenderTextFilter.
*/
public RenderTextFilter() {
}
/**
* Construct a RenderTextFilter.
* @param text the text
* @param font the font to use (may be null)
* @param paint the paint (may be null)
* @param composite the composite (may be null)
* @param transform the transform (may be null)
*/
public RenderTextFilter( String text, Font font, Paint paint, Composite composite, AffineTransform transform ) {
this.text = text;
this.font = font;
this.composite = composite;
this.paint = paint;
this.transform = transform;
}
/**
* Set the text to paint.
* @param text the text
* @see #getText
*/
public void setText( String text ) {
this.text = text;
}
/**
* Get the text to paint.
* @return the text
* @see #setText
*/
public String getText() {
return text;
}
/**
* Set the composite with which to paint the text.
* @param composite the composite
* @see #getComposite
*/
public void setComposite( Composite composite ) {
this.composite = composite;
}
/**
* Get the composite with which to paint the text.
* @return the composite
* @see #setComposite
*/
public Composite getComposite() {
return composite;
}
/**
* Set the paint with which to paint the text.
* @param paint the paint
* @see #getPaint
*/
public void setPaint( Paint paint ) {
this.paint = paint;
}
/**
* Get the paint with which to paint the text.
* @return the paint
* @see #setPaint
*/
public Paint getPaint() {
return paint;
}
/**
* Set the font with which to paint the text.
* @param font the font
* @see #getFont
*/
public void setFont( Font font ) {
this.font = font;
}
/**
* Get the font with which to paint the text.
* @return the font
* @see #setFont
*/
public Font getFont() {
return font;
}
/**
* Set the transform with which to paint the text.
* @param transform the transform
* @see #getTransform
*/
public void setTransform( AffineTransform transform ) {
this.transform = transform;
}
/**
* Get the transform with which to paint the text.
* @return the transform
* @see #setTransform
*/
public AffineTransform getTransform() {
return transform;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
Graphics2D g = dst.createGraphics();
g.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
if ( font != null )
g.setFont( font );
if ( transform != null )
g.setTransform( transform );
if ( composite != null )
g.setComposite( composite );
if ( paint != null )
g.setPaint( paint );
if ( text != null )
g.drawString( text, 10, 100 );
g.dispose();
return dst;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/OutlineFilter.java 0000644 0001750 0001750 00000003454 10562652111 026732 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* Given a binary image, this filter converts it to its outline, replacing all interior pixels with the 'new' color.
*/
public class OutlineFilter extends BinaryFilter {
public OutlineFilter() {
newColor = 0xffffffff;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = inPixels[y*width+x];
if (blackFunction.isBlack(pixel)) {
int neighbours = 0;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (!(dy == 0 && dx == 0) && 0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
if (blackFunction.isBlack(rgb))
neighbours++;
} else
neighbours++;
}
}
}
if (neighbours == 9)
pixel = newColor;
}
outPixels[index++] = pixel;
}
}
return outPixels;
}
public String toString() {
return "Binary/Outline...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/AbstractBufferedImageOp.java 0000644 0001750 0001750 00000007257 11331366535 030631 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A convenience class which implements those methods of BufferedImageOp which are rarely changed.
*/
public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
if ( dstCM == null )
dstCM = src.getColorModel();
return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
}
public Rectangle2D getBounds2D( BufferedImage src ) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
if ( dstPt == null )
dstPt = new Point2D.Double();
dstPt.setLocation( srcPt.getX(), srcPt.getY() );
return dstPt;
}
public RenderingHints getRenderingHints() {
return null;
}
/**
* A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
* penalty of BufferedImage.getRGB unmanaging the image.
* @param image a BufferedImage object
* @param x the left edge of the pixel block
* @param y the right edge of the pixel block
* @param width the width of the pixel arry
* @param height the height of the pixel arry
* @param pixels the array to hold the returned pixels. May be null.
* @return the pixels
* @see #setRGB
*/
public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
int type = image.getType();
// if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB || type == BufferedImage.TYPE_INT_ARGB_PRE)
return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
return image.getRGB( x, y, width, height, pixels, 0, width );
}
/**
* A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
* penalty of BufferedImage.setRGB unmanaging the image.
* @param image a BufferedImage object
* @param x the left edge of the pixel block
* @param y the right edge of the pixel block
* @param width the width of the pixel arry
* @param height the height of the pixel arry
* @param pixels the array of pixels to set
* @see #getRGB
*/
public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
int type = image.getType();
// if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB || type == BufferedImage.TYPE_INT_ARGB_PRE )
image.getRaster().setDataElements( x, y, width, height, pixels );
else
image.setRGB( x, y, width, height, pixels, 0, width );
}
public Object clone() {
try {
return super.clone();
}
catch ( CloneNotSupportedException e ) {
return null;
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/RippleFilter.java 0000644 0001750 0001750 00000010344 11331370524 026542 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* A filter which distorts an image by rippling it in the X or Y directions.
* The amplitude and wavelength of rippling can be specified as well as whether
* pixels going off the edges are wrapped or not.
*/
public class RippleFilter extends TransformFilter {
/**
* Sine wave ripples.
*/
public final static int SINE = 0;
/**
* Sawtooth wave ripples.
*/
public final static int SAWTOOTH = 1;
/**
* Triangle wave ripples.
*/
public final static int TRIANGLE = 2;
/**
* Noise ripples.
*/
public final static int NOISE = 3;
private float xAmplitude, yAmplitude;
private float xWavelength, yWavelength;
private int waveType;
/**
* Construct a RippleFilter.
*/
public RippleFilter() {
xAmplitude = 5.0f;
yAmplitude = 0.0f;
xWavelength = yWavelength = 16.0f;
}
/**
* Set the amplitude of ripple in the X direction.
* @param xAmplitude the amplitude (in pixels).
* @see #getXAmplitude
*/
public void setXAmplitude(float xAmplitude) {
this.xAmplitude = xAmplitude;
}
/**
* Get the amplitude of ripple in the X direction.
* @return the amplitude (in pixels).
* @see #setXAmplitude
*/
public float getXAmplitude() {
return xAmplitude;
}
/**
* Set the wavelength of ripple in the X direction.
* @param xWavelength the wavelength (in pixels).
* @see #getXWavelength
*/
public void setXWavelength(float xWavelength) {
this.xWavelength = xWavelength;
}
/**
* Get the wavelength of ripple in the X direction.
* @return the wavelength (in pixels).
* @see #setXWavelength
*/
public float getXWavelength() {
return xWavelength;
}
/**
* Set the amplitude of ripple in the Y direction.
* @param yAmplitude the amplitude (in pixels).
* @see #getYAmplitude
*/
public void setYAmplitude(float yAmplitude) {
this.yAmplitude = yAmplitude;
}
/**
* Get the amplitude of ripple in the Y direction.
* @return the amplitude (in pixels).
* @see #setYAmplitude
*/
public float getYAmplitude() {
return yAmplitude;
}
/**
* Set the wavelength of ripple in the Y direction.
* @param yWavelength the wavelength (in pixels).
* @see #getYWavelength
*/
public void setYWavelength(float yWavelength) {
this.yWavelength = yWavelength;
}
/**
* Get the wavelength of ripple in the Y direction.
* @return the wavelength (in pixels).
* @see #setYWavelength
*/
public float getYWavelength() {
return yWavelength;
}
/**
* Set the wave type.
* @param waveType the type.
* @see #getWaveType
*/
public void setWaveType(int waveType) {
this.waveType = waveType;
}
/**
* Get the wave type.
* @return the type.
* @see #setWaveType
*/
public int getWaveType() {
return waveType;
}
protected void transformSpace(Rectangle r) {
// if (edgeAction == ZERO) {
// r.x -= (int)xAmplitude;
// r.width += (int)(2*xAmplitude);
// r.y -= (int)yAmplitude;
// r.height += (int)(2*yAmplitude);
// }
}
protected void transformInverse(int x, int y, float[] out) {
float nx = (float)y / xWavelength;
float ny = (float)x / yWavelength;
float fx, fy;
switch (waveType) {
case SINE:
default:
fx = (float)Math.sin(nx);
fy = (float)Math.sin(ny);
break;
case SAWTOOTH:
fx = ImageMath.mod(nx, 1);
fy = ImageMath.mod(ny, 1);
break;
case TRIANGLE:
fx = ImageMath.triangle(nx);
fy = ImageMath.triangle(ny);
break;
case NOISE:
fx = Noise.noise1(nx);
fy = Noise.noise1(ny);
break;
}
out[0] = x + xAmplitude * fx;
out[1] = y + yAmplitude * fy;
}
public String toString() {
return "Distort/Ripple...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/AverageFilter.java 0000644 0001750 0001750 00000002022 10606647276 026672 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which averages the 3x3 neighbourhood of each pixel, providing a simple blur.
*/
public class AverageFilter extends ConvolveFilter {
/**
* The convolution kernal for the averaging.
*/
protected static float[] theMatrix = { 0.1f, 0.1f, 0.1f, 0.1f, 0.2f, 0.1f, 0.1f, 0.1f, 0.1f };
public AverageFilter() {
super( theMatrix );
}
public String toString() {
return "Blur/Average Blur";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/HighPassFilter.java 0000755 0001750 0001750 00000004304 10626011515 027015 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which adds Gaussian blur to an image, producing a glowing effect.
* @author Jerry Huxtable
*/
public class HighPassFilter extends GaussianFilter {
public HighPassFilter() {
radius = 10;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
src.getRGB( 0, 0, width, height, inPixels, 0, width );
if ( radius > 0 ) {
convolveAndTranspose(kernel, inPixels, outPixels, width, height, alpha, alpha && premultiplyAlpha, false, CLAMP_EDGES);
convolveAndTranspose(kernel, outPixels, inPixels, height, width, alpha, false, alpha && premultiplyAlpha, CLAMP_EDGES);
}
src.getRGB( 0, 0, width, height, outPixels, 0, width );
int index = 0;
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
int rgb1 = outPixels[index];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int rgb2 = inPixels[index];
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
r1 = (r1 + 255-r2) / 2;
g1 = (g1 + 255-g2) / 2;
b1 = (b1 + 255-b2) / 2;
inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1;
index++;
}
}
dst.setRGB( 0, 0, width, height, inPixels, 0, width );
return dst;
}
public String toString() {
return "Blur/High Pass...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/InvertAlphaFilter.java 0000644 0001750 0001750 00000002023 10562652111 027517 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A Filter to invert the alpha channel of an image. This is really only useful for inverting selections, where we only use the alpha channel.
*/
public class InvertAlphaFilter extends PointFilter {
public InvertAlphaFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
return rgb ^ 0xff000000;
}
public String toString() {
return "Alpha/Invert";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LifeFilter.java 0000644 0001750 0001750 00000003466 10566356614 026212 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which performs one round of the game of Life on an image.
*/
public class LifeFilter extends BinaryFilter {
public LifeFilter() {
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int r = 0, g = 0, b = 0;
int pixel = inPixels[y*width+x];
int a = pixel & 0xff000000;
int neighbours = 0;
for (int row = -1; row <= 1; row++) {
int iy = y+row;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int col = -1; col <= 1; col++) {
int ix = x+col;
if (!(row == 0 && col == 0) && 0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
if (blackFunction.isBlack(rgb))
neighbours++;
}
}
}
}
if (blackFunction.isBlack(pixel))
outPixels[index++] = (neighbours == 2 || neighbours == 3) ? pixel : 0xffffffff;
else
outPixels[index++] = neighbours == 3 ? 0xff000000 : pixel;
}
}
return outPixels;
}
public String toString() {
return "Binary/Life";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ErodeAlphaFilter.java 0000755 0001750 0001750 00000003266 10626011515 027321 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.image.*;
public class ErodeAlphaFilter extends PointFilter {
private float threshold;
private float softness = 0;
protected float radius = 5;
private float lowerThreshold;
private float upperThreshold;
public ErodeAlphaFilter() {
this( 3, 0.75f, 0 );
}
public ErodeAlphaFilter( float radius, float threshold, float softness ) {
this.radius = radius;
this.threshold = threshold;
this.softness = softness;
}
public void setRadius(float radius) {
this.radius = radius;
}
public float getRadius() {
return radius;
}
public void setThreshold(float threshold) {
this.threshold = threshold;
}
public float getThreshold() {
return threshold;
}
public void setSoftness(float softness) {
this.softness = softness;
}
public float getSoftness() {
return softness;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
dst = new GaussianFilter( (int)radius ).filter( src, null );
lowerThreshold = 255*(threshold - softness*0.5f);
upperThreshold = 255*(threshold + softness*0.5f);
return super.filter(dst, dst);
}
public int filterRGB(int x, int y, int rgb) {
int a = (rgb >> 24) & 0xff;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if ( a == 255 )
return 0xffffffff;
float f = ImageMath.smoothStep(lowerThreshold, upperThreshold, (float)a);
a = (int)(f * 255);
if ( a < 0 )
a = 0;
else if ( a > 255 )
a = 255;
return (a << 24) | 0xffffff;
}
public String toString() {
return "Alpha/Erode...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BorderFilter.java 0000644 0001750 0001750 00000011065 10566356614 026542 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter to add a border around an image using the supplied Paint, which may be null for no painting.
*/
public class BorderFilter extends AbstractBufferedImageOp {
private int leftBorder, rightBorder;
private int topBorder, bottomBorder;
private Paint borderPaint;
/**
* Construct a BorderFilter which does nothing.
*/
public BorderFilter() {
}
/**
* Construct a BorderFilter.
* @param leftBorder the left border value
* @param topBorder the top border value
* @param rightBorder the right border value
* @param bottomBorder the bottom border value
* @param borderPaint the paint with which to fill the border
*/
public BorderFilter( int leftBorder, int topBorder, int rightBorder, int bottomBorder, Paint borderPaint ) {
this.leftBorder = leftBorder;
this.topBorder = topBorder;
this.rightBorder = rightBorder;
this.bottomBorder = bottomBorder;
this.borderPaint = borderPaint;
}
/**
* Set the border size on the left edge.
* @param leftBorder the number of pixels of border to add to the edge
* @min-value 0
* @see #getLeftBorder
*/
public void setLeftBorder(int leftBorder) {
this.leftBorder = leftBorder;
}
/**
* Returns the left border value.
* @return the left border value.
* @see #setLeftBorder
*/
public int getLeftBorder() {
return leftBorder;
}
/**
* Set the border size on the right edge.
* @param rightBorder the number of pixels of border to add to the edge
* @min-value 0
* @see #getRightBorder
*/
public void setRightBorder(int rightBorder) {
this.rightBorder = rightBorder;
}
/**
* Returns the right border value.
* @return the right border value.
* @see #setRightBorder
*/
public int getRightBorder() {
return rightBorder;
}
/**
* Set the border size on the top edge.
* @param topBorder the number of pixels of border to add to the edge
* @min-value 0
* @see #getTopBorder
*/
public void setTopBorder(int topBorder) {
this.topBorder = topBorder;
}
/**
* Returns the top border value.
* @return the top border value.
* @see #setTopBorder
*/
public int getTopBorder() {
return topBorder;
}
/**
* Set the border size on the bottom edge.
* @param bottomBorder the number of pixels of border to add to the edge
* @min-value 0
* @see #getBottomBorder
*/
public void setBottomBorder(int bottomBorder) {
this.bottomBorder = bottomBorder;
}
/**
* Returns the border border value.
* @return the border border value.
* @see #setBottomBorder
*/
public int getBottomBorder() {
return bottomBorder;
}
/**
* Set the border paint.
* @param borderPaint the paint with which to fill the border
* @see #getBorderPaint
*/
public void setBorderPaint( Paint borderPaint ) {
this.borderPaint = borderPaint;
}
/**
* Get the border paint.
* @return the paint with which to fill the border
* @see #setBorderPaint
*/
public Paint getBorderPaint() {
return borderPaint;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = new BufferedImage( width+leftBorder+rightBorder, height+topBorder+bottomBorder, src.getType() );
Graphics2D g = dst.createGraphics();
if ( borderPaint != null ) {
g.setPaint( borderPaint );
if ( leftBorder > 0 )
g.fillRect( 0, 0, leftBorder, height );
if ( rightBorder > 0 )
g.fillRect( width-rightBorder, 0, rightBorder, height );
if ( topBorder > 0 )
g.fillRect( leftBorder, 0, width-leftBorder-rightBorder, topBorder );
if ( bottomBorder > 0 )
g.fillRect( leftBorder, height-bottomBorder, width-leftBorder-rightBorder, bottomBorder );
}
g.drawRenderedImage( src, AffineTransform.getTranslateInstance( leftBorder, rightBorder ) );
g.dispose();
return dst;
}
public String toString() {
return "Distort/Border...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/EqualizeFilter.java 0000644 0001750 0001750 00000003630 10566356614 027103 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter to perform auto-equalization on an image.
*/
public class EqualizeFilter extends WholeImageFilter {
private int[][] lut;
public EqualizeFilter() {
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
Histogram histogram = new Histogram(inPixels, width, height, 0, width);
int i, j;
if (histogram.getNumSamples() > 0) {
float scale = 255.0f / histogram.getNumSamples();
lut = new int[3][256];
for (i = 0; i < 3; i++) {
lut[i][0] = histogram.getFrequency(i, 0);
for (j = 1; j < 256; j++)
lut[i][j] = lut[i][j-1] + histogram.getFrequency(i, j);
for (j = 0; j < 256; j++)
lut[i][j] = (int)Math.round(lut[i][j]*scale);
}
} else
lut = null;
i = 0;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
inPixels[i] = filterRGB(x, y, inPixels[i]);
i++;
}
lut = null;
return inPixels;
}
private int filterRGB(int x, int y, int rgb) {
if (lut != null) {
int a = rgb & 0xff000000;
int r = lut[Histogram.RED][(rgb >> 16) & 0xff];
int g = lut[Histogram.GREEN][(rgb >> 8) & 0xff];
int b = lut[Histogram.BLUE][rgb & 0xff];
return a | (r << 16) | (g << 8) | b;
}
return rgb;
}
public String toString() {
return "Colors/Equalize";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MotionBlur.java 0000644 0001750 0001750 00000006254 11331367433 026245 0 ustar martin martin /*
Copyright 2010 Laszlo Balazs-Csiki
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImageOp;
/**
* A common interface for different types of motion blur
*/
public interface MotionBlur extends BufferedImageOp {
/**
* Specifies the angle of blur.
*
* @param angle the angle of blur.
* @angle
* @see #getAngle
*/
void setAngle(float angle);
/**
* Returns the angle of blur.
*
* @return the angle of blur.
* @see #setAngle
*/
float getAngle();
/**
* Set the distance of blur.
*
* @param distance the distance of blur.
* @see #getDistance
*/
void setDistance(float distance);
/**
* Get the distance of blur.
*
* @return the distance of blur.
* @see #setDistance
*/
float getDistance();
/**
* Set the blur rotation.
*
* @param rotation the angle of rotation.
* @see #getRotation
*/
void setRotation(float rotation);
/**
* Get the blur rotation.
*
* @return the angle of rotation.
* @see #setRotation
*/
float getRotation();
/**
* Set the blur zoom.
*
* @param zoom the zoom factor.
* @see #getZoom
*/
void setZoom(float zoom);
/**
* Get the blur zoom.
*
* @return the zoom factor.
* @see #setZoom
*/
float getZoom();
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
*
* @param centreX the center
* @see #getCentreX
*/
void setCentreX(float centreX);
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
*
* @return the center
* @see #setCentreX
*/
float getCentreX();
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
*
* @param centreY the center
* @see #getCentreY
*/
void setCentreY(float centreY);
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
*
* @return the center
* @see #setCentreY
*/
float getCentreY();
/**
* Set the centre of the effect as a proportion of the image size.
*
* @param centre the center
* @see #getCentre
*/
void setCentre(Point2D centre);
/**
* Get the centre of the effect as a proportion of the image size.
*
* @return the center
* @see #setCentre
*/
Point2D getCentre();
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PointillizeFilter.java 0000644 0001750 0001750 00000004676 10626010523 027620 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.util.*;
import com.jhlabs.math.*;
public class PointillizeFilter extends CellularFilter {
private float edgeThickness = 0.4f;
private boolean fadeEdges = false;
private int edgeColor = 0xff000000;
private float fuzziness = 0.1f;
public PointillizeFilter() {
setScale(16);
setRandomness(0.0f);
}
public void setEdgeThickness(float edgeThickness) {
this.edgeThickness = edgeThickness;
}
public float getEdgeThickness() {
return edgeThickness;
}
public void setFadeEdges(boolean fadeEdges) {
this.fadeEdges = fadeEdges;
}
public boolean getFadeEdges() {
return fadeEdges;
}
public void setEdgeColor(int edgeColor) {
this.edgeColor = edgeColor;
}
public int getEdgeColor() {
return edgeColor;
}
public void setFuzziness(float fuzziness) {
this.fuzziness = fuzziness;
}
public float getFuzziness() {
return fuzziness;
}
public int getPixel(int x, int y, int[] inPixels, int width, int height) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
nx += 1000;
ny += 1000; // Reduce artifacts around 0,0
float f = evaluate(nx, ny);
float f1 = results[0].distance;
int srcx = ImageMath.clamp((int)((results[0].x-1000)*scale), 0, width-1);
int srcy = ImageMath.clamp((int)((results[0].y-1000)*scale), 0, height-1);
int v = inPixels[srcy * width + srcx];
if (fadeEdges) {
float f2 = results[1].distance;
srcx = ImageMath.clamp((int)((results[1].x-1000)*scale), 0, width-1);
srcy = ImageMath.clamp((int)((results[1].y-1000)*scale), 0, height-1);
int v2 = inPixels[srcy * width + srcx];
v = ImageMath.mixColors(0.5f*f1/f2, v, v2);
} else {
f = 1-ImageMath.smoothStep(edgeThickness, edgeThickness+fuzziness, f1);
v = ImageMath.mixColors(f, edgeColor, v);
}
return v;
}
public String toString() {
return "Pixellate/Pointillize...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LevelsFilter.java 0000644 0001750 0001750 00000005507 10606647276 026565 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which allows levels adjustment on an image.
*/
public class LevelsFilter extends WholeImageFilter {
private int[][] lut;
private float lowLevel = 0;
private float highLevel = 1;
private float lowOutputLevel = 0;
private float highOutputLevel = 1;
public LevelsFilter() {
}
public void setLowLevel( float lowLevel ) {
this.lowLevel = lowLevel;
}
public float getLowLevel() {
return lowLevel;
}
public void setHighLevel( float highLevel ) {
this.highLevel = highLevel;
}
public float getHighLevel() {
return highLevel;
}
public void setLowOutputLevel( float lowOutputLevel ) {
this.lowOutputLevel = lowOutputLevel;
}
public float getLowOutputLevel() {
return lowOutputLevel;
}
public void setHighOutputLevel( float highOutputLevel ) {
this.highOutputLevel = highOutputLevel;
}
public float getHighOutputLevel() {
return highOutputLevel;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
Histogram histogram = new Histogram(inPixels, width, height, 0, width);
int i, j;
if (histogram.getNumSamples() > 0) {
float scale = 255.0f / histogram.getNumSamples();
lut = new int[3][256];
float low = lowLevel * 255;
float high = highLevel * 255;
if ( low == high )
high++;
for (i = 0; i < 3; i++) {
for (j = 0; j < 256; j++)
lut[i][j] = PixelUtils.clamp( (int)(255 * (lowOutputLevel + (highOutputLevel-lowOutputLevel) * (j-low)/(high-low))) );
}
} else
lut = null;
i = 0;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
inPixels[i] = filterRGB(x, y, inPixels[i]);
i++;
}
lut = null;
return inPixels;
}
public int filterRGB(int x, int y, int rgb) {
if (lut != null) {
int a = rgb & 0xff000000;
int r = lut[Histogram.RED][(rgb >> 16) & 0xff];
int g = lut[Histogram.GREEN][(rgb >> 8) & 0xff];
int b = lut[Histogram.BLUE][rgb & 0xff];
return a | (r << 16) | (g << 8) | b;
}
return rgb;
}
public String toString() {
return "Colors/Levels...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/EdgeFilter.java 0000644 0001750 0001750 00000006425 10562652111 026160 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* An edge-detection filter.
*/
public class EdgeFilter extends WholeImageFilter {
public final static float R2 = (float)Math.sqrt(2);
public final static float[] ROBERTS_V = {
0, 0, -1,
0, 1, 0,
0, 0, 0,
};
public final static float[] ROBERTS_H = {
-1, 0, 0,
0, 1, 0,
0, 0, 0,
};
public final static float[] PREWITT_V = {
-1, 0, 1,
-1, 0, 1,
-1, 0, 1,
};
public final static float[] PREWITT_H = {
-1, -1, -1,
0, 0, 0,
1, 1, 1,
};
public final static float[] SOBEL_V = {
-1, 0, 1,
-2, 0, 2,
-1, 0, 1,
};
public static float[] SOBEL_H = {
-1, -2, -1,
0, 0, 0,
1, 2, 1,
};
public final static float[] FREI_CHEN_V = {
-1, 0, 1,
-R2, 0, R2,
-1, 0, 1,
};
public static float[] FREI_CHEN_H = {
-1, -R2, -1,
0, 0, 0,
1, R2, 1,
};
protected float[] vEdgeMatrix = SOBEL_V;
protected float[] hEdgeMatrix = SOBEL_H;
public EdgeFilter() {
}
public void setVEdgeMatrix(float[] vEdgeMatrix) {
this.vEdgeMatrix = vEdgeMatrix;
}
public float[] getVEdgeMatrix() {
return vEdgeMatrix;
}
public void setHEdgeMatrix(float[] hEdgeMatrix) {
this.hEdgeMatrix = hEdgeMatrix;
}
public float[] getHEdgeMatrix() {
return hEdgeMatrix;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int r = 0, g = 0, b = 0;
int rh = 0, gh = 0, bh = 0;
int rv = 0, gv = 0, bv = 0;
int a = inPixels[y*width+x] & 0xff000000;
for (int row = -1; row <= 1; row++) {
int iy = y+row;
int ioffset;
if (0 <= iy && iy < height)
ioffset = iy*width;
else
ioffset = y*width;
int moffset = 3*(row+1)+1;
for (int col = -1; col <= 1; col++) {
int ix = x+col;
if (!(0 <= ix && ix < width))
ix = x;
int rgb = inPixels[ioffset+ix];
float h = hEdgeMatrix[moffset+col];
float v = vEdgeMatrix[moffset+col];
r = (rgb & 0xff0000) >> 16;
g = (rgb & 0x00ff00) >> 8;
b = rgb & 0x0000ff;
rh += (int)(h * r);
gh += (int)(h * g);
bh += (int)(h * b);
rv += (int)(v * r);
gv += (int)(v * g);
bv += (int)(v * b);
}
}
r = (int)(Math.sqrt(rh*rh + rv*rv) / 1.8);
g = (int)(Math.sqrt(gh*gh + gv*gv) / 1.8);
b = (int)(Math.sqrt(bh*bh + bv*bv) / 1.8);
r = PixelUtils.clamp(r);
g = PixelUtils.clamp(g);
b = PixelUtils.clamp(b);
outPixels[index++] = a | (r << 16) | (g << 8) | b;
}
}
return outPixels;
}
public String toString() {
return "Blur/Detect Edges";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MaximumFilter.java 0000644 0001750 0001750 00000003031 10566356614 026734 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which replcaes each pixel by the maximum of itself and its eight neightbours.
*/
public class MaximumFilter extends WholeImageFilter {
public MaximumFilter() {
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = 0xff000000;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (0 <= ix && ix < width) {
pixel = PixelUtils.combinePixels(pixel, inPixels[ioffset+ix], PixelUtils.MAX);
}
}
}
}
outPixels[index++] = pixel;
}
}
return outPixels;
}
public String toString() {
return "Blur/Maximum";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ChannelMixFilter.java 0000644 0001750 0001750 00000004210 10606647276 027347 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which allows the red, green and blue channels of an image to be mixed into each other.
*/
public class ChannelMixFilter extends PointFilter {
private int blueGreen, redBlue, greenRed;
private int intoR, intoG, intoB;
public ChannelMixFilter() {
canFilterIndexColorModel = true;
}
public void setBlueGreen(int blueGreen) {
this.blueGreen = blueGreen;
}
public int getBlueGreen() {
return blueGreen;
}
public void setRedBlue(int redBlue) {
this.redBlue = redBlue;
}
public int getRedBlue() {
return redBlue;
}
public void setGreenRed(int greenRed) {
this.greenRed = greenRed;
}
public int getGreenRed() {
return greenRed;
}
public void setIntoR(int intoR) {
this.intoR = intoR;
}
public int getIntoR() {
return intoR;
}
public void setIntoG(int intoG) {
this.intoG = intoG;
}
public int getIntoG() {
return intoG;
}
public void setIntoB(int intoB) {
this.intoB = intoB;
}
public int getIntoB() {
return intoB;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int nr = PixelUtils.clamp((intoR * (blueGreen*g+(255-blueGreen)*b)/255 + (255-intoR)*r)/255);
int ng = PixelUtils.clamp((intoG * (redBlue*b+(255-redBlue)*r)/255 + (255-intoG)*g)/255);
int nb = PixelUtils.clamp((intoB * (greenRed*r+(255-greenRed)*g)/255 + (255-intoB)*b)/255);
return a | (nr << 16) | (ng << 8) | nb;
}
public String toString() {
return "Colors/Mix Channels...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GradientWipeFilter.java 0000644 0001750 0001750 00000005713 10566572034 027706 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.util.*;
/**
* A filter which can be used to produce wipes by transferring the luma of a mask image into the alpha channel of the source.
*/
public class GradientWipeFilter extends AbstractBufferedImageOp {
private float density = 0;
private float softness = 0;
private boolean invert;
private BufferedImage mask;
public GradientWipeFilter() {
}
/**
* Set the density of the image in the range 0..1.
* *arg density The density
*/
public void setDensity( float density ) {
this.density = density;
}
public float getDensity() {
return density;
}
/**
* Set the softness of the dissolve in the range 0..1.
* @param softness the softness
* @min-value 0
* @max-value 1
* @see #getSoftness
*/
public void setSoftness( float softness ) {
this.softness = softness;
}
/**
* Get the softness of the dissolve.
* @return the softness
* @see #setSoftness
*/
public float getSoftness() {
return softness;
}
public void setMask( BufferedImage mask ) {
this.mask = mask;
}
public BufferedImage getMask() {
return mask;
}
public void setInvert( boolean invert ) {
this.invert = invert;
}
public boolean getInvert() {
return invert;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
if ( mask == null )
return dst;
int maskWidth = mask.getWidth();
int maskHeight = mask.getHeight();
float d = density * (1+softness);
float lower = 255 * (d-softness);
float upper = 255 * d;
int[] inPixels = new int[width];
int[] maskPixels = new int[maskWidth];
for ( int y = 0; y < height; y++ ) {
getRGB( src, 0, y, width, 1, inPixels );
getRGB( mask, 0, y % maskHeight, maskWidth, 1, maskPixels );
for ( int x = 0; x < width; x++ ) {
int maskRGB = maskPixels[x % maskWidth];
int inRGB = inPixels[x];
int v = PixelUtils.brightness( maskRGB );
float f = ImageMath.smoothStep( lower, upper, v );
int a = (int)(255 * f);
if ( invert )
a = 255-a;
inPixels[x] = (a << 24) | (inRGB & 0x00ffffff);
}
setRGB( dst, 0, y, width, 1, inPixels );
}
return dst;
}
public String toString() {
return "Transitions/Gradient Wipe...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SphereFilter.java 0000644 0001750 0001750 00000010432 10566572034 026544 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which simulates a lens placed over an image.
*/
public class SphereFilter extends TransformFilter {
private float a = 0;
private float b = 0;
private float a2 = 0;
private float b2 = 0;
private float centreX = 0.5f;
private float centreY = 0.5f;
private float refractionIndex = 1.5f;
private float icentreX;
private float icentreY;
public SphereFilter() {
setEdgeAction( CLAMP );
setRadius( 100.0f );
}
/**
* Set the index of refaction.
* @param refractionIndex the index of refaction
* @see #getRefractionIndex
*/
public void setRefractionIndex(float refractionIndex) {
this.refractionIndex = refractionIndex;
}
/**
* Get the index of refaction.
* @return the index of refaction
* @see #setRefractionIndex
*/
public float getRefractionIndex() {
return refractionIndex;
}
/**
* Set the radius of the effect.
* @param r the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float r) {
this.a = r;
this.b = r;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return a;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
icentreX = width * centreX;
icentreY = height * centreY;
if (a == 0)
a = width/2;
if (b == 0)
b = height/2;
a2 = a*a;
b2 = b*b;
return super.filter( src, dst );
}
protected void transformInverse(int x, int y, float[] out) {
float dx = x-icentreX;
float dy = y-icentreY;
float x2 = dx*dx;
float y2 = dy*dy;
if (y2 >= (b2 - (b2*x2)/a2)) {
out[0] = x;
out[1] = y;
} else {
float rRefraction = 1.0f / refractionIndex;
float z = (float)Math.sqrt((1.0f - x2/a2 - y2/b2) * (a*b));
float z2 = z*z;
float xAngle = (float)Math.acos(dx / Math.sqrt(x2+z2));
float angle1 = ImageMath.HALF_PI - xAngle;
float angle2 = (float)Math.asin(Math.sin(angle1)*rRefraction);
angle2 = ImageMath.HALF_PI - xAngle - angle2;
out[0] = x - (float)Math.tan(angle2)*z;
float yAngle = (float)Math.acos(dy / Math.sqrt(y2+z2));
angle1 = ImageMath.HALF_PI - yAngle;
angle2 = (float)Math.asin(Math.sin(angle1)*rRefraction);
angle2 = ImageMath.HALF_PI - yAngle - angle2;
out[1] = y - (float)Math.tan(angle2)*z;
}
}
public String toString() {
return "Distort/Sphere...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ImageMath.java 0000644 0001750 0001750 00000043545 10606647276 026025 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* A class containing static math methods useful for image processing.
*/
public class ImageMath {
/**
* The value of pi as a float.
*/
public final static float PI = (float)Math.PI;
/**
* The value of half pi as a float.
*/
public final static float HALF_PI = (float)Math.PI/2.0f;
/**
* The value of quarter pi as a float.
*/
public final static float QUARTER_PI = (float)Math.PI/4.0f;
/**
* The value of two pi as a float.
*/
public final static float TWO_PI = (float)Math.PI*2.0f;
/**
* Apply a bias to a number in the unit interval, moving numbers towards 0 or 1
* according to the bias parameter.
* @param a the number to bias
* @param b the bias parameter. 0.5 means no change, smaller values bias towards 0, larger towards 1.
* @return the output value
*/
public static float bias(float a, float b) {
// return (float)Math.pow(a, Math.log(b) / Math.log(0.5));
return a/((1.0f/b-2)*(1.0f-a)+1);
}
/**
* A variant of the gamma function.
* @param a the number to apply gain to
* @param b the gain parameter. 0.5 means no change, smaller values reduce gain, larger values increase gain.
* @return the output value
*/
public static float gain(float a, float b) {
/*
float p = (float)Math.log(1.0 - b) / (float)Math.log(0.5);
if (a < .001)
return 0.0f;
else if (a > .999)
return 1.0f;
if (a < 0.5)
return (float)Math.pow(2 * a, p) / 2;
else
return 1.0f - (float)Math.pow(2 * (1. - a), p) / 2;
*/
float c = (1.0f/b-2.0f) * (1.0f-2.0f*a);
if (a < 0.5)
return a/(c+1.0f);
else
return (c-a)/(c-1.0f);
}
/**
* The step function. Returns 0 below a threshold, 1 above.
* @param a the threshold position
* @param x the input parameter
* @return the output value - 0 or 1
*/
public static float step(float a, float x) {
return (x < a) ? 0.0f : 1.0f;
}
/**
* The pulse function. Returns 1 between two thresholds, 0 outside.
* @param a the lower threshold position
* @param b the upper threshold position
* @param x the input parameter
* @return the output value - 0 or 1
*/
public static float pulse(float a, float b, float x) {
return (x < a || x >= b) ? 0.0f : 1.0f;
}
/**
* A smoothed pulse function. A cubic function is used to smooth the step between two thresholds.
* @param a1 the lower threshold position for the start of the pulse
* @param a2 the upper threshold position for the start of the pulse
* @param b1 the lower threshold position for the end of the pulse
* @param b2 the upper threshold position for the end of the pulse
* @param x the input parameter
* @return the output value
*/
public static float smoothPulse(float a1, float a2, float b1, float b2, float x) {
if (x < a1 || x >= b2)
return 0;
if (x >= a2) {
if (x < b1)
return 1.0f;
x = (x - b1) / (b2 - b1);
return 1.0f - (x*x * (3.0f - 2.0f*x));
}
x = (x - a1) / (a2 - a1);
return x*x * (3.0f - 2.0f*x);
}
/**
* A smoothed step function. A cubic function is used to smooth the step between two thresholds.
* @param a the lower threshold position
* @param b the upper threshold position
* @param x the input parameter
* @return the output value
*/
public static float smoothStep(float a, float b, float x) {
if (x < a)
return 0;
if (x >= b)
return 1;
x = (x - a) / (b - a);
return x*x * (3 - 2*x);
}
/**
* A "circle up" function. Returns y on a unit circle given 1-x. Useful for forming bevels.
* @param x the input parameter in the range 0..1
* @return the output value
*/
public static float circleUp(float x) {
x = 1-x;
return (float)Math.sqrt(1-x*x);
}
/**
* A "circle down" function. Returns 1-y on a unit circle given x. Useful for forming bevels.
* @param x the input parameter in the range 0..1
* @return the output value
*/
public static float circleDown(float x) {
return 1.0f-(float)Math.sqrt(1-x*x);
}
/**
* Clamp a value to an interval.
* @param a the lower clamp threshold
* @param b the upper clamp threshold
* @param x the input parameter
* @return the clamped value
*/
public static float clamp(float x, float a, float b) {
return (x < a) ? a : (x > b) ? b : x;
}
/**
* Clamp a value to an interval.
* @param a the lower clamp threshold
* @param b the upper clamp threshold
* @param x the input parameter
* @return the clamped value
*/
public static int clamp(int x, int a, int b) {
return (x < a) ? a : (x > b) ? b : x;
}
/**
* Return a mod b. This differs from the % operator with respect to negative numbers.
* @param a the dividend
* @param b the divisor
* @return a mod b
*/
public static double mod(double a, double b) {
int n = (int)(a/b);
a -= n*b;
if (a < 0)
return a + b;
return a;
}
/**
* Return a mod b. This differs from the % operator with respect to negative numbers.
* @param a the dividend
* @param b the divisor
* @return a mod b
*/
public static float mod(float a, float b) {
int n = (int)(a/b);
a -= n*b;
if (a < 0)
return a + b;
return a;
}
/**
* Return a mod b. This differs from the % operator with respect to negative numbers.
* @param a the dividend
* @param b the divisor
* @return a mod b
*/
public static int mod(int a, int b) {
int n = a/b;
a -= n*b;
if (a < 0)
return a + b;
return a;
}
/**
* The triangle function. Returns a repeating triangle shape in the range 0..1 with wavelength 1.0
* @param x the input parameter
* @return the output value
*/
public static float triangle(float x) {
float r = mod(x, 1.0f);
return 2.0f*(r < 0.5 ? r : 1-r);
}
/**
* Linear interpolation.
* @param t the interpolation parameter
* @param a the lower interpolation range
* @param b the upper interpolation range
* @return the interpolated value
*/
public static float lerp(float t, float a, float b) {
return a + t * (b - a);
}
/**
* Linear interpolation.
* @param t the interpolation parameter
* @param a the lower interpolation range
* @param b the upper interpolation range
* @return the interpolated value
*/
public static int lerp(float t, int a, int b) {
return (int)(a + t * (b - a));
}
/**
* Linear interpolation of ARGB values.
* @param t the interpolation parameter
* @param rgb1 the lower interpolation range
* @param rgb2 the upper interpolation range
* @return the interpolated value
*/
public static int mixColors(float t, int rgb1, int rgb2) {
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int a2 = (rgb2 >> 24) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
a1 = lerp(t, a1, a2);
r1 = lerp(t, r1, r2);
g1 = lerp(t, g1, g2);
b1 = lerp(t, b1, b2);
return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
}
/**
* Bilinear interpolation of ARGB values.
* @param x the X interpolation parameter 0..1
* @param y the y interpolation parameter 0..1
* @param rgb array of four ARGB values in the order NW, NE, SW, SE
* @return the interpolated value
*/
public static int bilinearInterpolate(float x, float y, int nw, int ne, int sw, int se) {
float m0, m1;
int a0 = (nw >> 24) & 0xff;
int r0 = (nw >> 16) & 0xff;
int g0 = (nw >> 8) & 0xff;
int b0 = nw & 0xff;
int a1 = (ne >> 24) & 0xff;
int r1 = (ne >> 16) & 0xff;
int g1 = (ne >> 8) & 0xff;
int b1 = ne & 0xff;
int a2 = (sw >> 24) & 0xff;
int r2 = (sw >> 16) & 0xff;
int g2 = (sw >> 8) & 0xff;
int b2 = sw & 0xff;
int a3 = (se >> 24) & 0xff;
int r3 = (se >> 16) & 0xff;
int g3 = (se >> 8) & 0xff;
int b3 = se & 0xff;
float cx = 1.0f-x;
float cy = 1.0f-y;
m0 = cx * a0 + x * a1;
m1 = cx * a2 + x * a3;
int a = (int)(cy * m0 + y * m1);
m0 = cx * r0 + x * r1;
m1 = cx * r2 + x * r3;
int r = (int)(cy * m0 + y * m1);
m0 = cx * g0 + x * g1;
m1 = cx * g2 + x * g3;
int g = (int)(cy * m0 + y * m1);
m0 = cx * b0 + x * b1;
m1 = cx * b2 + x * b3;
int b = (int)(cy * m0 + y * m1);
return (a << 24) | (r << 16) | (g << 8) | b;
}
/**
* Return the NTSC gray level of an RGB value.
* @param rgb1 the input pixel
* @return the gray level (0-255)
*/
public static int brightnessNTSC(int rgb) {
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
return (int)(r*0.299f + g*0.587f + b*0.114f);
}
// Catmull-Rom splines
private final static float m00 = -0.5f;
private final static float m01 = 1.5f;
private final static float m02 = -1.5f;
private final static float m03 = 0.5f;
private final static float m10 = 1.0f;
private final static float m11 = -2.5f;
private final static float m12 = 2.0f;
private final static float m13 = -0.5f;
private final static float m20 = -0.5f;
private final static float m21 = 0.0f;
private final static float m22 = 0.5f;
private final static float m23 = 0.0f;
private final static float m30 = 0.0f;
private final static float m31 = 1.0f;
private final static float m32 = 0.0f;
private final static float m33 = 0.0f;
/**
* Compute a Catmull-Rom spline.
* @param x the input parameter
* @param numKnots the number of knots in the spline
* @param knots the array of knots
* @return the spline value
*/
public static float spline(float x, int numKnots, float[] knots) {
int span;
int numSpans = numKnots - 3;
float k0, k1, k2, k3;
float c0, c1, c2, c3;
if (numSpans < 1)
throw new IllegalArgumentException("Too few knots in spline");
x = clamp(x, 0, 1) * numSpans;
span = (int)x;
if (span > numKnots-4)
span = numKnots-4;
x -= span;
k0 = knots[span];
k1 = knots[span+1];
k2 = knots[span+2];
k3 = knots[span+3];
c3 = m00*k0 + m01*k1 + m02*k2 + m03*k3;
c2 = m10*k0 + m11*k1 + m12*k2 + m13*k3;
c1 = m20*k0 + m21*k1 + m22*k2 + m23*k3;
c0 = m30*k0 + m31*k1 + m32*k2 + m33*k3;
return ((c3*x + c2)*x + c1)*x + c0;
}
/**
* Compute a Catmull-Rom spline, but with variable knot spacing.
* @param x the input parameter
* @param numKnots the number of knots in the spline
* @param xknots the array of knot x values
* @param yknots the array of knot y values
* @return the spline value
*/
public static float spline(float x, int numKnots, int[] xknots, int[] yknots) {
int span;
int numSpans = numKnots - 3;
float k0, k1, k2, k3;
float c0, c1, c2, c3;
if (numSpans < 1)
throw new IllegalArgumentException("Too few knots in spline");
for (span = 0; span < numSpans; span++)
if (xknots[span+1] > x)
break;
if (span > numKnots-3)
span = numKnots-3;
float t = (float)(x-xknots[span]) / (xknots[span+1]-xknots[span]);
span--;
if (span < 0) {
span = 0;
t = 0;
}
k0 = yknots[span];
k1 = yknots[span+1];
k2 = yknots[span+2];
k3 = yknots[span+3];
c3 = m00*k0 + m01*k1 + m02*k2 + m03*k3;
c2 = m10*k0 + m11*k1 + m12*k2 + m13*k3;
c1 = m20*k0 + m21*k1 + m22*k2 + m23*k3;
c0 = m30*k0 + m31*k1 + m32*k2 + m33*k3;
return ((c3*t + c2)*t + c1)*t + c0;
}
/**
* Compute a Catmull-Rom spline for RGB values.
* @param x the input parameter
* @param numKnots the number of knots in the spline
* @param knots the array of knots
* @return the spline value
*/
public static int colorSpline(float x, int numKnots, int[] knots) {
int span;
int numSpans = numKnots - 3;
float k0, k1, k2, k3;
float c0, c1, c2, c3;
if (numSpans < 1)
throw new IllegalArgumentException("Too few knots in spline");
x = clamp(x, 0, 1) * numSpans;
span = (int)x;
if (span > numKnots-4)
span = numKnots-4;
x -= span;
int v = 0;
for (int i = 0; i < 4; i++) {
int shift = i * 8;
k0 = (knots[span] >> shift) & 0xff;
k1 = (knots[span+1] >> shift) & 0xff;
k2 = (knots[span+2] >> shift) & 0xff;
k3 = (knots[span+3] >> shift) & 0xff;
c3 = m00*k0 + m01*k1 + m02*k2 + m03*k3;
c2 = m10*k0 + m11*k1 + m12*k2 + m13*k3;
c1 = m20*k0 + m21*k1 + m22*k2 + m23*k3;
c0 = m30*k0 + m31*k1 + m32*k2 + m33*k3;
int n = (int)(((c3*x + c2)*x + c1)*x + c0);
if (n < 0)
n = 0;
else if (n > 255)
n = 255;
v |= n << shift;
}
return v;
}
/**
* Compute a Catmull-Rom spline for RGB values, but with variable knot spacing.
* @param x the input parameter
* @param numKnots the number of knots in the spline
* @param xknots the array of knot x values
* @param yknots the array of knot y values
* @return the spline value
*/
public static int colorSpline(int x, int numKnots, int[] xknots, int[] yknots) {
int span;
int numSpans = numKnots - 3;
float k0, k1, k2, k3;
float c0, c1, c2, c3;
if (numSpans < 1)
throw new IllegalArgumentException("Too few knots in spline");
for (span = 0; span < numSpans; span++)
if (xknots[span+1] > x)
break;
if (span > numKnots-3)
span = numKnots-3;
float t = (float)(x-xknots[span]) / (xknots[span+1]-xknots[span]);
span--;
if (span < 0) {
span = 0;
t = 0;
}
int v = 0;
for (int i = 0; i < 4; i++) {
int shift = i * 8;
k0 = (yknots[span] >> shift) & 0xff;
k1 = (yknots[span+1] >> shift) & 0xff;
k2 = (yknots[span+2] >> shift) & 0xff;
k3 = (yknots[span+3] >> shift) & 0xff;
c3 = m00*k0 + m01*k1 + m02*k2 + m03*k3;
c2 = m10*k0 + m11*k1 + m12*k2 + m13*k3;
c1 = m20*k0 + m21*k1 + m22*k2 + m23*k3;
c0 = m30*k0 + m31*k1 + m32*k2 + m33*k3;
int n = (int)(((c3*t + c2)*t + c1)*t + c0);
if (n < 0)
n = 0;
else if (n > 255)
n = 255;
v |= n << shift;
}
return v;
}
/**
* An implementation of Fant's resampling algorithm.
* @param source the source pixels
* @param dest the destination pixels
* @param length the length of the scanline to resample
* @param offset the start offset into the arrays
* @param stride the offset between pixels in consecutive rows
* @param out an array of output positions for each pixel
*/
public static void resample(int[] source, int[] dest, int length, int offset, int stride, float[] out) {
int i, j;
float sizfac;
float inSegment;
float outSegment;
int a, r, g, b, nextA, nextR, nextG, nextB;
float aSum, rSum, gSum, bSum;
float[] in;
int srcIndex = offset;
int destIndex = offset;
int lastIndex = source.length;
int rgb;
in = new float[length+2];
i = 0;
for (j = 0; j < length; j++) {
while (out[i+1] < j)
i++;
in[j] = i + (float) (j - out[i]) / (out[i + 1] - out[i]);
// in[j] = ImageMath.clamp( in[j], 0, length-1 );
}
in[length] = length;
in[length+1] = length;
inSegment = 1.0f;
outSegment = in[1];
sizfac = outSegment;
aSum = rSum = gSum = bSum = 0.0f;
rgb = source[srcIndex];
a = (rgb >> 24) & 0xff;
r = (rgb >> 16) & 0xff;
g = (rgb >> 8) & 0xff;
b = rgb & 0xff;
srcIndex += stride;
rgb = source[srcIndex];
nextA = (rgb >> 24) & 0xff;
nextR = (rgb >> 16) & 0xff;
nextG = (rgb >> 8) & 0xff;
nextB = rgb & 0xff;
srcIndex += stride;
i = 1;
while (i <= length) {
float aIntensity = inSegment * a + (1.0f - inSegment) * nextA;
float rIntensity = inSegment * r + (1.0f - inSegment) * nextR;
float gIntensity = inSegment * g + (1.0f - inSegment) * nextG;
float bIntensity = inSegment * b + (1.0f - inSegment) * nextB;
if (inSegment < outSegment) {
aSum += (aIntensity * inSegment);
rSum += (rIntensity * inSegment);
gSum += (gIntensity * inSegment);
bSum += (bIntensity * inSegment);
outSegment -= inSegment;
inSegment = 1.0f;
a = nextA;
r = nextR;
g = nextG;
b = nextB;
if (srcIndex < lastIndex)
rgb = source[srcIndex];
nextA = (rgb >> 24) & 0xff;
nextR = (rgb >> 16) & 0xff;
nextG = (rgb >> 8) & 0xff;
nextB = rgb & 0xff;
srcIndex += stride;
} else {
aSum += (aIntensity * outSegment);
rSum += (rIntensity * outSegment);
gSum += (gIntensity * outSegment);
bSum += (bIntensity * outSegment);
dest[destIndex] =
((int)Math.min(aSum/sizfac, 255) << 24) |
((int)Math.min(rSum/sizfac, 255) << 16) |
((int)Math.min(gSum/sizfac, 255) << 8) |
(int)Math.min(bSum/sizfac, 255);
destIndex += stride;
aSum = rSum = gSum = bSum = 0.0f;
inSegment -= outSegment;
outSegment = in[i+1] - in[i];
sizfac = outSegment;
i++;
}
}
}
/**
* Premultiply a block of pixels
*/
public static void premultiply( int[] p, int offset, int length ) {
length += offset;
for ( int i = offset; i < length; i ++ ) {
int rgb = p[i];
int a = (rgb >> 24) & 0xff;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
float f = a * (1.0f / 255.0f);
r *= f;
g *= f;
b *= f;
p[i] = (a << 24) | (r << 16) | (g << 8) | b;
}
}
/**
* Premultiply a block of pixels
*/
public static void unpremultiply( int[] p, int offset, int length ) {
length += offset;
for ( int i = offset; i < length; i ++ ) {
int rgb = p[i];
int a = (rgb >> 24) & 0xff;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if ( a != 0 && a != 255 ) {
float f = 255.0f / a;
r *= f;
g *= f;
b *= f;
if ( r > 255 )
r = 255;
if ( g > 255 )
g = 255;
if ( b > 255 )
b = 255;
p[i] = (a << 24) | (r << 16) | (g << 8) | b;
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ApplyMaskFilter.java 0000644 0001750 0001750 00000007362 10566356614 027233 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* A filter which uses the alpha channel of a "mask" image to interpolate between a source and destination image.
*/
public class ApplyMaskFilter extends AbstractBufferedImageOp {
private BufferedImage destination;
private BufferedImage maskImage;
/**
* Construct an ApplyMaskFIlter.
*/
public ApplyMaskFilter() {
}
/**
* Construct an ApplyMaskFIlter.
* @param maskImage the mask image
* @param destination the destination image
*/
public ApplyMaskFilter( BufferedImage maskImage, BufferedImage destination ) {
this.maskImage = maskImage;
this.destination = destination;
}
/**
* Set the destination image.
* @param destination the destination image
* @see #getDestination
*/
public void setDestination( BufferedImage destination ) {
this.destination = destination;
}
/**
* Get the destination image.
* @return the destination image
* @see #setDestination
*/
public BufferedImage getDestination() {
return destination;
}
/**
* Set the mask image.
* @param maskImage the mask image
* @see #getMaskImage
*/
public void setMaskImage( BufferedImage maskImage ) {
this.maskImage = maskImage;
}
/**
* Get the mask image.
* @return the mask image
* @see #setMaskImage
*/
public BufferedImage getMaskImage() {
return maskImage;
}
/**
* Interpolates between two rasters according to the alpha level of a mask raster.
* @param src the source raster
* @param dst the destination raster
* @param sel the mask raster
*/
public static void composeThroughMask(Raster src, WritableRaster dst, Raster sel) {
int x = src.getMinX();
int y = src.getMinY();
int w = src.getWidth();
int h = src.getHeight();
int srcRGB[] = null;
int selRGB[] = null;
int dstRGB[] = null;
for ( int i = 0; i < h; i++ ) {
srcRGB = src.getPixels(x, y, w, 1, srcRGB);
selRGB = sel.getPixels(x, y, w, 1, selRGB);
dstRGB = dst.getPixels(x, y, w, 1, dstRGB);
int k = x;
for ( int j = 0; j < w; j++ ) {
int sr = srcRGB[k];
int dir = dstRGB[k];
int sg = srcRGB[k+1];
int dig = dstRGB[k+1];
int sb = srcRGB[k+2];
int dib = dstRGB[k+2];
int sa = srcRGB[k+3];
int dia = dstRGB[k+3];
float a = selRGB[k+3]/255f;
float ac = 1-a;
dstRGB[k] = (int)(a*sr + ac*dir);
dstRGB[k+1] = (int)(a*sg + ac*dig);
dstRGB[k+2] = (int)(a*sb + ac*dib);
dstRGB[k+3] = (int)(a*sa + ac*dia);
k += 4;
}
dst.setPixels(x, y, w, 1, dstRGB);
y++;
}
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
WritableRaster dstRaster = dst.getRaster();
if ( destination != null && maskImage != null )
composeThroughMask( src.getRaster(), dst.getRaster(), maskImage.getRaster() );
return dst;
}
public String toString() {
return "Keying/Key...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/RGBAdjustFilter.java 0000644 0001750 0001750 00000003540 10562652111 027074 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class RGBAdjustFilter extends PointFilter {
public float rFactor, gFactor, bFactor;
public RGBAdjustFilter() {
this(0, 0, 0);
}
public RGBAdjustFilter(float r, float g, float b) {
rFactor = 1+r;
gFactor = 1+g;
bFactor = 1+b;
canFilterIndexColorModel = true;
}
public void setRFactor( float rFactor ) {
this.rFactor = 1+rFactor;
}
public float getRFactor() {
return rFactor-1;
}
public void setGFactor( float gFactor ) {
this.gFactor = 1+gFactor;
}
public float getGFactor() {
return gFactor-1;
}
public void setBFactor( float bFactor ) {
this.bFactor = 1+bFactor;
}
public float getBFactor() {
return bFactor-1;
}
public int[] getLUT() {
int[] lut = new int[256];
for ( int i = 0; i < 256; i++ ) {
lut[i] = filterRGB( 0, 0, (i << 24) | (i << 16) | (i << 8) | i );
}
return lut;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = PixelUtils.clamp((int)(r * rFactor));
g = PixelUtils.clamp((int)(g * gFactor));
b = PixelUtils.clamp((int)(b * bFactor));
return a | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Colors/Adjust RGB...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/UnsharpFilter.java 0000644 0001750 0001750 00000006261 10606647276 026751 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which subtracts Gaussian blur from an image, sharpening it.
* @author Jerry Huxtable
*/
public class UnsharpFilter extends GaussianFilter {
private float amount = 0.5f;
private int threshold = 1;
public UnsharpFilter() {
radius = 2;
}
/**
* Set the threshold value.
* @param threshold the threshold value
* @see #getThreshold
*/
public void setThreshold( int threshold ) {
this.threshold = threshold;
}
/**
* Get the threshold value.
* @return the threshold value
* @see #setThreshold
*/
public int getThreshold() {
return threshold;
}
/**
* Set the amount of sharpening.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount( float amount ) {
this.amount = amount;
}
/**
* Get the amount of sharpening.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
src.getRGB( 0, 0, width, height, inPixels, 0, width );
if ( radius > 0 ) {
convolveAndTranspose(kernel, inPixels, outPixels, width, height, alpha, alpha && premultiplyAlpha, false, CLAMP_EDGES);
convolveAndTranspose(kernel, outPixels, inPixels, height, width, alpha, false, alpha && premultiplyAlpha, CLAMP_EDGES);
}
src.getRGB( 0, 0, width, height, outPixels, 0, width );
float a = 4*amount;
int index = 0;
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
int rgb1 = outPixels[index];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int rgb2 = inPixels[index];
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
if ( Math.abs( r1 - r2 ) >= threshold )
r1 = PixelUtils.clamp( (int)((a+1) * (r1-r2) + r2) );
if ( Math.abs( g1 - g2 ) >= threshold )
g1 = PixelUtils.clamp( (int)((a+1) * (g1-g2) + g2) );
if ( Math.abs( b1 - b2 ) >= threshold )
b1 = PixelUtils.clamp( (int)((a+1) * (b1-b2) + b2) );
inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1;
index++;
}
}
dst.setRGB( 0, 0, width, height, inPixels, 0, width );
return dst;
}
public String toString() {
return "Blur/Unsharp Mask...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ShapeFilter.java 0000644 0001750 0001750 00000020177 10566356614 026371 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
// original code Copyright (C) Jerry Huxtable 1998
//
// customizations (C) Michele Puccini 19/12/2001
// - conversion from float to int math
// - complete rewrite of applyMap()
// - implemented merge to dest function
public class ShapeFilter extends WholeImageFilter {
public final static int LINEAR = 0;
public final static int CIRCLE_UP = 1;
public final static int CIRCLE_DOWN = 2;
public final static int SMOOTH = 3;
private float factor = 1.0f;
protected Colormap colormap;
private boolean useAlpha = true;
private boolean invert = false;
private boolean merge = false;
private int type;
private final static int one = 41;
private final static int sqrt2 = (int)(41*Math.sqrt(2));
private final static int sqrt5 = (int)(41*Math.sqrt(5));
public ShapeFilter() {
colormap = new LinearColormap();
}
public void setFactor(float factor) {
this.factor = factor;
}
public float getFactor() {
return factor;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public void setUseAlpha(boolean useAlpha) {
this.useAlpha = useAlpha;
}
public boolean getUseAlpha() {
return useAlpha;
}
public void setType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setInvert(boolean invert) {
this.invert = invert;
}
public boolean getInvert() {
return invert;
}
public void setMerge(boolean merge) {
this.merge = merge;
}
public boolean getMerge() {
return merge;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] map = new int[width * height];
makeMap(inPixels, map, width, height);
int max = distanceMap(map, width, height);
applyMap(map, inPixels, width, height, max);
return inPixels;
}
public int distanceMap(int[] map, int width, int height) {
int xmax = width - 3;
int ymax = height - 3;
int max = 0;
int v;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int offset = x + y * width;
if (map[offset] > 0) {
if (x < 2 || x > xmax || y < 2 || y > ymax)
v = setEdgeValue(x, y, map, width, offset, xmax, ymax);
else
v = setValue(map, width, offset);
if (v > max)
max = v;
}
}
}
for (int y = height-1; y >= 0; y--) {
for (int x = width-1; x >= 0; x--) {
int offset = x + y * width;
if (map[offset] > 0) {
if (x < 2 || x > xmax || y < 2 || y > ymax)
v = setEdgeValue(x, y, map, width, offset, xmax, ymax);
else
v = setValue(map, width, offset);
if (v > max)
max = v;
}
}
}
return max;
}
private void makeMap(int[] pixels, int[] map, int width, int height) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int offset = x + y * width;
int b = useAlpha ? (pixels[offset] >> 24) & 0xff : PixelUtils.brightness(pixels[offset]);
// map[offset] = b * one;
map[offset] = b * one / 10;
}
}
}
private void applyMap(int[] map, int[] pixels, int width, int height, int max) {
if (max == 0)
max = 1;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int offset = x + y * width;
int m = map[offset];
float v = 0;
int sa = 0, sr = 0, sg = 0, sb = 0;
if (m == 0) {
// default color
sa = sr = sg = sb = 0;
sa = (pixels[offset] >> 24) & 0xff;
} else {
// get V from map
v = ImageMath.clamp(factor * m / max, 0, 1);
switch (type) {
case CIRCLE_UP :
v = (ImageMath.circleUp(v));
break;
case CIRCLE_DOWN :
v = (ImageMath.circleDown(v));
break;
case SMOOTH :
v = (ImageMath.smoothStep(0, 1, v));
break;
}
if (colormap == null) {
sr = sg = sb = (int)(v*255);
} else {
int c = (colormap.getColor(v));
sr = (c >> 16) & 0xFF;
sg = (c >> 8) & 0xFF;
sb = (c) & 0xFF;
}
sa = useAlpha ? (pixels[offset] >> 24) & 0xff : PixelUtils.brightness(pixels[offset]);
// invert v if necessary
if (invert) {
sr = 255-sr;
sg = 255-sg;
sb = 255-sb;
}
}
// write results
if (merge) {
// merge with source
int transp = 255;
int col = pixels[offset];
int a = (col & 0xFF000000) >> 24;
int r = (col & 0xFF0000) >> 16;
int g = (col & 0xFF00) >> 8;
int b = (col & 0xFF);
r = (int)((sr*r/transp));
g = (int)((sg*g/transp));
b = (int)((sb*b/transp));
// clip colors
if (r < 0)
r = 0;
if (r > 255)
r = 255;
if (g < 0)
g = 0;
if (g > 255)
g = 255;
if (b < 0)
b = 0;
if (b > 255)
b = 255;
pixels[offset] = (a << 24) | (r << 16) | (g << 8) | b;
} else {
// write gray shades
pixels[offset] = (sa << 24) | (sr << 16) | (sg << 8) | sb;
}
}
}
}
private int setEdgeValue(int x, int y, int[] map, int width, int offset, int xmax, int ymax) {
int min, v;
int r1, r2, r3, r4, r5;
r1 = offset - width - width - 2;
r2 = r1 + width;
r3 = r2 + width;
r4 = r3 + width;
r5 = r4 + width;
if (y == 0 || x == 0 || y == ymax+2 || x == xmax+2)
return map[offset] = one;
v = map[r2 + 2] + one;
min = v;
v = map[r3 + 1] + one;
if (v < min)
min = v;
v = map[r3 + 3] + one;
if (v < min)
min = v;
v = map[r4 + 2] + one;
if (v < min)
min = v;
v = map[r2 + 1] + sqrt2;
if (v < min)
min = v;
v = map[r2 + 3] + sqrt2;
if (v < min)
min = v;
v = map[r4 + 1] + sqrt2;
if (v < min)
min = v;
v = map[r4 + 3] + sqrt2;
if (v < min)
min = v;
if (y == 1 || x == 1 || y == ymax+1 || x == xmax+1)
return map[offset] = min;
v = map[r1 + 1] + sqrt5;
if (v < min)
min = v;
v = map[r1 + 3] + sqrt5;
if (v < min)
min = v;
v = map[r2 + 4] + sqrt5;
if (v < min)
min = v;
v = map[r4 + 4] + sqrt5;
if (v < min)
min = v;
v = map[r5 + 3] + sqrt5;
if (v < min)
min = v;
v = map[r5 + 1] + sqrt5;
if (v < min)
min = v;
v = map[r4] + sqrt5;
if (v < min)
min = v;
v = map[r2] + sqrt5;
if (v < min)
min = v;
return map[offset] = min;
}
private int setValue(int[] map, int width, int offset) {
int min, v;
int r1, r2, r3, r4, r5;
r1 = offset - width - width - 2;
r2 = r1 + width;
r3 = r2 + width;
r4 = r3 + width;
r5 = r4 + width;
v = map[r2 + 2] + one;
min = v;
v = map[r3 + 1] + one;
if (v < min)
min = v;
v = map[r3 + 3] + one;
if (v < min)
min = v;
v = map[r4 + 2] + one;
if (v < min)
min = v;
v = map[r2 + 1] + sqrt2;
if (v < min)
min = v;
v = map[r2 + 3] + sqrt2;
if (v < min)
min = v;
v = map[r4 + 1] + sqrt2;
if (v < min)
min = v;
v = map[r4 + 3] + sqrt2;
if (v < min)
min = v;
v = map[r1 + 1] + sqrt5;
if (v < min)
min = v;
v = map[r1 + 3] + sqrt5;
if (v < min)
min = v;
v = map[r2 + 4] + sqrt5;
if (v < min)
min = v;
v = map[r4 + 4] + sqrt5;
if (v < min)
min = v;
v = map[r5 + 3] + sqrt5;
if (v < min)
min = v;
v = map[r5 + 1] + sqrt5;
if (v < min)
min = v;
v = map[r4] + sqrt5;
if (v < min)
min = v;
v = map[r2] + sqrt5;
if (v < min)
min = v;
return map[offset] = min;
}
public String toString() {
return "Stylize/Shapeburst...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MedianFilter.java 0000644 0001750 0001750 00000004764 10562652111 026515 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which performs a 3x3 median operation. Useful for removing dust and noise.
*/
public class MedianFilter extends WholeImageFilter {
public MedianFilter() {
}
private int median(int[] array) {
int max, maxIndex;
for (int i = 0; i < 4; i++) {
max = 0;
maxIndex = 0;
for (int j = 0; j < 9; j++) {
if (array[j] > max) {
max = array[j];
maxIndex = j;
}
}
array[maxIndex] = 0;
}
max = 0;
for (int i = 0; i < 9; i++) {
if (array[i] > max)
max = array[i];
}
return max;
}
private int rgbMedian(int[] r, int[] g, int[] b) {
int sum, index = 0, min = Integer.MAX_VALUE;
for (int i = 0; i < 9; i++) {
sum = 0;
for (int j = 0; j < 9; j++) {
sum += Math.abs(r[i]-r[j]);
sum += Math.abs(g[i]-g[j]);
sum += Math.abs(b[i]-b[j]);
}
if (sum < min) {
min = sum;
index = i;
}
}
return index;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] argb = new int[9];
int[] r = new int[9];
int[] g = new int[9];
int[] b = new int[9];
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int k = 0;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
if (0 <= iy && iy < height) {
int ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
argb[k] = rgb;
r[k] = (rgb >> 16) & 0xff;
g[k] = (rgb >> 8) & 0xff;
b[k] = rgb & 0xff;
k++;
}
}
}
}
while (k < 9) {
argb[k] = 0xff000000;
r[k] = g[k] = b[k] = 0;
k++;
}
outPixels[index++] = argb[rgbMedian(r, g, b)];
}
}
return outPixels;
}
public String toString() {
return "Blur/Median";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/JavaLnFFilter.java 0000644 0001750 0001750 00000002033 10562652111 026564 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which produces the stipple effect for Swing icons specified in the Java Look and Feel Guidelines.
*/
public class JavaLnFFilter extends PointFilter {
public JavaLnFFilter() {
}
public int filterRGB(int x, int y, int rgb) {
if ((x & 1) == (y & 1))
return rgb;
return ImageMath.mixColors(0.25f, 0xff999999, rgb);
}
public String toString() {
return "Stylize/Java L&F Stipple";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/OctTreeQuantizer.java 0000644 0001750 0001750 00000015407 10566572034 027427 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
/**
* An image Quantizer based on the Octree algorithm. This is a very basic implementation
* at present and could be much improved by picking the nodes to reduce more carefully
* (i.e. not completely at random) when I get the time.
*/
public class OctTreeQuantizer implements Quantizer {
/**
* The greatest depth the tree is allowed to reach
*/
final static int MAX_LEVEL = 5;
/**
* An Octtree node.
*/
class OctTreeNode {
int children;
int level;
OctTreeNode parent;
OctTreeNode leaf[] = new OctTreeNode[8];
boolean isLeaf;
int count;
int totalRed;
int totalGreen;
int totalBlue;
int index;
/**
* A debugging method which prints the tree out.
*/
public void list(PrintStream s, int level) {
for (int i = 0; i < level; i++)
System.out.print(' ');
if (count == 0)
System.out.println(index+": count="+count);
else
System.out.println(index+": count="+count+" red="+(totalRed/count)+" green="+(totalGreen/count)+" blue="+(totalBlue/count));
for (int i = 0; i < 8; i++)
if (leaf[i] != null)
leaf[i].list(s, level+2);
}
}
private int nodes = 0;
private OctTreeNode root;
private int reduceColors;
private int maximumColors;
private int colors = 0;
private Vector[] colorList;
public OctTreeQuantizer() {
setup(256);
colorList = new Vector[MAX_LEVEL+1];
for (int i = 0; i < MAX_LEVEL+1; i++)
colorList[i] = new Vector();
root = new OctTreeNode();
}
/**
* Initialize the quantizer. This should be called before adding any pixels.
* @param numColors the number of colors we're quantizing to.
*/
public void setup(int numColors) {
maximumColors = numColors;
reduceColors = Math.max(512, numColors * 2);
}
/**
* Add pixels to the quantizer.
* @param pixels the array of ARGB pixels
* @param offset the offset into the array
* @param count the count of pixels
*/
public void addPixels(int[] pixels, int offset, int count) {
for (int i = 0; i < count; i++) {
insertColor(pixels[i+offset]);
if (colors > reduceColors)
reduceTree(reduceColors);
}
}
/**
* Get the color table index for a color.
* @param rgb the color
* @return the index
*/
public int getIndexForColor(int rgb) {
int red = (rgb >> 16) & 0xff;
int green = (rgb >> 8) & 0xff;
int blue = rgb & 0xff;
OctTreeNode node = root;
for (int level = 0; level <= MAX_LEVEL; level++) {
OctTreeNode child;
int bit = 0x80 >> level;
int index = 0;
if ((red & bit) != 0)
index += 4;
if ((green & bit) != 0)
index += 2;
if ((blue & bit) != 0)
index += 1;
child = node.leaf[index];
if (child == null)
return node.index;
else if (child.isLeaf)
return child.index;
else
node = child;
}
System.out.println("getIndexForColor failed");
return 0;
}
private void insertColor(int rgb) {
int red = (rgb >> 16) & 0xff;
int green = (rgb >> 8) & 0xff;
int blue = rgb & 0xff;
OctTreeNode node = root;
// System.out.println("insertColor="+Integer.toHexString(rgb));
for (int level = 0; level <= MAX_LEVEL; level++) {
OctTreeNode child;
int bit = 0x80 >> level;
int index = 0;
if ((red & bit) != 0)
index += 4;
if ((green & bit) != 0)
index += 2;
if ((blue & bit) != 0)
index += 1;
child = node.leaf[index];
if (child == null) {
node.children++;
child = new OctTreeNode();
child.parent = node;
node.leaf[index] = child;
node.isLeaf = false;
nodes++;
colorList[level].addElement(child);
if (level == MAX_LEVEL) {
child.isLeaf = true;
child.count = 1;
child.totalRed = red;
child.totalGreen = green;
child.totalBlue = blue;
child.level = level;
colors++;
return;
}
node = child;
} else if (child.isLeaf) {
child.count++;
child.totalRed += red;
child.totalGreen += green;
child.totalBlue += blue;
return;
} else
node = child;
}
System.out.println("insertColor failed");
}
private void reduceTree(int numColors) {
for (int level = MAX_LEVEL-1; level >= 0; level--) {
Vector v = colorList[level];
if (v != null && v.size() > 0) {
for (int j = 0; j < v.size(); j++) {
OctTreeNode node = (OctTreeNode)v.elementAt(j);
if (node.children > 0) {
for (int i = 0; i < 8; i++) {
OctTreeNode child = node.leaf[i];
if (child != null) {
if (!child.isLeaf)
System.out.println("not a leaf!");
node.count += child.count;
node.totalRed += child.totalRed;
node.totalGreen += child.totalGreen;
node.totalBlue += child.totalBlue;
node.leaf[i] = null;
node.children--;
colors--;
nodes--;
colorList[level+1].removeElement(child);
}
}
node.isLeaf = true;
colors++;
if (colors <= numColors)
return;
}
}
}
}
System.out.println("Unable to reduce the OctTree");
}
/**
* Build the color table.
* @return the color table
*/
public int[] buildColorTable() {
int[] table = new int[colors];
buildColorTable(root, table, 0);
return table;
}
/**
* A quick way to use the quantizer. Just create a table the right size and pass in the pixels.
* @param inPixels the input colors
* @param table the output color table
*/
public void buildColorTable(int[] inPixels, int[] table) {
int count = inPixels.length;
maximumColors = table.length;
for (int i = 0; i < count; i++) {
insertColor(inPixels[i]);
if (colors > reduceColors)
reduceTree(reduceColors);
}
if (colors > maximumColors)
reduceTree(maximumColors);
buildColorTable(root, table, 0);
}
private int buildColorTable(OctTreeNode node, int[] table, int index) {
if (colors > maximumColors)
reduceTree(maximumColors);
if (node.isLeaf) {
int count = node.count;
table[index] = 0xff000000 |
((node.totalRed/count) << 16) |
((node.totalGreen/count) << 8) |
node.totalBlue/count;
node.index = index++;
} else {
for (int i = 0; i < 8; i++) {
if (node.leaf[i] != null) {
node.index = index;
index = buildColorTable(node.leaf[i], table, index);
}
}
}
return index;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DissolveFilter.java 0000644 0001750 0001750 00000004311 10566356614 027111 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.util.*;
/**
* A filter which "dissolves" an image by thresholding the alpha channel with random numbers.
*/
public class DissolveFilter extends PointFilter {
private float density = 1;
private float softness = 0;
private float minDensity, maxDensity;
private Random randomNumbers;
public DissolveFilter() {
}
/**
* Set the density of the image in the range 0..1.
* @param density the density
* @min-value 0
* @max-value 1
* @see #getDensity
*/
public void setDensity( float density ) {
this.density = density;
}
/**
* Get the density of the image.
* @return the density
* @see #setDensity
*/
public float getDensity() {
return density;
}
/**
* Set the softness of the dissolve in the range 0..1.
* @param softness the softness
* @min-value 0
* @max-value 1
* @see #getSoftness
*/
public void setSoftness( float softness ) {
this.softness = softness;
}
/**
* Get the softness of the dissolve.
* @return the softness
* @see #setSoftness
*/
public float getSoftness() {
return softness;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
float d = (1-density) * (1+softness);
minDensity = d-softness;
maxDensity = d;
randomNumbers = new Random( 0 );
return super.filter( src, dst );
}
public int filterRGB(int x, int y, int rgb) {
int a = (rgb >> 24) & 0xff;
float v = randomNumbers.nextFloat();
float f = ImageMath.smoothStep( minDensity, maxDensity, v );
return ((int)(a * f) << 24) | rgb & 0x00ffffff;
}
public String toString() {
return "Stylize/Dissolve...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LaplaceFilter.java 0000755 0001750 0001750 00000007461 10626011515 026657 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.composite.*;
/**
* Edge detection via the Laplacian operator.
* @author Jerry Huxtable
*/
public class LaplaceFilter extends AbstractBufferedImageOp {
private void brightness( int[] row ) {
for ( int i = 0; i < row.length; i++ ) {
int rgb = row[i];
int r = rgb >> 16 & 0xff;
int g = rgb >> 8 & 0xff;
int b = rgb & 0xff;
row[i] = (r + g + b) / 3;
}
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] row1 = null;
int[] row2 = null;
int[] row3 = null;
int[] pixels = new int[width];
row1 = getRGB( src, 0, 0, width, 1, row1 );
row2 = getRGB( src, 0, 0, width, 1, row2 );
brightness( row1 );
brightness( row2 );
for ( int y = 0; y < height; y++ ) {
if ( y < height-1) {
row3 = getRGB( src, 0, y+1, width, 1, row3 );
brightness( row3 );
}
pixels[0] = pixels[width-1] = 0xff000000;//FIXME
for ( int x = 1; x < width-1; x++ ) {
int l1 = row2[x-1];
int l2 = row1[x];
int l3 = row3[x];
int l4 = row2[x+1];
int l = row2[x];
int max = Math.max( Math.max( l1, l2 ), Math.max( l3, l4 ) );
int min = Math.min( Math.min( l1, l2 ), Math.min( l3, l4 ) );
int gradient = (int)(0.5f * Math.max( (max - l), (l - min) ));
int r = ((row1[x-1] + row1[x] + row1[x+1] +
row2[x-1] - (8 * row2[x]) + row2[x+1] +
row3[x-1] + row3[x] + row3[x+1]) > 0) ?
gradient : (128 + gradient);
pixels[x] = r;
}
setRGB( dst, 0, y, width, 1, pixels );
int[] t = row1; row1 = row2; row2 = row3; row3 = t;
}
row1 = getRGB( dst, 0, 0, width, 1, row1 );
row2 = getRGB( dst, 0, 0, width, 1, row2 );
for ( int y = 0; y < height; y++ ) {
if ( y < height-1) {
row3 = getRGB( dst, 0, y+1, width, 1, row3 );
}
pixels[0] = pixels[width-1] = 0xff000000;//FIXME
for ( int x = 1; x < width-1; x++ ) {
int r = row2[x];
r = (((r <= 128) &&
((row1[x - 1] > 128) ||
(row1[x] > 128) ||
(row1[x + 1] > 128) ||
(row2[x - 1] > 128) ||
(row2[x + 1] > 128) ||
(row3[x - 1] > 128) ||
(row3[x] > 128) ||
(row3[x + 1] > 128))) ?
((r >= 128) ? (r - 128) : r) : 0);
pixels[x] = 0xff000000 | (r << 16) | (r << 8) | r;
}
setRGB( dst, 0, y, width, 1, pixels );
int[] t = row1; row1 = row2; row2 = row3; row3 = t;
}
return dst;
}
public String toString() {
return "Edges/Laplace...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CurvesFilter.java 0000755 0001750 0001750 00000002226 10626011515 026557 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class CurvesFilter extends TransferFilter {
private Curve[] curves = new Curve[1];
public CurvesFilter() {
curves = new Curve[3];
curves[0] = new Curve();
curves[1] = new Curve();
curves[2] = new Curve();
}
protected void initialize() {
initialized = true;
if ( curves.length == 1 )
rTable = gTable = bTable = curves[0].makeTable();
else {
rTable = curves[0].makeTable();
gTable = curves[1].makeTable();
bTable = curves[2].makeTable();
}
}
public void setCurve( Curve curve ) {
curves = new Curve[] { curve };
initialized = false;
}
public void setCurves( Curve[] curves ) {
if ( curves == null || (curves.length != 1 && curves.length != 3) )
throw new IllegalArgumentException( "Curves must be length 1 or 3" );
this.curves = curves;
initialized = false;
}
public Curve[] getCurves() {
return curves;
}
public String toString() {
return "Colors/Curves...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LensBlurFilter.java 0000644 0001750 0001750 00000023421 11331367130 027034 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.color.*;
import com.jhlabs.math.*;
/**
* A filter which use FFTs to simulate lens blur on an image.
*/
public class LensBlurFilter extends AbstractBufferedImageOp {
private float radius = 10;
private float bloom = 2;
private float bloomThreshold = 192;
private float angle = 0;
private int sides = 5;
/**
* Set the radius of the kernel, and hence the amount of blur.
* @param radius the radius of the blur in pixels.
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the kernel.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
/**
* Set the number of sides of the aperture.
* @param sides the number of sides
* @see #getSides
*/
public void setSides(int sides) {
this.sides = sides;
}
/**
* Get the number of sides of the aperture.
* @return the number of sides
* @see #setSides
*/
public int getSides() {
return sides;
}
/**
* Set the bloom factor.
* @param bloom the bloom factor
* @see #getBloom
*/
public void setBloom(float bloom) {
this.bloom = bloom;
}
/**
* Get the bloom factor.
* @return the bloom factor
* @see #setBloom
*/
public float getBloom() {
return bloom;
}
/**
* Set the bloom threshold.
* @param bloomThreshold the bloom threshold
* @see #getBloomThreshold
*/
public void setBloomThreshold(float bloomThreshold) {
this.bloomThreshold = bloomThreshold;
}
/**
* Get the bloom threshold.
* @return the bloom threshold
* @see #setBloomThreshold
*/
public float getBloomThreshold() {
return bloomThreshold;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int rows = 1, cols = 1;
int log2rows = 0, log2cols = 0;
int iradius = (int)Math.ceil(radius);
int tileWidth = 128;
int tileHeight = tileWidth;
// int adjustedWidth = (int)(width + iradius*2);
// int adjustedHeight = (int)(height + iradius*2);
tileWidth = iradius < 32 ? Math.min(128, width+2*iradius) : Math.min(256, width+2*iradius);
tileHeight = iradius < 32 ? Math.min(128, height+2*iradius) : Math.min(256, height+2*iradius);
if ( dst == null )
dst = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
while (rows < tileHeight) {
rows *= 2;
log2rows++;
}
while (cols < tileWidth) {
cols *= 2;
log2cols++;
}
int w = cols;
int h = rows;
tileWidth = w;
tileHeight = h;//FIXME-tileWidth, w, and cols are always all the same
FFT fft = new FFT( Math.max(log2rows, log2cols) );
int[] rgb = new int[w*h];
float[][] mask = new float[2][w*h];
float[][] gb = new float[2][w*h];
float[][] ar = new float[2][w*h];
// Create the kernel
double polyAngle = Math.PI/sides;
double polyScale = 1.0f / Math.cos(polyAngle);
double r2 = radius*radius;
double rangle = Math.toRadians(angle);
float total = 0;
int i = 0;
for ( int y = 0; y < h; y++ ) {
for ( int x = 0; x < w; x++ ) {
double dx = x-w/2f;
double dy = y-h/2f;
double r = dx*dx+dy*dy;
double f = r < r2 ? 1 : 0;
if (f != 0) {
r = Math.sqrt(r);
if ( sides != 0 ) {
double a = Math.atan2(dy, dx)+rangle;
a = ImageMath.mod(a, polyAngle*2)-polyAngle;
f = Math.cos(a) * polyScale;
} else
f = 1;
f = f*r < radius ? 1 : 0;
}
total += (float)f;
mask[0][i] = (float)f;
mask[1][i] = 0;
i++;
}
}
// Normalize the kernel
i = 0;
for ( int y = 0; y < h; y++ ) {
for ( int x = 0; x < w; x++ ) {
mask[0][i] /= total;
i++;
}
}
fft.transform2D( mask[0], mask[1], w, h, true );
for ( int tileY = -iradius; tileY < height; tileY += tileHeight-2*iradius ) {
for ( int tileX = -iradius; tileX < width; tileX += tileWidth-2*iradius ) {
// System.out.println("Tile: "+tileX+" "+tileY+" "+tileWidth+" "+tileHeight);
// Clip the tile to the image bounds
int tx = tileX, ty = tileY, tw = tileWidth, th = tileHeight;
int fx = 0, fy = 0;
if ( tx < 0 ) {
tw += tx;
fx -= tx;
tx = 0;
}
if ( ty < 0 ) {
th += ty;
fy -= ty;
ty = 0;
}
if ( tx+tw > width )
tw = width-tx;
if ( ty+th > height )
th = height-ty;
src.getRGB( tx, ty, tw, th, rgb, fy*w+fx, w );
// Create a float array from the pixels. Any pixels off the edge of the source image get duplicated from the edge.
i = 0;
for ( int y = 0; y < h; y++ ) {
int imageY = y+tileY;
int j;
if ( imageY < 0 )
j = fy;
else if ( imageY > height )
j = fy+th-1;
else
j = y;
j *= w;
for ( int x = 0; x < w; x++ ) {
int imageX = x+tileX;
int k;
if ( imageX < 0 )
k = fx;
else if ( imageX > width )
k = fx+tw-1;
else
k = x;
k += j;
ar[0][i] = ((rgb[k] >> 24) & 0xff);
float r = ((rgb[k] >> 16) & 0xff);
float g = ((rgb[k] >> 8) & 0xff);
float b = (rgb[k] & 0xff);
// Bloom...
if ( r > bloomThreshold )
r *= bloom;
// r = bloomThreshold + (r-bloomThreshold) * bloom;
if ( g > bloomThreshold )
g *= bloom;
// g = bloomThreshold + (g-bloomThreshold) * bloom;
if ( b > bloomThreshold )
b *= bloom;
// b = bloomThreshold + (b-bloomThreshold) * bloom;
ar[1][i] = r;
gb[0][i] = g;
gb[1][i] = b;
i++;
k++;
}
}
// Transform into frequency space
fft.transform2D( ar[0], ar[1], cols, rows, true );
fft.transform2D( gb[0], gb[1], cols, rows, true );
// Multiply the transformed pixels by the transformed kernel
i = 0;
for ( int y = 0; y < h; y++ ) {
for ( int x = 0; x < w; x++ ) {
float re = ar[0][i];
float im = ar[1][i];
float rem = mask[0][i];
float imm = mask[1][i];
ar[0][i] = re*rem-im*imm;
ar[1][i] = re*imm+im*rem;
re = gb[0][i];
im = gb[1][i];
gb[0][i] = re*rem-im*imm;
gb[1][i] = re*imm+im*rem;
i++;
}
}
// Transform back
fft.transform2D( ar[0], ar[1], cols, rows, false );
fft.transform2D( gb[0], gb[1], cols, rows, false );
// Convert back to RGB pixels, with quadrant remapping
int row_flip = w >> 1;
int col_flip = h >> 1;
int index = 0;
//FIXME-don't bother converting pixels off image edges
for ( int y = 0; y < w; y++ ) {
int ym = y ^ row_flip;
int yi = ym*cols;
for ( int x = 0; x < w; x++ ) {
int xm = yi + (x ^ col_flip);
int a = (int)ar[0][xm];
int r = (int)ar[1][xm];
int g = (int)gb[0][xm];
int b = (int)gb[1][xm];
// Clamp high pixels due to blooming
if ( r > 255 )
r = 255;
if ( g > 255 )
g = 255;
if ( b > 255 )
b = 255;
int argb = (a << 24) | (r << 16) | (g << 8) | b;
rgb[index++] = argb;
}
}
// Clip to the output image
tx = tileX+iradius;
ty = tileY+iradius;
tw = tileWidth-2*iradius;
th = tileHeight-2*iradius;
if ( tx+tw > width )
tw = width-tx;
if ( ty+th > height )
th = height-ty;
dst.setRGB( tx, ty, tw, th, rgb, iradius*w+iradius, w );
}
}
return dst;
}
public String toString() {
return "Blur/Lens Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FadeFilter.java 0000644 0001750 0001750 00000006027 10566356614 026166 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
public class FadeFilter extends PointFilter {
private int width, height;
private float angle = 0.0f;
private float fadeStart = 1.0f;
private float fadeWidth = 10.0f;
private int sides;
private boolean invert;
private float m00 = 1.0f;
private float m01 = 0.0f;
private float m10 = 0.0f;
private float m11 = 1.0f;
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(angle);
float sin = (float)Math.sin(angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
public void setSides(int sides) {
this.sides = sides;
}
public int getSides() {
return sides;
}
public void setFadeStart(float fadeStart) {
this.fadeStart = fadeStart;
}
public float getFadeStart() {
return fadeStart;
}
public void setFadeWidth(float fadeWidth) {
this.fadeWidth = fadeWidth;
}
public float getFadeWidth() {
return fadeWidth;
}
public void setInvert(boolean invert) {
this.invert = invert;
}
public boolean getInvert() {
return invert;
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
super.setDimensions(width, height);
}
public int filterRGB(int x, int y, int rgb) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
if (sides == 2)
nx = (float)Math.sqrt(nx*nx + ny*ny);
else if (sides == 3)
nx = ImageMath.mod(nx, 16);
else if (sides == 4)
nx = symmetry(nx, 16);
int alpha = (int)(ImageMath.smoothStep(fadeStart, fadeStart+fadeWidth, nx) * 255);
if (invert)
alpha = 255-alpha;
return (alpha << 24) | (rgb & 0x00ffffff);
}
public float symmetry(float x, float b) {
/*
int d = (int)(x / b);
x = ImageMath.mod(x, b);
if ((d & 1) == 1)
return b-x;
return x;
*/
x = ImageMath.mod(x, 2*b);
if (x > b)
return 2*b-x;
return x;
}
/*
public float star(float x, float y, int sides, float rMin, float rMax) {
float sideAngle = 2*Math.PI / sides;
float angle = Math.atan2(y, x);
float r = Math.sqrt(x*x + y*y);
float t = ImageMath.mod(angle, sideAngle) / sideAngle;
if (t > 0.5)
t = 1.0-t;
}
*/
public String toString() {
return "Fade...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ConvolveFilter.java 0000644 0001750 0001750 00000027622 10606647276 027130 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
/**
* A filter which applies a convolution kernel to an image.
* @author Jerry Huxtable
*/
public class ConvolveFilter extends AbstractBufferedImageOp {
/**
* Treat pixels off the edge as zero.
*/
public static int ZERO_EDGES = 0;
/**
* Clamp pixels off the edge to the nearest edge.
*/
public static int CLAMP_EDGES = 1;
/**
* Wrap pixels off the edge to the opposite edge.
*/
public static int WRAP_EDGES = 2;
/**
* The convolution kernel.
*/
protected Kernel kernel = null;
/**
* Whether to convolve alpha.
*/
protected boolean alpha = true;
/**
* Whether to promultiply the alpha before convolving.
*/
protected boolean premultiplyAlpha = true;
/**
* What do do at the image edges.
*/
private int edgeAction = CLAMP_EDGES;
/**
* Construct a filter with a null kernel. This is only useful if you're going to change the kernel later on.
*/
public ConvolveFilter() {
this(new float[9]);
}
/**
* Construct a filter with the given 3x3 kernel.
* @param matrix an array of 9 floats containing the kernel
*/
public ConvolveFilter(float[] matrix) {
this(new Kernel(3, 3, matrix));
}
/**
* Construct a filter with the given kernel.
* @param rows the number of rows in the kernel
* @param cols the number of columns in the kernel
* @param matrix an array of rows*cols floats containing the kernel
*/
public ConvolveFilter(int rows, int cols, float[] matrix) {
this(new Kernel(cols, rows, matrix));
}
/**
* Construct a filter with the given 3x3 kernel.
* @param kernel the convolution kernel
*/
public ConvolveFilter(Kernel kernel) {
this.kernel = kernel;
}
/**
* Set the convolution kernel.
* @param kernel the kernel
* @see #getKernel
*/
public void setKernel(Kernel kernel) {
this.kernel = kernel;
}
/**
* Get the convolution kernel.
* @return the kernel
* @see #setKernel
*/
public Kernel getKernel() {
return kernel;
}
/**
* Set the action to perfomr for pixels off the image edges.
* @param edgeAction the action
* @see #getEdgeAction
*/
public void setEdgeAction(int edgeAction) {
this.edgeAction = edgeAction;
}
/**
* Get the action to perfomr for pixels off the image edges.
* @return the action
* @see #setEdgeAction
*/
public int getEdgeAction() {
return edgeAction;
}
/**
* Set whether to convolve the alpha channel.
* @param useAlpha true to convolve the alpha
* @see #getUseAlpha
*/
public void setUseAlpha( boolean useAlpha ) {
this.alpha = useAlpha;
}
/**
* Get whether to convolve the alpha channel.
* @return true to convolve the alpha
* @see #setUseAlpha
*/
public boolean getUseAlpha() {
return alpha;
}
/**
* Set whether to premultiply the alpha channel.
* @param premultiplyAlpha true to premultiply the alpha
* @see #getPremultiplyAlpha
*/
public void setPremultiplyAlpha( boolean premultiplyAlpha ) {
this.premultiplyAlpha = premultiplyAlpha;
}
/**
* Get whether to premultiply the alpha channel.
* @return true to premultiply the alpha
* @see #setPremultiplyAlpha
*/
public boolean getPremultiplyAlpha() {
return premultiplyAlpha;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
getRGB( src, 0, 0, width, height, inPixels );
if ( premultiplyAlpha )
ImageMath.premultiply( inPixels, 0, inPixels.length );
convolve(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
if ( premultiplyAlpha )
ImageMath.unpremultiply( outPixels, 0, outPixels.length );
setRGB( dst, 0, 0, width, height, outPixels );
return dst;
}
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
if ( dstCM == null )
dstCM = src.getColorModel();
return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
}
public Rectangle2D getBounds2D( BufferedImage src ) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
if ( dstPt == null )
dstPt = new Point2D.Double();
dstPt.setLocation( srcPt.getX(), srcPt.getY() );
return dstPt;
}
public RenderingHints getRenderingHints() {
return null;
}
/**
* Convolve a block of pixels.
* @param kernel the kernel
* @param inPixels the input pixels
* @param outPixels the output pixels
* @param width the width
* @param height the height
* @param edgeAction what to do at the edges
*/
public static void convolve(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, int edgeAction) {
convolve(kernel, inPixels, outPixels, width, height, true, edgeAction);
}
/**
* Convolve a block of pixels.
* @param kernel the kernel
* @param inPixels the input pixels
* @param outPixels the output pixels
* @param width the width
* @param height the height
* @param alpha include alpha channel
* @param edgeAction what to do at the edges
*/
public static void convolve(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) {
if (kernel.getHeight() == 1)
convolveH(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
else if (kernel.getWidth() == 1)
convolveV(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
else
convolveHV(kernel, inPixels, outPixels, width, height, alpha, edgeAction);
}
/**
* Convolve with a 2D kernel.
* @param kernel the kernel
* @param inPixels the input pixels
* @param outPixels the output pixels
* @param width the width
* @param height the height
* @param alpha include alpha channel
* @param edgeAction what to do at the edges
*/
public static void convolveHV(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) {
int index = 0;
float[] matrix = kernel.getKernelData( null );
int rows = kernel.getHeight();
int cols = kernel.getWidth();
int rows2 = rows/2;
int cols2 = cols/2;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float r = 0, g = 0, b = 0, a = 0;
for (int row = -rows2; row <= rows2; row++) {
int iy = y+row;
int ioffset;
if (0 <= iy && iy < height)
ioffset = iy*width;
else if ( edgeAction == CLAMP_EDGES )
ioffset = y*width;
else if ( edgeAction == WRAP_EDGES )
ioffset = ((iy+height) % height) * width;
else
continue;
int moffset = cols*(row+rows2)+cols2;
for (int col = -cols2; col <= cols2; col++) {
float f = matrix[moffset+col];
if (f != 0) {
int ix = x+col;
if (!(0 <= ix && ix < width)) {
if ( edgeAction == CLAMP_EDGES )
ix = x;
else if ( edgeAction == WRAP_EDGES )
ix = (x+width) % width;
else
continue;
}
int rgb = inPixels[ioffset+ix];
a += f * ((rgb >> 24) & 0xff);
r += f * ((rgb >> 16) & 0xff);
g += f * ((rgb >> 8) & 0xff);
b += f * (rgb & 0xff);
}
}
}
int ia = alpha ? PixelUtils.clamp((int)(a+0.5)) : 0xff;
int ir = PixelUtils.clamp((int)(r+0.5));
int ig = PixelUtils.clamp((int)(g+0.5));
int ib = PixelUtils.clamp((int)(b+0.5));
outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
}
}
}
/**
* Convolve with a kernel consisting of one row.
* @param kernel the kernel
* @param inPixels the input pixels
* @param outPixels the output pixels
* @param width the width
* @param height the height
* @param alpha include alpha channel
* @param edgeAction what to do at the edges
*/
public static void convolveH(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) {
int index = 0;
float[] matrix = kernel.getKernelData( null );
int cols = kernel.getWidth();
int cols2 = cols/2;
for (int y = 0; y < height; y++) {
int ioffset = y*width;
for (int x = 0; x < width; x++) {
float r = 0, g = 0, b = 0, a = 0;
int moffset = cols2;
for (int col = -cols2; col <= cols2; col++) {
float f = matrix[moffset+col];
if (f != 0) {
int ix = x+col;
if ( ix < 0 ) {
if ( edgeAction == CLAMP_EDGES )
ix = 0;
else if ( edgeAction == WRAP_EDGES )
ix = (x+width) % width;
} else if ( ix >= width) {
if ( edgeAction == CLAMP_EDGES )
ix = width-1;
else if ( edgeAction == WRAP_EDGES )
ix = (x+width) % width;
}
int rgb = inPixels[ioffset+ix];
a += f * ((rgb >> 24) & 0xff);
r += f * ((rgb >> 16) & 0xff);
g += f * ((rgb >> 8) & 0xff);
b += f * (rgb & 0xff);
}
}
int ia = alpha ? PixelUtils.clamp((int)(a+0.5)) : 0xff;
int ir = PixelUtils.clamp((int)(r+0.5));
int ig = PixelUtils.clamp((int)(g+0.5));
int ib = PixelUtils.clamp((int)(b+0.5));
outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
}
}
}
/**
* Convolve with a kernel consisting of one column.
* @param kernel the kernel
* @param inPixels the input pixels
* @param outPixels the output pixels
* @param width the width
* @param height the height
* @param alpha include alpha channel
* @param edgeAction what to do at the edges
*/
public static void convolveV(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) {
int index = 0;
float[] matrix = kernel.getKernelData( null );
int rows = kernel.getHeight();
int rows2 = rows/2;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float r = 0, g = 0, b = 0, a = 0;
for (int row = -rows2; row <= rows2; row++) {
int iy = y+row;
int ioffset;
if ( iy < 0 ) {
if ( edgeAction == CLAMP_EDGES )
ioffset = 0;
else if ( edgeAction == WRAP_EDGES )
ioffset = ((y+height) % height)*width;
else
ioffset = iy*width;
} else if ( iy >= height) {
if ( edgeAction == CLAMP_EDGES )
ioffset = (height-1)*width;
else if ( edgeAction == WRAP_EDGES )
ioffset = ((y+height) % height)*width;
else
ioffset = iy*width;
} else
ioffset = iy*width;
float f = matrix[row+rows2];
if (f != 0) {
int rgb = inPixels[ioffset+x];
a += f * ((rgb >> 24) & 0xff);
r += f * ((rgb >> 16) & 0xff);
g += f * ((rgb >> 8) & 0xff);
b += f * (rgb & 0xff);
}
}
int ia = alpha ? PixelUtils.clamp((int)(a+0.5)) : 0xff;
int ir = PixelUtils.clamp((int)(r+0.5));
int ig = PixelUtils.clamp((int)(g+0.5));
int ib = PixelUtils.clamp((int)(b+0.5));
outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
}
}
}
public String toString() {
return "Blur/Convolve...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BumpFilter.java 0000644 0001750 0001750 00000001643 10566356614 026231 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A simple embossing filter.
*/
public class BumpFilter extends ConvolveFilter {
private static float[] embossMatrix = {
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f
};
public BumpFilter() {
super(embossMatrix);
}
public String toString() {
return "Blur/Emboss Edges";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SwizzleFilter.java 0000644 0001750 0001750 00000003065 10626011515 026756 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* A filter which allows channels to be swapped. You provide a matrix with specifying the input channel for
* each output channel.
*/
public class SwizzleFilter extends PointFilter {
private int[] matrix = {
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
};
public SwizzleFilter() {
}
/**
* Set the swizzle matrix.
* @param matrix the matrix
* @see #getMatrix
*/
public void setMatrix( int[] matrix ) {
this.matrix = matrix;
}
/**
* Get the swizzle matrix.
* @return the matrix
* @see #setMatrix
*/
public int[] getMatrix() {
return matrix;
}
public int filterRGB(int x, int y, int rgb) {
int a = (rgb >> 24) & 0xff;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
a = matrix[0]*a + matrix[1]*r + matrix[2]*g + matrix[3]*b + matrix[4]*255;
r = matrix[5]*a + matrix[6]*r + matrix[7]*g + matrix[8]*b + matrix[9]*255;
g = matrix[10]*a + matrix[11]*r + matrix[12]*g + matrix[13]*b + matrix[14]*255;
b = matrix[15]*a + matrix[16]*r + matrix[17]*g + matrix[18]*b + matrix[19]*255;
a = PixelUtils.clamp( a );
r = PixelUtils.clamp( r );
g = PixelUtils.clamp( g );
b = PixelUtils.clamp( b );
return (a << 24) | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Channels/Swizzle...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/IteratedFilter.java 0000644 0001750 0001750 00000002404 10566356614 027063 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A BufferedImageOp which iterates another BufferedImageOp.
*/
public class IteratedFilter extends AbstractBufferedImageOp {
private BufferedImageOp filter;
private int iterations;
/**
* Construct an IteratedFilter.
* @param filter the filetr to iterate
* @param iterations the number of iterations
*/
public IteratedFilter( BufferedImageOp filter, int iterations ) {
this.filter = filter;
this.iterations = iterations;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
BufferedImage image = src;
for ( int i = 0; i < iterations; i++ )
image = filter.filter( image, dst );
return image;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/WarpGrid.java 0000644 0001750 0001750 00000021171 10562652111 025660 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A warp grid.
* From "A simplified approach to Image Processing" by Randy Crane
*/
public class WarpGrid {
public float[] xGrid = null;
public float[] yGrid = null;
public int rows, cols;
public WarpGrid(int rows, int cols, int w, int h) {
this.rows = rows;
this.cols = cols;
xGrid = new float[rows*cols];
yGrid = new float[rows*cols];
int index = 0;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
xGrid[index] = (float)col*(w-1)/(cols-1);
yGrid[index] = (float)row*(h-1)/(rows-1);
index++;
}
}
}
/**
* Add a new row to the grid. "before" must be in the range 1..rows-1. i.e. you can only add rows inside the grid.
*/
public void addRow( int before ) {
int size = (rows+1) * cols;
float[] x = new float[size];
float[] y = new float[size];
rows++;
int i = 0;
int j = 0;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
int k = j+col;
int l = i+col;
if ( row == before ) {
x[k] = (xGrid[l]+xGrid[k])/2;
y[k] = (yGrid[l]+yGrid[k])/2;
} else {
x[k] = xGrid[l];
y[k] = yGrid[l];
}
}
if ( row != before-1 )
i += cols;
j += cols;
}
xGrid = x;
yGrid = y;
}
/**
* Add a new column to the grid. "before" must be in the range 1..cols-1. i.e. you can only add columns inside the grid.
*/
public void addCol( int before ) {
int size = rows * (cols+1);
float[] x = new float[size];
float[] y = new float[size];
cols++;
int i = 0;
int j = 0;
for (int row = 0; row < rows; row++) {
// int i = row*(cols-1);
// int j = row*cols;
for (int col = 0; col < cols; col++) {
if ( col == before ) {
x[j] = (xGrid[i]+xGrid[i-1])/2;
y[j] = (yGrid[i]+yGrid[i-1])/2;
} else {
x[j] = xGrid[i];
y[j] = yGrid[i];
i++;
}
j++;
}
}
xGrid = x;
yGrid = y;
}
/**
* Remove a row from the grid.
*/
public void removeRow( int r ) {
int size = (rows-1) * cols;
float[] x = new float[size];
float[] y = new float[size];
rows--;
int i = 0;
int j = 0;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
int k = j+col;
int l = i+col;
x[k] = xGrid[l];
y[k] = yGrid[l];
}
if ( row == r-1 )
i += cols;
i += cols;
j += cols;
}
xGrid = x;
yGrid = y;
}
/**
* Remove a column from the grid.
*/
public void removeCol( int r ) {
int size = rows * (cols+1);
float[] x = new float[size];
float[] y = new float[size];
cols--;
for (int row = 0; row < rows; row++) {
int i = row*(cols+1);
int j = row*cols;
for (int col = 0; col < cols; col++) {
x[j] = xGrid[i];
y[j] = yGrid[i];
if ( col == r-1 )
i++;
i++;
j++;
}
}
xGrid = x;
yGrid = y;
}
public void lerp(float t, WarpGrid destination, WarpGrid intermediate) {
if (rows != destination.rows || cols != destination.cols)
throw new IllegalArgumentException("source and destination are different sizes");
if (rows != intermediate.rows || cols != intermediate.cols)
throw new IllegalArgumentException("source and intermediate are different sizes");
int index = 0;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
intermediate.xGrid[index] = (float)ImageMath.lerp(t, xGrid[index], destination.xGrid[index]);
intermediate.yGrid[index] = (float)ImageMath.lerp(t, yGrid[index], destination.yGrid[index]);
index++;
}
}
}
public void warp(int[] inPixels, int cols, int rows, WarpGrid sourceGrid, WarpGrid destGrid, int[] outPixels) {
try {
int x, y;
int u, v;
int[] intermediate;
WarpGrid splines;
if (sourceGrid.rows != destGrid.rows || sourceGrid.cols != destGrid.cols)
throw new IllegalArgumentException("source and destination grids are different sizes");
int size = Math.max(cols, rows);
float[] xrow = new float[size];
float[] yrow = new float[size];
float[] scale = new float[size + 1];
float[] interpolated = new float[size + 1];
int gridCols = sourceGrid.cols;
int gridRows = sourceGrid.rows;
splines = new WarpGrid(rows, gridCols, 1, 1);
for (u = 0; u < gridCols;u++) {
int i = u;
for (v = 0; v < gridRows;v++) {
xrow[v] = sourceGrid.xGrid[i];
yrow[v] = sourceGrid.yGrid[i];
i += gridCols;
}
interpolateSpline(yrow, xrow, 0, gridRows, interpolated, 0, rows);
i = u;
for (y = 0;y < rows;y++) {
splines.xGrid[i] = interpolated[y];
i += gridCols;
}
}
for (u = 0; u < gridCols;u++) {
int i = u;
for (v = 0; v < gridRows;v++) {
xrow[v] = destGrid.xGrid[i];
yrow[v] = destGrid.yGrid[i];
i += gridCols;
}
interpolateSpline(yrow, xrow, 0, gridRows, interpolated, 0, rows);
i = u;
for (y = 0;y < rows; y++) {
splines.yGrid[i] = interpolated[y];
i += gridCols;
}
}
/* first pass: warp x using splines */
intermediate = new int[rows*cols];
int offset = 0;
for (y = 0; y < rows; y++) {
/* fit spline to x-intercepts;resample over all cols */
interpolateSpline(splines.xGrid, splines.yGrid, offset, gridCols, scale, 0, cols);
scale[cols] = cols;
ImageMath.resample(inPixels, intermediate, cols, y*cols, 1, scale);
offset += gridCols;
}
/* create table of y-intercepts for intermediate mesh's hor splines */
splines = new WarpGrid(gridRows, cols, 1, 1);
offset = 0;
int offset2 = 0;
for (v = 0; v < gridRows; v++) {
interpolateSpline(sourceGrid.xGrid, sourceGrid.yGrid, offset, gridCols, splines.xGrid, offset2, cols);
offset += gridCols;
offset2 += cols;
}
offset = 0;
offset2 = 0;
for (v = 0; v < gridRows; v++) {
interpolateSpline(destGrid.xGrid, destGrid.yGrid, offset, gridCols, splines.yGrid, offset2, cols);
offset += gridCols;
offset2 += cols;
}
/* second pass: warp y */
for (x = 0; x < cols; x++) {
int i = x;
for (v = 0; v < gridRows; v++) {
xrow[v] = splines.xGrid[i];;
yrow[v] = splines.yGrid[i];;
i += cols;
}
interpolateSpline(xrow, yrow, 0, gridRows, scale, 0, rows);
scale[rows] = rows;
ImageMath.resample(intermediate, outPixels, rows, x, cols, scale);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private final static float m00 = -0.5f;
private final static float m01 = 1.5f;
private final static float m02 = -1.5f;
private final static float m03 = 0.5f;
private final static float m10 = 1.0f;
private final static float m11 = -2.5f;
private final static float m12 = 2.0f;
private final static float m13 = -0.5f;
private final static float m20 = -0.5f;
private final static float m22 = 0.5f;
private final static float m31 = 1.0f;
protected void interpolateSpline(float[] xKnots, float[] yKnots, int offset, int length, float[] splineY, int splineOffset, int splineLength) {
int index = offset;
int end = offset+length-1;
float x0, x1;
float k0, k1, k2, k3;
float c0, c1, c2, c3;
x0 = xKnots[index];
k0 = k1 = k2 = yKnots[index];
x1 = xKnots[index+1];
k3 = yKnots[index+1];
for (int i = 0;i < splineLength;i++) {
if (index <= end && i > xKnots[index]) {
k0 = k1;
k1 = k2;
k2 = k3;
x0 = xKnots[index];
index++;
if ( index <= end )
x1 = xKnots[index];
if ( index < end )
k3 = yKnots[index+1];
else
k3 = k2;
}
float t = (i - x0) / (x1 - x0);
c3 = m00*k0 + m01*k1 + m02*k2 + m03*k3;
c2 = m10*k0 + m11*k1 + m12*k2 + m13*k3;
c1 = m20*k0 + m22*k2;
c0 = m31*k1;
splineY[splineOffset+i] = ((c3*t + c2)*t + c1)*t + c0;
}
}
protected void interpolateSpline2(float[] xKnots, float[] yKnots, int offset, float[] splineY, int splineOffset, int splineLength) {
int index = offset;
float leftX, rightX;
float leftY, rightY;
leftX = xKnots[index];
leftY = yKnots[index];
rightX = xKnots[index+1];
rightY = yKnots[index+1];
for (int i = 0;i < splineLength;i++) {
if (i > xKnots[index]) {
leftX = xKnots[index];
leftY = yKnots[index];
index++;
rightX = xKnots[index];
rightY = yKnots[index];
}
float f = (i - leftX) / (rightX - leftX);
splineY[splineOffset+i] = leftY + f * (rightY - leftY);
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TextureFilter.java 0000644 0001750 0001750 00000011046 10566356614 026764 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import com.jhlabs.math.*;
public class TextureFilter extends PointFilter {
private float scale = 32;
private float stretch = 1.0f;
private float angle = 0.0f;
public float amount = 1.0f;
public float turbulence = 1.0f;
public float gain = 0.5f;
public float bias = 0.5f;
public int operation;
private float m00 = 1.0f;
private float m01 = 0.0f;
private float m10 = 0.0f;
private float m11 = 1.0f;
private Colormap colormap = new Gradient();
private Function2D function = new Noise();
public TextureFilter() {
}
/**
* Set the amount of texture.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of texture.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public void setFunction(Function2D function) {
this.function = function;
}
public Function2D getFunction() {
return function;
}
public void setOperation(int operation) {
this.operation = operation;
}
public int getOperation() {
return operation;
}
/**
* Specifies the scale of the texture.
* @param scale the scale of the texture.
* @min-value 1
* @max-value 300+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the texture.
* @return the scale of the texture.
* @see #setScale
*/
public float getScale() {
return scale;
}
/**
* Specifies the stretch factor of the texture.
* @param stretch the stretch factor of the texture.
* @min-value 1
* @max-value 50+
* @see #getStretch
*/
public void setStretch(float stretch) {
this.stretch = stretch;
}
/**
* Returns the stretch factor of the texture.
* @return the stretch factor of the texture.
* @see #setStretch
*/
public float getStretch() {
return stretch;
}
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(angle);
float sin = (float)Math.sin(angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Specifies the turbulence of the texture.
* @param turbulence the turbulence of the texture.
* @min-value 0
* @max-value 1
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the texture.
* @return the turbulence of the texture.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public int filterRGB(int x, int y, int rgb) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
float f = turbulence == 1.0 ? Noise.noise2(nx, ny) : Noise.turbulence2(nx, ny, turbulence);
f = (f * 0.5f) + 0.5f;
f = ImageMath.gain(f, gain);
f = ImageMath.bias(f, bias);
f *= amount;
int a = rgb & 0xff000000;
int v;
if (colormap != null)
v = colormap.getColor(f);
else {
v = PixelUtils.clamp((int)(f*255));
int r = v << 16;
int g = v << 8;
int b = v;
v = a|r|g|b;
}
if (operation != PixelUtils.REPLACE)
v = PixelUtils.combinePixels(rgb, v, operation);
return v;
}
public String toString() {
return "Texture/Noise...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CausticsFilter.java 0000644 0001750 0001750 00000017645 10566572034 027111 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import com.jhlabs.math.*;
/**
* A filter which simulates underwater caustics. This can be animated to get a bottom-of-the-swimming-pool effect.
*/
public class CausticsFilter extends WholeImageFilter {
private float scale = 32;
private float angle = 0.0f;
private int brightness = 10;
private float amount = 1.0f;
private float turbulence = 1.0f;
private float dispersion = 0.0f;
private float time = 0.0f;
private int samples = 2;
private int bgColor = 0xff799fff;
private float s, c;
public CausticsFilter() {
}
/**
* Specifies the scale of the texture.
* @param scale the scale of the texture.
* @min-value 1
* @max-value 300+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the texture.
* @return the scale of the texture.
* @see #setScale
*/
public float getScale() {
return scale;
}
/**
* Set the brightness.
* @param brightness the brightness.
* @min-value 0
* @max-value 1
* @see #getBrightness
*/
public void setBrightness(int brightness) {
this.brightness = brightness;
}
/**
* Get the brightness.
* @return the brightness.
* @see #setBrightness
*/
public int getBrightness() {
return brightness;
}
/**
* Specifies the turbulence of the texture.
* @param turbulence the turbulence of the texture.
* @min-value 0
* @max-value 1
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the effect.
* @return the turbulence of the effect.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
/**
* Set the amount of effect.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of effect.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
/**
* Set the dispersion.
* @param dispersion the dispersion
* @min-value 0
* @max-value 1
* @see #getDispersion
*/
public void setDispersion(float dispersion) {
this.dispersion = dispersion;
}
/**
* Get the dispersion.
* @return the dispersion
* @see #setDispersion
*/
public float getDispersion() {
return dispersion;
}
/**
* Set the time. Use this to animate the effect.
* @param time the time
* @see #getTime
*/
public void setTime(float time) {
this.time = time;
}
/**
* Set the time.
* @return the time
* @see #setTime
*/
public float getTime() {
return time;
}
/**
* Set the number of samples per pixel. More samples means better quality, but slower rendering.
* @param samples the number of samples
* @see #getSamples
*/
public void setSamples(int samples) {
this.samples = samples;
}
/**
* Get the number of samples per pixel.
* @return the number of samples
* @see #setSamples
*/
public int getSamples() {
return samples;
}
/**
* Set the background color.
* @param c the color
* @see #getBgColor
*/
public void setBgColor(int c) {
bgColor = c;
}
/**
* Get the background color.
* @return the color
* @see #setBgColor
*/
public int getBgColor() {
return bgColor;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
Random random = new Random(0);
s = (float)Math.sin(0.1);
c = (float)Math.cos(0.1);
int srcWidth = originalSpace.width;
int srcHeight = originalSpace.height;
int outWidth = transformedSpace.width;
int outHeight = transformedSpace.height;
int index = 0;
int[] pixels = new int[outWidth * outHeight];
for (int y = 0; y < outHeight; y++) {
for (int x = 0; x < outWidth; x++) {
pixels[index++] = bgColor;
}
}
int v = brightness/samples;
if (v == 0)
v = 1;
float rs = 1.0f/scale;
float d = 0.95f;
index = 0;
for (int y = 0; y < outHeight; y++) {
for (int x = 0; x < outWidth; x++) {
for (int s = 0; s < samples; s++) {
float sx = x+random.nextFloat();
float sy = y+random.nextFloat();
float nx = sx*rs;
float ny = sy*rs;
float xDisplacement, yDisplacement;
float focus = 0.1f+amount;
xDisplacement = evaluate(nx-d, ny) - evaluate(nx+d, ny);
yDisplacement = evaluate(nx, ny+d) - evaluate(nx, ny-d);
if (dispersion > 0) {
for (int c = 0; c < 3; c++) {
float ca = (1+c*dispersion);
float srcX = sx + scale*focus * xDisplacement*ca;
float srcY = sy + scale*focus * yDisplacement*ca;
if (srcX < 0 || srcX >= outWidth-1 || srcY < 0 || srcY >= outHeight-1) {
} else {
int i = ((int)srcY)*outWidth+(int)srcX;
int rgb = pixels[i];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if (c == 2)
r += v;
else if (c == 1)
g += v;
else
b += v;
if (r > 255)
r = 255;
if (g > 255)
g = 255;
if (b > 255)
b = 255;
pixels[i] = 0xff000000 | (r << 16) | (g << 8) | b;
}
}
} else {
float srcX = sx + scale*focus * xDisplacement;
float srcY = sy + scale*focus * yDisplacement;
if (srcX < 0 || srcX >= outWidth-1 || srcY < 0 || srcY >= outHeight-1) {
} else {
int i = ((int)srcY)*outWidth+(int)srcX;
int rgb = pixels[i];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r += v;
g += v;
b += v;
if (r > 255)
r = 255;
if (g > 255)
g = 255;
if (b > 255)
b = 255;
pixels[i] = 0xff000000 | (r << 16) | (g << 8) | b;
}
}
}
}
}
return pixels;
}
private static int add(int rgb, float brightness) {
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r += brightness;
g += brightness;
b += brightness;
if (r > 255)
r = 255;
if (g > 255)
g = 255;
if (b > 255)
b = 255;
return 0xff000000 | (r << 16) | (g << 8) | b;
}
private static int add(int rgb, float brightness, int c) {
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if (c == 2)
r += brightness;
else if (c == 1)
g += brightness;
else
b += brightness;
if (r > 255)
r = 255;
if (g > 255)
g = 255;
if (b > 255)
b = 255;
return 0xff000000 | (r << 16) | (g << 8) | b;
}
private static float turbulence2(float x, float y, float time, float octaves) {
float value = 0.0f;
float remainder;
float lacunarity = 2.0f;
float f = 1.0f;
int i;
// to prevent "cascading" effects
x += 371;
y += 529;
for (i = 0; i < (int)octaves; i++) {
value += Noise.noise3(x, y, time) / f;
x *= lacunarity;
y *= lacunarity;
f *= 2;
}
remainder = octaves - (int)octaves;
if (remainder != 0)
value += remainder * Noise.noise3(x, y, time) / f;
return value;
}
private float evaluate(float x, float y) {
float xt = s*x + c*time;
float tt = c*x - c*time;
float f = turbulence == 0.0 ? Noise.noise3(xt, y, tt) : turbulence2(xt, y, tt, turbulence);
return f;
}
public String toString() {
return "Texture/Caustics...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SplineColormap.java 0000644 0001750 0001750 00000006664 10566572034 027113 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.Color;
import java.util.Vector;
import java.io.*;
/**
* A Colormap implemented using Catmull-Rom colour splines. The map has a variable number
* of knots with a minimum of four. The first and last knots give the tangent at the end
* of the spline, and colours are interpolated from the second to the second-last knots.
*/
public class SplineColormap extends ArrayColormap {
private int numKnots = 4;
private int[] xKnots = {
0, 0, 255, 255
};
private int[] yKnots = {
0xff000000, 0xff000000, 0xffffffff, 0xffffffff,
};
/**
* Construct a SplineColormap.
*/
public SplineColormap() {
rebuildGradient();
}
/**
* Construct a SplineColormap.
* @param xKnots the knot positions
* @param yKnots the knot colors
*/
public SplineColormap(int[] xKnots, int[] yKnots) {
this.xKnots = xKnots;
this.yKnots = yKnots;
numKnots = xKnots.length;
rebuildGradient();
}
/**
* Set a knot color.
* @param n the knot index
* @param color the color
* @see #getKnot
*/
public void setKnot(int n, int color) {
yKnots[n] = color;
rebuildGradient();
}
/**
* Get a knot color.
* @param n the knot index
* @return the knot color
* @see #setKnot
*/
public int getKnot(int n) {
return yKnots[n];
}
/**
* Add a new knot.
* @param x the knot position
* @param color the color
* @see #removeKnot
*/
public void addKnot(int x, int color) {
int[] nx = new int[numKnots+1];
int[] ny = new int[numKnots+1];
System.arraycopy(xKnots, 0, nx, 0, numKnots);
System.arraycopy(yKnots, 0, ny, 0, numKnots);
xKnots = nx;
yKnots = ny;
xKnots[numKnots] = x;
yKnots[numKnots] = color;
numKnots++;
sortKnots();
rebuildGradient();
}
/**
* Remove a knot.
* @param n the knot index
* @see #addKnot
*/
public void removeKnot(int n) {
if (numKnots <= 4)
return;
if (n < numKnots-1) {
System.arraycopy(xKnots, n+1, xKnots, n, numKnots-n-1);
System.arraycopy(yKnots, n+1, yKnots, n, numKnots-n-1);
}
numKnots--;
rebuildGradient();
}
/**
* Set a knot position.
* @param n the knot index
* @param x the knot position
*/
public void setKnotPosition(int n, int x) {
xKnots[n] = PixelUtils.clamp(x);
sortKnots();
rebuildGradient();
}
private void rebuildGradient() {
xKnots[0] = -1;
xKnots[numKnots-1] = 256;
yKnots[0] = yKnots[1];
yKnots[numKnots-1] = yKnots[numKnots-2];
for (int i = 0; i < 256; i++)
map[i] = ImageMath.colorSpline(i, numKnots, xKnots, yKnots);
}
private void sortKnots() {
for (int i = 1; i < numKnots; i++) {
for (int j = 1; j < i; j++) {
if (xKnots[i] < xKnots[j]) {
int t = xKnots[i];
xKnots[i] = xKnots[j];
xKnots[j] = t;
t = yKnots[i];
yKnots[i] = yKnots[j];
yKnots[j] = t;
}
}
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/WarpFilter.java 0000644 0001750 0001750 00000010360 10566572034 026227 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
/**
* A filter for warping images using the gridwarp algorithm.
* You need to supply two warp grids, one for the source image and
* one for the destination image. The image will be warped so that
* a point in the source grid moves to its counterpart in the destination
* grid.
*/
public class WarpFilter extends WholeImageFilter {
private WarpGrid sourceGrid;
private WarpGrid destGrid;
private int frames = 1;
private BufferedImage morphImage;
private float time;
/**
* Create a WarpFilter.
*/
public WarpFilter() {
}
/**
* Create a WarpFilter with two warp grids.
* @param sourceGrid the source grid
* @param destGrid the destination grid
*/
public WarpFilter(WarpGrid sourceGrid, WarpGrid destGrid) {
this.sourceGrid = sourceGrid;
this.destGrid = destGrid;
}
/**
* Set the source warp grid.
* @param sourceGrid the source grid
* @see #getSourceGrid
*/
public void setSourceGrid(WarpGrid sourceGrid) {
this.sourceGrid = sourceGrid;
}
/**
* Get the source warp grid.
* @return the source grid
* @see #setSourceGrid
*/
public WarpGrid getSourceGrid() {
return sourceGrid;
}
/**
* Set the destination warp grid.
* @param destGrid the destination grid
* @see #getDestGrid
*/
public void setDestGrid(WarpGrid destGrid) {
this.destGrid = destGrid;
}
/**
* Get the destination warp grid.
* @return the destination grid
* @see #setDestGrid
*/
public WarpGrid getDestGrid() {
return destGrid;
}
public void setFrames(int frames) {
this.frames = frames;
}
public int getFrames() {
return frames;
}
/**
* For morphing, sets the image we're morphing to. If not, set then we're just warping.
*/
public void setMorphImage(BufferedImage morphImage) {
this.morphImage = morphImage;
}
public BufferedImage getMorphImage() {
return morphImage;
}
public void setTime(float time) {
this.time = time;
}
public float getTime() {
return time;
}
protected void transformSpace(Rectangle r) {
r.width *= frames;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
if ( morphImage != null ) {
int[] morphPixels = getRGB( morphImage, 0, 0, width, height, null );
morph( inPixels, morphPixels, outPixels, sourceGrid, destGrid, width, height, time );
} else if (frames <= 1) {
sourceGrid.warp(inPixels, width, height, sourceGrid, destGrid, outPixels);
} else {
WarpGrid newGrid = new WarpGrid(sourceGrid.rows, sourceGrid.cols, width, height);
for (int i = 0; i < frames; i++) {
float t = (float)i/(frames-1);
sourceGrid.lerp(t, destGrid, newGrid);
sourceGrid.warp(inPixels, width, height, sourceGrid, newGrid, outPixels);
}
}
return outPixels;
}
public void morph(int[] srcPixels, int[] destPixels, int[] outPixels, WarpGrid srcGrid, WarpGrid destGrid, int width, int height, float t) {
WarpGrid newGrid = new WarpGrid(srcGrid.rows, srcGrid.cols, width, height);
srcGrid.lerp(t, destGrid, newGrid);
srcGrid.warp(srcPixels, width, height, srcGrid, newGrid, outPixels);
int[] destPixels2 = new int[width * height];
destGrid.warp(destPixels, width, height, destGrid, newGrid, destPixels2);
crossDissolve(outPixels, destPixels2, width, height, t);
}
public void crossDissolve(int[] pixels1, int[] pixels2, int width, int height, float t) {
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixels1[index] = ImageMath.mixColors(t, pixels1[index], pixels2[index]);
index++;
}
}
}
public String toString() {
return "Distort/Mesh Warp...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Gradient.java 0000644 0001750 0001750 00000031541 11331373211 025674 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.Color;
import java.util.Vector;
import java.io.*;
/**
* A Colormap implemented using Catmull-Rom colour splines. The map has a variable number
* of knots with a minimum of four. The first and last knots give the tangent at the end
* of the spline, and colours are interpolated from the second to the second-last knots.
* Each knot can be given a type of interpolation. These are:
*
*
LINEAR - linear interpolation to next knot
*
SPLINE - spline interpolation to next knot
*
CONSTANT - no interpolation - the colour is constant to the next knot
*
HUE_CW - interpolation of hue clockwise to next knot
*
HUE_CCW - interpolation of hue counter-clockwise to next knot
*
*/
public class Gradient extends ArrayColormap implements Cloneable {
/**
* Interpolate in RGB space.
*/
public final static int RGB = 0x00;
/**
* Interpolate hue clockwise.
*/
public final static int HUE_CW = 0x01;
/**
* Interpolate hue counter clockwise.
*/
public final static int HUE_CCW = 0x02;
/**
* Interpolate linearly.
*/
public final static int LINEAR = 0x10;
/**
* Interpolate using a spline.
*/
public final static int SPLINE = 0x20;
/**
* Interpolate with a rising circle shape curve.
*/
public final static int CIRCLE_UP = 0x30;
/**
* Interpolate with a falling circle shape curve.
*/
public final static int CIRCLE_DOWN = 0x40;
/**
* Don't tnterpolate - just use the starting value.
*/
public final static int CONSTANT = 0x50;
private final static int COLOR_MASK = 0x03;
private final static int BLEND_MASK = 0x70;
private int numKnots = 4;
private int[] xKnots = {
-1, 0, 255, 256
};
private int[] yKnots = {
0xff000000, 0xff000000, 0xffffffff, 0xffffffff,
};
private byte[] knotTypes = {
RGB|SPLINE, RGB|SPLINE, RGB|SPLINE, RGB|SPLINE
};
/**
* Construct a Gradient.
*/
public Gradient() {
rebuildGradient();
}
/**
* Construct a Gradient with the given colors.
* @param rgb the colors
*/
public Gradient(int[] rgb) {
this(null, rgb, null);
}
/**
* Construct a Gradient with the given colors and knot positions.
* @param x the knot positions
* @param rgb the colors
*/
public Gradient(int[] x, int[] rgb) {
this(x, rgb, null);
}
/**
* Construct a Gradient with the given colors, knot positions and interpolation types.
* @param x the knot positions
* @param rgb the colors
* @param types interpolation types
*/
public Gradient(int[] x, int[] rgb, byte[] types) {
setKnots(x, rgb, types);
}
public Object clone() {
Gradient g = (Gradient)super.clone();
g.map = (int[])map.clone();
g.xKnots = (int[])xKnots.clone();
g.yKnots = (int[])yKnots.clone();
g.knotTypes = (byte[])knotTypes.clone();
return g;
}
/**
* Copy one Gradient into another.
* @param g the Gradient to copy into
*/
public void copyTo(Gradient g) {
g.numKnots = numKnots;
g.map = (int[])map.clone();
g.xKnots = (int[])xKnots.clone();
g.yKnots = (int[])yKnots.clone();
g.knotTypes = (byte[])knotTypes.clone();
}
/**
* Set a knot color.
* @param n the knot index
* @param color the color
*/
public void setColor(int n, int color) {
int firstColor = map[0];
int lastColor = map[256-1];
if (n > 0)
for (int i = 0; i < n; i++)
map[i] = ImageMath.mixColors((float)i/n, firstColor, color);
if (n < 256-1)
for (int i = n; i < 256; i++)
map[i] = ImageMath.mixColors((float)(i-n)/(256-n), color, lastColor);
}
/**
* Get the number of knots in the gradient.
* @return the number of knots.
*/
public int getNumKnots() {
return numKnots;
}
/**
* Set a knot color.
* @param n the knot index
* @param color the color
* @see #getKnot
*/
public void setKnot(int n, int color) {
yKnots[n] = color;
rebuildGradient();
}
/**
* Get a knot color.
* @param n the knot index
* @return the knot color
* @see #setKnot
*/
public int getKnot(int n) {
return yKnots[n];
}
/**
* Set a knot type.
* @param n the knot index
* @param type the type
* @see #getKnotType
*/
public void setKnotType(int n, int type) {
knotTypes[n] = (byte)((knotTypes[n] & ~COLOR_MASK) | type);
rebuildGradient();
}
/**
* Get a knot type.
* @param n the knot index
* @return the knot type
* @see #setKnotType
*/
public int getKnotType(int n) {
return (byte)(knotTypes[n] & COLOR_MASK);
}
/**
* Set a knot blend type.
* @param n the knot index
* @param type the knot blend type
* @see #getKnotBlend
*/
public void setKnotBlend(int n, int type) {
knotTypes[n] = (byte)((knotTypes[n] & ~BLEND_MASK) | type);
rebuildGradient();
}
/**
* Get a knot blend type.
* @param n the knot index
* @return the knot blend type
* @see #setKnotBlend
*/
public byte getKnotBlend(int n) {
return (byte)(knotTypes[n] & BLEND_MASK);
}
/**
* Add a new knot.
* @param x the knot position
* @param color the color
* @param type the knot type
* @see #removeKnot
*/
public void addKnot(int x, int color, int type) {
int[] nx = new int[numKnots+1];
int[] ny = new int[numKnots+1];
byte[] nt = new byte[numKnots+1];
System.arraycopy(xKnots, 0, nx, 0, numKnots);
System.arraycopy(yKnots, 0, ny, 0, numKnots);
System.arraycopy(knotTypes, 0, nt, 0, numKnots);
xKnots = nx;
yKnots = ny;
knotTypes = nt;
// Insert one position before the end so the sort works correctly
xKnots[numKnots] = xKnots[numKnots-1];
yKnots[numKnots] = yKnots[numKnots-1];
knotTypes[numKnots] = knotTypes[numKnots-1];
xKnots[numKnots-1] = x;
yKnots[numKnots-1] = color;
knotTypes[numKnots-1] = (byte)type;
numKnots++;
sortKnots();
rebuildGradient();
}
/**
* Remove a knot.
* @param n the knot index
* @see #addKnot
*/
public void removeKnot(int n) {
if (numKnots <= 4)
return;
if (n < numKnots-1) {
System.arraycopy(xKnots, n+1, xKnots, n, numKnots-n-1);
System.arraycopy(yKnots, n+1, yKnots, n, numKnots-n-1);
System.arraycopy(knotTypes, n+1, knotTypes, n, numKnots-n-1);
}
numKnots--;
if (xKnots[1] > 0)
xKnots[1] = 0;
rebuildGradient();
}
/**
* Set the values of all the knots.
* This version does not require the "extra" knots at -1 and 256
* @param x the knot positions
* @param rgb the knot colors
* @param types the knot types
*/
public void setKnots(int[] x, int[] rgb, byte[] types) {
numKnots = rgb.length+2;
xKnots = new int[numKnots];
yKnots = new int[numKnots];
knotTypes = new byte[numKnots];
if (x != null)
System.arraycopy(x, 0, xKnots, 1, numKnots-2);
else
for (int i = 1; i > numKnots-1; i++)
xKnots[i] = 255*i/(numKnots-2);
System.arraycopy(rgb, 0, yKnots, 1, numKnots-2);
if (types != null)
System.arraycopy(types, 0, knotTypes, 1, numKnots-2);
else
for (int i = 0; i > numKnots; i++)
knotTypes[i] = RGB|SPLINE;
sortKnots();
rebuildGradient();
}
/**
* Set the values of a set of knots.
* @param x the knot positions
* @param y the knot colors
* @param types the knot types
* @param offset the first knot to set
* @param count the number of knots
*/
public void setKnots(int[] x, int[] y, byte[] types, int offset, int count) {
numKnots = count;
xKnots = new int[numKnots];
yKnots = new int[numKnots];
knotTypes = new byte[numKnots];
System.arraycopy(x, offset, xKnots, 0, numKnots);
System.arraycopy(y, offset, yKnots, 0, numKnots);
System.arraycopy(types, offset, knotTypes, 0, numKnots);
sortKnots();
rebuildGradient();
}
/**
* Split a span into two by adding a knot in the middle.
* @param n the span index
*/
public void splitSpan(int n) {
int x = (xKnots[n] + xKnots[n+1])/2;
addKnot(x, getColor(x/256.0f), knotTypes[n]);
rebuildGradient();
}
/**
* Set a knot position.
* @param n the knot index
* @param x the knot position
* @see #setKnotPosition
*/
public void setKnotPosition(int n, int x) {
xKnots[n] = ImageMath.clamp(x, 0, 255);
sortKnots();
rebuildGradient();
}
/**
* Get a knot position.
* @param n the knot index
* @return the knot position
* @see #setKnotPosition
*/
public int getKnotPosition(int n) {
return xKnots[n];
}
/**
* Return the knot at a given position.
* @param x the position
* @return the knot number, or 1 if no knot found
*/
public int knotAt(int x) {
for (int i = 1; i < numKnots-1; i++)
if (xKnots[i+1] > x)
return i;
return 1;
}
private void rebuildGradient() {
xKnots[0] = -1;
xKnots[numKnots-1] = 256;
yKnots[0] = yKnots[1];
yKnots[numKnots-1] = yKnots[numKnots-2];
// int knot = 0;
for (int i = 1; i < numKnots-1; i++) {
float spanLength = xKnots[i+1]-xKnots[i];
int end = xKnots[i+1];
if (i == numKnots-2)
end++;
for (int j = xKnots[i]; j < end; j++) {
int rgb1 = yKnots[i];
int rgb2 = yKnots[i+1];
float hsb1[] = Color.RGBtoHSB((rgb1 >> 16) & 0xff, (rgb1 >> 8) & 0xff, rgb1 & 0xff, null);
float hsb2[] = Color.RGBtoHSB((rgb2 >> 16) & 0xff, (rgb2 >> 8) & 0xff, rgb2 & 0xff, null);
float t = (float)(j-xKnots[i])/spanLength;
int type = getKnotType(i);
int blend = getKnotBlend(i);
if (j >= 0 && j <= 255) {
switch (blend) {
case CONSTANT:
t = 0;
break;
case LINEAR:
break;
case SPLINE:
// map[i] = ImageMath.colorSpline(j, numKnots, xKnots, yKnots);
t = ImageMath.smoothStep(0.15f, 0.85f, t);
break;
case CIRCLE_UP:
t = t-1;
t = (float)Math.sqrt(1-t*t);
break;
case CIRCLE_DOWN:
t = 1-(float)Math.sqrt(1-t*t);
break;
}
// if (blend != SPLINE) {
switch (type) {
case RGB:
map[j] = ImageMath.mixColors(t, rgb1, rgb2);
break;
case HUE_CW:
case HUE_CCW:
if (type == HUE_CW) {
if (hsb2[0] <= hsb1[0])
hsb2[0] += 1.0f;
} else {
if (hsb1[0] <= hsb2[1])
hsb1[0] += 1.0f;
}
float h = ImageMath.lerp(t, hsb1[0], hsb2[0]) % (ImageMath.TWO_PI);
float s = ImageMath.lerp(t, hsb1[1], hsb2[1]);
float b = ImageMath.lerp(t, hsb1[2], hsb2[2]);
map[j] = 0xff000000 | Color.HSBtoRGB((float)h, (float)s, (float)b);//FIXME-alpha
break;
}
// }
}
}
}
}
private void sortKnots() {
for (int i = 1; i < numKnots-1; i++) {
for (int j = 1; j < i; j++) {
if (xKnots[i] < xKnots[j]) {
int t = xKnots[i];
xKnots[i] = xKnots[j];
xKnots[j] = t;
t = yKnots[i];
yKnots[i] = yKnots[j];
yKnots[j] = t;
byte bt = knotTypes[i];
knotTypes[i] = knotTypes[j];
knotTypes[j] = bt;
}
}
}
}
private void rebuild() {
sortKnots();
rebuildGradient();
}
/**
* Randomize the gradient.
*/
public void randomize() {
numKnots = 4 + (int)(6*Math.random());
xKnots = new int[numKnots];
yKnots = new int[numKnots];
knotTypes = new byte[numKnots];
for (int i = 0; i < numKnots; i++) {
xKnots[i] = (int)(255 * Math.random());
yKnots[i] = 0xff000000 | ((int)(255 * Math.random()) << 16) | ((int)(255 * Math.random()) << 8) | (int)(255 * Math.random());
knotTypes[i] = RGB|SPLINE;
}
xKnots[0] = -1;
xKnots[1] = 0;
xKnots[numKnots-2] = 255;
xKnots[numKnots-1] = 256;
sortKnots();
rebuildGradient();
}
/**
* Mutate the gradient.
* @param amount the amount in the range zero to one
*/
public void mutate(float amount) {
for (int i = 0; i < numKnots; i++) {
int rgb = yKnots[i];
int r = ((rgb >> 16) & 0xff);
int g = ((rgb >> 8) & 0xff);
int b = (rgb & 0xff);
r = PixelUtils.clamp( (int)(r + amount * 255 * (Math.random()-0.5)) );
g = PixelUtils.clamp( (int)(g + amount * 255 * (Math.random()-0.5)) );
b = PixelUtils.clamp( (int)(b + amount * 255 * (Math.random()-0.5)) );
yKnots[i] = 0xff000000 | (r << 16) | (g << 8) | b;
knotTypes[i] = RGB|SPLINE;
}
sortKnots();
rebuildGradient();
}
/**
* Build a random gradient.
* @return the new Gradient
*/
public static Gradient randomGradient() {
Gradient g = new Gradient();
g.randomize();
return g;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BicubicScaleFilter.java 0000644 0001750 0001750 00000004064 10566356614 027636 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* Scales an image using bi-cubic interpolation, which can't be done with AffineTransformOp.
*/
public class BicubicScaleFilter extends AbstractBufferedImageOp {
private int width;
private int height;
/**
* Construct a BicubicScaleFilter which resizes to 32x32 pixels.
*/
public BicubicScaleFilter() {
this(32, 32);
}
/**
* Constructor for a filter which scales the input image to the given width and height using bicubic interpolation.
* Unfortunately, it appears that bicubic actually looks worse than bilinear interpolation on most Java implementations,
* but you can be the judge.
* @param width the width of the output image
* @param height the height of the output image
*/
public BicubicScaleFilter( int width, int height ) {
this.width = width;
this.height = height;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int w = src.getWidth();
int h = src.getHeight();
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(width, height), dstCM.isAlphaPremultiplied(), null);
}
Graphics2D g = dst.createGraphics();
g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
g.drawImage( src, 0, 0, width, height, null );
g.dispose();
return dst;
}
public String toString() {
return "Distort/Bicubic Scale";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ImageUtils.java 0000644 0001750 0001750 00000022130 10566572034 026211 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import com.jhlabs.image.*;
/**
* A class containing some static utility methods for dealing with BufferedImages.
*/
public abstract class ImageUtils {
private static BufferedImage backgroundImage = null;
/**
* Cretae a BufferedImage from an ImageProducer.
* @param producer the ImageProducer
* @return a new TYPE_INT_ARGB BufferedImage
*/
public static BufferedImage createImage(ImageProducer producer) {
PixelGrabber pg = new PixelGrabber(producer, 0, 0, -1, -1, null, 0, 0);
try {
pg.grabPixels();
} catch (InterruptedException e) {
throw new RuntimeException("Image fetch interrupted");
}
if ((pg.status() & ImageObserver.ABORT) != 0)
throw new RuntimeException("Image fetch aborted");
if ((pg.status() & ImageObserver.ERROR) != 0)
throw new RuntimeException("Image fetch error");
BufferedImage p = new BufferedImage(pg.getWidth(), pg.getHeight(), BufferedImage.TYPE_INT_ARGB);
p.setRGB(0, 0, pg.getWidth(), pg.getHeight(), (int[])pg.getPixels(), 0, pg.getWidth());
return p;
}
/**
* Convert an Image into a TYPE_INT_ARGB BufferedImage. If the image is already of this type, the original image is returned unchanged.
* @param image the image to convert
* @return the converted image
*/
public static BufferedImage convertImageToARGB( Image image ) {
if ( image instanceof BufferedImage && ((BufferedImage)image).getType() == BufferedImage.TYPE_INT_ARGB )
return (BufferedImage)image;
BufferedImage p = new BufferedImage( image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = p.createGraphics();
g.drawImage( image, 0, 0, null );
g.dispose();
return p;
}
/**
* Returns a *copy* of a subimage of image. This avoids the performance problems associated with BufferedImage.getSubimage.
* @param image the image
* @param x the x position
* @param y the y position
* @param w the width
* @param h the height
* @return the subimage
*/
public static BufferedImage getSubimage( BufferedImage image, int x, int y, int w, int h ) {
BufferedImage newImage = new BufferedImage( w, h, BufferedImage.TYPE_INT_ARGB );
Graphics2D g = newImage.createGraphics();
g.drawRenderedImage( image, AffineTransform.getTranslateInstance(-x, -y) );
g.dispose();
return newImage;
}
/**
* Clones a BufferedImage.
* @param image the image to clone
* @return the cloned image
*/
public static BufferedImage cloneImage( BufferedImage image ) {
BufferedImage newImage = new BufferedImage( image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB );
Graphics2D g = newImage.createGraphics();
g.drawRenderedImage( image, null );
g.dispose();
return newImage;
}
/**
* Paint a check pattern, used for a background to indicate image transparency.
* @param c the component to draw into
* @param g the Graphics objects
* @param x the x position
* @param y the y position
* @param width the width
* @param height the height
*/
public static void paintCheckedBackground(Component c, Graphics g, int x, int y, int width, int height) {
if ( backgroundImage == null ) {
backgroundImage = new BufferedImage( 64, 64, BufferedImage.TYPE_INT_ARGB );
Graphics bg = backgroundImage.createGraphics();
for ( int by = 0; by < 64; by += 8 ) {
for ( int bx = 0; bx < 64; bx += 8 ) {
bg.setColor( ((bx^by) & 8) != 0 ? Color.lightGray : Color.white );
bg.fillRect( bx, by, 8, 8 );
}
}
bg.dispose();
}
if ( backgroundImage != null ) {
Shape saveClip = g.getClip();
Rectangle r = g.getClipBounds();
if (r == null)
r = new Rectangle(c.getSize());
r = r.intersection(new Rectangle(x, y, width, height));
g.setClip(r);
int w = backgroundImage.getWidth();
int h = backgroundImage.getHeight();
if (w != -1 && h != -1) {
int x1 = (r.x / w) * w;
int y1 = (r.y / h) * h;
int x2 = ((r.x + r.width + w - 1) / w) * w;
int y2 = ((r.y + r.height + h - 1) / h) * h;
for (y = y1; y < y2; y += h)
for (x = x1; x < x2; x += w)
g.drawImage(backgroundImage, x, y, c);
}
g.setClip(saveClip);
}
}
/**
* Calculates the bounds of the non-transparent parts of the given image.
* @param p the image
* @return the bounds of the non-transparent area
*/
public static Rectangle getSelectedBounds(BufferedImage p) {
int width = p.getWidth();
int height = p.getHeight();
int maxX = 0, maxY = 0, minX = width, minY = height;
boolean anySelected = false;
int y1;
int [] pixels = null;
for (y1 = height-1; y1 >= 0; y1--) {
pixels = getRGB( p, 0, y1, width, 1, pixels );
for (int x = 0; x < minX; x++) {
if ((pixels[x] & 0xff000000) != 0) {
minX = x;
maxY = y1;
anySelected = true;
break;
}
}
for (int x = width-1; x >= maxX; x--) {
if ((pixels[x] & 0xff000000) != 0) {
maxX = x;
maxY = y1;
anySelected = true;
break;
}
}
if ( anySelected )
break;
}
pixels = null;
for (int y = 0; y < y1; y++) {
pixels = getRGB( p, 0, y, width, 1, pixels );
for (int x = 0; x < minX; x++) {
if ((pixels[x] & 0xff000000) != 0) {
minX = x;
if ( y < minY )
minY = y;
anySelected = true;
break;
}
}
for (int x = width-1; x >= maxX; x--) {
if ((pixels[x] & 0xff000000) != 0) {
maxX = x;
if ( y < minY )
minY = y;
anySelected = true;
break;
}
}
}
if ( anySelected )
return new Rectangle( minX, minY, maxX-minX+1, maxY-minY+1 );
return null;
}
/**
* Compose src onto dst using the alpha of sel to interpolate between the two.
* I can't think of a way to do this using AlphaComposite.
* @param src the source raster
* @param dst the destination raster
* @param sel the mask raster
*/
public static void composeThroughMask(Raster src, WritableRaster dst, Raster sel) {
int x = src.getMinX();
int y = src.getMinY();
int w = src.getWidth();
int h = src.getHeight();
int srcRGB[] = null;
int selRGB[] = null;
int dstRGB[] = null;
for ( int i = 0; i < h; i++ ) {
srcRGB = src.getPixels(x, y, w, 1, srcRGB);
selRGB = sel.getPixels(x, y, w, 1, selRGB);
dstRGB = dst.getPixels(x, y, w, 1, dstRGB);
int k = x;
for ( int j = 0; j < w; j++ ) {
int sr = srcRGB[k];
int dir = dstRGB[k];
int sg = srcRGB[k+1];
int dig = dstRGB[k+1];
int sb = srcRGB[k+2];
int dib = dstRGB[k+2];
int sa = srcRGB[k+3];
int dia = dstRGB[k+3];
float a = selRGB[k+3]/255f;
float ac = 1-a;
dstRGB[k] = (int)(a*sr + ac*dir);
dstRGB[k+1] = (int)(a*sg + ac*dig);
dstRGB[k+2] = (int)(a*sb + ac*dib);
dstRGB[k+3] = (int)(a*sa + ac*dia);
k += 4;
}
dst.setPixels(x, y, w, 1, dstRGB);
y++;
}
}
/**
* A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
* penalty of BufferedImage.getRGB unmanaging the image.
* @param image a BufferedImage object
* @param x the left edge of the pixel block
* @param y the right edge of the pixel block
* @param width the width of the pixel arry
* @param height the height of the pixel arry
* @param pixels the array to hold the returned pixels. May be null.
* @return the pixels
* @see #setRGB
*/
public static int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
int type = image.getType();
if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
return image.getRGB( x, y, width, height, pixels, 0, width );
}
/**
* A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
* penalty of BufferedImage.setRGB unmanaging the image.
* @param image a BufferedImage object
* @param x the left edge of the pixel block
* @param y the right edge of the pixel block
* @param width the width of the pixel arry
* @param height the height of the pixel arry
* @param pixels the array of pixels to set
* @see #getRGB
*/
public static void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
int type = image.getType();
if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
image.getRaster().setDataElements( x, y, width, height, pixels );
else
image.setRGB( x, y, width, height, pixels, 0, width );
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PointFilter.java 0000644 0001750 0001750 00000004017 10562652111 026400 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* An abstract superclass for point filters. The interface is the same as the old RGBImageFilter.
*/
public abstract class PointFilter extends AbstractBufferedImageOp {
protected boolean canFilterIndexColorModel = false;
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
WritableRaster dstRaster = dst.getRaster();
setDimensions( width, height);
int[] inPixels = new int[width];
for ( int y = 0; y < height; y++ ) {
// We try to avoid calling getRGB on images as it causes them to become unmanaged, causing horrible performance problems.
if ( type == BufferedImage.TYPE_INT_ARGB ) {
srcRaster.getDataElements( 0, y, width, 1, inPixels );
for ( int x = 0; x < width; x++ )
inPixels[x] = filterRGB( x, y, inPixels[x] );
dstRaster.setDataElements( 0, y, width, 1, inPixels );
} else {
src.getRGB( 0, y, width, 1, inPixels, 0, width );
for ( int x = 0; x < width; x++ )
inPixels[x] = filterRGB( x, y, inPixels[x] );
dst.setRGB( 0, y, width, 1, inPixels, 0, width );
}
}
return dst;
}
public void setDimensions(int width, int height) {
}
public abstract int filterRGB(int x, int y, int rgb);
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/RotateFilter.java 0000644 0001750 0001750 00000005614 10566572034 026562 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which rotates an image. These days this is easier done with Java2D, but this filter remains.
*/
public class RotateFilter extends TransformFilter {
private float angle;
private float cos, sin;
private boolean resize = true;
/**
* Construct a RotateFilter.
*/
public RotateFilter() {
this(ImageMath.PI);
}
/**
* Construct a RotateFilter.
* @param angle the angle to rotate
*/
public RotateFilter(float angle) {
this(angle, true);
}
/**
* Construct a RotateFilter.
* @param angle the angle to rotate
* @param resize true if the output image should be resized
*/
public RotateFilter(float angle, boolean resize) {
setAngle(angle);
this.resize = resize;
}
/**
* Specifies the angle of rotation.
* @param angle the angle of rotation.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
cos = (float)Math.cos(this.angle);
sin = (float)Math.sin(this.angle);
}
/**
* Returns the angle of rotation.
* @return the angle of rotation.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
protected void transformSpace(Rectangle rect) {
if (resize) {
Point out = new Point(0, 0);
int minx = Integer.MAX_VALUE;
int miny = Integer.MAX_VALUE;
int maxx = Integer.MIN_VALUE;
int maxy = Integer.MIN_VALUE;
int w = rect.width;
int h = rect.height;
int x = rect.x;
int y = rect.y;
for (int i = 0; i < 4; i++) {
switch (i) {
case 0: transform(x, y, out); break;
case 1: transform(x + w, y, out); break;
case 2: transform(x, y + h, out); break;
case 3: transform(x + w, y + h, out); break;
}
minx = Math.min(minx, out.x);
miny = Math.min(miny, out.y);
maxx = Math.max(maxx, out.x);
maxy = Math.max(maxy, out.y);
}
rect.x = minx;
rect.y = miny;
rect.width = maxx - rect.x;
rect.height = maxy - rect.y;
}
}
private void transform(int x, int y, Point out) {
out.x = (int)((x * cos) + (y * sin));
out.y = (int)((y * cos) - (x * sin));
}
protected void transformInverse(int x, int y, float[] out) {
out[0] = (x * cos) - (y * sin);
out[1] = (y * cos) + (x * sin);
}
public String toString() {
return "Rotate "+(int)(angle * 180 / Math.PI);
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CheckFilter.java 0000644 0001750 0001750 00000007321 10606647276 026344 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A Filter to draw grids and check patterns.
*/
public class CheckFilter extends PointFilter {
private int xScale = 8;
private int yScale = 8;
private int foreground = 0xffffffff;
private int background = 0xff000000;
private int fuzziness = 0;
private float angle = 0.0f;
private float m00 = 1.0f;
private float m01 = 0.0f;
private float m10 = 0.0f;
private float m11 = 1.0f;
public CheckFilter() {
}
/**
* Set the foreground color.
* @param foreground the color.
* @see #getForeground
*/
public void setForeground(int foreground) {
this.foreground = foreground;
}
/**
* Get the foreground color.
* @return the color.
* @see #setForeground
*/
public int getForeground() {
return foreground;
}
/**
* Set the background color.
* @param background the color.
* @see #getBackground
*/
public void setBackground(int background) {
this.background = background;
}
/**
* Get the background color.
* @return the color.
* @see #setBackground
*/
public int getBackground() {
return background;
}
/**
* Set the X scale of the texture.
* @param xScale the scale.
* @see #getXScale
*/
public void setXScale(int xScale) {
this.xScale = xScale;
}
/**
* Get the X scale of the texture.
* @return the scale.
* @see #setXScale
*/
public int getXScale() {
return xScale;
}
/**
* Set the Y scale of the texture.
* @param yScale the scale.
* @see #getYScale
*/
public void setYScale(int yScale) {
this.yScale = yScale;
}
/**
* Get the Y scale of the texture.
* @return the scale.
* @see #setYScale
*/
public int getYScale() {
return yScale;
}
/**
* Set the fuzziness of the texture.
* @param fuzziness the fuzziness.
* @see #getFuzziness
*/
public void setFuzziness(int fuzziness) {
this.fuzziness = fuzziness;
}
/**
* Get the fuzziness of the texture.
* @return the fuzziness.
* @see #setFuzziness
*/
public int getFuzziness() {
return fuzziness;
}
/**
* Set the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(angle);
float sin = (float)Math.sin(angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Get the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
public int filterRGB(int x, int y, int rgb) {
float nx = (m00*x + m01*y) / xScale;
float ny = (m10*x + m11*y) / yScale;
float f = ((int)(nx+100000) % 2 != (int)(ny+100000) % 2) ? 1.0f : 0.0f;
if (fuzziness != 0) {
float fuzz = (fuzziness/100.0f);
float fx = ImageMath.smoothPulse(0, fuzz, 1-fuzz, 1, ImageMath.mod(nx, 1));
float fy = ImageMath.smoothPulse(0, fuzz, 1-fuzz, 1, ImageMath.mod(ny, 1));
f *= fx*fy;
}
return ImageMath.mixColors(f, foreground, background);
}
public String toString() {
return "Texture/Checkerboard...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ColorHalftoneFilter.java 0000755 0001750 0001750 00000014230 11201001401 030024 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A Filter to pixellate images.
*/
public class ColorHalftoneFilter extends AbstractBufferedImageOp {
private float dotRadius = 8;
private float cyanScreenAngle = (float)Math.toRadians( 108 );
private float magentaScreenAngle = (float)Math.toRadians( 162 );
private float yellowScreenAngle = (float)Math.toRadians( 90 );
public ColorHalftoneFilter() {
}
/**
* Set the pixel block size.
* @param dotRadius the number of pixels along each block edge
* @min-value 1
* @max-value 100+
* @see #getdotRadius
*/
public void setdotRadius( float dotRadius ) {
this.dotRadius = dotRadius;
}
/**
* Get the pixel block size.
* @return the number of pixels along each block edge
* @see #setdotRadius
*/
public float getdotRadius() {
return dotRadius;
}
/**
* Get the cyan screen angle.
* @return the cyan screen angle (in radians)
* @see #setCyanScreenAngle
*/
public float getCyanScreenAngle() {
return cyanScreenAngle;
}
/**
* Set the cyan screen angle.
* @param cyanScreenAngle the cyan screen angle (in radians)
* @see #getCyanScreenAngle
*/
public void setCyanScreenAngle( float cyanScreenAngle ) {
this.cyanScreenAngle = cyanScreenAngle;
}
/**
* Get the magenta screen angle.
* @return the magenta screen angle (in radians)
* @see #setMagentaScreenAngle
*/
public float getMagentaScreenAngle() {
return magentaScreenAngle;
}
/**
* Set the magenta screen angle.
* @param magentaScreenAngle the magenta screen angle (in radians)
* @see #getMagentaScreenAngle
*/
public void setMagentaScreenAngle( float magentaScreenAngle ) {
this.magentaScreenAngle = magentaScreenAngle;
}
/**
* Get the yellow screen angle.
* @return the yellow screen angle (in radians)
* @see #setYellowScreenAngle
*/
public float getYellowScreenAngle() {
return yellowScreenAngle;
}
/**
* Set the yellow screen angle.
* @param yellowScreenAngle the yellow screen angle (in radians)
* @see #getYellowScreenAngle
*/
public void setYellowScreenAngle( float yellowScreenAngle ) {
this.yellowScreenAngle = yellowScreenAngle;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
float gridSize = 2*dotRadius*1.414f;
float[] angles = { cyanScreenAngle, magentaScreenAngle, yellowScreenAngle };
float[] mx = new float[] { 0, -1, 1, 0, 0 };
float[] my = new float[] { 0, 0, 0, -1, 1 };
float halfGridSize = (float)gridSize/2;
int[] outPixels = new int[width];
int[] inPixels = getRGB( src, 0, 0, width, height, null );
for ( int y = 0; y < height; y++ ) {
for ( int x = 0, ix = y*width; x < width; x++, ix++ )
outPixels[x] = (inPixels[ix] & 0xff000000) | 0xffffff;
for ( int channel = 0; channel < 3; channel++ ) {
int shift = 16-8*channel;
int mask = 0x000000ff << shift;
float angle = angles[channel];
float sin = (float)Math.sin( angle );
float cos = (float)Math.cos( angle );
for ( int x = 0; x < width; x++ ) {
// Transform x,y into halftone screen coordinate space
float tx = x*cos + y*sin;
float ty = -x*sin + y*cos;
// Find the nearest grid point
tx = tx-ImageMath.mod( tx-halfGridSize, gridSize )+halfGridSize;
ty = ty-ImageMath.mod( ty-halfGridSize, gridSize )+halfGridSize;
float f = 1;
// TODO: Efficiency warning: Because the dots overlap, we need to check neighbouring grid squares.
// We check all four neighbours, but in practice only one can ever overlap any given point.
for ( int i = 0; i < 5; i++ ) {
// Find neigbouring grid point
float ttx = tx + mx[i]*gridSize;
float tty = ty + my[i]*gridSize;
// Transform back into image space
float ntx = ttx*cos - tty*sin;
float nty = ttx*sin + tty*cos;
// Clamp to the image
int nx = ImageMath.clamp( (int)ntx, 0, width-1 );
int ny = ImageMath.clamp( (int)nty, 0, height-1 );
int argb = inPixels[ny*width+nx];
int nr = (argb >> shift) & 0xff;
float l = nr/255.0f;
l = 1-l*l;
l *= halfGridSize*1.414;
float dx = x-ntx;
float dy = y-nty;
float dx2 = dx*dx;
float dy2 = dy*dy;
float R = (float)Math.sqrt( dx2+dy2 );
float f2 = 1-ImageMath.smoothStep( R, R+1, l );
f = Math.min( f, f2 );
}
int v = (int)(255 * f);
v <<= shift;
v ^= ~mask;
v |= 0xff000000;
outPixels[x] &= v;
}
}
setRGB( dst, 0, y, width, 1, outPixels );
}
return dst;
}
public String toString() {
return "Pixellate/Color Halftone...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ExposureFilter.java 0000644 0001750 0001750 00000002513 10566356614 027135 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which changes the exposure of an image.
*/
public class ExposureFilter extends TransferFilter {
private float exposure = 1.0f;
protected float transferFunction( float f ) {
return 1 - (float)Math.exp(-f * exposure);
}
/**
* Set the exposure level.
* @param exposure the exposure level
* @min-value 0
* @max-value 5+
* @see #getExposure
*/
public void setExposure(float exposure) {
this.exposure = exposure;
initialized = false;
}
/**
* Get the exposure level.
* @return the exposure level
* @see #setExposure
*/
public float getExposure() {
return exposure;
}
public String toString() {
return "Colors/Exposure...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/WeaveFilter.java 0000644 0001750 0001750 00000007674 10562652111 026372 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class WeaveFilter extends PointFilter {
private float xWidth = 16;
private float yWidth = 16;
private float xGap = 6;
private float yGap = 6;
private int rows = 4;
private int cols = 4;
private int rgbX = 0xffff8080;
private int rgbY = 0xff8080ff;
private boolean useImageColors = true;
private boolean roundThreads = false;
private boolean shadeCrossings = true;
public int[][] matrix = {
{ 0, 1, 0, 1 },
{ 1, 0, 1, 0 },
{ 0, 1, 0, 1 },
{ 1, 0, 1, 0 },
};
public WeaveFilter() {
}
public void setXGap(float xGap) {
this.xGap = xGap;
}
public void setXWidth(float xWidth) {
this.xWidth = xWidth;
}
public float getXWidth() {
return xWidth;
}
public void setYWidth(float yWidth) {
this.yWidth = yWidth;
}
public float getYWidth() {
return yWidth;
}
public float getXGap() {
return xGap;
}
public void setYGap(float yGap) {
this.yGap = yGap;
}
public float getYGap() {
return yGap;
}
public void setCrossings(int[][] matrix) {
this.matrix = matrix;
}
public int[][] getCrossings() {
return matrix;
}
public void setUseImageColors(boolean useImageColors) {
this.useImageColors = useImageColors;
}
public boolean getUseImageColors() {
return useImageColors;
}
public void setRoundThreads(boolean roundThreads) {
this.roundThreads = roundThreads;
}
public boolean getRoundThreads() {
return roundThreads;
}
public void setShadeCrossings(boolean shadeCrossings) {
this.shadeCrossings = shadeCrossings;
}
public boolean getShadeCrossings() {
return shadeCrossings;
}
public int filterRGB(int x, int y, int rgb) {
x += xWidth+xGap/2;
y += yWidth+yGap/2;
float nx = ImageMath.mod(x, xWidth+xGap);
float ny = ImageMath.mod(y, yWidth+yGap);
int ix = (int)(x / (xWidth+xGap));
int iy = (int)(y / (yWidth+yGap));
boolean inX = nx < xWidth;
boolean inY = ny < yWidth;
float dX, dY;
float cX, cY;
int lrgbX, lrgbY;
if (roundThreads) {
dX = Math.abs(xWidth/2-nx) / xWidth / 2;
dY = Math.abs(yWidth/2-ny) / yWidth / 2;
} else {
dX = dY = 0;
}
if (shadeCrossings) {
cX = ImageMath.smoothStep(xWidth/2, xWidth/2+xGap, Math.abs(xWidth/2-nx));
cY = ImageMath.smoothStep(yWidth/2, yWidth/2+yGap, Math.abs(yWidth/2-ny));
} else {
cX = cY = 0;
}
if (useImageColors) {
lrgbX = lrgbY = rgb;
} else {
lrgbX = rgbX;
lrgbY = rgbY;
}
int v;
int ixc = ix % cols;
int iyr = iy % rows;
int m = matrix[iyr][ixc];
if (inX) {
if (inY) {
v = m == 1 ? lrgbX : lrgbY;
v = ImageMath.mixColors(2 * (m == 1 ? dX : dY), v, 0xff000000);
} else {
if (shadeCrossings) {
if (m != matrix[(iy+1) % rows][ixc]) {
if (m == 0)
cY = 1-cY;
cY *= 0.5f;
lrgbX = ImageMath.mixColors(cY, lrgbX, 0xff000000);
} else if (m == 0)
lrgbX = ImageMath.mixColors(0.5f, lrgbX, 0xff000000);
}
v = ImageMath.mixColors(2 * dX, lrgbX, 0xff000000);
}
} else if (inY) {
if (shadeCrossings) {
if (m != matrix[iyr][(ix+1) % cols]) {
if (m == 1)
cX = 1-cX;
cX *= 0.5f;
lrgbY = ImageMath.mixColors(cX, lrgbY, 0xff000000);
} else if (m == 1)
lrgbY = ImageMath.mixColors(0.5f, lrgbY, 0xff000000);
}
v = ImageMath.mixColors(2 * dY, lrgbY, 0xff000000);
} else
v = 0x00000000;
return v;
}
public String toString() {
return "Texture/Weave...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GlowFilter.java 0000644 0001750 0001750 00000005171 10606647276 026240 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which adds Gaussian blur to an image, producing a glowing effect.
* @author Jerry Huxtable
*/
public class GlowFilter extends GaussianFilter {
private float amount = 0.5f;
public GlowFilter() {
radius = 2;
}
/**
* Set the amount of glow.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount( float amount ) {
this.amount = amount;
}
/**
* Get the amount of glow.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
src.getRGB( 0, 0, width, height, inPixels, 0, width );
if ( radius > 0 ) {
convolveAndTranspose(kernel, inPixels, outPixels, width, height, alpha, alpha && premultiplyAlpha, false, CLAMP_EDGES);
convolveAndTranspose(kernel, outPixels, inPixels, height, width, alpha, false, alpha && premultiplyAlpha, CLAMP_EDGES);
}
src.getRGB( 0, 0, width, height, outPixels, 0, width );
float a = 4*amount;
int index = 0;
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
int rgb1 = outPixels[index];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int rgb2 = inPixels[index];
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
r1 = PixelUtils.clamp( (int)(r1 + a * r2) );
g1 = PixelUtils.clamp( (int)(g1 + a * g2) );
b1 = PixelUtils.clamp( (int)(b1 + a * b2) );
inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1;
index++;
}
}
dst.setRGB( 0, 0, width, height, inPixels, 0, width );
return dst;
}
public String toString() {
return "Blur/Glow...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DilateFilter.java 0000644 0001750 0001750 00000004740 10566356614 026531 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* Given a binary image, this filter performs binary dilation, setting all added pixels to the given 'new' color.
*/
public class DilateFilter extends BinaryFilter {
private int threshold = 2;
public DilateFilter() {
}
/**
* Set the threshold - the number of neighbouring pixels for dilation to occur.
* @param threshold the new threshold
* @see #getThreshold
*/
public void setThreshold(int threshold) {
this.threshold = threshold;
}
/**
* Return the threshold - the number of neighbouring pixels for dilation to occur.
* @return the current threshold
* @see #setThreshold
*/
public int getThreshold() {
return threshold;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
for (int i = 0; i < iterations; i++) {
int index = 0;
if (i > 0) {
int[] t = inPixels;
inPixels = outPixels;
outPixels = t;
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = inPixels[y*width+x];
if (!blackFunction.isBlack(pixel)) {
int neighbours = 0;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (!(dy == 0 && dx == 0) && 0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
if (blackFunction.isBlack(rgb))
neighbours++;
}
}
}
}
if (neighbours >= threshold) {
if (colormap != null)
pixel = colormap.getColor((float)i/iterations);
else
pixel = newColor;
}
}
outPixels[index++] = pixel;
}
}
}
return outPixels;
}
public String toString() {
return "Binary/Dilate...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/RescaleFilter.java 0000644 0001750 0001750 00000002626 10606646776 026714 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which simply multiplies pixel values by a given scale factor.
*/
public class RescaleFilter extends TransferFilter {
private float scale = 1.0f;
public RescaleFilter() {
}
public RescaleFilter(float scale) {
this.scale = scale;
}
protected float transferFunction( float v ) {
return v * scale;
}
/**
* Specifies the scale factor.
* @param scale the scale factor.
* @min-value 1
* @max-value 5+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
initialized = false;
}
/**
* Returns the scale factor.
* @return the scale factor.
* @see #setScale
*/
public float getScale() {
return scale;
}
public String toString() {
return "Colors/Rescale...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DoGFilter.java 0000755 0001750 0001750 00000010221 10626011515 025753 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.composite.*;
/**
* Edge detection by difference of Gaussians.
* @author Jerry Huxtable
*/
public class DoGFilter extends AbstractBufferedImageOp {
private float radius1 = 1;
private float radius2 = 2;
private boolean normalize = true;
private boolean invert;
public DoGFilter() {
}
/**
* Set the radius of the kernel, and hence the amount of blur. The bigger the radius, the longer this filter will take.
* @param radius the radius of the blur in pixels.
* @min-value 0
* @max-value 100+
* @see #getRadius
*/
public void setRadius1(float radius1) {
this.radius1 = radius1;
}
/**
* Get the radius of the kernel.
* @return the radius
* @see #setRadius
*/
public float getRadius1() {
return radius1;
}
/**
* Set the radius of the kernel, and hence the amount of blur. The bigger the radius, the longer this filter will take.
* @param radius the radius of the blur in pixels.
* @min-value 0
* @max-value 100+
* @see #getRadius
*/
public void setRadius2(float radius2) {
this.radius2 = radius2;
}
/**
* Get the radius of the kernel.
* @return the radius
* @see #setRadius
*/
public float getRadius2() {
return radius2;
}
public void setNormalize( boolean normalize ) {
this.normalize = normalize;
}
public boolean getNormalize() {
return normalize;
}
public void setInvert( boolean invert ) {
this.invert = invert;
}
public boolean getInvert() {
return invert;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
BufferedImage image1 = new BoxBlurFilter( radius1, radius1, 3 ).filter( src, null );
BufferedImage image2 = new BoxBlurFilter( radius2, radius2, 3 ).filter( src, null );
Graphics2D g2d = image2.createGraphics();
g2d.setComposite( new SubtractComposite( 1.0f ) );
g2d.drawImage( image1, 0, 0, null );
g2d.dispose();
if ( normalize && radius1 != radius2 ) {
int[] pixels = null;
int max = 0;
for ( int y = 0; y < height; y++ ) {
pixels = getRGB( image2, 0, y, width, 1, pixels );
for ( int x = 0; x < width; x++ ) {
int rgb = pixels[x];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if ( r > max )
max = r;
if ( g > max )
max = g;
if ( b > max )
max = b;
}
}
for ( int y = 0; y < height; y++ ) {
pixels = getRGB( image2, 0, y, width, 1, pixels );
for ( int x = 0; x < width; x++ ) {
int rgb = pixels[x];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = r * 255 / max;
g = g * 255 / max;
b = b * 255 / max;
pixels[x] = (rgb & 0xff000000) | (r << 16) | (g << 8) | b;
}
setRGB( image2, 0, y, width, 1, pixels );
}
}
if ( invert )
image2 = new InvertFilter().filter( image2, image2 );
return image2;
}
public String toString() {
return "Blur/Difference of Gaussians...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BinaryFilter.java 0000644 0001750 0001750 00000004037 10566572034 026546 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* The superclass for some of the filters which work on binary images.
*/
public abstract class BinaryFilter extends WholeImageFilter {
protected int newColor = 0xff000000;
protected BinaryFunction blackFunction = new BlackFunction();
protected int iterations = 1;
protected Colormap colormap;
/**
* Set the number of iterations the effect is performed.
* @param iterations the number of iterations
* @min-value 0
* @see #getIterations
*/
public void setIterations(int iterations) {
this.iterations = iterations;
}
/**
* Get the number of iterations the effect is performed.
* @return the number of iterations
* @see #setIterations
*/
public int getIterations() {
return iterations;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public void setNewColor(int newColor) {
this.newColor = newColor;
}
public int getNewColor() {
return newColor;
}
public void setBlackFunction(BinaryFunction blackFunction) {
this.blackFunction = blackFunction;
}
public BinaryFunction getBlackFunction() {
return blackFunction;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TritoneFilter.java 0000755 0001750 0001750 00000005301 10626011515 026731 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which performs a tritone conversion on an image. Given three colors for shadows, midtones and highlights,
* it converts the image to grayscale and then applies a color mapping based on the colors.
*/
public class TritoneFilter extends PointFilter {
private int shadowColor = 0xff000000;
private int midColor = 0xff888888;
private int highColor = 0xffffffff;
private int[] lut;
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
lut = new int[256];
for ( int i = 0; i < 128; i++ ) {
float t = i / 127.0f;
lut[i] = ImageMath.mixColors( t, shadowColor, midColor );
}
for ( int i = 128; i < 256; i++ ) {
float t = (i-127) / 128.0f;
lut[i] = ImageMath.mixColors( t, midColor, highColor );
}
dst = super.filter( src, dst );
lut = null;
return dst;
}
public int filterRGB( int x, int y, int rgb ) {
return lut[ PixelUtils.brightness( rgb ) ];
}
/**
* Set the shadow color.
* @param shadowColor the shadow color
* @see #getShadowColor
*/
public void setShadowColor( int shadowColor ) {
this.shadowColor = shadowColor;
}
/**
* Get the shadow color.
* @return the shadow color
* @see #setShadowColor
*/
public int getShadowColor() {
return shadowColor;
}
/**
* Set the mid color.
* @param midColor the mid color
* @see #getmidColor
*/
public void setMidColor( int midColor ) {
this.midColor = midColor;
}
/**
* Get the mid color.
* @return the mid color
* @see #setmidColor
*/
public int getMidColor() {
return midColor;
}
/**
* Set the high color.
* @param highColor the high color
* @see #gethighColor
*/
public void setHighColor( int highColor ) {
this.highColor = highColor;
}
/**
* Get the high color.
* @return the high color
* @see #sethighColor
*/
public int getHighColor() {
return highColor;
}
public String toString() {
return "Colors/Tritone...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FieldWarpFilter.java 0000644 0001750 0001750 00000010730 10566356614 027200 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A class which warps an image using a field Warp algorithm.
*/
public class FieldWarpFilter extends TransformFilter {
public static class Line {
public int x1, y1, x2, y2;
public int dx, dy;
public float length, lengthSquared;
public Line(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public void setup() {
dx = x2-x1;
dy = y2-y1;
lengthSquared = dx*dx + dy*dy;
length = (float)Math.sqrt(lengthSquared);
}
}
private float amount = 1.0f;
private float power = 1.0f;
private float strength = 2.0f;
private Line[] inLines;
private Line[] outLines;
private Line[] intermediateLines;
private float width, height;
public FieldWarpFilter() {
}
/**
* Set the amount of warp.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of warp.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public void setPower(float power) {
this.power = power;
}
public float getPower() {
return power;
}
public void setStrength(float strength) {
this.strength = strength;
}
public float getStrength() {
return strength;
}
public void setInLines( Line[] inLines ) {
this.inLines = inLines;
}
public Line[] getInLines() {
return inLines;
}
public void setOutLines( Line[] outLines ) {
this.outLines = outLines;
}
public Line[] getOutLines() {
return outLines;
}
protected void transform(int x, int y, Point out) {
}
protected void transformInverse(int x, int y, float[] out) {
float u = 0, v = 0;
float fraction = 0;
float distance;
float fdist;
float weight;
float a = 0.001f;
float b = 1.5f*strength + 0.5f;
float p = power;
float totalWeight = 0.0f;
float sumX = 0.0f;
float sumY = 0.0f;
for (int line = 0; line < inLines.length; line++) {
Line l1 = inLines[line];
Line l = intermediateLines[line];
float dx = x - l.x1;
float dy = y - l.y1;
fraction = (dx * l.dx + dy * l.dy) / l.lengthSquared;
fdist = (dy * l.dx - dx * l.dy) / l.length;
if (fraction <= 0)
distance = (float)Math.sqrt(dx*dx + dy*dy);
else if (fraction >= 1) {
dx = x - l.x2;
dy = y - l.y2;
distance = (float)Math.sqrt(dx*dx + dy*dy);
} else if (fdist >= 0)
distance = fdist;
else
distance = -fdist;
u = l1.x1 + fraction * l1.dx - fdist * l1.dy / l1.length;
v = l1.y1 + fraction * l1.dy + fdist * l1.dx / l1.length;
weight = (float)Math.pow(Math.pow(l.length, p) / (a + distance), b);
sumX += (u - x) * weight;
sumY += (v - y) * weight;
//if (x % 10 == 0&&y == 20)System.out.println("distance="+distance+" weight="+weight+" sumX="+sumX+" sumY="+sumY+" u="+u+" v="+v);
totalWeight += weight;
}
// out[0] = ImageMath.clamp(x + sumX / totalWeight + 0.5f, 0, width-1);
// out[1] = ImageMath.clamp(y + sumY / totalWeight + 0.5f, 0, height-1);
out[0] = x + sumX / totalWeight + 0.5f;
out[1] = y + sumY / totalWeight + 0.5f;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
this.width = width;
this.height = height;
if ( inLines != null && outLines != null ) {
intermediateLines = new Line[inLines.length];
for (int line = 0; line < inLines.length; line++) {
Line l = intermediateLines[line] = new Line(
ImageMath.lerp(amount, inLines[line].x1, outLines[line].x1),
ImageMath.lerp(amount, inLines[line].y1, outLines[line].y1),
ImageMath.lerp(amount, inLines[line].x2, outLines[line].x2),
ImageMath.lerp(amount, inLines[line].y2, outLines[line].y2)
);
l.setup();
inLines[line].setup();
}
dst = super.filter( src, dst );
intermediateLines = null;
return dst;
}
return src;
}
public String toString() {
return "Distort/Field Warp...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SolarizeFilter.java 0000644 0001750 0001750 00000001550 10562652111 027076 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which solarizes an image.
*/
public class SolarizeFilter extends TransferFilter {
protected float transferFunction( float v ) {
return v > 0.5f ? 2*(v-0.5f) : 2*(0.5f-v);
}
public String toString() {
return "Colors/Solarize";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GammaFilter.java 0000644 0001750 0001750 00000005247 10566356614 026354 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter for changing the gamma of an image.
*/
public class GammaFilter extends TransferFilter {
private float rGamma, gGamma, bGamma;
/**
* Construct a GammaFilter.
*/
public GammaFilter() {
this(1.0f);
}
/**
* Construct a GammaFilter.
* @param gamma the gamma level for all RGB channels
*/
public GammaFilter(float gamma) {
this(gamma, gamma, gamma);
}
/**
* Construct a GammaFilter.
* @param rGamma the gamma level for the red channel
* @param gGamma the gamma level for the blue channel
* @param bGamma the gamma level for the green channel
*/
public GammaFilter(float rGamma, float gGamma, float bGamma) {
setGamma(rGamma, gGamma, bGamma);
}
/**
* Set the gamma levels.
* @param rGamma the gamma level for the red channel
* @param gGamma the gamma level for the blue channel
* @param bGamma the gamma level for the green channel
* @see #getGamma
*/
public void setGamma(float rGamma, float gGamma, float bGamma) {
this.rGamma = rGamma;
this.gGamma = gGamma;
this.bGamma = bGamma;
initialized = false;
}
/**
* Set the gamma level.
* @param gamma the gamma level for all RGB channels
* @see #getGamma
*/
public void setGamma(float gamma) {
setGamma(gamma, gamma, gamma);
}
/**
* Get the gamma level.
* @return the gamma level for all RGB channels
* @see #setGamma
*/
public float getGamma() {
return rGamma;
}
protected void initialize() {
rTable = makeTable(rGamma);
if (gGamma == rGamma)
gTable = rTable;
else
gTable = makeTable(gGamma);
if (bGamma == rGamma)
bTable = rTable;
else if (bGamma == gGamma)
bTable = gTable;
else
bTable = makeTable(bGamma);
}
private int[] makeTable(float gamma) {
int[] table = new int[256];
for (int i = 0; i < 256; i++) {
int v = (int) ((255.0 * Math.pow(i/255.0, 1.0 / gamma)) + 0.5);
if (v > 255)
v = 255;
table[i] = v;
}
return table;
}
public String toString() {
return "Colors/Gamma...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/LightFilter.java 0000644 0001750 0001750 00000044025 10606647276 026400 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import com.jhlabs.math.*;
import com.jhlabs.vecmath.*;
import java.awt.*;
import java.io.*;
import java.util.*;
/**
* A filter which produces lighting and embossing effects.
*/
public class LightFilter extends WholeImageFilter {
/**
* Take the output colors from the input image.
*/
public final static int COLORS_FROM_IMAGE = 0;
/**
* Use constant material color.
*/
public final static int COLORS_CONSTANT = 1;
/**
* Use the input image brightness as the bump map.
*/
public final static int BUMPS_FROM_IMAGE = 0;
/**
* Use the input image alpha as the bump map.
*/
public final static int BUMPS_FROM_IMAGE_ALPHA = 1;
/**
* Use a separate image alpha channel as the bump map.
*/
public final static int BUMPS_FROM_MAP = 2;
/**
* Use a custom function as the bump map.
*/
public final static int BUMPS_FROM_BEVEL = 3;
private float bumpHeight;
private float bumpSoftness;
private float viewDistance = 10000.0f;
private Material material;
private Vector lights;
private int colorSource = COLORS_FROM_IMAGE;
private int bumpSource = BUMPS_FROM_IMAGE;
private Function2D bumpFunction;
private Image environmentMap;
private int[] envPixels;
private int envWidth = 1, envHeight = 1;
// Temporary variables used to avoid per-pixel memory allocation while filtering
private Vector3f l;
private Vector3f v;
private Vector3f n;
private Color4f shadedColor;
private Color4f diffuse_color;
private Color4f specular_color;
private Vector3f tmpv, tmpv2;
public LightFilter() {
lights = new Vector();
addLight(new DistantLight());
bumpHeight = 1.0f;
bumpSoftness = 5.0f;
material = new Material();
l = new Vector3f();
v = new Vector3f();
n = new Vector3f();
shadedColor = new Color4f();
diffuse_color = new Color4f();
specular_color = new Color4f();
tmpv = new Vector3f();
tmpv2 = new Vector3f();
}
public void setMaterial( Material material ) {
this.material = material;
}
public Material getMaterial() {
return material;
}
public void setBumpFunction(Function2D bumpFunction) {
this.bumpFunction = bumpFunction;
}
public Function2D getBumpFunction() {
return bumpFunction;
}
public void setBumpHeight(float bumpHeight) {
this.bumpHeight = bumpHeight;
}
public float getBumpHeight() {
return bumpHeight;
}
public void setBumpSoftness(float bumpSoftness) {
this.bumpSoftness = bumpSoftness;
}
public float getBumpSoftness() {
return bumpSoftness;
}
public void setViewDistance(float viewDistance) {
this.viewDistance = viewDistance;
}
public float getViewDistance() {
return viewDistance;
}
public void setEnvironmentMap(BufferedImage environmentMap) {
this.environmentMap = environmentMap;
if (environmentMap != null) {
envWidth = environmentMap.getWidth();
envHeight = environmentMap.getHeight();
envPixels = getRGB( environmentMap, 0, 0, envWidth, envHeight, null );
} else {
envWidth = envHeight = 1;
envPixels = null;
}
}
public Image getEnvironmentMap() {
return environmentMap;
}
public void setColorSource(int colorSource) {
this.colorSource = colorSource;
}
public int getColorSource() {
return colorSource;
}
public void setBumpSource(int bumpSource) {
this.bumpSource = bumpSource;
}
public int getBumpSource() {
return bumpSource;
}
public void setDiffuseColor(int diffuseColor) {
material.diffuseColor = diffuseColor;
}
public int getDiffuseColor() {
return material.diffuseColor;
}
public void addLight(Light light) {
lights.addElement(light);
}
public void removeLight(Light light) {
lights.removeElement(light);
}
public Vector getLights() {
return lights;
}
protected final static float r255 = 1.0f/255.0f;
protected void setFromRGB( Color4f c, int argb ) {
c.set( ((argb >> 16) & 0xff) * r255, ((argb >> 8) & 0xff) * r255, (argb & 0xff) * r255, ((argb >> 24) & 0xff) * r255 );
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
float width45 = Math.abs(6.0f * bumpHeight);
boolean invertBumps = bumpHeight < 0;
Vector3f position = new Vector3f(0.0f, 0.0f, 0.0f);
Vector3f viewpoint = new Vector3f((float)width / 2.0f, (float)height / 2.0f, viewDistance);
Vector3f normal = new Vector3f();
Color4f envColor = new Color4f();
Color4f diffuseColor = new Color4f( new Color(material.diffuseColor) );
Color4f specularColor = new Color4f( new Color(material.specularColor) );
Function2D bump = bumpFunction;
// Apply the bump softness
if (bumpSource == BUMPS_FROM_IMAGE || bumpSource == BUMPS_FROM_IMAGE_ALPHA || bumpSource == BUMPS_FROM_MAP || bump == null) {
if ( bumpSoftness != 0 ) {
int bumpWidth = width;
int bumpHeight = height;
int[] bumpPixels = inPixels;
if ( bumpSource == BUMPS_FROM_MAP && bumpFunction instanceof ImageFunction2D ) {
ImageFunction2D if2d = (ImageFunction2D)bumpFunction;
bumpWidth = if2d.getWidth();
bumpHeight = if2d.getHeight();
bumpPixels = if2d.getPixels();
}
int [] tmpPixels = new int[bumpWidth * bumpHeight];
int [] softPixels = new int[bumpWidth * bumpHeight];
/*
for (int i = 0; i < 3; i++ ) {
BoxBlurFilter.blur( bumpPixels, tmpPixels, bumpWidth, bumpHeight, (int)bumpSoftness );
BoxBlurFilter.blur( tmpPixels, softPixels, bumpHeight, bumpWidth, (int)bumpSoftness );
}
*/
Kernel kernel = GaussianFilter.makeKernel( bumpSoftness );
GaussianFilter.convolveAndTranspose( kernel, bumpPixels, tmpPixels, bumpWidth, bumpHeight, true, false, false, GaussianFilter.WRAP_EDGES );
GaussianFilter.convolveAndTranspose( kernel, tmpPixels, softPixels, bumpHeight, bumpWidth, true, false, false, GaussianFilter.WRAP_EDGES );
bump = new ImageFunction2D(softPixels, bumpWidth, bumpHeight, ImageFunction2D.CLAMP, bumpSource == BUMPS_FROM_IMAGE_ALPHA);
} else if ( bumpSource != BUMPS_FROM_MAP )
bump = new ImageFunction2D(inPixels, width, height, ImageFunction2D.CLAMP, bumpSource == BUMPS_FROM_IMAGE_ALPHA);
}
float reflectivity = material.reflectivity;
float areflectivity = (1-reflectivity);
Vector3f v1 = new Vector3f();
Vector3f v2 = new Vector3f();
Vector3f n = new Vector3f();
Light[] lightsArray = new Light[lights.size()];
lights.copyInto(lightsArray);
for (int i = 0; i < lightsArray.length; i++)
lightsArray[i].prepare(width, height);
float[][] heightWindow = new float[3][width];
for (int x = 0; x < width; x++)
heightWindow[1][x] = width45*bump.evaluate(x, 0);
// Loop through each source pixel
for (int y = 0; y < height; y++) {
boolean y0 = y > 0;
boolean y1 = y < height-1;
position.y = y;
for (int x = 0; x < width; x++)
heightWindow[2][x] = width45*bump.evaluate(x, y+1);
for (int x = 0; x < width; x++) {
boolean x0 = x > 0;
boolean x1 = x < width-1;
// Calculate the normal at this point
if (bumpSource != BUMPS_FROM_BEVEL) {
// Complicated and slower method
// Calculate four normals using the gradients in +/- X/Y directions
int count = 0;
normal.x = normal.y = normal.z = 0;
float m0 = heightWindow[1][x];
float m1 = x0 ? heightWindow[1][x-1]-m0 : 0;
float m2 = y0 ? heightWindow[0][x]-m0 : 0;
float m3 = x1 ? heightWindow[1][x+1]-m0 : 0;
float m4 = y1 ? heightWindow[2][x]-m0 : 0;
if (x0 && y1) {
v1.x = -1.0f; v1.y = 0.0f; v1.z = m1;
v2.x = 0.0f; v2.y = 1.0f; v2.z = m4;
n.cross(v1, v2);
n.normalize();
if (n.z < 0.0)
n.z = -n.z;
normal.add(n);
count++;
}
if (x0 && y0) {
v1.x = -1.0f; v1.y = 0.0f; v1.z = m1;
v2.x = 0.0f; v2.y = -1.0f; v2.z = m2;
n.cross(v1, v2);
n.normalize();
if (n.z < 0.0)
n.z = -n.z;
normal.add(n);
count++;
}
if (y0 && x1) {
v1.x = 0.0f; v1.y = -1.0f; v1.z = m2;
v2.x = 1.0f; v2.y = 0.0f; v2.z = m3;
n.cross(v1, v2);
n.normalize();
if (n.z < 0.0)
n.z = -n.z;
normal.add(n);
count++;
}
if (x1 && y1) {
v1.x = 1.0f; v1.y = 0.0f; v1.z = m3;
v2.x = 0.0f; v2.y = 1.0f; v2.z = m4;
n.cross(v1, v2);
n.normalize();
if (n.z < 0.0)
n.z = -n.z;
normal.add(n);
count++;
}
// Average the four normals
normal.x /= count;
normal.y /= count;
normal.z /= count;
}
if (invertBumps) {
normal.x = -normal.x;
normal.y = -normal.y;
}
position.x = x;
if (normal.z >= 0) {
// Get the material colour at this point
if (colorSource == COLORS_FROM_IMAGE)
setFromRGB(diffuseColor, inPixels[index]);
else
setFromRGB(diffuseColor, material.diffuseColor);
if (reflectivity != 0 && environmentMap != null) {
//FIXME-too much normalizing going on here
tmpv2.set(viewpoint);
tmpv2.sub(position);
tmpv2.normalize();
tmpv.set(normal);
tmpv.normalize();
// Reflect
tmpv.scale( 2.0f*tmpv.dot(tmpv2) );
tmpv.sub(v);
tmpv.normalize();
setFromRGB(envColor, getEnvironmentMap(tmpv, inPixels, width, height));//FIXME-interpolate()
diffuseColor.x = reflectivity*envColor.x + areflectivity*diffuseColor.x;
diffuseColor.y = reflectivity*envColor.y + areflectivity*diffuseColor.y;
diffuseColor.z = reflectivity*envColor.z + areflectivity*diffuseColor.z;
}
// Shade the pixel
Color4f c = phongShade(position, viewpoint, normal, diffuseColor, specularColor, material, lightsArray);
int alpha = inPixels[index] & 0xff000000;
int rgb = ((int)(c.x * 255) << 16) | ((int)(c.y * 255) << 8) | (int)(c.z * 255);
outPixels[index++] = alpha | rgb;
} else
outPixels[index++] = 0;
}
float[] t = heightWindow[0];
heightWindow[0] = heightWindow[1];
heightWindow[1] = heightWindow[2];
heightWindow[2] = t;
}
return outPixels;
}
protected Color4f phongShade(Vector3f position, Vector3f viewpoint, Vector3f normal, Color4f diffuseColor, Color4f specularColor, Material material, Light[] lightsArray) {
shadedColor.set(diffuseColor);
shadedColor.scale(material.ambientIntensity);
for (int i = 0; i < lightsArray.length; i++) {
Light light = lightsArray[i];
n.set(normal);
l.set(light.position);
if (light.type != DISTANT)
l.sub(position);
l.normalize();
float nDotL = n.dot(l);
if (nDotL >= 0.0) {
float dDotL = 0;
v.set(viewpoint);
v.sub(position);
v.normalize();
// Spotlight
if (light.type == SPOT) {
dDotL = light.direction.dot(l);
if (dDotL < light.cosConeAngle)
continue;
}
n.scale(2.0f * nDotL);
n.sub(l);
float rDotV = n.dot(v);
float rv;
if (rDotV < 0.0)
rv = 0.0f;
else
// rv = (float)Math.pow(rDotV, material.highlight);
rv = rDotV / (material.highlight - material.highlight*rDotV + rDotV); // Fast approximation to pow
// Spotlight
if (light.type == SPOT) {
dDotL = light.cosConeAngle/dDotL;
float e = dDotL;
e *= e;
e *= e;
e *= e;
e = (float)Math.pow(dDotL, light.focus*10)*(1 - e);
rv *= e;
nDotL *= e;
}
diffuse_color.set(diffuseColor);
diffuse_color.scale(material.diffuseReflectivity);
diffuse_color.x *= light.realColor.x * nDotL;
diffuse_color.y *= light.realColor.y * nDotL;
diffuse_color.z *= light.realColor.z * nDotL;
specular_color.set(specularColor);
specular_color.scale(material.specularReflectivity);
specular_color.x *= light.realColor.x * rv;
specular_color.y *= light.realColor.y * rv;
specular_color.z *= light.realColor.z * rv;
diffuse_color.add(specular_color);
diffuse_color.clamp( 0, 1 );
shadedColor.add(diffuse_color);
}
}
shadedColor.clamp( 0, 1 );
return shadedColor;
}
private int getEnvironmentMap(Vector3f normal, int[] inPixels, int width, int height) {
if (environmentMap != null) {
float angle = (float)Math.acos(-normal.y);
float x, y;
y = angle/ImageMath.PI;
if (y == 0.0f || y == 1.0f)
x = 0.0f;
else {
float f = normal.x/(float)Math.sin(angle);
if (f > 1.0f)
f = 1.0f;
else if (f < -1.0f)
f = -1.0f;
x = (float)Math.acos(f)/ImageMath.PI;
}
// A bit of empirical scaling....
x = ImageMath.clamp(x * envWidth, 0, envWidth-1);
y = ImageMath.clamp(y * envHeight, 0, envHeight-1);
int ix = (int)x;
int iy = (int)y;
float xWeight = x-ix;
float yWeight = y-iy;
int i = envWidth*iy + ix;
int dx = ix == envWidth-1 ? 0 : 1;
int dy = iy == envHeight-1 ? 0 : envWidth;
return ImageMath.bilinearInterpolate( xWeight, yWeight, envPixels[i], envPixels[i+dx], envPixels[i+dy], envPixels[i+dx+dy] );
}
return 0;
}
public String toString() {
return "Stylize/Light Effects...";
}
/**
* A class representing material properties.
*/
public static class Material {
int diffuseColor;
int specularColor;
float ambientIntensity;
float diffuseReflectivity;
float specularReflectivity;
float highlight;
float reflectivity;
public Material() {
ambientIntensity = 0.5f;
diffuseReflectivity = 1.0f;
specularReflectivity = 1.0f;
highlight = 3.0f;
reflectivity = 0.0f;
diffuseColor = 0xff888888;
specularColor = 0xffffffff;
}
public void setDiffuseColor(int diffuseColor) {
this.diffuseColor = diffuseColor;
}
public int getDiffuseColor() {
return diffuseColor;
}
}
public final static int AMBIENT = 0;
public final static int DISTANT = 1;
public final static int POINT = 2;
public final static int SPOT = 3;
/**
* A class representing a light.
*/
public static class Light implements Cloneable {
int type = AMBIENT;
Vector3f position;
Vector3f direction;
Color4f realColor = new Color4f();
int color = 0xffffffff;
float intensity;
float azimuth;
float elevation;
float focus = 0.5f;
float centreX = 0.5f, centreY = 0.5f;
float coneAngle = ImageMath.PI/6;
float cosConeAngle;
float distance = 100.0f;
public Light() {
this(270*ImageMath.PI/180.0f, 0.5235987755982988f, 1.0f);
}
public Light(float azimuth, float elevation, float intensity) {
this.azimuth = azimuth;
this.elevation = elevation;
this.intensity = intensity;
}
public void setAzimuth(float azimuth) {
this.azimuth = azimuth;
}
public float getAzimuth() {
return azimuth;
}
public void setElevation(float elevation) {
this.elevation = elevation;
}
public float getElevation() {
return elevation;
}
public void setDistance(float distance) {
this.distance = distance;
}
public float getDistance() {
return distance;
}
public void setIntensity(float intensity) {
this.intensity = intensity;
}
public float getIntensity() {
return intensity;
}
public void setConeAngle(float coneAngle) {
this.coneAngle = coneAngle;
}
public float getConeAngle() {
return coneAngle;
}
public void setFocus(float focus) {
this.focus = focus;
}
public float getFocus() {
return focus;
}
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
/**
* Set the centre of the light in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX(float x) {
centreX = x;
}
/**
* Get the centre of the light in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the light in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY(float y) {
centreY = y;
}
/**
* Get the centre of the light in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Prepare the light for rendering.
* @param width the output image width
* @param height the output image height
*/
public void prepare(int width, int height) {
float lx = (float)(Math.cos(azimuth) * Math.cos(elevation));
float ly = (float)(Math.sin(azimuth) * Math.cos(elevation));
float lz = (float)Math.sin(elevation);
direction = new Vector3f(lx, ly, lz);
direction.normalize();
if (type != DISTANT) {
lx *= distance;
ly *= distance;
lz *= distance;
lx += width * centreX;
ly += height * centreY;
}
position = new Vector3f(lx, ly, lz);
realColor.set( new Color(color) );
realColor.scale(intensity);
cosConeAngle = (float)Math.cos(coneAngle);
}
public Object clone() {
try {
Light copy = (Light)super.clone();
return copy;
}
catch (CloneNotSupportedException e) {
return null;
}
}
public String toString() {
return "Light";
}
}
public class AmbientLight extends Light {
public String toString() {
return "Ambient Light";
}
}
public class PointLight extends Light {
public PointLight() {
type = POINT;
}
public String toString() {
return "Point Light";
}
}
public class DistantLight extends Light {
public DistantLight() {
type = DISTANT;
}
public String toString() {
return "Distant Light";
}
}
public class SpotLight extends Light {
public SpotLight() {
type = SPOT;
}
public String toString() {
return "Spotlight";
}
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GrayscaleFilter.java 0000644 0001750 0001750 00000002302 10566356614 027231 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which converts an image to grayscale using the NTSC brightness calculation.
*/
public class GrayscaleFilter extends PointFilter {
public GrayscaleFilter() {
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
// rgb = (r + g + b) / 3; // simple average
rgb = (r * 77 + g * 151 + b * 28) >> 8; // NTSC luma
return a | (rgb << 16) | (rgb << 8) | rgb;
}
public String toString() {
return "Colors/Grayscale";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MapColorsFilter.java 0000644 0001750 0001750 00000002615 10566572034 027221 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which replaces one color by another in an image. This is frankly, not often useful, but has its occasional
* uses when dealing with GIF transparency and the like.
*/
public class MapColorsFilter extends PointFilter {
private int oldColor;
private int newColor;
/**
* Construct a MapColorsFilter.
*/
public MapColorsFilter() {
this( 0xffffffff, 0xff000000 );
}
/**
* Construct a MapColorsFilter.
* @param oldColor the color to replace
* @param newColor the color to replace it with
*/
public MapColorsFilter(int oldColor, int newColor) {
canFilterIndexColorModel = true;
this.oldColor = oldColor;
this.newColor = newColor;
}
public int filterRGB(int x, int y, int rgb) {
if (rgb == oldColor)
return newColor;
return rgb;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ShadowFilter.java 0000644 0001750 0001750 00000016155 11201001401 026517 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which draws a drop shadow based on the alpha channel of the image.
*/
public class ShadowFilter extends AbstractBufferedImageOp {
private float radius = 5;
private float angle = (float)Math.PI*6/4;
private float distance = 5;
private float opacity = 0.5f;
private boolean addMargins = false;
private boolean shadowOnly = false;
private int shadowColor = 0xff000000;
/**
* Construct a ShadowFilter.
*/
public ShadowFilter() {
}
/**
* Construct a ShadowFilter.
* @param radius the radius of the shadow
* @param xOffset the X offset of the shadow
* @param yOffset the Y offset of the shadow
* @param opacity the opacity of the shadow
*/
public ShadowFilter(float radius, float xOffset, float yOffset, float opacity) {
this.radius = radius;
this.angle = (float)Math.atan2(yOffset, xOffset);
this.distance = (float)Math.sqrt(xOffset*xOffset + yOffset*yOffset);
this.opacity = opacity;
}
/**
* Specifies the angle of the shadow.
* @param angle the angle of the shadow.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
}
/**
* Returns the angle of the shadow.
* @return the angle of the shadow.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the distance of the shadow.
* @param distance the distance.
* @see #getDistance
*/
public void setDistance(float distance) {
this.distance = distance;
}
/**
* Get the distance of the shadow.
* @return the distance.
* @see #setDistance
*/
public float getDistance() {
return distance;
}
/**
* Set the radius of the kernel, and hence the amount of blur. The bigger the radius, the longer this filter will take.
* @param radius the radius of the blur in pixels.
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the kernel.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
/**
* Set the opacity of the shadow.
* @param opacity the opacity.
* @see #getOpacity
*/
public void setOpacity(float opacity) {
this.opacity = opacity;
}
/**
* Get the opacity of the shadow.
* @return the opacity.
* @see #setOpacity
*/
public float getOpacity() {
return opacity;
}
/**
* Set the color of the shadow.
* @param shadowColor the color.
* @see #getShadowColor
*/
public void setShadowColor(int shadowColor) {
this.shadowColor = shadowColor;
}
/**
* Get the color of the shadow.
* @return the color.
* @see #setShadowColor
*/
public int getShadowColor() {
return shadowColor;
}
/**
* Set whether to increase the size of the output image to accomodate the shadow.
* @param addMargins true to add margins.
* @see #getAddMargins
*/
public void setAddMargins(boolean addMargins) {
this.addMargins = addMargins;
}
/**
* Get whether to increase the size of the output image to accomodate the shadow.
* @return true to add margins.
* @see #setAddMargins
*/
public boolean getAddMargins() {
return addMargins;
}
/**
* Set whether to only draw the shadow without the original image.
* @param shadowOnly true to only draw the shadow.
* @see #getShadowOnly
*/
public void setShadowOnly(boolean shadowOnly) {
this.shadowOnly = shadowOnly;
}
/**
* Get whether to only draw the shadow without the original image.
* @return true to only draw the shadow.
* @see #setShadowOnly
*/
public boolean getShadowOnly() {
return shadowOnly;
}
public Rectangle2D getBounds2D( BufferedImage src ) {
Rectangle r = new Rectangle(0, 0, src.getWidth(), src.getHeight());
if ( addMargins ) {
float xOffset = distance*(float)Math.cos(angle);
float yOffset = -distance*(float)Math.sin(angle);
r.width += (int)(Math.abs(xOffset)+2*radius);
r.height += (int)(Math.abs(yOffset)+2*radius);
}
return r;
}
public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
if ( dstPt == null )
dstPt = new Point2D.Double();
if ( addMargins ) {
float xOffset = distance*(float)Math.cos(angle);
float yOffset = -distance*(float)Math.sin(angle);
float topShadow = Math.max( 0, radius-yOffset );
float leftShadow = Math.max( 0, radius-xOffset );
dstPt.setLocation( srcPt.getX()+leftShadow, srcPt.getY()+topShadow );
} else
dstPt.setLocation( srcPt.getX(), srcPt.getY() );
return dstPt;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
float xOffset = distance*(float)Math.cos(angle);
float yOffset = -distance*(float)Math.sin(angle);
if ( dst == null ) {
if ( addMargins ) {
ColorModel cm = src.getColorModel();
dst = new BufferedImage(cm, cm.createCompatibleWritableRaster(src.getWidth() + (int) (Math.abs(xOffset) + radius), src.getHeight() + (int) (Math.abs(yOffset) + radius)), cm.isAlphaPremultiplied(), null);
} else
dst = createCompatibleDestImage( src, null );
}
float shadowR = ((shadowColor >> 16) & 0xff) / 255f;
float shadowG = ((shadowColor >> 8) & 0xff) / 255f;
float shadowB = (shadowColor & 0xff) / 255f;
// Make a black mask from the image's alpha channel
float[][] extractAlpha = {
{ 0, 0, 0, shadowR },
{ 0, 0, 0, shadowG },
{ 0, 0, 0, shadowB },
{ 0, 0, 0, opacity }
};
BufferedImage shadow = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
new BandCombineOp( extractAlpha, null ).filter( src.getRaster(), shadow.getRaster() );
shadow = new GaussianFilter( radius ).filter( shadow, null );
Graphics2D g = dst.createGraphics();
g.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, opacity ) );
if ( addMargins ) {
float radius2 = radius/2;
float topShadow = Math.max( 0, radius-yOffset );
float leftShadow = Math.max( 0, radius-xOffset );
g.translate( leftShadow, topShadow );
}
g.drawRenderedImage( shadow, AffineTransform.getTranslateInstance( xOffset, yOffset ) );
if ( !shadowOnly ) {
g.setComposite( AlphaComposite.SrcOver );
g.drawRenderedImage( src, null );
}
g.dispose();
return dst;
}
public String toString() {
return "Stylize/Drop Shadow...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FillFilter.java 0000644 0001750 0001750 00000003012 10566356614 026204 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which fills an image with a given color. Normally you would just call Graphics.fillRect but it can sometimes be useful
* to go via a filter to fit in with an existing API.
*/
public class FillFilter extends PointFilter {
private int fillColor;
/**
* Construct a FillFilter.
*/
public FillFilter() {
this(0xff000000);
}
/**
* Construct a FillFilter.
* @param color the fill color
*/
public FillFilter(int color) {
this.fillColor = color;
}
/**
* Set the fill color.
* @param fillColor the fill color
* @see #getFillColor
*/
public void setFillColor(int fillColor) {
this.fillColor = fillColor;
}
/**
* Get the fill color.
* @return the fill color
* @see #setFillColor
*/
public int getFillColor() {
return fillColor;
}
public int filterRGB(int x, int y, int rgb) {
return fillColor;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BlockFilter.java 0000644 0001750 0001750 00000005770 10626007760 026355 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A Filter to pixellate images.
*/
public class BlockFilter extends AbstractBufferedImageOp {
private int blockSize = 2;
/**
* Construct a BlockFilter.
*/
public BlockFilter() {
}
/**
* Construct a BlockFilter.
* @param blockSize the number of pixels along each block edge
*/
public BlockFilter( int blockSize ) {
this.blockSize = blockSize;
}
/**
* Set the pixel block size.
* @param blockSize the number of pixels along each block edge
* @min-value 1
* @max-value 100+
* @see #getBlockSize
*/
public void setBlockSize(int blockSize) {
this.blockSize = blockSize;
}
/**
* Get the pixel block size.
* @return the number of pixels along each block edge
* @see #setBlockSize
*/
public int getBlockSize() {
return blockSize;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] pixels = new int[blockSize * blockSize];
for ( int y = 0; y < height; y += blockSize ) {
for ( int x = 0; x < width; x += blockSize ) {
int w = Math.min( blockSize, width-x );
int h = Math.min( blockSize, height-y );
int t = w*h;
getRGB( src, x, y, w, h, pixels );
int r = 0, g = 0, b = 0;
int argb;
int i = 0;
for ( int by = 0; by < h; by++ ) {
for ( int bx = 0; bx < w; bx++ ) {
argb = pixels[i];
r += (argb >> 16) & 0xff;
g += (argb >> 8) & 0xff;
b += argb & 0xff;
i++;
}
}
argb = ((r/t) << 16) | ((g/t) << 8) | (b/t);
i = 0;
for ( int by = 0; by < h; by++ ) {
for ( int bx = 0; bx < w; bx++ ) {
pixels[i] = (pixels[i] & 0xff000000) | argb;
i++;
}
}
setRGB( dst, x, y, w, h, pixels );
}
}
return dst;
}
public String toString() {
return "Pixellate/Mosaic...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/KeyFilter.java 0000644 0001750 0001750 00000012275 10566356614 026061 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* An experimental filter which can be used for keying against a clean shot. Given a source image, a clean image and a destination image,
* the filter replaces all pixels in the source which nearly equal the equivalent clean pixel by destination pixels.
*/
public class KeyFilter extends AbstractBufferedImageOp {
private float hTolerance = 0;
private float sTolerance = 0;
private float bTolerance = 0;
private BufferedImage destination;
private BufferedImage cleanImage;
/**
* Construct a KeyFilter.
*/
public KeyFilter() {
}
/**
* Set the hue tolerance of the image in the range 0..1.
* @param hTolerance the tolerance
* @see #getHTolerance
*/
public void setHTolerance( float hTolerance ) {
this.hTolerance = hTolerance;
}
/**
* Get the hue tolerance.
* @return the tolerance
* @see #setHTolerance
*/
public float getHTolerance() {
return hTolerance;
}
/**
* Set the saturation tolerance of the image in the range 0..1.
* @param sTolerance the tolerance
* @see #getSTolerance
*/
public void setSTolerance( float sTolerance ) {
this.sTolerance = sTolerance;
}
/**
* Get the saturation tolerance.
* @return the tolerance
* @see #setSTolerance
*/
public float getSTolerance() {
return sTolerance;
}
/**
* Set the brightness tolerance of the image in the range 0..1.
* @param bTolerance the tolerance
* @see #getBTolerance
*/
public void setBTolerance( float bTolerance ) {
this.bTolerance = bTolerance;
}
/**
* Get the brightness tolerance.
* @return the tolerance
* @see #setBTolerance
*/
public float getBTolerance() {
return bTolerance;
}
/**
* Set the destination image.
* @param destination the destination image
* @see #getDestination
*/
public void setDestination( BufferedImage destination ) {
this.destination = destination;
}
/**
* Get the destination image.
* @return the destination image
* @see #setDestination
*/
public BufferedImage getDestination() {
return destination;
}
/**
* Get the clean image.
* @param cleanImage the clean image
* @see #getCleanImage
*/
public void setCleanImage( BufferedImage cleanImage ) {
this.cleanImage = cleanImage;
}
/**
* Get the clean image.
* @return the clean image
* @see #setCleanImage
*/
public BufferedImage getCleanImage() {
return cleanImage;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
WritableRaster dstRaster = dst.getRaster();
if ( destination != null && cleanImage != null ) {
float[] hsb1 = null;
float[] hsb2 = null;
int[] inPixels = null;
int[] outPixels = null;
int[] cleanPixels = null;
for ( int y = 0; y < height; y++ ) {
inPixels = getRGB( src, 0, y, width, 1, inPixels );
outPixels = getRGB( destination, 0, y, width, 1, outPixels );
cleanPixels = getRGB( cleanImage, 0, y, width, 1, cleanPixels );
for ( int x = 0; x < width; x++ ) {
int rgb1 = inPixels[x];
int out = outPixels[x];
int rgb2 = cleanPixels[x];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
hsb1 = Color.RGBtoHSB( r1, b1, g1, hsb1 );
hsb2 = Color.RGBtoHSB( r2, b2, g2, hsb2 );
// int tolerance = (int)(255*tolerance);
// return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
// if ( PixelUtils.nearColors( in, clean, (int)(255*tolerance) ) )
if ( Math.abs( hsb1[0] - hsb2[0] ) < hTolerance && Math.abs( hsb1[1] - hsb2[1] ) < sTolerance && Math.abs( hsb1[2] - hsb2[2] ) < bTolerance )
inPixels[x] = out;
else
inPixels[x] = rgb1;
}
setRGB( dst, 0, y, width, 1, inPixels );
}
}
return dst;
}
public String toString() {
return "Keying/Key...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/HSBAdjustFilter.java 0000644 0001750 0001750 00000003610 10562652111 027074 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
public class HSBAdjustFilter extends PointFilter {
public float hFactor, sFactor, bFactor;
private float[] hsb = new float[3];
public HSBAdjustFilter() {
this(0, 0, 0);
}
public HSBAdjustFilter(float r, float g, float b) {
hFactor = r;
sFactor = g;
bFactor = b;
canFilterIndexColorModel = true;
}
public void setHFactor( float hFactor ) {
this.hFactor = hFactor;
}
public float getHFactor() {
return hFactor;
}
public void setSFactor( float sFactor ) {
this.sFactor = sFactor;
}
public float getSFactor() {
return sFactor;
}
public void setBFactor( float bFactor ) {
this.bFactor = bFactor;
}
public float getBFactor() {
return bFactor;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
Color.RGBtoHSB(r, g, b, hsb);
hsb[0] += hFactor;
while (hsb[0] < 0)
hsb[0] += Math.PI*2;
hsb[1] += sFactor;
if (hsb[1] < 0)
hsb[1] = 0;
else if (hsb[1] > 1.0)
hsb[1] = 1.0f;
hsb[2] += bFactor;
if (hsb[2] < 0)
hsb[2] = 0;
else if (hsb[2] > 1.0)
hsb[2] = 1.0f;
rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
return a | (rgb & 0xffffff);
}
public String toString() {
return "Colors/Adjust HSB...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/HalftoneFilter.java 0000644 0001750 0001750 00000010035 10626010435 027042 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.util.*;
/**
* A filter which uses a another image as a ask to produce a halftoning effect.
*/
public class HalftoneFilter extends AbstractBufferedImageOp {
private float softness = 0.1f;
private boolean invert;
private boolean monochrome;
private BufferedImage mask;
public HalftoneFilter() {
}
/**
* Set the softness of the effect in the range 0..1.
* @param softness the softness
* @min-value 0
* @max-value 1
* @see #getSoftness
*/
public void setSoftness( float softness ) {
this.softness = softness;
}
/**
* Get the softness of the effect.
* @return the softness
* @see #setSoftness
*/
public float getSoftness() {
return softness;
}
/**
* Set the halftone mask.
* @param mask the mask
* @see #getMask
*/
public void setMask( BufferedImage mask ) {
this.mask = mask;
}
/**
* Get the halftone mask.
* @return the mask
* @see #setMask
*/
public BufferedImage getMask() {
return mask;
}
public void setInvert( boolean invert ) {
this.invert = invert;
}
public boolean getInvert() {
return invert;
}
/**
* Set whether to do monochrome halftoning.
* @param monochrome true for monochrome halftoning
* @see #getMonochrome
*/
public void setMonochrome(boolean monochrome) {
this.monochrome = monochrome;
}
/**
* Get whether to do monochrome halftoning.
* @return true for monochrome halftoning
* @see #setMonochrome
*/
public boolean getMonochrome() {
return monochrome;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
if ( mask == null )
return dst;
int maskWidth = mask.getWidth();
int maskHeight = mask.getHeight();
float s = 255*softness;
int[] inPixels = new int[width];
int[] maskPixels = new int[maskWidth];
for ( int y = 0; y < height; y++ ) {
getRGB( src, 0, y, width, 1, inPixels );
getRGB( mask, 0, y % maskHeight, maskWidth, 1, maskPixels );
for ( int x = 0; x < width; x++ ) {
int maskRGB = maskPixels[x % maskWidth];
int inRGB = inPixels[x];
if ( invert )
maskRGB ^= 0xffffff;
if ( monochrome ) {
int v = PixelUtils.brightness( maskRGB );
int iv = PixelUtils.brightness( inRGB );
float f = 1-ImageMath.smoothStep( iv-s, iv+s, v );
int a = (int)(255 * f);
inPixels[x] = (inRGB & 0xff000000) | (a << 16) | (a << 8) | a;
} else {
int ir = (inRGB >> 16) & 0xff;
int ig = (inRGB >> 8) & 0xff;
int ib = inRGB & 0xff;
int mr = (maskRGB >> 16) & 0xff;
int mg = (maskRGB >> 8) & 0xff;
int mb = maskRGB & 0xff;
int r = (int)(255 * (1-ImageMath.smoothStep( ir-s, ir+s, mr )));
int g = (int)(255 * (1-ImageMath.smoothStep( ig-s, ig+s, mg )));
int b = (int)(255 * (1-ImageMath.smoothStep( ib-s, ib+s, mb )));
inPixels[x] = (inRGB & 0xff000000) | (r << 16) | (g << 8) | b;
}
}
setRGB( dst, 0, y, width, 1, inPixels );
}
return dst;
}
public String toString() {
return "Stylize/Halftone...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PixelUtils.java 0000644 0001750 0001750 00000013341 10562652111 026243 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.util.*;
import java.awt.Color;
/**
* Some more useful math functions for image processing.
* These are becoming obsolete as we move to Java2D. Use MiscComposite instead.
*/
public class PixelUtils {
public final static int REPLACE = 0;
public final static int NORMAL = 1;
public final static int MIN = 2;
public final static int MAX = 3;
public final static int ADD = 4;
public final static int SUBTRACT = 5;
public final static int DIFFERENCE = 6;
public final static int MULTIPLY = 7;
public final static int HUE = 8;
public final static int SATURATION = 9;
public final static int VALUE = 10;
public final static int COLOR = 11;
public final static int SCREEN = 12;
public final static int AVERAGE = 13;
public final static int OVERLAY = 14;
public final static int CLEAR = 15;
public final static int EXCHANGE = 16;
public final static int DISSOLVE = 17;
public final static int DST_IN = 18;
public final static int ALPHA = 19;
public final static int ALPHA_TO_GRAY = 20;
private static Random randomGenerator = new Random();
/**
* Clamp a value to the range 0..255
*/
public static int clamp(int c) {
if (c < 0)
return 0;
if (c > 255)
return 255;
return c;
}
public static int interpolate(int v1, int v2, float f) {
return clamp((int)(v1+f*(v2-v1)));
}
public static int brightness(int rgb) {
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
return (r+g+b)/3;
}
public static boolean nearColors(int rgb1, int rgb2, int tolerance) {
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
}
private final static float hsb1[] = new float[3];//FIXME-not thread safe
private final static float hsb2[] = new float[3];//FIXME-not thread safe
// Return rgb1 painted onto rgb2
public static int combinePixels(int rgb1, int rgb2, int op) {
return combinePixels(rgb1, rgb2, op, 0xff);
}
public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha, int channelMask) {
return (rgb2 & ~channelMask) | combinePixels(rgb1 & channelMask, rgb2, op, extraAlpha);
}
public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha) {
if (op == REPLACE)
return rgb1;
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int a2 = (rgb2 >> 24) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
switch (op) {
case NORMAL:
break;
case MIN:
r1 = Math.min(r1, r2);
g1 = Math.min(g1, g2);
b1 = Math.min(b1, b2);
break;
case MAX:
r1 = Math.max(r1, r2);
g1 = Math.max(g1, g2);
b1 = Math.max(b1, b2);
break;
case ADD:
r1 = clamp(r1+r2);
g1 = clamp(g1+g2);
b1 = clamp(b1+b2);
break;
case SUBTRACT:
r1 = clamp(r2-r1);
g1 = clamp(g2-g1);
b1 = clamp(b2-b1);
break;
case DIFFERENCE:
r1 = clamp(Math.abs(r1-r2));
g1 = clamp(Math.abs(g1-g2));
b1 = clamp(Math.abs(b1-b2));
break;
case MULTIPLY:
r1 = clamp(r1*r2/255);
g1 = clamp(g1*g2/255);
b1 = clamp(b1*b2/255);
break;
case DISSOLVE:
if ((randomGenerator.nextInt() & 0xff) <= a1) {
r1 = r2;
g1 = g2;
b1 = b2;
}
break;
case AVERAGE:
r1 = (r1+r2)/2;
g1 = (g1+g2)/2;
b1 = (b1+b2)/2;
break;
case HUE:
case SATURATION:
case VALUE:
case COLOR:
Color.RGBtoHSB(r1, g1, b1, hsb1);
Color.RGBtoHSB(r2, g2, b2, hsb2);
switch (op) {
case HUE:
hsb2[0] = hsb1[0];
break;
case SATURATION:
hsb2[1] = hsb1[1];
break;
case VALUE:
hsb2[2] = hsb1[2];
break;
case COLOR:
hsb2[0] = hsb1[0];
hsb2[1] = hsb1[1];
break;
}
rgb1 = Color.HSBtoRGB(hsb2[0], hsb2[1], hsb2[2]);
r1 = (rgb1 >> 16) & 0xff;
g1 = (rgb1 >> 8) & 0xff;
b1 = rgb1 & 0xff;
break;
case SCREEN:
r1 = 255 - ((255 - r1) * (255 - r2)) / 255;
g1 = 255 - ((255 - g1) * (255 - g2)) / 255;
b1 = 255 - ((255 - b1) * (255 - b2)) / 255;
break;
case OVERLAY:
int m, s;
s = 255 - ((255 - r1) * (255 - r2)) / 255;
m = r1 * r2 / 255;
r1 = (s * r1 + m * (255 - r1)) / 255;
s = 255 - ((255 - g1) * (255 - g2)) / 255;
m = g1 * g2 / 255;
g1 = (s * g1 + m * (255 - g1)) / 255;
s = 255 - ((255 - b1) * (255 - b2)) / 255;
m = b1 * b2 / 255;
b1 = (s * b1 + m * (255 - b1)) / 255;
break;
case CLEAR:
r1 = g1 = b1 = 0xff;
break;
case DST_IN:
r1 = clamp((r2*a1)/255);
g1 = clamp((g2*a1)/255);
b1 = clamp((b2*a1)/255);
a1 = clamp((a2*a1)/255);
return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
case ALPHA:
a1 = a1*a2/255;
return (a1 << 24) | (r2 << 16) | (g2 << 8) | b2;
case ALPHA_TO_GRAY:
int na = 255-a1;
return (a1 << 24) | (na << 16) | (na << 8) | na;
}
if (extraAlpha != 0xff || a1 != 0xff) {
a1 = a1*extraAlpha/255;
int a3 = (255-a1)*a2/255;
r1 = clamp((r1*a1+r2*a3)/255);
g1 = clamp((g1*a1+g2*a3)/255);
b1 = clamp((b1*a1+b2*a3)/255);
a1 = clamp(a1+a3);
}
return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/WholeImageFilter.java 0000644 0001750 0001750 00000004722 11331371033 027327 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which acts as a superclass for filters which need to have the whole image in memory
* to do their stuff.
*/
public abstract class WholeImageFilter extends AbstractBufferedImageOp {
/**
* The output image bounds.
*/
protected Rectangle transformedSpace;
/**
* The input image bounds.
*/
protected Rectangle originalSpace;
/**
* Construct a WholeImageFilter.
*/
public WholeImageFilter() {
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
// int type = src.getType();
// WritableRaster srcRaster = src.getRaster();
originalSpace = new Rectangle(0, 0, width, height);
transformedSpace = new Rectangle(0, 0, width, height);
transformSpace(transformedSpace);
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null);
}
// WritableRaster dstRaster = dst.getRaster();
int[] inPixels = getRGB( src, 0, 0, width, height, null );
inPixels = filterPixels( width, height, inPixels, transformedSpace );
setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels );
return dst;
}
/**
* Calculate output bounds for given input bounds.
* @param rect input and output rectangle
*/
protected void transformSpace(Rectangle rect) {
}
/**
* Actually filter the pixels.
* @param width the image width
* @param height the image height
* @param inPixels the image pixels
* @param transformedSpace the output bounds
* @return the output pixels
*/
protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace );
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CrystallizeFilter.java 0000644 0001750 0001750 00000004672 10566356614 027640 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.util.*;
import com.jhlabs.math.*;
/**
* A filter which applies a crystallizing effect to an image, by producing Voronoi cells filled with colours from the image.
*/
public class CrystallizeFilter extends CellularFilter {
private float edgeThickness = 0.4f;
private boolean fadeEdges = false;
private int edgeColor = 0xff000000;
public CrystallizeFilter() {
setScale(16);
setRandomness(0.0f);
}
public void setEdgeThickness(float edgeThickness) {
this.edgeThickness = edgeThickness;
}
public float getEdgeThickness() {
return edgeThickness;
}
public void setFadeEdges(boolean fadeEdges) {
this.fadeEdges = fadeEdges;
}
public boolean getFadeEdges() {
return fadeEdges;
}
public void setEdgeColor(int edgeColor) {
this.edgeColor = edgeColor;
}
public int getEdgeColor() {
return edgeColor;
}
public int getPixel(int x, int y, int[] inPixels, int width, int height) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
nx += 1000;
ny += 1000; // Reduce artifacts around 0,0
float f = evaluate(nx, ny);
float f1 = results[0].distance;
float f2 = results[1].distance;
int srcx = ImageMath.clamp((int)((results[0].x-1000)*scale), 0, width-1);
int srcy = ImageMath.clamp((int)((results[0].y-1000)*scale), 0, height-1);
int v = inPixels[srcy * width + srcx];
f = (f2 - f1) / edgeThickness;
f = ImageMath.smoothStep(0, edgeThickness, f);
if (fadeEdges) {
srcx = ImageMath.clamp((int)((results[1].x-1000)*scale), 0, width-1);
srcy = ImageMath.clamp((int)((results[1].y-1000)*scale), 0, height-1);
int v2 = inPixels[srcy * width + srcx];
v2 = ImageMath.mixColors(0.5f, v2, v);
v = ImageMath.mixColors(f, v2, v);
} else
v = ImageMath.mixColors(f, edgeColor, v);
return v;
}
public String toString() {
return "Stylize/Crystallize...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PosterizeFilter.java 0000644 0001750 0001750 00000003546 10566356614 027316 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter to posterize an image.
*/
public class PosterizeFilter extends PointFilter {
private int numLevels;
private int[] levels;
private boolean initialized = false;
public PosterizeFilter() {
setNumLevels(6);
}
/**
* Set the number of levels in the output image.
* @param numLevels the number of levels
* @see #getNumLevels
*/
public void setNumLevels(int numLevels) {
this.numLevels = numLevels;
initialized = false;
}
/**
* Get the number of levels in the output image.
* @return the number of levels
* @see #setNumLevels
*/
public int getNumLevels() {
return numLevels;
}
/**
* Initialize the filter.
*/
protected void initialize() {
levels = new int[256];
if (numLevels != 1)
for (int i = 0; i < 256; i++)
levels[i] = 255 * (numLevels*i / 256) / (numLevels-1);
}
public int filterRGB(int x, int y, int rgb) {
if (!initialized) {
initialized = true;
initialize();
}
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = levels[r];
g = levels[g];
b = levels[b];
return a | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Colors/Posterize...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CellularFilter.java 0000644 0001750 0001750 00000030611 10566356614 027066 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import com.jhlabs.math.*;
/**
* A filter which produces an image with a cellular texture.
*/
public class CellularFilter extends WholeImageFilter implements Function2D, Cloneable {
protected float scale = 32;
protected float stretch = 1.0f;
protected float angle = 0.0f;
public float amount = 1.0f;
public float turbulence = 1.0f;
public float gain = 0.5f;
public float bias = 0.5f;
public float distancePower = 2;
public boolean useColor = false;
protected Colormap colormap = new Gradient();
protected float[] coefficients = { 1, 0, 0, 0 };
protected float angleCoefficient;
protected Random random = new Random();
protected float m00 = 1.0f;
protected float m01 = 0.0f;
protected float m10 = 0.0f;
protected float m11 = 1.0f;
protected Point[] results = null;
protected float randomness = 0;
protected int gridType = HEXAGONAL;
private float min;
private float max;
private static byte[] probabilities;
private float gradientCoefficient;
public final static int RANDOM = 0;
public final static int SQUARE = 1;
public final static int HEXAGONAL = 2;
public final static int OCTAGONAL = 3;
public final static int TRIANGULAR = 4;
public CellularFilter() {
results = new Point[3];
for (int j = 0; j < results.length; j++)
results[j] = new Point();
if (probabilities == null) {
probabilities = new byte[8192];
float factorial = 1;
float total = 0;
float mean = 2.5f;
for (int i = 0; i < 10; i++) {
if (i > 1)
factorial *= i;
float probability = (float)Math.pow(mean, i) * (float)Math.exp(-mean) / factorial;
int start = (int)(total * 8192);
total += probability;
int end = (int)(total * 8192);
for (int j = start; j < end; j++)
probabilities[j] = (byte)i;
}
}
}
/**
* Specifies the scale of the texture.
* @param scale the scale of the texture.
* @min-value 1
* @max-value 300+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the texture.
* @return the scale of the texture.
* @see #setScale
*/
public float getScale() {
return scale;
}
/**
* Specifies the stretch factor of the texture.
* @param stretch the stretch factor of the texture.
* @min-value 1
* @max-value 50+
* @see #getStretch
*/
public void setStretch(float stretch) {
this.stretch = stretch;
}
/**
* Returns the stretch factor of the texture.
* @return the stretch factor of the texture.
* @see #setStretch
*/
public float getStretch() {
return stretch;
}
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
float cos = (float)Math.cos(angle);
float sin = (float)Math.sin(angle);
m00 = cos;
m01 = sin;
m10 = -sin;
m11 = cos;
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
public void setCoefficient(int i, float v) {
coefficients[i] = v;
}
public float getCoefficient(int i) {
return coefficients[i];
}
public void setAngleCoefficient(float angleCoefficient) {
this.angleCoefficient = angleCoefficient;
}
public float getAngleCoefficient() {
return angleCoefficient;
}
public void setGradientCoefficient(float gradientCoefficient) {
this.gradientCoefficient = gradientCoefficient;
}
public float getGradientCoefficient() {
return gradientCoefficient;
}
public void setF1( float v ) {
coefficients[0] = v;
}
public float getF1() {
return coefficients[0];
}
public void setF2( float v ) {
coefficients[1] = v;
}
public float getF2() {
return coefficients[1];
}
public void setF3( float v ) {
coefficients[2] = v;
}
public float getF3() {
return coefficients[2];
}
public void setF4( float v ) {
coefficients[3] = v;
}
public float getF4() {
return coefficients[3];
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public void setRandomness(float randomness) {
this.randomness = randomness;
}
public float getRandomness() {
return randomness;
}
public void setGridType(int gridType) {
this.gridType = gridType;
}
public int getGridType() {
return gridType;
}
public void setDistancePower(float distancePower) {
this.distancePower = distancePower;
}
public float getDistancePower() {
return distancePower;
}
/**
* Specifies the turbulence of the texture.
* @param turbulence the turbulence of the texture.
* @min-value 0
* @max-value 1
* @see #getTurbulence
*/
public void setTurbulence(float turbulence) {
this.turbulence = turbulence;
}
/**
* Returns the turbulence of the effect.
* @return the turbulence of the effect.
* @see #setTurbulence
*/
public float getTurbulence() {
return turbulence;
}
/**
* Set the amount of effect.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of texture.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public class Point {
public int index;
public float x, y;
public float dx, dy;
public float cubeX, cubeY;
public float distance;
}
private float checkCube(float x, float y, int cubeX, int cubeY, Point[] results) {
int numPoints;
random.setSeed(571*cubeX + 23*cubeY);
switch (gridType) {
case RANDOM:
default:
numPoints = probabilities[random.nextInt() & 0x1fff];
break;
case SQUARE:
numPoints = 1;
break;
case HEXAGONAL:
numPoints = 1;
break;
case OCTAGONAL:
numPoints = 2;
break;
case TRIANGULAR:
numPoints = 2;
break;
}
for (int i = 0; i < numPoints; i++) {
float px = 0, py = 0;
float weight = 1.0f;
switch (gridType) {
case RANDOM:
px = random.nextFloat();
py = random.nextFloat();
break;
case SQUARE:
px = py = 0.5f;
if (randomness != 0) {
px += randomness * (random.nextFloat()-0.5);
py += randomness * (random.nextFloat()-0.5);
}
break;
case HEXAGONAL:
if ((cubeX & 1) == 0) {
px = 0.75f; py = 0;
} else {
px = 0.75f; py = 0.5f;
}
if (randomness != 0) {
px += randomness * Noise.noise2(271*(cubeX+px), 271*(cubeY+py));
py += randomness * Noise.noise2(271*(cubeX+px)+89, 271*(cubeY+py)+137);
}
break;
case OCTAGONAL:
switch (i) {
case 0: px = 0.207f; py = 0.207f; break;
case 1: px = 0.707f; py = 0.707f; weight = 1.6f; break;
}
if (randomness != 0) {
px += randomness * Noise.noise2(271*(cubeX+px), 271*(cubeY+py));
py += randomness * Noise.noise2(271*(cubeX+px)+89, 271*(cubeY+py)+137);
}
break;
case TRIANGULAR:
if ((cubeY & 1) == 0) {
if (i == 0) {
px = 0.25f; py = 0.35f;
} else {
px = 0.75f; py = 0.65f;
}
} else {
if (i == 0) {
px = 0.75f; py = 0.35f;
} else {
px = 0.25f; py = 0.65f;
}
}
if (randomness != 0) {
px += randomness * Noise.noise2(271*(cubeX+px), 271*(cubeY+py));
py += randomness * Noise.noise2(271*(cubeX+px)+89, 271*(cubeY+py)+137);
}
break;
}
float dx = (float)Math.abs(x-px);
float dy = (float)Math.abs(y-py);
float d;
dx *= weight;
dy *= weight;
if (distancePower == 1.0f)
d = dx + dy;
else if (distancePower == 2.0f)
d = (float)Math.sqrt(dx*dx + dy*dy);
else
d = (float)Math.pow((float)Math.pow(dx, distancePower) + (float)Math.pow(dy, distancePower), 1/distancePower);
// Insertion sort the long way round to speed it up a bit
if (d < results[0].distance) {
Point p = results[2];
results[2] = results[1];
results[1] = results[0];
results[0] = p;
p.distance = d;
p.dx = dx;
p.dy = dy;
p.x = cubeX+px;
p.y = cubeY+py;
} else if (d < results[1].distance) {
Point p = results[2];
results[2] = results[1];
results[1] = p;
p.distance = d;
p.dx = dx;
p.dy = dy;
p.x = cubeX+px;
p.y = cubeY+py;
} else if (d < results[2].distance) {
Point p = results[2];
p.distance = d;
p.dx = dx;
p.dy = dy;
p.x = cubeX+px;
p.y = cubeY+py;
}
}
return results[2].distance;
}
public float evaluate(float x, float y) {
for (int j = 0; j < results.length; j++)
results[j].distance = Float.POSITIVE_INFINITY;
int ix = (int)x;
int iy = (int)y;
float fx = x-ix;
float fy = y-iy;
float d = checkCube(fx, fy, ix, iy, results);
if (d > fy)
d = checkCube(fx, fy+1, ix, iy-1, results);
if (d > 1-fy)
d = checkCube(fx, fy-1, ix, iy+1, results);
if (d > fx) {
checkCube(fx+1, fy, ix-1, iy, results);
if (d > fy)
d = checkCube(fx+1, fy+1, ix-1, iy-1, results);
if (d > 1-fy)
d = checkCube(fx+1, fy-1, ix-1, iy+1, results);
}
if (d > 1-fx) {
d = checkCube(fx-1, fy, ix+1, iy, results);
if (d > fy)
d = checkCube(fx-1, fy+1, ix+1, iy-1, results);
if (d > 1-fy)
d = checkCube(fx-1, fy-1, ix+1, iy+1, results);
}
float t = 0;
for (int i = 0; i < 3; i++)
t += coefficients[i] * results[i].distance;
if (angleCoefficient != 0) {
float angle = (float)Math.atan2(y-results[0].y, x-results[0].x);
if (angle < 0)
angle += 2*(float)Math.PI;
angle /= 4*(float)Math.PI;
t += angleCoefficient * angle;
}
if (gradientCoefficient != 0) {
float a = 1/(results[0].dy+results[0].dx);
t += gradientCoefficient * a;
}
return t;
}
public float turbulence2(float x, float y, float freq) {
float t = 0.0f;
for (float f = 1.0f; f <= freq; f *= 2)
t += evaluate(f*x, f*y) / f;
return t;
}
public int getPixel(int x, int y, int[] inPixels, int width, int height) {
float nx = m00*x + m01*y;
float ny = m10*x + m11*y;
nx /= scale;
ny /= scale * stretch;
nx += 1000;
ny += 1000; // Reduce artifacts around 0,0
float f = turbulence == 1.0f ? evaluate(nx, ny) : turbulence2(nx, ny, turbulence);
// Normalize to 0..1
// f = (f-min)/(max-min);
f *= 2;
f *= amount;
int a = 0xff000000;
int v;
if (colormap != null) {
v = colormap.getColor(f);
if (useColor) {
int srcx = ImageMath.clamp((int)((results[0].x-1000)*scale), 0, width-1);
int srcy = ImageMath.clamp((int)((results[0].y-1000)*scale), 0, height-1);
v = inPixels[srcy * width + srcx];
f = (results[1].distance - results[0].distance) / (results[1].distance + results[0].distance);
f = ImageMath.smoothStep(coefficients[1], coefficients[0], f);
v = ImageMath.mixColors(f, 0xff000000, v);
}
return v;
} else {
v = PixelUtils.clamp((int)(f*255));
int r = v << 16;
int g = v << 8;
int b = v;
return a|r|g|b;
}
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
// float[] minmax = Noise.findRange(this, null);
// min = minmax[0];
// max = minmax[1];
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
outPixels[index++] = getPixel(x, y, inPixels, width, height);
}
}
return outPixels;
}
public Object clone() {
CellularFilter f = (CellularFilter)super.clone();
f.coefficients = (float[])coefficients.clone();
f.results = (Point[])results.clone();
f.random = new Random();
// if (colormap != null)
// f.colormap = (Colormap)colormap.clone();
return f;
}
public String toString() {
return "Texture/Cellular...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BlurFilter.java 0000644 0001750 0001750 00000002020 10566356614 026220 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A simple blur filter. You should probably use BoxBlurFilter instead.
*/
public class BlurFilter extends ConvolveFilter {
/**
* A 3x3 convolution kernel for a simple blur.
*/
protected static float[] blurMatrix = {
1/14f, 2/14f, 1/14f,
2/14f, 2/14f, 2/14f,
1/14f, 2/14f, 1/14f
};
public BlurFilter() {
super( blurMatrix );
}
public String toString() {
return "Blur/Simple Blur";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/Flush3DFilter.java 0000644 0001750 0001750 00000003000 10562652111 026546 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* This filter tries to apply the Swing "flush 3D" effect to the black lines in an image.
*/
public class Flush3DFilter extends WholeImageFilter {
public Flush3DFilter() {
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = inPixels[y*width+x];
if (pixel != 0xff000000 && y > 0 && x > 0) {
int count = 0;
if (inPixels[y*width+x-1] == 0xff000000)
count++;
if (inPixels[(y-1)*width+x] == 0xff000000)
count++;
if (inPixels[(y-1)*width+x-1] == 0xff000000)
count++;
if (count >= 2)
pixel = 0xffffffff;
}
outPixels[index++] = pixel;
}
}
return outPixels;
}
public String toString() {
return "Stylize/Flush 3D...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DitherFilter.java 0000644 0001750 0001750 00000015662 10566356614 026553 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which performs ordered dithering on an image.
*/
public class DitherFilter extends PointFilter {
/**
* 2x2 magic square.
*/
protected final static int[] ditherMagic2x2Matrix = {
0, 2,
3, 1
};
/**
* 4x4 magic square.
*/
protected final static int[] ditherMagic4x4Matrix = {
0, 14, 3, 13,
11, 5, 8, 6,
12, 2, 15, 1,
7, 9, 4, 10
};
/**
* 4x4 ordered dither.
*/
public final static int[] ditherOrdered4x4Matrix = {
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
};
/**
* 4x4 lines.
*/
public final static int[] ditherLines4x4Matrix = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15
};
/**
* 6x6 90 degree halftone.
*/
public final static int[] dither90Halftone6x6Matrix = {
29, 18, 12, 19, 30, 34,
17, 7, 4, 8, 20, 28,
11, 3, 0, 1, 9, 27,
16, 6, 2, 5, 13, 26,
25, 15, 10, 14, 21, 31,
33, 25, 24, 23, 33, 36
};
/*
* The following dithering matrices are taken from "Digital Halftoning"
* by Robert Ulichney, MIT Press, ISBN 0-262-21009-6.
*/
/**
* Order-6 ordered dither.
*/
public final static int[] ditherOrdered6x6Matrix = {
1, 59, 15, 55, 2, 56, 12, 52,
33, 17, 47, 31, 34, 18, 44, 28,
9, 49, 5, 63, 10, 50, 6, 60,
41, 25, 37, 21, 42, 26, 38, 22,
3, 57, 13, 53, 0, 58, 14, 54,
35, 19, 45, 29, 32, 16, 46, 30,
11, 51, 7, 61, 8, 48, 4, 62,
43, 27, 39, 23, 40, 24, 36, 20
};
/**
* Order-8 ordered dither.
*/
public final static int[] ditherOrdered8x8Matrix = {
1,235, 59,219, 15,231, 55,215, 2,232, 56,216, 12,228, 52,212,
129, 65,187,123,143, 79,183,119,130, 66,184,120,140, 76,180,116,
33,193, 17,251, 47,207, 31,247, 34,194, 18,248, 44,204, 28,244,
161, 97,145, 81,175,111,159, 95,162, 98,146, 82,172,108,156, 92,
9,225, 49,209, 5,239, 63,223, 10,226, 50,210, 6,236, 60,220,
137, 73,177,113,133, 69,191,127,138, 74,178,114,134, 70,188,124,
41,201, 25,241, 37,197, 21,255, 42,202, 26,242, 38,198, 22,252,
169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86,
3,233, 57,217, 13,229, 53,213, 0,234, 58,218, 14,230, 54,214,
131, 67,185,121,141, 77,181,117,128, 64,186,122,142, 78,182,118,
35,195, 19,249, 45,205, 29,245, 32,192, 16,250, 46,206, 30,246,
163, 99,147, 83,173,109,157, 93,160, 96,144, 80,174,110,158, 94,
11,227, 51,211, 7,237, 61,221, 8,224, 48,208, 4,238, 62,222,
139, 75,179,115,135, 71,189,125,136, 72,176,112,132, 68,190,126,
43,203, 27,243, 39,199, 23,253, 40,200, 24,240, 36,196, 20,254,
171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84 };
/**
* Order-3 clustered dither.
*/
public final static int[] ditherCluster3Matrix = {
9,11,10, 8, 6, 7,
12,17,16, 5, 0, 1,
13,14,15, 4, 3, 2,
8, 6, 7, 9,11,10,
5, 0, 1,12,17,16,
4, 3, 2,13,14,15 };
/**
* Order-4 clustered dither.
*/
public final static int[] ditherCluster4Matrix = {
18,20,19,16,13,11,12,15,
27,28,29,22, 4, 3, 2, 9,
26,31,30,21, 5, 0, 1,10,
23,25,24,17, 8, 6, 7,14,
13,11,12,15,18,20,19,16,
4, 3, 2, 9,27,28,29,22,
5, 0, 1,10,26,31,30,21,
8, 6, 7,14,23,25,24,17 };
/**
* Order-8 clustered dither.
*/
public final static int[] ditherCluster8Matrix = {
64, 69, 77, 87, 86, 76, 68, 67, 63, 58, 50, 40, 41, 51, 59, 60,
70, 94,100,109,108, 99, 93, 75, 57, 33, 27, 18, 19, 28, 34, 52,
78,101,114,116,115,112, 98, 83, 49, 26, 13, 11, 12, 15, 29, 44,
88,110,123,124,125,118,107, 85, 39, 17, 4, 3, 2, 9, 20, 42,
89,111,122,127,126,117,106, 84, 38, 16, 5, 0, 1, 10, 21, 43,
79,102,119,121,120,113, 97, 82, 48, 25, 8, 6, 7, 14, 30, 45,
71, 95,103,104,105, 96, 92, 74, 56, 32, 24, 23, 22, 31, 35, 53,
65, 72, 80, 90, 91, 81, 73, 66, 62, 55, 47, 37, 36, 46, 54, 61,
63, 58, 50, 40, 41, 51, 59, 60, 64, 69, 77, 87, 86, 76, 68, 67,
57, 33, 27, 18, 19, 28, 34, 52, 70, 94,100,109,108, 99, 93, 75,
49, 26, 13, 11, 12, 15, 29, 44, 78,101,114,116,115,112, 98, 83,
39, 17, 4, 3, 2, 9, 20, 42, 88,110,123,124,125,118,107, 85,
38, 16, 5, 0, 1, 10, 21, 43, 89,111,122,127,126,117,106, 84,
48, 25, 8, 6, 7, 14, 30, 45, 79,102,119,121,120,113, 97, 82,
56, 32, 24, 23, 22, 31, 35, 53, 71, 95,103,104,105, 96, 92, 74,
62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66 };
private int[] matrix;
private int rows, cols, levels;
private int[] mod;
private int[] div;
private int[] map;
private boolean colorDither;
private boolean initialized = false;
/**
* Constuct a DitherFilter.
*/
public DitherFilter() {
rows = 2;
cols = 2;
matrix = ditherMagic4x4Matrix;
levels = 6;
colorDither = true;
}
/**
* Set the dither matrix.
* @param matrix the dither matrix
* @see #getMatrix
*/
public void setMatrix(int[] matrix) {
this.matrix = matrix;
}
/**
* Get the dither matrix.
* @return the dither matrix
* @see #setMatrix
*/
public int[] getMatrix() {
return matrix;
}
/**
* Set the number of dither levels.
* @param levels the number of levels
* @see #getLevels
*/
public void setLevels(int levels) {
this.levels = levels;
}
/**
* Get the number of dither levels.
* @return the number of levels
* @see #setLevels
*/
public int getLevels() {
return levels;
}
/**
* Initialize the filter.
*/
protected void initialize() {
rows = cols = (int)Math.sqrt(matrix.length);
map = new int[levels];
for (int i = 0; i < levels; i++) {
int v = 255 * i / (levels-1);
map[i] = v;
}
div = new int[256];
mod = new int[256];
int rc = (rows*cols+1);
for (int i = 0; i < 256; i++) {
div[i] = (levels-1)*i / 256;
mod[i] = i*rc/256;
}
}
public int filterRGB(int x, int y, int rgb) {
if (!initialized) {
initialized = true;
initialize();
}
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int col = x % cols;
int row = y % rows;
int v = matrix[row*cols+col];
if (colorDither) {
r = map[mod[r] > v ? div[r] + 1 : div[r]];
g = map[mod[g] > v ? div[g] + 1 : div[g]];
b = map[mod[b] > v ? div[b] + 1 : div[b]];
} else {
int value = (r+g+b)/3;
r = g = b = map[mod[value] > v ? div[value] + 1 : div[value]];
}
return a | (r << 16) | (g << 8) | b;
}
public String toString() {
return "Colors/Dither...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/FlipFilter.java 0000644 0001750 0001750 00000010413 10566356614 026213 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which flips images or rotates by multiples of 90 degrees.
*/
public class FlipFilter extends AbstractBufferedImageOp {
/**
* Flip the image horizontally.
*/
public static final int FLIP_H = 1;
/**
* Flip the image vertically.
*/
public static final int FLIP_V = 2;
/**
* Flip the image horizontally and vertically.
*/
public static final int FLIP_HV = 3;
/**
* Rotate the image 90 degrees clockwise.
*/
public static final int FLIP_90CW = 4;
/**
* Rotate the image 90 degrees counter-clockwise.
*/
public static final int FLIP_90CCW = 5;
/**
* Rotate the image 180 degrees.
*/
public static final int FLIP_180 = 6;
private int operation;
private int width, height;
private int newWidth, newHeight;
/**
* Construct a FlipFilter which flips horizontally and vertically.
*/
public FlipFilter() {
this(FLIP_HV);
}
/**
* Construct a FlipFilter.
* @param operation the filter operation
*/
public FlipFilter(int operation) {
this.operation = operation;
}
/**
* Set the filter operation.
* @param operation the filter operation
* @see #getOperation
*/
public void setOperation(int operation) {
this.operation = operation;
}
/**
* Get the filter operation.
* @return the filter operation
* @see #setOperation
*/
public int getOperation() {
return operation;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
int[] inPixels = getRGB( src, 0, 0, width, height, null );
int x = 0, y = 0;
int w = width;
int h = height;
int newX = 0;
int newY = 0;
int newW = w;
int newH = h;
switch (operation) {
case FLIP_H:
newX = width - (x + w);
break;
case FLIP_V:
newY = height - (y + h);
break;
case FLIP_HV:
newW = h;
newH = w;
newX = y;
newY = x;
break;
case FLIP_90CW:
newW = h;
newH = w;
newX = height - (y + h);
newY = x;
break;
case FLIP_90CCW:
newW = h;
newH = w;
newX = y;
newY = width - (x + w);
break;
case FLIP_180:
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 * width + col;
int newRow = row;
int newCol = col;
switch (operation) {
case FLIP_H:
newCol = w - col - 1;
break;
case FLIP_V:
newRow = h - row - 1;
break;
case FLIP_HV:
newRow = col;
newCol = row;
break;
case FLIP_90CW:
newRow = col;
newCol = h - row - 1;;
break;
case FLIP_90CCW:
newRow = w - col - 1;
newCol = row;
break;
case FLIP_180:
newRow = h - row - 1;
newCol = w - col - 1;
break;
}
int newIndex = newRow * newW + newCol;
newPixels[newIndex] = inPixels[index];
}
}
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(newW, newH), dstCM.isAlphaPremultiplied(), null);
}
WritableRaster dstRaster = dst.getRaster();
setRGB( dst, 0, 0, newW, newH, newPixels );
return dst;
}
public String toString() {
switch (operation) {
case FLIP_H:
return "Flip Horizontal";
case FLIP_V:
return "Flip Vertical";
case FLIP_HV:
return "Flip Diagonal";
case FLIP_90CW:
return "Rotate 90";
case FLIP_90CCW:
return "Rotate -90";
case FLIP_180:
return "Rotate 180";
}
return "Flip";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GrayscaleColormap.java 0000644 0001750 0001750 00000002006 10562652111 027544 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
/**
* A grayscale colormap. Black is 0, white is 1.
*/
public class GrayscaleColormap implements Colormap {
public GrayscaleColormap() {
}
/**
* Convert a value in the range 0..1 to an RGB color.
* @param v a value in the range 0..1
* @return an RGB color
*/
public int getColor(float v) {
int n = (int)(v*255);
if (n < 0)
n = 0;
else if (n > 255)
n = 255;
return 0xff000000 | (n << 16) | (n << 8) | n;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BoxBlurFilter.java 0000644 0001750 0001750 00000017777 10606647276 026724 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
/**
* A filter which performs a box blur on an image. The horizontal and vertical blurs can be specified separately
* and a number of iterations can be given which allows an approximation to Gaussian blur.
*/
public class BoxBlurFilter extends AbstractBufferedImageOp {
private float hRadius;
private float vRadius;
private int iterations = 1;
private boolean premultiplyAlpha = true;
/**
* Construct a default BoxBlurFilter.
*/
public BoxBlurFilter() {
}
/**
* Construct a BoxBlurFilter.
* @param hRadius the horizontal radius of blur
* @param vRadius the vertical radius of blur
* @param iterations the number of time to iterate the blur
*/
public BoxBlurFilter( float hRadius, float vRadius, int iterations ) {
this.hRadius = hRadius;
this.vRadius = vRadius;
this.iterations = iterations;
}
/**
* Set whether to premultiply the alpha channel.
* @param premultiplyAlpha true to premultiply the alpha
* @see #getPremultiplyAlpha
*/
public void setPremultiplyAlpha( boolean premultiplyAlpha ) {
this.premultiplyAlpha = premultiplyAlpha;
}
/**
* Get whether to premultiply the alpha channel.
* @return true to premultiply the alpha
* @see #setPremultiplyAlpha
*/
public boolean getPremultiplyAlpha() {
return premultiplyAlpha;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
getRGB( src, 0, 0, width, height, inPixels );
if ( premultiplyAlpha )
ImageMath.premultiply( inPixels, 0, inPixels.length );
for (int i = 0; i < iterations; i++ ) {
blur( inPixels, outPixels, width, height, hRadius );
blur( outPixels, inPixels, height, width, vRadius );
}
blurFractional( inPixels, outPixels, width, height, hRadius );
blurFractional( outPixels, inPixels, height, width, vRadius );
if ( premultiplyAlpha )
ImageMath.unpremultiply( inPixels, 0, inPixels.length );
setRGB( dst, 0, 0, width, height, inPixels );
return dst;
}
/**
* Blur and transpose a block of ARGB pixels.
* @param in the input pixels
* @param out the output pixels
* @param width the width of the pixel array
* @param height the height of the pixel array
* @param radius the radius of blur
*/
public static void blur( int[] in, int[] out, int width, int height, float radius ) {
int widthMinus1 = width-1;
int r = (int)radius;
int tableSize = 2*r+1;
int divide[] = new int[256*tableSize];
for ( int i = 0; i < 256*tableSize; i++ )
divide[i] = i/tableSize;
int inIndex = 0;
for ( int y = 0; y < height; y++ ) {
int outIndex = y;
int ta = 0, tr = 0, tg = 0, tb = 0;
for ( int i = -r; i <= r; i++ ) {
int rgb = in[inIndex + ImageMath.clamp(i, 0, width-1)];
ta += (rgb >> 24) & 0xff;
tr += (rgb >> 16) & 0xff;
tg += (rgb >> 8) & 0xff;
tb += rgb & 0xff;
}
for ( int x = 0; x < width; x++ ) {
out[ outIndex ] = (divide[ta] << 24) | (divide[tr] << 16) | (divide[tg] << 8) | divide[tb];
int i1 = x+r+1;
if ( i1 > widthMinus1 )
i1 = widthMinus1;
int i2 = x-r;
if ( i2 < 0 )
i2 = 0;
int rgb1 = in[inIndex+i1];
int rgb2 = in[inIndex+i2];
ta += ((rgb1 >> 24) & 0xff)-((rgb2 >> 24) & 0xff);
tr += ((rgb1 & 0xff0000)-(rgb2 & 0xff0000)) >> 16;
tg += ((rgb1 & 0xff00)-(rgb2 & 0xff00)) >> 8;
tb += (rgb1 & 0xff)-(rgb2 & 0xff);
outIndex += height;
}
inIndex += width;
}
}
public static void blurFractional( int[] in, int[] out, int width, int height, float radius ) {
radius -= (int)radius;
float f = 1.0f/(1+2*radius);
int inIndex = 0;
for ( int y = 0; y < height; y++ ) {
int outIndex = y;
out[ outIndex ] = in[0];
outIndex += height;
for ( int x = 1; x < width-1; x++ ) {
int i = inIndex+x;
int rgb1 = in[i-1];
int rgb2 = in[i];
int rgb3 = in[i+1];
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int a2 = (rgb2 >> 24) & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
int a3 = (rgb3 >> 24) & 0xff;
int r3 = (rgb3 >> 16) & 0xff;
int g3 = (rgb3 >> 8) & 0xff;
int b3 = rgb3 & 0xff;
a1 = a2 + (int)((a1 + a3) * radius);
r1 = r2 + (int)((r1 + r3) * radius);
g1 = g2 + (int)((g1 + g3) * radius);
b1 = b2 + (int)((b1 + b3) * radius);
a1 *= f;
r1 *= f;
g1 *= f;
b1 *= f;
out[ outIndex ] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
outIndex += height;
}
out[ outIndex ] = in[width-1];
inIndex += width;
}
}
/**
* Set the horizontal size of the blur.
* @param hRadius the radius of the blur in the horizontal direction
* @min-value 0
* @see #getHRadius
*/
public void setHRadius(float hRadius) {
this.hRadius = hRadius;
}
/**
* Get the horizontal size of the blur.
* @return the radius of the blur in the horizontal direction
* @see #setHRadius
*/
public float getHRadius() {
return hRadius;
}
/**
* Set the vertical size of the blur.
* @param vRadius the radius of the blur in the vertical direction
* @min-value 0
* @see #getVRadius
*/
public void setVRadius(float vRadius) {
this.vRadius = vRadius;
}
/**
* Get the vertical size of the blur.
* @return the radius of the blur in the vertical direction
* @see #setVRadius
*/
public float getVRadius() {
return vRadius;
}
/**
* Set both the horizontal and vertical sizes of the blur.
* @param radius the radius of the blur in both directions
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.hRadius = this.vRadius = radius;
}
/**
* Get the size of the blur.
* @return the radius of the blur in the horizontal direction
* @see #setRadius
*/
public float getRadius() {
return hRadius;
}
/**
* Set the number of iterations the blur is performed.
* @param iterations the number of iterations
* @min-value 0
* @see #getIterations
*/
public void setIterations(int iterations) {
this.iterations = iterations;
}
/**
* Get the number of iterations the blur is performed.
* @return the number of iterations
* @see #setIterations
*/
public int getIterations() {
return iterations;
}
public String toString() {
return "Blur/Box Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GainFilter.java 0000644 0001750 0001750 00000003241 10566572034 026174 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which changes the gain and bias of an image - similar to ContrastFilter.
*/
public class GainFilter extends TransferFilter {
private float gain = 0.5f;
private float bias = 0.5f;
protected float transferFunction( float f ) {
f = ImageMath.gain(f, gain);
f = ImageMath.bias(f, bias);
return f;
}
/**
* Set the gain.
* @param gain the gain
* @min-value: 0
* @max-value: 1
* @see #getGain
*/
public void setGain(float gain) {
this.gain = gain;
initialized = false;
}
/**
* Get the gain.
* @return the gain
* @see #setGain
*/
public float getGain() {
return gain;
}
/**
* Set the bias.
* @param bias the bias
* @min-value: 0
* @max-value: 1
* @see #getBias
*/
public void setBias(float bias) {
this.bias = bias;
initialized = false;
}
/**
* Get the bias.
* @return the bias
* @see #setBias
*/
public float getBias() {
return bias;
}
public String toString() {
return "Colors/Gain...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MotionBlurOp.java 0000644 0001750 0001750 00000014542 11331370026 026533 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which produces motion blur the faster, but lower-quality way.
*/
public class MotionBlurOp extends AbstractBufferedImageOp implements MotionBlur {
private float centreX = 0.5f, centreY = 0.5f;
private float distance;
private float angle;
private float rotation;
private float zoom;
/**
* Construct a MotionBlurOp.
*/
public MotionBlurOp() {
}
/**
* Construct a MotionBlurOp.
* @param distance the distance of blur.
* @param angle the angle of blur.
* @param rotation the angle of rotation.
* @param zoom the zoom factor.
*/
public MotionBlurOp( float distance, float angle, float rotation, float zoom ) {
this.distance = distance;
this.angle = angle;
this.rotation = rotation;
this.zoom = zoom;
}
/**
* Specifies the angle of blur.
* @param angle the angle of blur.
* @angle
* @see #getAngle
*/
public void setAngle( float angle ) {
this.angle = angle;
}
/**
* Returns the angle of blur.
* @return the angle of blur.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the distance of blur.
* @param distance the distance of blur.
* @see #getDistance
*/
public void setDistance( float distance ) {
this.distance = distance;
}
/**
* Get the distance of blur.
* @return the distance of blur.
* @see #setDistance
*/
public float getDistance() {
return distance;
}
/**
* Set the blur rotation.
* @param rotation the angle of rotation.
* @see #getRotation
*/
public void setRotation( float rotation ) {
this.rotation = rotation;
}
/**
* Get the blur rotation.
* @return the angle of rotation.
* @see #setRotation
*/
public float getRotation() {
return rotation;
}
/**
* Set the blur zoom.
* @param zoom the zoom factor.
* @see #getZoom
*/
public void setZoom( float zoom ) {
this.zoom = zoom;
}
/**
* Get the blur zoom.
* @return the zoom factor.
* @see #setZoom
*/
public float getZoom() {
return zoom;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
private int log2( int n ) {
int m = 1;
int log2n = 0;
while (m < n) {
m *= 2;
log2n++;
}
return log2n;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
BufferedImage tsrc = src;
float cx = (float)src.getWidth() * centreX;
float cy = (float)src.getHeight() * centreY;
float imageRadius = (float)Math.sqrt( cx*cx + cy*cy );
float translateX = (float)(distance * Math.cos( angle ));
float translateY = (float)(distance * -Math.sin( angle ));
float scale = zoom;
float rotate = rotation;
float maxDistance = distance + Math.abs(rotation*imageRadius) + zoom*imageRadius;
int steps = log2((int)maxDistance);
translateX /= maxDistance;
translateY /= maxDistance;
scale /= maxDistance;
rotate /= maxDistance;
if ( steps == 0 ) {
Graphics2D g = dst.createGraphics();
g.drawRenderedImage( src, null );
g.dispose();
return dst;
}
BufferedImage tmp = createCompatibleDestImage( src, null );
for ( int i = 0; i < steps; i++ ) {
Graphics2D g = tmp.createGraphics();
g.drawImage( tsrc, null, null );
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
g.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, 0.5f ) );
g.translate( cx+translateX, cy+translateY );
g.scale( 1.0001+scale, 1.0001+scale ); // The .0001 works round a bug on Windows where drawImage throws an ArrayIndexOutofBoundException
if ( rotation != 0 )
g.rotate( rotate );
g.translate( -cx, -cy );
g.drawImage( dst, null, null );
g.dispose();
BufferedImage ti = dst;
dst = tmp;
tmp = ti;
tsrc = dst;
translateX *= 2;
translateY *= 2;
scale *= 2;
rotate *= 2;
}
return dst;
}
public String toString() {
return "Blur/Faster Motion Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PinchFilter.java 0000644 0001750 0001750 00000010515 10566356614 026365 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which performs the popular whirl-and-pinch distortion effect.
*/
public class PinchFilter extends TransformFilter {
private float angle = 0;
private float centreX = 0.5f;
private float centreY = 0.5f;
private float radius = 100;
private float amount = 0.5f;
private float radius2 = 0;
private float icentreX;
private float icentreY;
private float width;
private float height;
public PinchFilter() {
}
/**
* Set the angle of twirl in radians. 0 means no distortion.
* @param angle the angle of twirl. This is the angle by which pixels at the nearest edge of the image will move.
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
}
/**
* Get the angle of twist.
* @return the angle in radians.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(float radius) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public float getRadius() {
return radius;
}
/**
* Set the amount of pinch.
* @param amount the amount
* @min-value -1
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of pinch.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
width = src.getWidth();
height = src.getHeight();
icentreX = width * centreX;
icentreY = height * centreY;
if ( radius == 0 )
radius = Math.min(icentreX, icentreY);
radius2 = radius*radius;
return super.filter( src, dst );
}
protected void transformInverse(int x, int y, float[] out) {
float dx = x-icentreX;
float dy = y-icentreY;
float distance = dx*dx + dy*dy;
if ( distance > radius2 || distance == 0 ) {
out[0] = x;
out[1] = y;
} else {
float d = (float)Math.sqrt( distance / radius2 );
float t = (float)Math.pow( Math.sin( Math.PI*0.5 * d ), -amount);
dx *= t;
dy *= t;
float e = 1 - d;
float a = angle * e * e;
float s = (float)Math.sin( a );
float c = (float)Math.cos( a );
out[0] = icentreX + c*dx - s*dy;
out[1] = icentreY + s*dx + c*dy;
}
}
public String toString() {
return "Distort/Pinch...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/OilFilter.java 0000644 0001750 0001750 00000006375 11201001401 026020 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which produces a "oil-painting" effect.
*/
public class OilFilter extends WholeImageFilter {
private int range = 3;
private int levels = 256;
public OilFilter() {
}
/**
* Set the range of the effect in pixels.
* @param range the range
* @see #getRange
*/
public void setRange( int range ) {
this.range = range;
}
/**
* Get the range of the effect in pixels.
* @return the range
* @see #setRange
*/
public int getRange() {
return range;
}
/**
* Set the number of levels for the effect.
* @param levels the number of levels
* @see #getLevels
*/
public void setLevels( int levels ) {
this.levels = levels;
}
/**
* Get the number of levels for the effect.
* @return the number of levels
* @see #setLevels
*/
public int getLevels() {
return levels;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int index = 0;
int[] rHistogram = new int[levels];
int[] gHistogram = new int[levels];
int[] bHistogram = new int[levels];
int[] rTotal = new int[levels];
int[] gTotal = new int[levels];
int[] bTotal = new int[levels];
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int i = 0; i < levels; i++)
rHistogram[i] = gHistogram[i] = bHistogram[i] = rTotal[i] = gTotal[i] = bTotal[i] = 0;
for (int row = -range; row <= range; row++) {
int iy = y+row;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int col = -range; col <= range; col++) {
int ix = x+col;
if (0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int ri = r*levels/256;
int gi = g*levels/256;
int bi = b*levels/256;
rTotal[ri] += r;
gTotal[gi] += g;
bTotal[bi] += b;
rHistogram[ri]++;
gHistogram[gi]++;
bHistogram[bi]++;
}
}
}
}
int r = 0, g = 0, b = 0;
for (int i = 1; i < levels; i++) {
if (rHistogram[i] > rHistogram[r])
r = i;
if (gHistogram[i] > gHistogram[g])
g = i;
if (bHistogram[i] > bHistogram[b])
b = i;
}
r = rTotal[r] / rHistogram[r];
g = gTotal[g] / gHistogram[g];
b = bTotal[b] / bHistogram[b];
outPixels[index] = (inPixels[index] & 0xff000000) | ( r << 16 ) | ( g << 8 ) | b;
index++;
}
}
return outPixels;
}
public String toString() {
return "Stylize/Oil...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MaskFilter.java 0000644 0001750 0001750 00000002251 10562652111 026200 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
/**
* Applies a bit mask to each ARGB pixel of an image. You can use this for, say, masking out the red channel.
*/
public class MaskFilter extends PointFilter {
private int mask;
public MaskFilter() {
this(0xff00ffff);
}
public MaskFilter(int mask) {
canFilterIndexColorModel = true;
setMask(mask);
}
public void setMask(int mask) {
this.mask = mask;
}
public int getMask() {
return mask;
}
public int filterRGB(int x, int y, int rgb) {
return rgb & mask;
}
public String toString() {
return "Mask";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SaturationFilter.java 0000755 0001750 0001750 00000003321 10626011515 027436 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter to change the saturation of an image. This works by calculating a grayscale version of the image
* and then extrapolating away from it.
*/
public class SaturationFilter extends PointFilter {
public float amount = 1;
/**
* Construct a SaturationFilter.
*/
public SaturationFilter() {
}
/**
* Construct a SaturationFilter.
* The amount of saturation change.
*/
public SaturationFilter( float amount ) {
this.amount = amount;
canFilterIndexColorModel = true;
}
/**
* Set the amount of saturation change. 1 leaves the image unchanged, values between 0 and 1 desaturate, 0 completely
* desaturates it and values above 1 increase the saturation.
* @param amount the amount
*/
public void setAmount( float amount ) {
this.amount = amount;
}
/**
* Set the amount of saturation change.
* @return the amount
*/
public float getAmount() {
return amount;
}
public int filterRGB(int x, int y, int rgb) {
if ( amount != 1 ) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int v = ( r + g + b )/3; // or a better brightness calculation if you prefer
r = PixelUtils.clamp( (int)(v + amount * (r-v)) );
g = PixelUtils.clamp( (int)(v + amount * (g-v)) );
b = PixelUtils.clamp( (int)(v + amount * (b-v)) );
return a | (r << 16) | (g << 8) | b;
}
return rgb;
}
public String toString() {
return "Colors/Saturation...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/DiffuseFilter.java 0000644 0001750 0001750 00000003647 10566356614 026721 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import com.jhlabs.math.*;
/**
* This filter diffuses an image by moving its pixels in random directions.
*/
public class DiffuseFilter extends TransformFilter {
private float[] sinTable, cosTable;
private float scale = 4;
public DiffuseFilter() {
setEdgeAction(CLAMP);
}
/**
* Specifies the scale of the texture.
* @param scale the scale of the texture.
* @min-value 1
* @max-value 100+
* @see #getScale
*/
public void setScale(float scale) {
this.scale = scale;
}
/**
* Returns the scale of the texture.
* @return the scale of the texture.
* @see #setScale
*/
public float getScale() {
return scale;
}
protected void transformInverse(int x, int y, float[] out) {
int angle = (int)(Math.random() * 255);
float distance = (float)Math.random();
out[0] = x + distance * sinTable[angle];
out[1] = y + distance * cosTable[angle];
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
sinTable = new float[256];
cosTable = new float[256];
for (int i = 0; i < 256; i++) {
float angle = ImageMath.TWO_PI*i/256f;
sinTable[i] = (float)(scale*Math.sin(angle));
cosTable[i] = (float)(scale*Math.cos(angle));
}
return super.filter( src, dst );
}
public String toString() {
return "Distort/Diffuse...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TransformFilter.java 0000644 0001750 0001750 00000017225 11331370714 027270 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* An abstract superclass for filters which distort images in some way. The subclass only needs to override
* two methods to provide the mapping between source and destination pixels.
*/
public abstract class TransformFilter extends AbstractBufferedImageOp {
/**
* Treat pixels off the edge as zero.
*/
public final static int ZERO = 0;
/**
* Clamp pixels to the image edges.
*/
public final static int CLAMP = 1;
/**
* Wrap pixels off the edge onto the oppsoite edge.
*/
public final static int WRAP = 2;
/**
* Clamp pixels RGB to the image edges, but zero the alpha. This prevents gray borders on your image.
*/
public final static int RGB_CLAMP = 3;
/**
* Use nearest-neighbout interpolation.
*/
public final static int NEAREST_NEIGHBOUR = 0;
/**
* Use bilinear interpolation.
*/
public final static int BILINEAR = 1;
/**
* The action to take for pixels off the image edge.
*/
protected int edgeAction = RGB_CLAMP;
/**
* The type of interpolation to use.
*/
protected int interpolation = BILINEAR;
/**
* The output image rectangle.
*/
protected Rectangle transformedSpace;
/**
* The input image rectangle.
*/
protected Rectangle originalSpace;
/**
* Set the action to perform for pixels off the edge of the image.
* @param edgeAction one of ZERO, CLAMP or WRAP
* @see #getEdgeAction
*/
public void setEdgeAction(int edgeAction) {
this.edgeAction = edgeAction;
}
/**
* Get the action to perform for pixels off the edge of the image.
* @return one of ZERO, CLAMP or WRAP
* @see #setEdgeAction
*/
public int getEdgeAction() {
return edgeAction;
}
/**
* Set the type of interpolation to perform.
* @param interpolation one of NEAREST_NEIGHBOUR or BILINEAR
* @see #getInterpolation
*/
public void setInterpolation(int interpolation) {
this.interpolation = interpolation;
}
/**
* Get the type of interpolation to perform.
* @return one of NEAREST_NEIGHBOUR or BILINEAR
* @see #setInterpolation
*/
public int getInterpolation() {
return interpolation;
}
/**
* Inverse transform a point. This method needs to be overriden by all subclasses.
* @param x the X position of the pixel in the output image
* @param y the Y position of the pixel in the output image
* @param out the position of the pixel in the input image
*/
protected abstract void transformInverse(int x, int y, float[] out);
/**
* Forward transform a rectangle. Used to determine the size of the output image.
* @param rect the rectangle to transform
*/
protected void transformSpace(Rectangle rect) {
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
// int type = src.getType();
// WritableRaster srcRaster = src.getRaster();
originalSpace = new Rectangle(0, 0, width, height);
transformedSpace = new Rectangle(0, 0, width, height);
transformSpace(transformedSpace);
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null);
}
// WritableRaster dstRaster = dst.getRaster();
int[] inPixels = getRGB( src, 0, 0, width, height, null );
if ( interpolation == NEAREST_NEIGHBOUR )
return filterPixelsNN( dst, width, height, inPixels, transformedSpace );
int srcWidth = width;
int srcHeight = height;
int srcWidth1 = width-1;
int srcHeight1 = height-1;
int outWidth = transformedSpace.width;
int outHeight = transformedSpace.height;
int outX, outY;
// int index = 0;
int[] outPixels = new int[outWidth];
outX = transformedSpace.x;
outY = transformedSpace.y;
float[] out = new float[2];
for (int y = 0; y < outHeight; y++) {
for (int x = 0; x < outWidth; x++) {
transformInverse(outX+x, outY+y, out);
int srcX = (int)Math.floor( out[0] );
int srcY = (int)Math.floor( out[1] );
float xWeight = out[0]-srcX;
float yWeight = out[1]-srcY;
int nw, ne, sw, se;
if ( srcX >= 0 && srcX < srcWidth1 && srcY >= 0 && srcY < srcHeight1) {
// Easy case, all corners are in the image
int i = srcWidth*srcY + srcX;
nw = inPixels[i];
ne = inPixels[i+1];
sw = inPixels[i+srcWidth];
se = inPixels[i+srcWidth+1];
} else {
// Some of the corners are off the image
nw = getPixel( inPixels, srcX, srcY, srcWidth, srcHeight );
ne = getPixel( inPixels, srcX+1, srcY, srcWidth, srcHeight );
sw = getPixel( inPixels, srcX, srcY+1, srcWidth, srcHeight );
se = getPixel( inPixels, srcX+1, srcY+1, srcWidth, srcHeight );
}
outPixels[x] = ImageMath.bilinearInterpolate(xWeight, yWeight, nw, ne, sw, se);
}
setRGB( dst, 0, y, transformedSpace.width, 1, outPixels );
}
return dst;
}
final private int getPixel( int[] pixels, int x, int y, int width, int height ) {
if (x < 0 || x >= width || y < 0 || y >= height) {
switch (edgeAction) {
case ZERO:
default:
return 0;
case WRAP:
return pixels[(ImageMath.mod(y, height) * width) + ImageMath.mod(x, width)];
case CLAMP:
return pixels[(ImageMath.clamp(y, 0, height-1) * width) + ImageMath.clamp(x, 0, width-1)];
case RGB_CLAMP:
return pixels[(ImageMath.clamp(y, 0, height-1) * width) + ImageMath.clamp(x, 0, width-1)] & 0x00ffffff;
}
}
return pixels[ y*width+x ];
}
protected BufferedImage filterPixelsNN( BufferedImage dst, int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int srcWidth = width;
int srcHeight = height;
int outWidth = transformedSpace.width;
int outHeight = transformedSpace.height;
int outX, outY, srcX, srcY;
int[] outPixels = new int[outWidth];
outX = transformedSpace.x;
outY = transformedSpace.y;
// int[] rgb = new int[4];
float[] out = new float[2];
for (int y = 0; y < outHeight; y++) {
for (int x = 0; x < outWidth; x++) {
transformInverse(outX+x, outY+y, out);
srcX = (int)out[0];
srcY = (int)out[1];
// int casting rounds towards zero, so we check out[0] < 0, not srcX < 0
if (out[0] < 0 || srcX >= srcWidth || out[1] < 0 || srcY >= srcHeight) {
int p;
switch (edgeAction) {
case ZERO:
default:
p = 0;
break;
case WRAP:
p = inPixels[(ImageMath.mod(srcY, srcHeight) * srcWidth) + ImageMath.mod(srcX, srcWidth)];
break;
case CLAMP:
p = inPixels[(ImageMath.clamp(srcY, 0, srcHeight-1) * srcWidth) + ImageMath.clamp(srcX, 0, srcWidth-1)];
break;
case RGB_CLAMP:
p = inPixels[(ImageMath.clamp(srcY, 0, srcHeight-1) * srcWidth) + ImageMath.clamp(srcX, 0, srcWidth-1)] & 0x00ffffff;
}
outPixels[x] = p;
} else {
int i = srcWidth*srcY + srcX;
// rgb[0] = inPixels[i];
outPixels[x] = inPixels[i];
}
}
setRGB( dst, 0, y, transformedSpace.width, 1, outPixels );
}
return dst;
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ErodeFilter.java 0000644 0001750 0001750 00000004770 10566356614 026370 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* Given a binary image, this filter performs binary erosion, setting all removed pixels to the given 'new' color.
*/
public class ErodeFilter extends BinaryFilter {
private int threshold = 2;
public ErodeFilter() {
newColor = 0xffffffff;
}
/**
* Set the threshold - the number of neighbouring pixels for dilation to occur.
* @param threshold the new threshold
* @see #getThreshold
*/
public void setThreshold(int threshold) {
this.threshold = threshold;
}
/**
* Return the threshold - the number of neighbouring pixels for dilation to occur.
* @return the current threshold
* @see #setThreshold
*/
public int getThreshold() {
return threshold;
}
protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
int[] outPixels = new int[width * height];
for (int i = 0; i < iterations; i++) {
int index = 0;
if (i > 0) {
int[] t = inPixels;
inPixels = outPixels;
outPixels = t;
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = inPixels[y*width+x];
if (blackFunction.isBlack(pixel)) {
int neighbours = 0;
for (int dy = -1; dy <= 1; dy++) {
int iy = y+dy;
int ioffset;
if (0 <= iy && iy < height) {
ioffset = iy*width;
for (int dx = -1; dx <= 1; dx++) {
int ix = x+dx;
if (!(dy == 0 && dx == 0) && 0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
if (!blackFunction.isBlack(rgb))
neighbours++;
}
}
}
}
if (neighbours >= threshold) {
if (colormap != null)
pixel = colormap.getColor((float)i/iterations);
else
pixel = newColor;
}
}
outPixels[index++] = pixel;
}
}
}
return outPixels;
}
public String toString() {
return "Binary/Erode...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/PolarFilter.java 0000644 0001750 0001750 00000013200 11331370402 026351 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which distorts and image by performing coordinate conversions between rectangular and polar coordinates.
*/
public class PolarFilter extends TransformFilter {
/**
* Convert from rectangular to polar coordinates.
*/
public final static int RECT_TO_POLAR = 0;
/**
* Convert from polar to rectangular coordinates.
*/
public final static int POLAR_TO_RECT = 1;
/**
* Invert the image in a circle.
*/
public final static int INVERT_IN_CIRCLE = 2;
private int type;
private float width, height;
private float centreX, centreY;
private float radius;
private float relativeCentreX = 0.5f;
private float relativeCentreY = 0.5f;
/**
* Construct a PolarFilter.
*/
public PolarFilter() {
this(RECT_TO_POLAR);
}
/**
* Construct a PolarFilter.
* @param type the distortion type
*/
public PolarFilter(int type) {
this.type = type;
setEdgeAction(CLAMP);
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
this.width = src.getWidth();
this.height = src.getHeight();
// centreX = width/2;
// centreY = height/2;
centreX = width * relativeCentreX;
centreY = height * relativeCentreY;
radius = Math.max(centreY, centreX);
return super.filter( src, dst );
}
/**
* Set the distortion type.
* @param type the distortion type
* @see #getType
*/
public void setType(int type) {
this.type = type;
}
/**
* Get the distortion type.
* @return the distortion type
* @see #setType
*/
public int getType() {
return type;
}
private float sqr(float x) {
return x*x;
}
protected void transformInverse(int x, int y, float[] out) {
float theta, t;
float m, xmax, ymax;
float r = 0;
switch (type) {
case RECT_TO_POLAR:
theta = 0;
if (x >= centreX) {
if (y > centreY) {
theta = ImageMath.PI - (float)Math.atan(((float)(x - centreX))/((float)(y - centreY)));
r = (float)Math.sqrt(sqr (x - centreX) + sqr (y - centreY));
} else if (y < centreY) {
theta = (float)Math.atan (((float)(x - centreX))/((float)(centreY - y)));
r = (float)Math.sqrt (sqr (x - centreX) + sqr (centreY - y));
} else {
theta = ImageMath.HALF_PI;
r = x - centreX;
}
} else if (x < centreX) {
if (y < centreY) {
theta = ImageMath.TWO_PI - (float)Math.atan (((float)(centreX -x))/((float)(centreY - y)));
r = (float)Math.sqrt (sqr (centreX - x) + sqr (centreY - y));
} else if (y > centreY) {
theta = ImageMath.PI + (float)Math.atan (((float)(centreX - x))/((float)(y - centreY)));
r = (float)Math.sqrt (sqr (centreX - x) + sqr (y - centreY));
} else {
theta = 1.5f * ImageMath.PI;
r = centreX - x;
}
}
if (x != centreX)
m = Math.abs (((float)(y - centreY)) / ((float)(x - centreX)));
else
m = 0;
if (m <= ((float)height / (float)width)) {
if (x == centreX) {
xmax = 0;
ymax = centreY;
} else {
xmax = centreX;
ymax = m * xmax;
}
} else {
ymax = centreY;
xmax = ymax / m;
}
out[0] = (width-1) - (width - 1)/ImageMath.TWO_PI * theta;
out[1] = height * r / radius;
break;
case POLAR_TO_RECT:
theta = x / width * ImageMath.TWO_PI;
float theta2;
if (theta >= 1.5f * ImageMath.PI)
theta2 = ImageMath.TWO_PI - theta;
else if (theta >= ImageMath.PI)
theta2 = theta - ImageMath.PI;
else if (theta >= 0.5f * ImageMath.PI)
theta2 = ImageMath.PI - theta;
else
theta2 = theta;
t = (float)Math.tan(theta2);
if (t != 0)
m = 1.0f / t;
else
m = 0;
if (m <= ((float)(height) / (float)(width))) {
if (theta2 == 0) {
xmax = 0;
ymax = centreY;
} else {
xmax = centreX;
ymax = m * xmax;
}
} else {
ymax = centreY;
xmax = ymax / m;
}
r = radius * (float)(y / (float)(height));
float nx = -r * (float)Math.sin(theta2);
float ny = r * (float)Math.cos(theta2);
if (theta >= 1.5f * ImageMath.PI) {
out[0] = (float)centreX - nx;
out[1] = (float)centreY - ny;
} else if (theta >= Math.PI) {
out[0] = (float)centreX - nx;
out[1] = (float)centreY + ny;
} else if (theta >= 0.5 * Math.PI) {
out[0] = (float)centreX + nx;
out[1] = (float)centreY + ny;
} else {
out[0] = (float)centreX + nx;
out[1] = (float)centreY - ny;
}
break;
case INVERT_IN_CIRCLE:
float dx = x-centreX;
float dy = y-centreY;
float distance2 = dx*dx+dy*dy;
out[0] = centreX + centreX*centreX * dx/distance2;
out[1] = centreY + centreY*centreY * dy/distance2;
break;
}
}
public void setRelativeCentreX(float relativeCentreX) {
this.relativeCentreX = relativeCentreX;
}
public void setRelativeCentreY(float relativeCentreY) {
this.relativeCentreY = relativeCentreY;
}
public float getRelativeCentreX() {
return relativeCentreX;
}
public float getRelativeCentreY() {
return relativeCentreY;
}
public String toString() {
return "Distort/Polar Coordinates...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ScratchFilter.java 0000755 0001750 0001750 00000005072 10626011515 026701 0 ustar martin martin /*
** Copyright 2005 Huxtable.com. All rights reserved.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
public class ScratchFilter extends AbstractBufferedImageOp {
private float density = 0.1f;
private float angle;
private float angleVariation = 1.0f;
private float width = 0.5f;
private float length = 0.5f;
private int color = 0xffffffff;
private int seed = 0;
public ScratchFilter() {
}
public void setAngle( float angle ) {
this.angle = angle;
}
public float getAngle() {
return angle;
}
public void setAngleVariation( float angleVariation ) {
this.angleVariation = angleVariation;
}
public float getAngleVariation() {
return angleVariation;
}
public void setDensity( float density ) {
this.density = density;
}
public float getDensity() {
return density;
}
public void setLength( float length ) {
this.length = length;
}
public float getLength() {
return length;
}
public void setWidth( float width ) {
this.width = width;
}
public float getWidth() {
return width;
}
public void setColor( int color ) {
this.color = color;
}
public int getColor() {
return color;
}
public void setSeed( int seed ) {
this.seed = seed;
}
public int getSeed() {
return seed;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int width = src.getWidth();
int height = src.getHeight();
int numScratches = (int)(density * width * height / 100);
float l = length * width;
Random random = new Random( seed );
Graphics2D g = dst.createGraphics();
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g.setColor( new Color( color ) );
g.setStroke( new BasicStroke( this.width ) );
for ( int i = 0; i < numScratches; i++ ) {
float x = width * random.nextFloat();
float y = height * random.nextFloat();
float a = angle + ImageMath.TWO_PI * (angleVariation * (random.nextFloat() - 0.5f));
float s = (float)Math.sin( a ) * l;
float c = (float)Math.cos( a ) * l;
float x1 = x-c;
float y1 = y-s;
float x2 = x+c;
float y2 = y+s;
g.drawLine( (int)x1, (int)y1, (int)x2, (int)y2 );
}
g.dispose();
return dst;
}
public String toString() {
return "Render/Scratches...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/BrushedMetalFilter.java 0000644 0001750 0001750 00000017547 10566356614 027717 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.util.*;
/**
* A filter which produces an image simulating brushed metal.
*/
public class BrushedMetalFilter implements BufferedImageOp {
private int radius = 10;
private float amount = 0.1f;
private int color = 0xff888888;
private float shine = 0.1f;
private boolean monochrome = true;
private Random randomNumbers;
/**
* Constructs a BrushedMetalFilter object.
*/
public BrushedMetalFilter() {
}
/**
* Constructs a BrushedMetalFilter object.
*
* @param color an int specifying the metal color
* @param radius an int specifying the blur size
* @param amount a float specifying the amount of texture
* @param monochrome a boolean -- true for monochrome texture
* @param shine a float specifying the shine to add
*/
public BrushedMetalFilter( int color, int radius, float amount, boolean monochrome, float shine) {
this.color = color;
this.radius = radius;
this.amount = amount;
this.monochrome = monochrome;
this.shine = shine;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width];
int[] outPixels = new int[width];
randomNumbers = new Random(0);
int a = color & 0xff000000;
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = color & 0xff;
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
int tr = r;
int tg = g;
int tb = b;
if ( shine != 0 ) {
int f = (int)(255*shine*Math.sin( (double)x/width*Math.PI ));
tr += f;
tg += f;
tb += f;
}
if (monochrome) {
int n = (int)(255 * (2*randomNumbers.nextFloat() - 1) * amount);
inPixels[x] = a | (clamp(tr+n) << 16) | (clamp(tg+n) << 8) | clamp(tb+n);
} else {
inPixels[x] = a | (random(tr) << 16) | (random(tg) << 8) | random(tb);
}
}
if ( radius != 0 ) {
blur( inPixels, outPixels, width, radius );
setRGB( dst, 0, y, width, 1, outPixels );
} else
setRGB( dst, 0, y, width, 1, inPixels );
}
return dst;
}
private int random(int x) {
x += (int)(255*(2*randomNumbers.nextFloat() - 1) * amount);
if (x < 0)
x = 0;
else if (x > 0xff)
x = 0xff;
return x;
}
private static int clamp(int c) {
if (c < 0)
return 0;
if (c > 255)
return 255;
return c;
}
/**
* Return a mod b. This differs from the % operator with respect to negative numbers.
* @param a the dividend
* @param b the divisor
* @return a mod b
*/
private static int mod(int a, int b) {
int n = a/b;
a -= n*b;
if (a < 0)
return a + b;
return a;
}
private void blur( int[] in, int[] out, int width, int radius ) {
int widthMinus1 = width-1;
int r2 = 2*radius+1;
int tr = 0, tg = 0, tb = 0;
for ( int i = -radius; i <= radius; i++ ) {
int rgb = in[mod(i, width)];
tr += (rgb >> 16) & 0xff;
tg += (rgb >> 8) & 0xff;
tb += rgb & 0xff;
}
for ( int x = 0; x < width; x++ ) {
out[x] = 0xff000000 | ((tr/r2) << 16) | ((tg/r2) << 8) | (tb/r2);
int i1 = x+radius+1;
if ( i1 > widthMinus1 )
i1 = mod( i1, width );
int i2 = x-radius;
if ( i2 < 0 )
i2 = mod( i2, width );
int rgb1 = in[i1];
int rgb2 = in[i2];
tr += ((rgb1 & 0xff0000)-(rgb2 & 0xff0000)) >> 16;
tg += ((rgb1 & 0xff00)-(rgb2 & 0xff00)) >> 8;
tb += (rgb1 & 0xff)-(rgb2 & 0xff);
}
}
/**
* Set the horizontal size of the blur.
* @param radius the radius of the blur in the horizontal direction
* @min-value 0
* @max-value 100+
* @see #getRadius
*/
public void setRadius(int radius) {
this.radius = radius;
}
/**
* Get the horizontal size of the blur.
* @return the radius of the blur in the horizontal direction
* @see #setRadius
*/
public int getRadius() {
return radius;
}
/**
* Set the amount of noise to add in the range 0..1.
* @param amount the amount of noise
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of noise to add.
* @return the amount of noise
* @see #setAmount
*/
public float getAmount() {
return amount;
}
/**
* Set the amount of shine to add to the range 0..1.
* @param shine the amount of shine
* @min-value 0
* @max-value 1
* @see #getShine
*/
public void setShine( float shine ) {
this.shine = shine;
}
/**
* Get the amount of shine to add in the range 0..1.
* @return the amount of shine
* @see #setShine
*/
public float getShine() {
return shine;
}
/**
* Set the color of the metal.
* @param color the color in ARGB form
* @see #getColor
*/
public void setColor(int color) {
this.color = color;
}
/**
* Get the color of the metal.
* @return the color in ARGB form
* @see #setColor
*/
public int getColor() {
return color;
}
/**
* Set the type of noise to add.
* @param monochrome true for monochrome noise
* @see #getMonochrome
*/
public void setMonochrome(boolean monochrome) {
this.monochrome = monochrome;
}
/**
* Get the type of noise to add.
* @return true for monochrome noise
* @see #setMonochrome
*/
public boolean getMonochrome() {
return monochrome;
}
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
if ( dstCM == null )
dstCM = src.getColorModel();
return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
}
public Rectangle2D getBounds2D( BufferedImage src ) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
if ( dstPt == null )
dstPt = new Point2D.Double();
dstPt.setLocation( srcPt.getX(), srcPt.getY() );
return dstPt;
}
public RenderingHints getRenderingHints() {
return null;
}
/**
* A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
* penalty of BufferedImage.setRGB unmanaging the image.
*/
private void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
int type = image.getType();
if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
image.getRaster().setDataElements( x, y, width, height, pixels );
else
image.setRGB( x, y, width, height, pixels, 0, width );
}
public String toString() {
return "Texture/Brushed Metal...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TransitionFilter.java 0000644 0001750 0001750 00000011544 10566572034 027455 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.*;
import java.beans.*;
import java.util.*;
/**
* A filter which uses another filter to perform a transition.
* e.g. to create a blur transition, you could write: new TransitionFilter( new BoxBlurFilter(), "radius", 0, 100 );
*/
public class TransitionFilter extends AbstractBufferedImageOp {
private float transition = 0;
private BufferedImage destination;
private String property;
private Method method;
/**
* The filter used for the transition.
*/
protected BufferedImageOp filter;
/**
* The start value for the filter property.
*/
protected float minValue;
/**
* The end value for the filter property.
*/
protected float maxValue;
/**
* Construct a TransitionFilter.
*/
private TransitionFilter() {
}
/**
* Construct a TransitionFilter.
* @param filter the filter to use
* @param property the filter property which is changed over the transition
* @param minValue the start value for the filter property
* @param maxValue the end value for the filter property
*/
public TransitionFilter( BufferedImageOp filter, String property, float minValue, float maxValue ) {
this.filter = filter;
this.property = property;
this.minValue = minValue;
this.maxValue = maxValue;
try {
BeanInfo info = Introspector.getBeanInfo( filter.getClass() );
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for ( int i = 0; i < pds.length; i++ ) {
PropertyDescriptor pd = pds[i];
if ( property.equals( pd.getName() ) ) {
method = pd.getWriteMethod();
break;
}
}
if ( method == null )
throw new IllegalArgumentException( "No such property in object: "+property );
}
catch (IntrospectionException e) {
throw new IllegalArgumentException( e.toString() );
}
}
/**
* Set the transition of the image in the range 0..1.
* @param transition the transition
* @min-value 0
* @max-value 1
* @see #getTransition
*/
public void setTransition( float transition ) {
this.transition = transition;
}
/**
* Get the transition of the image.
* @return the transition
* @see #setTransition
*/
public float getTransition() {
return transition;
}
/**
* Set the destination image.
* @param destination the destination image
* @see #getDestination
*/
public void setDestination( BufferedImage destination ) {
this.destination = destination;
}
/**
* Get the destination image.
* @return the destination image
* @see #setDestination
*/
public BufferedImage getDestination() {
return destination;
}
/*
public void setFilter( BufferedImageOp filter ) {
this.filter = filter;
}
public int getFilter() {
return filter;
}
*/
/**
* Prepare the filter for the transiton at a given time.
* The default implementation sets the given filter property, but you could override this method to make other changes.
* @param transition the transition time in the range 0 - 1
*/
public void prepareFilter( float transition ) {
try {
method.invoke( filter, new Object[] { new Float( transition ) } );
}
catch ( Exception e ) {
throw new IllegalArgumentException("Error setting value for property: "+property);
}
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
if ( dst == null )
dst = createCompatibleDestImage( src, null );
if ( destination == null )
return dst;
float itransition = 1-transition;
Graphics2D g = dst.createGraphics();
if ( transition != 1 ) {
float t = minValue + transition * ( maxValue-minValue );
prepareFilter( t );
g.drawImage( src, filter, 0, 0 );
}
if ( transition != 0 ) {
g.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, transition ) );
float t = minValue + itransition * ( maxValue-minValue );
prepareFilter( t );
g.drawImage( destination, filter, 0, 0 );
}
g.dispose();
return dst;
}
public String toString() {
return "Transitions/Transition...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/ChromeFilter.java 0000644 0001750 0001750 00000003627 10566356614 026547 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
/**
* A filter which simulates chrome.
*/
public class ChromeFilter extends LightFilter {
private float amount = 0.5f;
private float exposure = 1.0f;
/**
* Set the amount of effect.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(float amount) {
this.amount = amount;
}
/**
* Get the amount of chrome.
* @return the amount
* @see #setAmount
*/
public float getAmount() {
return amount;
}
/**
* Set the exppsure of the effect.
* @param exposure the exposure
* @min-value 0
* @max-value 1
* @see #getExposure
*/
public void setExposure(float exposure) {
this.exposure = exposure;
}
/**
* Get the exppsure of the effect.
* @return the exposure
* @see #setExposure
*/
public float getExposure() {
return exposure;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
setColorSource( LightFilter.COLORS_CONSTANT );
dst = super.filter( src, dst );
TransferFilter tf = new TransferFilter() {
protected float transferFunction( float v ) {
v += amount * (float)Math.sin( v * 2 * Math.PI );
return 1 - (float)Math.exp(-v * exposure);
}
};
return tf.filter( dst, dst );
}
public String toString() {
return "Effects/Chrome...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/MotionBlurFilter.java 0000644 0001750 0001750 00000017317 11331367711 027414 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.awt.geom.*;
/**
* A filter which produces motion blur the slow, but higher-quality way.
*/
public class MotionBlurFilter extends AbstractBufferedImageOp implements MotionBlur {
private float angle = 0.0f;
private float falloff = 1.0f;
private float distance = 1.0f;
private float zoom = 0.0f;
private float rotation = 0.0f;
private boolean wrapEdges = false;
private boolean premultiplyAlpha = true;
private float centreY = 0.5f;
private float centreX = 0.5f;
/**
* Construct a MotionBlurFilter.
*/
public MotionBlurFilter() {
}
/**
* Construct a MotionBlurFilter.
* @param distance the distance of blur.
* @param angle the angle of blur.
* @param rotation the angle of rotation.
* @param zoom the zoom factor.
*/
public MotionBlurFilter( float distance, float angle, float rotation, float zoom ) {
this.distance = distance;
this.angle = angle;
this.rotation = rotation;
this.zoom = zoom;
}
/**
* Set the centre of the effect in the X direction as a proportion of the image size.
* @param centreX the center
* @see #getCentreX
*/
public void setCentreX( float centreX ) {
this.centreX = centreX;
}
/**
* Get the centre of the effect in the X direction as a proportion of the image size.
* @return the center
* @see #setCentreX
*/
public float getCentreX() {
return centreX;
}
/**
* Set the centre of the effect in the Y direction as a proportion of the image size.
* @param centreY the center
* @see #getCentreY
*/
public void setCentreY( float centreY ) {
this.centreY = centreY;
}
/**
* Get the centre of the effect in the Y direction as a proportion of the image size.
* @return the center
* @see #setCentreY
*/
public float getCentreY() {
return centreY;
}
/**
* Set the centre of the effect as a proportion of the image size.
* @param centre the center
* @see #getCentre
*/
public void setCentre( Point2D centre ) {
this.centreX = (float)centre.getX();
this.centreY = (float)centre.getY();
}
/**
* Get the centre of the effect as a proportion of the image size.
* @return the center
* @see #setCentre
*/
public Point2D getCentre() {
return new Point2D.Float( centreX, centreY );
}
/**
* Specifies the angle of blur.
* @param angle the angle of blur.
* @angle
* @see #getAngle
*/
public void setAngle( float angle ) {
this.angle = angle;
}
/**
* Returns the angle of blur.
* @return the angle of blur.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the distance of blur.
* @param distance the distance of blur.
* @see #getDistance
*/
public void setDistance( float distance ) {
this.distance = distance;
}
/**
* Get the distance of blur.
* @return the distance of blur.
* @see #setDistance
*/
public float getDistance() {
return distance;
}
/**
* Set the blur rotation.
* @param rotation the angle of rotation.
* @see #getRotation
*/
public void setRotation( float rotation ) {
this.rotation = rotation;
}
/**
* Get the blur rotation.
* @return the angle of rotation.
* @see #setRotation
*/
public float getRotation() {
return rotation;
}
/**
* Set the blur zoom.
* @param zoom the zoom factor.
* @see #getZoom
*/
public void setZoom( float zoom ) {
this.zoom = zoom;
}
/**
* Get the blur zoom.
* @return the zoom factor.
* @see #setZoom
*/
public float getZoom() {
return zoom;
}
/**
* Set whether to wrap at the image edges.
* @param wrapEdges true if it should wrap.
* @see #getWrapEdges
*/
public void setWrapEdges(boolean wrapEdges) {
this.wrapEdges = wrapEdges;
}
/**
* Get whether to wrap at the image edges.
* @return true if it should wrap.
* @see #setWrapEdges
*/
public boolean getWrapEdges() {
return wrapEdges;
}
/**
* Set whether to premultiply the alpha channel.
* @param premultiplyAlpha true to premultiply the alpha
* @see #getPremultiplyAlpha
*/
public void setPremultiplyAlpha( boolean premultiplyAlpha ) {
this.premultiplyAlpha = premultiplyAlpha;
}
/**
* Get whether to premultiply the alpha channel.
* @return true to premultiply the alpha
* @see #setPremultiplyAlpha
*/
public boolean getPremultiplyAlpha() {
return premultiplyAlpha;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
getRGB( src, 0, 0, width, height, inPixels );
// float sinAngle = (float)Math.sin(angle);
// float cosAngle = (float)Math.cos(angle);
//
// float total;
// int cx = width/2;
// int cy = height/2;
int cx = (int) (width * centreX);
int cy = (int) (height * centreY);
int index = 0;
float imageRadius = (float)Math.sqrt( cx*cx + cy*cy );
float translateX = (float)(distance * Math.cos( angle ));
float translateY = (float)(distance * -Math.sin( angle ));
float maxDistance = distance + Math.abs(rotation*imageRadius) + zoom*imageRadius;
int repetitions = (int)maxDistance;
AffineTransform t = new AffineTransform();
Point2D.Float p = new Point2D.Float();
if ( premultiplyAlpha )
ImageMath.premultiply( inPixels, 0, inPixels.length );
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int a = 0, r = 0, g = 0, b = 0;
int count = 0;
for (int i = 0; i < repetitions; i++) {
int newX = x, newY = y;
float f = (float)i/repetitions;
p.x = x;
p.y = y;
t.setToIdentity();
t.translate( cx+f*translateX, cy+f*translateY );
float s = 1-zoom*f;
t.scale( s, s );
if ( rotation != 0 )
t.rotate( -rotation*f );
t.translate( -cx, -cy );
t.transform( p, p );
newX = (int)p.x;
newY = (int)p.y;
if (newX < 0 || newX >= width) {
if ( wrapEdges )
newX = ImageMath.mod( newX, width );
else
break;
}
if (newY < 0 || newY >= height) {
if ( wrapEdges )
newY = ImageMath.mod( newY, height );
else
break;
}
count++;
int rgb = inPixels[newY*width+newX];
a += (rgb >> 24) & 0xff;
r += (rgb >> 16) & 0xff;
g += (rgb >> 8) & 0xff;
b += rgb & 0xff;
}
if (count == 0) {
outPixels[index] = inPixels[index];
} else {
a = PixelUtils.clamp((int)(a/count));
r = PixelUtils.clamp((int)(r/count));
g = PixelUtils.clamp((int)(g/count));
b = PixelUtils.clamp((int)(b/count));
outPixels[index] = (a << 24) | (r << 16) | (g << 8) | b;
}
index++;
}
}
if ( premultiplyAlpha )
ImageMath.unpremultiply( outPixels, 0, inPixels.length );
setRGB( dst, 0, 0, width, height, outPixels );
return dst;
}
public String toString() {
return "Blur/Motion Blur...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/TileImageFilter.java 0000644 0001750 0001750 00000004613 10566572034 027162 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
/**
* A filter which tiles an image into a lerger one.
*/
public class TileImageFilter extends AbstractBufferedImageOp {
private int width;
private int height;
private int tileWidth;
private int tileHeight;
/**
* Construct a TileImageFilter.
*/
public TileImageFilter() {
this(32, 32);
}
/**
* Construct a TileImageFilter.
* @param width the output image width
* @param height the output image height
*/
public TileImageFilter(int width, int height) {
this.width = width;
this.height = height;
}
/**
* Set the output image width.
* @param width the width
* @see #getWidth
*/
public void setWidth(int width) {
this.width = width;
}
/**
* Get the output image width.
* @return the width
* @see #setWidth
*/
public int getWidth() {
return width;
}
/**
* Set the output image height.
* @param height the height
* @see #getHeight
*/
public void setHeight(int height) {
this.height = height;
}
/**
* Get the output image height.
* @return the height
* @see #setHeight
*/
public int getHeight() {
return height;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int tileWidth = src.getWidth();
int tileHeight = src.getHeight();
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(width, height), dstCM.isAlphaPremultiplied(), null);
}
Graphics2D g = dst.createGraphics();
for ( int y = 0; y < height; y += tileHeight) {
for ( int x = 0; x < width; x += tileWidth ) {
g.drawImage( src, null, x, y );
}
}
g.dispose();
return dst;
}
public String toString() {
return "Tile";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/SparkleFilter.java 0000644 0001750 0001750 00000007473 11331373357 026730 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.image.*;
import java.util.*;
public class SparkleFilter extends PointFilter {
private int rays = 50;
private int radius = 25;
private int amount = 50;
private int color = 0xffffffff;
private int randomness = 25;
private int width, height;
private int centreX, centreY;
private long seed = 371;
private float[] rayLengths;
private Random randomNumbers = new Random();
private float relativeCentreX = 0.5f;
private float relativeCentreY = 0.5f;
private boolean lightOnly;
public SparkleFilter() {
}
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
public void setRandomness(int randomness) {
this.randomness = randomness;
}
public int getRandomness() {
return randomness;
}
/**
* Set the amount of sparkle.
* @param amount the amount
* @min-value 0
* @max-value 1
* @see #getAmount
*/
public void setAmount(int amount) {
this.amount = amount;
}
/**
* Get the amount of sparkle.
* @return the amount
* @see #setAmount
*/
public int getAmount() {
return amount;
}
public void setRays(int rays) {
this.rays = rays;
}
public int getRays() {
return rays;
}
/**
* Set the radius of the effect.
* @param radius the radius
* @min-value 0
* @see #getRadius
*/
public void setRadius(int radius) {
this.radius = radius;
}
/**
* Get the radius of the effect.
* @return the radius
* @see #setRadius
*/
public int getRadius() {
return radius;
}
public void setDimensions(int width, int height) {
this.width = width;
this.height = height;
centreX = (int) (width * relativeCentreX);
centreY = (int) (height * relativeCentreY);
super.setDimensions(width, height);
randomNumbers.setSeed(seed);
rayLengths = new float[rays];
for (int i = 0; i < rays; i++)
rayLengths[i] = radius + randomness / 100.0f * radius * (float)randomNumbers.nextGaussian();
}
public int filterRGB(int x, int y, int rgb) {
float dx = x-centreX;
float dy = y-centreY;
float distance = dx*dx+dy*dy;
float angle = (float)Math.atan2(dy, dx);
float d = (angle+ImageMath.PI) / (ImageMath.TWO_PI) * rays;
int i = (int)d;
float f = d - i;
if (radius != 0) {
float length = ImageMath.lerp(f, rayLengths[i % rays], rayLengths[(i+1) % rays]);
float g = length*length / (distance+0.0001f);
g = (float)Math.pow(g, (100-amount) / 50.0);
f -= 0.5f;
// f *= amount/50.0f;
f = 1 - f*f;
f *= g;
}
f = ImageMath.clamp(f, 0, 1);
if(lightOnly) {
return ImageMath.mixColors(f, 0, color);
} else {
return ImageMath.mixColors(f, rgb, color);
}
}
public void setRelativeCentreX(float relativeCentreX) {
this.relativeCentreX = relativeCentreX;
}
public void setRelativeCentreY(float relativeCentreY) {
this.relativeCentreY = relativeCentreY;
}
public float getRelativeCentreX() {
return relativeCentreX;
}
public float getRelativeCentreY() {
return relativeCentreY;
}
public boolean isLightOnly() {
return lightOnly;
}
public void setLightOnly(boolean lightOnly) {
this.lightOnly = lightOnly;
}
public String toString() {
return "Stylize/Sparkle...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/GradientFilter.java 0000644 0001750 0001750 00000020464 10566356614 027065 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* A filter which draws a coloured gradient. This is largely superceded by GradientPaint in Java1.2, but does provide a few
* more gradient options.
*/
public class GradientFilter extends AbstractBufferedImageOp {
public final static int LINEAR = 0;
public final static int BILINEAR = 1;
public final static int RADIAL = 2;
public final static int CONICAL = 3;
public final static int BICONICAL = 4;
public final static int SQUARE = 5;
public final static int INT_LINEAR = 0;
public final static int INT_CIRCLE_UP = 1;
public final static int INT_CIRCLE_DOWN = 2;
public final static int INT_SMOOTH = 3;
private float angle = 0;
private int color1 = 0xff000000;
private int color2 = 0xffffffff;
private Point p1 = new Point(0, 0), p2 = new Point(64, 64);
private boolean repeat = false;
private float x1;
private float y1;
private float dx;
private float dy;
private Colormap colormap = null;
private int type;
private int interpolation = INT_LINEAR;
private int paintMode = PixelUtils.NORMAL;
public GradientFilter() {
}
public GradientFilter(Point p1, Point p2, int color1, int color2, boolean repeat, int type, int interpolation) {
this.p1 = p1;
this.p2 = p2;
this.color1 = color1;
this.color2 = color2;
this.repeat = repeat;
this.type = type;
this.interpolation = interpolation;
colormap = new LinearColormap(color1, color2);
}
public void setPoint1(Point point1) {
this.p1 = point1;
}
public Point getPoint1() {
return p1;
}
public void setPoint2(Point point2) {
this.p2 = point2;
}
public Point getPoint2() {
return p2;
}
public void setType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setInterpolation(int interpolation) {
this.interpolation = interpolation;
}
public int getInterpolation() {
return interpolation;
}
/**
* Specifies the angle of the texture.
* @param angle the angle of the texture.
* @angle
* @see #getAngle
*/
public void setAngle(float angle) {
this.angle = angle;
p2 = new Point((int)(64*Math.cos(angle)), (int)(64*Math.sin(angle)));
}
/**
* Returns the angle of the texture.
* @return the angle of the texture.
* @see #setAngle
*/
public float getAngle() {
return angle;
}
/**
* Set the colormap to be used for the filter.
* @param colormap the colormap
* @see #getColormap
*/
public void setColormap(Colormap colormap) {
this.colormap = colormap;
}
/**
* Get the colormap to be used for the filter.
* @return the colormap
* @see #setColormap
*/
public Colormap getColormap() {
return colormap;
}
public void setPaintMode(int paintMode) {
this.paintMode = paintMode;
}
public int getPaintMode() {
return paintMode;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int width = src.getWidth();
int height = src.getHeight();
if ( dst == null )
dst = createCompatibleDestImage( src, null );
int rgb1, rgb2;
float x1, y1, x2, y2;
x1 = p1.x;
x2 = p2.x;
if (x1 > x2 && type != RADIAL) {
y1 = x1;
x1 = x2;
x2 = y1;
y1 = p2.y;
y2 = p1.y;
rgb1 = color2;
rgb2 = color1;
} else {
y1 = p1.y;
y2 = p2.y;
rgb1 = color1;
rgb2 = color2;
}
float dx = x2 - x1;
float dy = y2 - y1;
float lenSq = dx * dx + dy * dy;
this.x1 = x1;
this.y1 = y1;
if (lenSq >= Float.MIN_VALUE) {
dx = dx / lenSq;
dy = dy / lenSq;
if (repeat) {
dx = dx % 1.0f;
dy = dy % 1.0f;
}
}
this.dx = dx;
this.dy = dy;
int[] pixels = new int[width];
for (int y = 0; y < height; y++ ) {
getRGB( src, 0, y, width, 1, pixels );
switch (type) {
case LINEAR:
case BILINEAR:
linearGradient(pixels, y, width, 1);
break;
case RADIAL:
radialGradient(pixels, y, width, 1);
break;
case CONICAL:
case BICONICAL:
conicalGradient(pixels, y, width, 1);
break;
case SQUARE:
squareGradient(pixels, y, width, 1);
break;
}
setRGB( dst, 0, y, width, 1, pixels );
}
return dst;
}
private void repeatGradient(int[] pixels, int w, int h, float rowrel, float dx, float dy) {
int off = 0;
for (int y = 0; y < h; y++) {
float colrel = rowrel;
int j = w;
int rgb;
while (--j >= 0) {
if (type == BILINEAR)
rgb = colormap.getColor(map(ImageMath.triangle(colrel)));
else
rgb = colormap.getColor(map(ImageMath.mod(colrel, 1.0f)));
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
colrel += dx;
}
rowrel += dy;
}
}
private void singleGradient(int[] pixels, int w, int h, float rowrel, float dx, float dy) {
int off = 0;
for (int y = 0; y < h; y++) {
float colrel = rowrel;
int j = w;
int rgb;
if (colrel <= 0.0) {
rgb = colormap.getColor(0);
do {
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
colrel += dx;
} while (--j > 0 && colrel <= 0.0);
}
while (colrel < 1.0 && --j >= 0) {
if (type == BILINEAR)
rgb = colormap.getColor(map(ImageMath.triangle(colrel)));
else
rgb = colormap.getColor(map(colrel));
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
colrel += dx;
}
if (j > 0) {
if (type == BILINEAR)
rgb = colormap.getColor(0.0f);
else
rgb = colormap.getColor(1.0f);
do {
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
} while (--j > 0);
}
rowrel += dy;
}
}
private void linearGradient(int[] pixels, int y, int w, int h) {
int x = 0;
float rowrel = (x - x1) * dx + (y - y1) * dy;
if (repeat)
repeatGradient(pixels, w, h, rowrel, dx, dy);
else
singleGradient(pixels, w, h, rowrel, dx, dy);
}
private void radialGradient(int[] pixels, int y, int w, int h) {
int off = 0;
float radius = distance(p2.x-p1.x, p2.y-p1.y);
for (int x = 0; x < w; x++) {
float distance = distance(x-p1.x, y-p1.y);
float ratio = distance / radius;
if (repeat)
ratio = ratio % 2;
else if (ratio > 1.0)
ratio = 1.0f;
int rgb = colormap.getColor(map(ratio));
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
}
}
private void squareGradient(int[] pixels, int y, int w, int h) {
int off = 0;
float radius = Math.max(Math.abs(p2.x-p1.x), Math.abs(p2.y-p1.y));
for (int x = 0; x < w; x++) {
float distance = Math.max(Math.abs(x-p1.x), Math.abs(y-p1.y));
float ratio = distance / radius;
if (repeat)
ratio = ratio % 2;
else if (ratio > 1.0)
ratio = 1.0f;
int rgb = colormap.getColor(map(ratio));
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
}
}
private void conicalGradient(int[] pixels, int y, int w, int h) {
int off = 0;
float angle0 = (float)Math.atan2(p2.x-p1.x, p2.y-p1.y);
for (int x = 0; x < w; x++) {
float angle = (float)(Math.atan2(x-p1.x, y-p1.y) - angle0) / (ImageMath.TWO_PI);
angle += 1.0f;
angle %= 1.0f;
if (type == BICONICAL)
angle = ImageMath.triangle(angle);
int rgb = colormap.getColor(map(angle));
pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode);
off++;
}
}
private float map(float v) {
if (repeat)
v = v > 1.0 ? 2.0f-v : v;
switch (interpolation) {
case INT_CIRCLE_UP:
v = ImageMath.circleUp(ImageMath.clamp(v, 0.0f, 1.0f));
break;
case INT_CIRCLE_DOWN:
v = ImageMath.circleDown(ImageMath.clamp(v, 0.0f, 1.0f));
break;
case INT_SMOOTH:
v = ImageMath.smoothStep(0, 1, v);
break;
}
return v;
}
private float distance(float a, float b) {
return (float)Math.sqrt(a*a+b*b);
}
public String toString() {
return "Other/Gradient Fill...";
}
}
libpixels-java-2.1.3+svn.orig/src/main/java/com/jhlabs/image/CropFilter.java 0000644 0001750 0001750 00000006430 10606647276 026232 0 ustar martin martin /*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.jhlabs.image;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
* A filter which crops an image to a given rectangle.
*/
public class CropFilter extends AbstractBufferedImageOp {
private int x;
private int y;
private int width;
private int height;
/**
* Construct a CropFilter.
*/
public CropFilter() {
this(0, 0, 32, 32);
}
/**
* Construct a CropFilter.
* @param x the left edge of the crop rectangle
* @param y the top edge of the crop rectangle
* @param width the width of the crop rectangle
* @param height the height of the crop rectangle
*/
public CropFilter(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
/**
* Set the left edge of the crop rectangle.
* @param x the left edge of the crop rectangle
* @see #getX
*/
public void setX(int x) {
this.x = x;
}
/**
* Get the left edge of the crop rectangle.
* @return the left edge of the crop rectangle
* @see #setX
*/
public int getX() {
return x;
}
/**
* Set the top edge of the crop rectangle.
* @param y the top edge of the crop rectangle
* @see #getY
*/
public void setY(int y) {
this.y = y;
}
/**
* Get the top edge of the crop rectangle.
* @return the top edge of the crop rectangle
* @see #setY
*/
public int getY() {
return y;
}
/**
* Set the width of the crop rectangle.
* @param width the width of the crop rectangle
* @see #getWidth
*/
public void setWidth(int width) {
this.width = width;
}
/**
* Get the width of the crop rectangle.
* @return the width of the crop rectangle
* @see #setWidth
*/
public int getWidth() {
return width;
}
/**
* Set the height of the crop rectangle.
* @param height the height of the crop rectangle
* @see #getHeight
*/
public void setHeight(int height) {
this.height = height;
}
/**
* Get the height of the crop rectangle.
* @return the height of the crop rectangle
* @see #setHeight
*/
public int getHeight() {
return height;
}
public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
int w = src.getWidth();
int h = src.getHeight();
if ( dst == null ) {
ColorModel dstCM = src.getColorModel();
dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(width, height), dstCM.isAlphaPremultiplied(), null);
}
Graphics2D g = dst.createGraphics();
g.drawRenderedImage( src, AffineTransform.getTranslateInstance(-x, -y) );
g.dispose();
return dst;
}
public String toString() {
return "Distort/Crop";
}
}
libpixels-java-2.1.3+svn.orig/src/main/resources/ 0000755 0001750 0001750 00000000000 11412236310 021254 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/test/ 0000755 0001750 0001750 00000000000 11412236303 017277 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/test/java/ 0000755 0001750 0001750 00000000000 11412236303 020220 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/test/resources/ 0000755 0001750 0001750 00000000000 11412236303 021311 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/site/ 0000755 0001750 0001750 00000000000 11412236303 017264 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/site/resources/ 0000755 0001750 0001750 00000000000 11412236303 021276 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/site/resources/screenshots/ 0000755 0001750 0001750 00000000000 11412236304 023637 5 ustar martin martin libpixels-java-2.1.3+svn.orig/src/site/resources/screenshots/ContrastFilter.jpg 0000644 0001750 0001750 00000101214 10565274750 027322 0 ustar martin martin C C "
} !1AQa"q2#BR$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
w !1AQaq"2B #3Rbr
$4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ? &b-QPwF]s$𱴑' Hqav 9cā[ $9
A9]sn>Aqϧ$s*M8O96\Ͻ[brIҽ4۹J*ѐ$Ea@O~cDV \y}GCNJbFIy2aO'=={q[cRpo99<l,A뫞F{*Uގk<)kԌs47{qOkk4vۉlT0ss d`ӷ9[Ě~,r-_w܅TTOKG
:;7~x.9hIXзFA9o$c `vea`z%wu{M8qKNͽ^{<՝1|
m9vf