mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
62 lines
No EOL
1.6 KiB
C++
62 lines
No EOL
1.6 KiB
C++
#include "bicubic.h"
|
|
|
|
#if 1
|
|
|
|
static int sGetA(int a, int src, int tgt, int method)
|
|
{
|
|
if(method != DOWNSCALE_WIDE)
|
|
return a;
|
|
return max(src / tgt, 1) * a;
|
|
}
|
|
|
|
Image RescaleWithKernelE(const Image& _img, int cx, int cy, double (*kernel)(double x), int a,
|
|
int method)
|
|
{
|
|
Image img = _img;
|
|
Size isz = img.GetSize();
|
|
if(method == DOWNSCALE_MIPMAP) {
|
|
Size sz = isz / Size(cx, cy);
|
|
if(sz.cx >= a || sz.cy >= a) {
|
|
img = DownScale(img, max(sz.cx, 1), max(sz.cy, 1));
|
|
isz = img.GetSize();
|
|
}
|
|
}
|
|
ImageBuffer ib(cx, cy);
|
|
RGBA *t = ~ib;
|
|
int ax = sGetA(a, isz.cx, cx, method);
|
|
int ay = sGetA(a, isz.cy, cy, method);
|
|
double inv_cx = 1.0 / cx;
|
|
for(int y = 0; y < cy; y++) {
|
|
int sy = (y * isz.cy) / cy;
|
|
double dy = y * isz.cy / (double)cy - sy;
|
|
for(int x = 0; x < cx; x++) {
|
|
int sx = (x * isz.cx) / cx;
|
|
double dx = x * isz.cx * inv_cx - sx;
|
|
double red = 0;
|
|
double green = 0;
|
|
double blue = 0;
|
|
double alpha = 0;
|
|
double w = 0;
|
|
for(int yy = -ay + 1; yy <= ay; yy++) {
|
|
double ky = kernel((yy - dy) * a / ay);
|
|
const RGBA *l = img[minmax(sy + yy, 0, isz.cy - 1)];
|
|
for(int xx = -ax + 1; xx <= ax; xx++) {
|
|
const RGBA& s = l[minmax(sx + xx, 0, isz.cx - 1)];
|
|
double weight = ky * kernel((xx - dx) * a / ax);
|
|
red += weight * s.r;
|
|
green += weight * s.g;
|
|
blue += weight * s.b;
|
|
alpha += weight * s.a;
|
|
w += weight;
|
|
}
|
|
}
|
|
t->r = Saturate255((int)(red / w));
|
|
t->g = Saturate255((int)(green / w));
|
|
t->b = Saturate255((int)(blue / w));
|
|
t->a = Saturate255((int)(alpha / w));
|
|
t++;
|
|
}
|
|
}
|
|
return ib;
|
|
}
|
|
#endif |