58 lines
1.6 KiB
Java
58 lines
1.6 KiB
Java
|
|
package org.jcodec.scale;
|
||
|
|
|
||
|
|
import org.jcodec.common.model.Size;
|
||
|
|
|
||
|
|
public class BicubicResampler extends BaseResampler {
|
||
|
|
private short[][] horizontalTaps;
|
||
|
|
|
||
|
|
private short[][] verticalTaps;
|
||
|
|
|
||
|
|
private static double alpha = 0.6D;
|
||
|
|
|
||
|
|
public BicubicResampler(Size from, Size to) {
|
||
|
|
super(from, to);
|
||
|
|
this.horizontalTaps = buildFilterTaps(to.getWidth(), from.getWidth());
|
||
|
|
this.verticalTaps = buildFilterTaps(to.getHeight(), from.getHeight());
|
||
|
|
}
|
||
|
|
|
||
|
|
private static short[][] buildFilterTaps(int to, int from) {
|
||
|
|
double[] taps = new double[4];
|
||
|
|
short[][] tapsOut = new short[to][4];
|
||
|
|
double ratio = (double)from / (double)to;
|
||
|
|
double toByFrom = (double)to / (double)from;
|
||
|
|
double srcPos = 0.0D;
|
||
|
|
for (int i = 0; i < to; i++) {
|
||
|
|
double fraction = srcPos - (double)(int)srcPos;
|
||
|
|
for (int t = -1; t < 3; t++) {
|
||
|
|
double d = (double)t - fraction;
|
||
|
|
if (to < from)
|
||
|
|
d *= toByFrom;
|
||
|
|
double x = Math.abs(d);
|
||
|
|
double xx = x * x;
|
||
|
|
double xxx = xx * x;
|
||
|
|
if (d >= -1.0D && d <= 1.0D) {
|
||
|
|
taps[t + 1] = (2.0D - alpha) * xxx + (-3.0D + alpha) * xx + 1.0D;
|
||
|
|
} else if (d < -2.0D || d > 2.0D) {
|
||
|
|
taps[t + 1] = 0.0D;
|
||
|
|
} else {
|
||
|
|
taps[t + 1] = -alpha * xxx + 5.0D * alpha * xx - 8.0D * alpha * x + 4.0D * alpha;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
normalizeAndGenerateFixedPrecision(taps, 7, tapsOut[i]);
|
||
|
|
srcPos += ratio;
|
||
|
|
}
|
||
|
|
return tapsOut;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected short[] getTapsX(int dstX) {
|
||
|
|
return this.horizontalTaps[dstX];
|
||
|
|
}
|
||
|
|
|
||
|
|
protected short[] getTapsY(int dstY) {
|
||
|
|
return this.verticalTaps[dstY];
|
||
|
|
}
|
||
|
|
|
||
|
|
protected int nTaps() {
|
||
|
|
return 4;
|
||
|
|
}
|
||
|
|
}
|