mirror of https://github.com/adamdruppe/arsd.git
Templatize bilinear up/down scaler
This commit is contained in:
parent
7f91abfc0a
commit
31308e0777
|
@ -3019,13 +3019,7 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
|
||||
// ==== Bilinear ====
|
||||
static if ((filter == ScalingFilter.bilinear) || (filter == ScalingFilter.fauxLinear)) {
|
||||
const Size delta = (target.size - source.size);
|
||||
|
||||
const ScalingDirection[2] directions = [
|
||||
scalingDirectionFromDelta(delta.width),
|
||||
scalingDirectionFromDelta(delta.height),
|
||||
];
|
||||
|
||||
void scaleToLinearImpl(ScalingDirection directionX, ScalingDirection directionY)() {
|
||||
auto dst = PixmapScannerRW(target);
|
||||
|
||||
size_t y = 0;
|
||||
|
@ -3040,17 +3034,17 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
|
||||
const int[2] posSrcX = () {
|
||||
int[2] result;
|
||||
if (directions[idxX] == none) {
|
||||
static if (directionX == none) {
|
||||
result = [
|
||||
posSrc[idxX].castTo!int,
|
||||
posSrc[idxX].castTo!int,
|
||||
];
|
||||
} else if (directions[idxX] == up) {
|
||||
} else static if (directionX == up) {
|
||||
result = [
|
||||
min(sourceMaxX, posSrc[idxX].floor().castTo!int),
|
||||
min(sourceMaxX, posSrc[idxX].ceil().castTo!int),
|
||||
];
|
||||
} else /* if (directions[0] == down) */ {
|
||||
} else /* if (directionX == down) */ {
|
||||
const ratioXHalf = (ratios[idxX] >> 1);
|
||||
result = [
|
||||
max((posSrc[idxX] - ratioXHalf).roundEven().castTo!int, 0),
|
||||
|
@ -3062,17 +3056,17 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
|
||||
const int[2] posSrcY = () {
|
||||
int[2] result;
|
||||
if (directions[idxY] == none) {
|
||||
static if (directionY == none) {
|
||||
result = [
|
||||
posSrc[idxY].castTo!int,
|
||||
posSrc[idxY].castTo!int,
|
||||
];
|
||||
} else if (directions[idxY] == up) {
|
||||
} else static if (directionY == up) {
|
||||
result = [
|
||||
min(sourceMaxY, posSrc[idxY].floor().castTo!int),
|
||||
min(sourceMaxY, posSrc[idxY].ceil().castTo!int),
|
||||
];
|
||||
} else /* if (directions[idxY] == down) */ {
|
||||
} else /* if (directionY == down) */ {
|
||||
const ratioHalf = (ratios[idxY] >> 1);
|
||||
result = [
|
||||
max((posSrc[idxY] - ratioHalf).roundEven().castTo!int, 0),
|
||||
|
@ -3121,9 +3115,9 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
ulong sampleX() {
|
||||
pragma(inline, true);
|
||||
|
||||
if (directions[0] == none) {
|
||||
static if (directionX == none) {
|
||||
return (() @trusted => pxNeighs[idxTL].components.ptr[ib])();
|
||||
} else if (directions[0] == down) {
|
||||
} else static if (directionX == down) {
|
||||
const nSamples = 1 + posSrcX[idxR] - posSrcX[idxL];
|
||||
const posSampling = Point(posSrcX[idxL], posSrcY[idxT]);
|
||||
const samplingOffset = source.scanTo(posSampling);
|
||||
|
@ -3138,7 +3132,7 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
}
|
||||
|
||||
return (xSum / nSamples);
|
||||
} else /* if (directions[0] == up) */ {
|
||||
} else /* if (directionX == up) */ {
|
||||
ulong xSum = 0;
|
||||
|
||||
const ulong[2] weightsX = () {
|
||||
|
@ -3160,7 +3154,7 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
ulong[2] sampleXDual() {
|
||||
pragma(inline, true);
|
||||
|
||||
if (directions[0] == none) {
|
||||
static if (directionX == none) {
|
||||
return () @trusted {
|
||||
ulong[2] result = [
|
||||
pxNeighs[idxTL].components.ptr[ib],
|
||||
|
@ -3168,7 +3162,7 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
];
|
||||
return result;
|
||||
}();
|
||||
} else if (directions[0] == down) {
|
||||
} else static if (directionX == down) {
|
||||
const nSamples = 1 + posSrcX[idxR] - posSrcX[idxL];
|
||||
const Point[2] posSampling = [
|
||||
Point(posSrcX[idxL], posSrcY[idxT]),
|
||||
|
@ -3198,7 +3192,7 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
|
||||
xSums[] /= nSamples;
|
||||
return xSums;
|
||||
} else /* if (directions[0] == up) */ {
|
||||
} else /* if (directionX == up) */ {
|
||||
ulong[2] xSums = [0, 0];
|
||||
|
||||
const ulong[2] weightsX = () {
|
||||
|
@ -3240,12 +3234,12 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
return linesSum;
|
||||
}
|
||||
|
||||
if (directions[0] == none) {
|
||||
static if (directionX == none) {
|
||||
ySum = foreachLine(delegate(const Point posLine) {
|
||||
const pxSrc = source.getPixel(posLine);
|
||||
return ulong((() @trusted => pxSrc.components.ptr[ib])());
|
||||
});
|
||||
} else if (directions[0] == down) {
|
||||
} else static if (directionX == down) {
|
||||
const nSamples = 1 + posSrcX[idxR] - posSrcX[idxL];
|
||||
|
||||
ySum = foreachLine(delegate(const Point posLine) {
|
||||
|
@ -3264,7 +3258,7 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
});
|
||||
|
||||
ySum /= nSamples;
|
||||
} else /* if (directions[0] == up) */ {
|
||||
} else /* if (directionX == up) */ {
|
||||
const nSamples = 1 + posSrcX[idxR] - posSrcX[idxL];
|
||||
|
||||
ySum = foreachLine(delegate(const Point posLine) {
|
||||
|
@ -3296,11 +3290,11 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
return (ySum / nLines);
|
||||
}
|
||||
|
||||
if (directions[idxY] == none) {
|
||||
static if (directionY == none) {
|
||||
c = clamp255(sampleX());
|
||||
} else if (directions[idxY] == down) {
|
||||
} else static if (directionY == down) {
|
||||
c = clamp255(sampleXMulti());
|
||||
} else /* if (directions[idxY] == up) */ {
|
||||
} else /* if (directionY == up) */ {
|
||||
// looks ass
|
||||
const ulong[2] weightsY = () {
|
||||
ulong[2] result;
|
||||
|
@ -3328,6 +3322,43 @@ private void scaleToImpl(ScalingFilter filter)(const Pixmap source, Pixmap targe
|
|||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
const Size delta = (target.size - source.size);
|
||||
|
||||
const ScalingDirection[2] directions = [
|
||||
scalingDirectionFromDelta(delta.width),
|
||||
scalingDirectionFromDelta(delta.height),
|
||||
];
|
||||
|
||||
if (directions[0] == none) {
|
||||
if (directions[1] == none) {
|
||||
version (none)
|
||||
scaleToLinearImpl!(none, none)();
|
||||
else
|
||||
return;
|
||||
} else if (directions[1] == up) {
|
||||
scaleToLinearImpl!(none, up)();
|
||||
} else /* if (directions[1] == down) */ {
|
||||
scaleToLinearImpl!(none, down)();
|
||||
}
|
||||
} else if (directions[0] == up) {
|
||||
if (directions[1] == none) {
|
||||
scaleToLinearImpl!(up, none)();
|
||||
} else if (directions[1] == up) {
|
||||
scaleToLinearImpl!(up, up)();
|
||||
} else /* if (directions[1] == down) */ {
|
||||
scaleToLinearImpl!(up, down)();
|
||||
}
|
||||
} else /* if (directions[0] == down) */ {
|
||||
if (directions[1] == none) {
|
||||
scaleToLinearImpl!(down, none)();
|
||||
} else if (directions[1] == up) {
|
||||
scaleToLinearImpl!(down, up)();
|
||||
} else /* if (directions[1] == down) */ {
|
||||
scaleToLinearImpl!(down, down)();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Document this function
|
||||
|
|
Loading…
Reference in New Issue