mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-28 05:26:22 +00:00
323 lines
9.5 KiB
Java
323 lines
9.5 KiB
Java
/*
|
|
* Copyright (C) 2025 JPEXS
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.jpexs.decompiler.flash.easygui;
|
|
|
|
import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER;
|
|
import java.lang.reflect.Field;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Convolution prset;
|
|
*
|
|
* @author JPEXS
|
|
*/
|
|
public class ConvolutionPreset {
|
|
|
|
public static final ConvolutionPreset Identity = new ConvolutionPreset("identity", 3, 3, new float[]{
|
|
0, 0, 0,
|
|
0, 1, 0,
|
|
0, 0, 0
|
|
});
|
|
public static final ConvolutionPreset BoxBlur = new ConvolutionPreset("boxBlur", 3, 3, new float[]{
|
|
1, 1, 1,
|
|
1, 1, 1,
|
|
1, 1, 1
|
|
}, 9);
|
|
public static final ConvolutionPreset GaussianBlur = new ConvolutionPreset("gaussianBlur", 3, 3, new float[]{
|
|
1, 2, 1,
|
|
2, 4, 2,
|
|
1, 2, 1
|
|
}, 16);
|
|
public static final ConvolutionPreset Sharpen = new ConvolutionPreset("sharpen", 3, 3, new float[]{
|
|
0, -1, 0,
|
|
-1, 5, -1,
|
|
0, -1, 0
|
|
});
|
|
public static final ConvolutionPreset EdgeDetectionXSobel = new ConvolutionPreset("edgeDetectionXSobel", 3, 3, new float[]{
|
|
-1, 0, 1,
|
|
-2, 0, 2,
|
|
-1, 0, 1
|
|
});
|
|
public static final ConvolutionPreset EdgeDetectionYSobel = new ConvolutionPreset("edgeDetectionYSobel", 3, 3, new float[]{
|
|
-1, -2, -1,
|
|
0, 0, 0,
|
|
1, 2, 1
|
|
});
|
|
public static final ConvolutionPreset EdgeDetectionXPrewitt = new ConvolutionPreset("edgeDetectionXPrewitt", 3, 3, new float[]{
|
|
-1, 0, 1,
|
|
-1, 0, 1,
|
|
-1, 0, 1
|
|
});
|
|
public static final ConvolutionPreset EdgeDetectionYPrewitt = new ConvolutionPreset("edgeDetectionYPrewitt", 3, 3, new float[]{
|
|
-1, -1, -1,
|
|
0, 0, 0,
|
|
1, 1, 1
|
|
});
|
|
public static final ConvolutionPreset EdgeDetectionXScharr = new ConvolutionPreset("edgeDetectionXScharr", 3, 3, new float[]{
|
|
3, 0, -3,
|
|
10, 0, -10,
|
|
3, 0, -3
|
|
});
|
|
public static final ConvolutionPreset EdgeDetectionYScharr = new ConvolutionPreset("edgeDetectionYScharr", 3, 3, new float[]{
|
|
3, 10, 3,
|
|
0, 0, 0,
|
|
-3, -10, -3
|
|
});
|
|
public static final ConvolutionPreset Laplacian = new ConvolutionPreset("laplacian", 3, 3, new float[]{
|
|
0, -1, 0,
|
|
-1, 4, -1,
|
|
0, -1, 0
|
|
});
|
|
public static final ConvolutionPreset Emboss = new ConvolutionPreset("emboss", 3, 3, new float[]{
|
|
-2, -1, 0,
|
|
-1, 1, 1,
|
|
0, 1, 2
|
|
});
|
|
public static final ConvolutionPreset Outline = new ConvolutionPreset("outline", 3, 3, new float[]{
|
|
-1, -1, -1,
|
|
-1, 8, -1,
|
|
-1, -1, -1
|
|
});
|
|
public static final ConvolutionPreset MotionBlurX = new ConvolutionPreset("motionBlurX", 5, 1, new float[]{
|
|
1, 1, 1, 1, 1
|
|
}, 5);
|
|
public static final ConvolutionPreset MotionBlurY = new ConvolutionPreset("motionBlurY", 1, 5, new float[]{
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
1
|
|
}, 5);
|
|
public static final ConvolutionPreset HighPass = new ConvolutionPreset("highPass", 3, 3, new float[]{
|
|
-1, -1, -1,
|
|
-1, 9, -1,
|
|
-1, -1, -1
|
|
});
|
|
private final String identifier;
|
|
|
|
private final int matrixX;
|
|
private final int matrixY;
|
|
private final float[] matrix;
|
|
private final float divisor;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param identifier Convolution type identifier
|
|
* @param matrixX Matrix width
|
|
* @param matrixY Matrix height
|
|
* @param matrix Matrix
|
|
*/
|
|
public ConvolutionPreset(String identifier, int matrixX, int matrixY, float[] matrix) {
|
|
this(identifier, matrixX, matrixY, matrix, 1);
|
|
|
|
}
|
|
|
|
/**
|
|
* Constructor with divisor
|
|
*
|
|
* @param identifier Convolution type identifier
|
|
* @param matrixX Matrix width
|
|
* @param matrixY Matrix height
|
|
* @param matrix Matrix
|
|
* @param divisor Divisor of values
|
|
*/
|
|
public ConvolutionPreset(String identifier, int matrixX, int matrixY, float[] matrix, float divisor) {
|
|
this.identifier = identifier;
|
|
this.matrixX = matrixX;
|
|
this.matrixY = matrixY;
|
|
this.matrix = matrix;
|
|
this.divisor = divisor;
|
|
}
|
|
|
|
/**
|
|
* Get matrix
|
|
*
|
|
* @return
|
|
*/
|
|
public float[] getMatrix() {
|
|
return matrix;
|
|
}
|
|
|
|
/**
|
|
* Get matrix width
|
|
*
|
|
* @return
|
|
*/
|
|
public int getMatrixX() {
|
|
return matrixX;
|
|
}
|
|
|
|
/**
|
|
* Get matrix height
|
|
*
|
|
* @return
|
|
*/
|
|
public int getMatrixY() {
|
|
return matrixY;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return EasyStrings.translate("convolution." + identifier);
|
|
}
|
|
|
|
/**
|
|
* Creates new CONVOLUTIONFILTER with the preset values
|
|
*
|
|
* @return The filter
|
|
*/
|
|
public CONVOLUTIONFILTER createFilter() {
|
|
CONVOLUTIONFILTER filter = new CONVOLUTIONFILTER();
|
|
filter.matrixX = matrixX;
|
|
filter.matrixY = matrixY;
|
|
filter.matrix = matrix.clone();
|
|
filter.divisor = divisor;
|
|
return filter;
|
|
}
|
|
|
|
/**
|
|
* Returns all built-in presets
|
|
*
|
|
* @return List of presets
|
|
*/
|
|
public static List<ConvolutionPreset> getAllPresets() {
|
|
List<ConvolutionPreset> ret = new ArrayList<>();
|
|
for (Field field : ConvolutionPreset.class.getFields()) {
|
|
if (field.getType() == ConvolutionPreset.class) {
|
|
try {
|
|
ret.add((ConvolutionPreset) field.get(ConvolutionPreset.class));
|
|
} catch (IllegalArgumentException | IllegalAccessException ex) {
|
|
//ignore
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public boolean matchesFilter(CONVOLUTIONFILTER other) {
|
|
int maxX = Math.max(other.matrixX, matrixX);
|
|
int maxY = Math.max(other.matrixY, matrixY);
|
|
|
|
int halfMaxX = (maxX - 1) / 2;
|
|
int halfMaxY = (maxY - 1) / 2;
|
|
|
|
int halfX = (matrixX - 1) / 2;
|
|
int halfY = (matrixY - 1) / 2;
|
|
|
|
int halfOtherX = (other.matrixX - 1) / 2;
|
|
int halfOtherY = (other.matrixY - 1) / 2;
|
|
|
|
int halfMax = Math.max(halfMaxX, halfMaxY);
|
|
|
|
for (int i = 0; i <= halfMax; i++) {
|
|
for (int x = -i; x <= i; x++) {
|
|
if (!compare(other, halfX + x, halfY - i, halfOtherX + x, halfOtherY - i)) {
|
|
return false;
|
|
}
|
|
if (!compare(other, halfX + x, halfY + i, halfOtherX + x, halfOtherY + i)) {
|
|
return false;
|
|
}
|
|
}
|
|
for (int y = -i; y <= i; y++) {
|
|
if (!compare(other, halfX - i, halfY + y, halfOtherX - i, halfOtherY + y)) {
|
|
return false;
|
|
}
|
|
if (!compare(other, halfX + i, halfY + y, halfOtherX + i, halfOtherY + y)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean compare(CONVOLUTIONFILTER other, int x1, int y1, int x2, int y2) {
|
|
int thisIndex = y1 * matrixX + x1;
|
|
int otherIndex = y2 * other.matrixX + x2;
|
|
|
|
float val = x1 < 0 || x1 >= matrixX || y1 < 0 || y1 >= matrixY ? 0f : matrix[thisIndex] / divisor;
|
|
float otherVal = x2 < 0 || x2 >= other.matrixX || y2 < 0 || y2 >= other.matrixY ? 0f : other.matrix[otherIndex] / other.divisor;
|
|
|
|
return val == otherVal;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
ConvolutionPreset p1 = new ConvolutionPreset("x1", 3, 3, new float[]{
|
|
1, 2, 3,
|
|
4, 5, 6,
|
|
7, 8, 9
|
|
});
|
|
|
|
CONVOLUTIONFILTER f1 = new CONVOLUTIONFILTER();
|
|
f1.matrixX = 5;
|
|
f1.matrixY = 5;
|
|
f1.matrix = new float[]{
|
|
0, 0, 0, 0, 0,
|
|
0, 1, 2, 3, 0,
|
|
0, 4, 5, 6, 0,
|
|
0, 7, 8, 9, 0,
|
|
0, 0, 0, 0, 0
|
|
};
|
|
|
|
assertMatch(p1, f1);
|
|
|
|
CONVOLUTIONFILTER f2 = new CONVOLUTIONFILTER();
|
|
f2.matrixX = 5;
|
|
f2.matrixY = 3;
|
|
f2.matrix = new float[]{
|
|
0, 1, 2, 3, 0,
|
|
0, 4, 5, 6, 0,
|
|
0, 7, 8, 9, 0
|
|
};
|
|
|
|
assertMatch(p1, f2);
|
|
|
|
ConvolutionPreset p2 = new ConvolutionPreset("x1", 3, 3, new float[]{
|
|
1, 2, 3,
|
|
4, 5, 6,
|
|
7, 8, 9
|
|
}, 5);
|
|
|
|
CONVOLUTIONFILTER f3 = new CONVOLUTIONFILTER();
|
|
f3.matrixX = 3;
|
|
f3.matrixY = 3;
|
|
f3.matrix = new float[]{
|
|
1 / 5f, 2 / 5f, 3 / 5f,
|
|
4 / 5f, 5 / 5f, 6 / 5f,
|
|
7 / 5f, 8 / 5f, 9 / 5f
|
|
};
|
|
|
|
assertMatch(p2, f3);
|
|
}
|
|
|
|
private static void assertMatch(ConvolutionPreset preset, CONVOLUTIONFILTER filter) {
|
|
if (!preset.matchesFilter(filter)) {
|
|
throw new RuntimeException("Preset and filter do not match!");
|
|
}
|
|
}
|
|
|
|
public static ConvolutionPreset getPresetOfFilter(CONVOLUTIONFILTER filter) {
|
|
for (ConvolutionPreset preset : getAllPresets()) {
|
|
if (preset.matchesFilter(filter)) {
|
|
return preset;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|