package ip.gui;
import ip.gui.frames.ColorFrame;
import ip.gui.frames.ImageFrameInterface;
import math.Mat3;
abstract public class FloatPlane {
public float r[][];
public float g[][];
public float b[][];
protected int width;
protected int height;
private ColorFrame parent;
public float rBar, gBar, bBar;
public float min, max;
public FloatPlane(ColorFrame _cf) {
copyFloats(_cf);
}
public void zeroOut() {
r = new float[width][height];
g = new float[width][height];
b = new float[width][height];
}
public void oneOnF() {
int w = width;
int h = height;
int xc = w / 2;
int yc = h / 2;
float rn[][] = new float[width][height];
float gn[][] = new float[width][height];
float bn[][] = new float[width][height];
double p[] = new double[2];
int red, green, blue;
int xp, yp, i, j;
double radiusMax = Math.sqrt((w / 2) * (w / 2) + (h / 2) * (h / 2));
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++) {
double dx = x - xc;
double dy = y - yc;
double radius = Math.sqrt(dx * dx + dy * dy);
double a = Math.atan2(dy, dx);
p[0] = radius * Math.cos(a);
p[1] = radius * Math.sin(a);
double oneOnF = radiusMax / (radius + .01);
xp = (int) p[0] + xc;
yp = (int) p[1] + yc;
if ((xp < w) && (yp < h) && (xp >= 0) && (yp >= 0)) {
rn[x][y] = (float) (oneOnF * r[xp][yp]);
gn[x][y] = (float) (oneOnF * g[xp][yp]);
bn[x][y] = (float) (oneOnF * b[xp][yp]);
}
}
r = rn;
g = gn;
b = bn;
}
public void transpose() {
float ro[][] = new float[r[0].length][r.length];
float go[][] = new float[r[0].length][r.length];
float bo[][] = new float[r[0].length][r.length];
for (int x = 0; x < r.length; x++)
for (int y = 0; y < r[0].length; y++) {
ro[y][x] = r[x][y];
go[y][x] = g[x][y];
bo[y][x] = b[x][y];
}
height = r.length;
width = r[0].length;
r = ro;
g = go;
b = bo;
}
public void copyFloats(ColorFrame _cf) {
parent = _cf;
ImageFrameInterface frame = parent;
width = frame.getImageWidth();
ImageFrameInterface frame1 = parent;
height = frame1.getImageHeight();
r = new float[width][height];
g = new float[width][height];
b = new float[width][height];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
r[x][y] = parent.getR()[x][y];
g[x][y] = parent.getG()[x][y];
b[x][y] = parent.getB()[x][y];
}
}
public void linearTransform() {
computeStats();
float Vmin = min;
float Vmax = max;
int Dmin = 0;
int Dmax = 255;
double deltaV = Vmax - Vmin;
double deltaD = Dmax - Dmin;
double c = deltaD / deltaV;
double b = (Dmin * Vmax - Dmax * Vmin) / deltaV;
linearTransform(c, b);
}
public void linearTransform(double c, double br) {
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
r[x][y] = (float) (c * r[x][y] + br);
g[x][y] = (float) (c * g[x][y] + br);
b[x][y] = (float) (c * b[x][y] + br);
}
}
public void computeStats() {
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
rBar = 0;
gBar = 0;
bBar = 0;
double N = width * height;
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
rBar += r[x][y];
gBar += g[x][y];
bBar += b[x][y];
min = Math.min(r[x][y], min);
min = Math.min(g[x][y], min);
min = Math.min(b[x][y], min);
max = Math.max(r[x][y], max);
max = Math.max(g[x][y], max);
max = Math.max(b[x][y], max);
}
rBar /= N;
gBar /= N;
bBar /= N;
}
public abstract void toRgb();
public abstract void fromRgb();
public float getMin(float a[][]) {
float min = Float.MAX_VALUE;
for (int x = 0; x < a.length; x++)
for (int y = 0; y < a[0].length; y++) {
if (min > a[x][y]) min = a[x][y];
}
return min;
}
public float min(float m1, float m2, float m3) {
if ((m1 <= m2) && (m1 <= m3)) return m1;
if ((m2 <= m1) && (m2 <= m3)) return m2;
return m3;
}
public float max(float m1, float m2, float m3) {
if ((m1 >= m2) && (m1 >= m3)) return m1;
if ((m2 >= m1) && (m2 >= m3)) return m2;
return m3;
}
public float getMin() {
return min(getMin(r), getMin(g), getMin(b));
}
public float getMax() {
return max(getMax(r), getMax(g), getMax(b));
}
public void printStatistics() {
System.out.println("Max:" + getMax());
System.out.println("Min:" + getMin());
}
public void normalize(float a[][]) {
float min = getMin(a);
if (min < 0) addArray(a, -min);
if (min > 0) addArray(a, min);
scaleArray(a, 1 / getMax(a));
}
public void normalize() {
float min = getMin();
if (min < 0) min = -min;
addArray(r, min);
addArray(g, min);
addArray(b, min);
float s = 1 / getMax();
scaleArray(r, s);
scaleArray(g, s);
scaleArray(b, s);
}
public void scaleArray(float a[][], float s) {
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
a[x][y] *= s;
}
public void powArray(float a[][], float s) {
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
if (a[x][y] < 0)
a[x][y] = (float) (-Math.pow(-a[x][y], s));
else
a[x][y] = (float) Math.pow(a[x][y], s);
}
public void pow(float s) {
powArray(r, s);
powArray(g, s);
powArray(b, s);
}
public void scale(float s) {
scaleArray(r, s);
scaleArray(g, s);
scaleArray(b, s);
}
public void addArray(float a[][], float s) {
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
a[x][y] += s;
}
public float getMax(float a[][]) {
float max = Float.MIN_VALUE;
for (int x = 0; x < a.length; x++)
for (int y = 0; y < a[0].length; y++) {
if (max < a[x][y]) max = a[x][y];
}
return max;
}
public void convertSpace(Mat3 m) {
float pel[];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
pel = m.multiply(r[x][y], g[x][y], b[x][y]);
r[x][y] = pel[0];
g[x][y] = pel[1];
b[x][y] = pel[2];
}
}
public void subSampleChroma2To1() {
b = oneDSubsampleTwoTo1(b);
g = oneDSubsampleTwoTo1(g);
}
public float[][] oneDSubsampleTwoTo1(float f[][]) {
int width = f.length;
int height = f[0].length;
float h[][] = new float[width][height];
double sum = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width - 2; x = x + 2) {
float a = (float) ((f[x][y] + f[x + 1][y]) / 2.0);
h[x][y] = a;
h[x + 1][y] = a;
}
}
return h;
}
public void subSampleChroma4To1() {
b = oneDSubsample4To1(b);
g = oneDSubsample4To1(g);
}
public float[][] oneDSubsample4To1(float f[][]) {
int width = f.length;
int height = f[0].length;
float h[][] = new float[width][height];
double sum = 0;
for (int y = 0; y < height - 2; y = y + 2) {
for (int x = 0; x < width - 2; x = x + 2) {
float a = (f[x][y] + f[x + 1][y] + f[x + 1][y + 1] + f[x][y + 1]) / 4f;
h[x][y] = a;
h[x + 1][y] = a;
h[x][y + 1] = a;
h[x + 1][y + 1] = a;
}
}
return h;
}
public void updateParent(float scaleFactor) {
ImageFrameInterface frame = parent;
int width1 = width;
frame.setImageWidth(width1);
ImageFrameInterface frame1 = parent;
int height1 = height;
frame1.setImageHeight(height1);
parent.setR(new short[width][height]);
parent.setG(new short[width][height]);
parent.setB(new short[width][height]);
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
parent.getR()[x][y] = (short) (scaleFactor * r[x][y]);
parent.getG()[x][y] = (short) (scaleFactor * g[x][y]);
parent.getB()[x][y] = (short) (scaleFactor * b[x][y]);
}
parent.short2Image();
}
public void updateParent() {
ImageFrameInterface frame = parent;
int width1 = width;
frame.setImageWidth(width1);
ImageFrameInterface frame1 = parent;
int height1 = height;
frame1.setImageHeight(height1);
parent.setR(new short[width][height]);
parent.setG(new short[width][height]);
parent.setB(new short[width][height]);
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
parent.getR()[x][y] = (short) r[x][y];
parent.getG()[x][y] = (short) g[x][y];
parent.getB()[x][y] = (short) b[x][y];
}
parent.short2Image();
}
}