/*
JWildfire - an image and animation processor written in Java
Copyright (C) 1995-2011 Andreas Maschke
This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this software;
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jwildfire.transform;
import org.jwildfire.image.Pixel;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;
import org.jwildfire.swing.Buffer.BufferType;
public abstract class Mesh2DTransformer extends Transformer {
protected SimpleImage srcImg;
protected Pixel srcP = new Pixel();
protected Pixel srcQ = new Pixel();
protected Pixel srcR = new Pixel();
protected Pixel srcS = new Pixel();
protected abstract void performPixelTransformation(WFImage pImg);
@Override
public boolean acceptsInputBufferType(BufferType pBufferType) {
return pBufferType == BufferType.IMAGE;
}
protected void readSrcPixels(double pX, double pY) {
int x = (int) (pX + 0.5);
int y = (int) (pY + 0.5);
int w = srcImg.getImageWidth();
int h = srcImg.getImageHeight();
if ((x < 0) || (x >= w) || (y < 0) || (y >= h)) {
srcP.clear();
srcQ.clear();
srcR.clear();
srcS.clear();
}
else {
srcP.setARGBValue(srcImg.getBufferedImg().getRGB(x, y));
if (x < w - 1)
srcQ.setARGBValue(srcImg.getBufferedImg().getRGB(x + 1, y));
else
srcQ.assign(srcP);
if (y < h - 1) {
srcR.setARGBValue(srcImg.getBufferedImg().getRGB(x, y + 1));
if (x < w - 1)
srcS.setARGBValue(srcImg.getBufferedImg().getRGB(x + 1, y + 1));
else
srcS.assign(srcQ);
}
else {
srcR.assign(srcP);
srcS.assign(srcQ);
}
}
}
@Override
protected void initTransformation(WFImage pImg) {
super.initTransformation(pImg);
srcImg = ((SimpleImage) pImg).clone();
}
@Override
protected void cleanupTransformation(WFImage pImg) {
srcImg = null;
super.cleanupTransformation(pImg);
}
@Override
protected void performImageTransformation(WFImage pImg) {
performPixelTransformation(pImg);
}
protected void applySmoothing(SimpleImage pImg, int pSmoothingAmount) {
int width = pImg.getImageWidth();
int height = pImg.getImageHeight();
Pixel pixel = new Pixel();
for (int k = 0; k < pSmoothingAmount; k++) {
for (int i = 1; i < (height - 1); i++) {
/* process pixels 2..width-1 */
for (int j = 1; j < (width - 1); j++) {
pixel.setARGBValue(pImg.getARGBValue(j, i - 1));
int r1 = pixel.r;
int g1 = pixel.g;
int b1 = pixel.b;
pixel.setARGBValue(pImg.getARGBValue(j + 1, i));
int r2 = pixel.r;
int g2 = pixel.g;
int b2 = pixel.b;
pixel.setARGBValue(pImg.getARGBValue(j, i + 1));
int r3 = pixel.r;
int g3 = pixel.g;
int b3 = pixel.b;
pixel.setARGBValue(pImg.getARGBValue(j, i));
int r = pixel.r;
int g = pixel.g;
int b = pixel.b;
int av1 = (r1 + g1 + b1);
int av2 = (r2 + g2 + b2);
int av3 = (r3 + g3 + b3);
int av = (r + g + b);
int d1 = av1 - av;
if (d1 < 0)
d1 = 0 - d1;
int d2 = av2 - av;
if (d2 < 0)
d2 = 0 - d2;
int d3 = av3 - av;
if (d3 < 0)
d3 = 0 - d3;
if ((d1 > 64) && (d2 > 64)) {
int rv = r1 * d1 + r2 * d2;
rv /= (d1 + d2);
rv += r;
rv /= 2;
int gv = g1 * d1 + g2 * d2;
gv /= (d1 + d2);
gv += g;
gv /= 2;
int bv = b1 * d1 + b2 * d2;
bv /= (d1 + d2);
bv += b;
bv /= 2;
pImg.setRGB(j, i, rv, gv, bv);
}
else if ((d2 > 64) && (d3 > 64)) {
int rv = r2 * d2 + r3 * d3;
rv /= (d2 + d3);
rv += r;
rv /= 2;
int gv = g2 * d2 + g3 * d3;
gv /= (d2 + d3);
gv += g;
gv /= 2;
int bv = b2 * d2 + b3 * d3;
bv /= (d2 + d3);
bv += b;
bv /= 2;
pImg.setRGB(j, i, rv, gv, bv);
}
}
}
}
}
@Override
public boolean supports3DOutput() {
return false;
}
}