44 const short imaprepeat,
45 const short imapextend);
72 col[0] = float(rect[0]) * (1.0f / 255.0f);
73 col[1] = float(rect[1]) * (1.0f / 255.0f);
74 col[2] = float(rect[2]) * (1.0f / 255.0f);
75 col[3] = float(rect[3]) * (1.0f / 255.0f);
86 const float texvec[3],
89 const bool skip_load_image)
100 if (ima ==
nullptr) {
113 local_iuser = tex->
iuser;
114 iuser = &local_iuser;
170 fx = (fx - 0.5f) / (1.0f - tex->
checkerdist) + 0.5f;
171 fy = (fy - 0.5f) / (1.0f - tex->
checkerdist) + 0.5f;
179 if (
x < 0 ||
y < 0 || x >= ibuf->
x ||
y >= ibuf->
y || texvec[2] < -1.0f || texvec[2] > 1.0f) {
236 float filterx, filtery;
243 fx -= float(xi -
x) / float(ibuf->
x);
244 fy -= float(yi -
y) / float(ibuf->
y);
266 texres->
trgba[3] = texres->
tin = 1.0;
276 fx = 1.0f / texres->
trgba[3];
277 texres->
trgba[0] *= fx;
278 texres->
trgba[1] *= fx;
279 texres->
trgba[2] *= fx;
301 rf->
xmin += (x2 - x1);
302 rf->
xmax += (x2 - x1);
306 newrct = stack + *
count;
310 newrct->
xmin = rf->
xmin + (x2 - x1);
321 else if (rf->
xmax > x2) {
323 rf->
xmin -= (x2 - x1);
324 rf->
xmax -= (x2 - x1);
328 newrct = stack + *
count;
332 newrct->
xmax = rf->
xmax - (x2 - x1);
357 rf->
ymin += (y2 - y1);
358 rf->
ymax += (y2 - y1);
362 newrct = stack + *
count;
366 newrct->
ymin = rf->
ymin + (y2 - y1);
377 else if (rf->
ymax > y2) {
379 rf->
ymin -= (y2 - y1);
380 rf->
ymax -= (y2 - y1);
384 newrct = stack + *
count;
388 newrct->
ymax = rf->
ymax - (y2 - y1);
454 float muly, mulx, div,
col[4];
455 int x,
y, startx, endx, starty, endy;
462 startx = std::max(startx, 0);
463 starty = std::max(starty, 0);
464 if (endx >= ibuf->
x) {
467 if (endy >= ibuf->
y) {
471 if (starty == endy && startx == endx) {
476 for (
y = starty;
y <= endy;
y++) {
480 if (starty == endy) {
485 muly = 1.0f - (rf->
ymin -
y);
488 muly = (rf->
ymax -
y);
492 if (startx == endx) {
500 for (
x = startx;
x <= endx;
x++) {
503 mulx *= 1.0f - (rf->
xmin -
x);
506 mulx *= (rf->
xmax -
x);
540 const short imaprepeat,
541 const short imapextend)
555 float opp, tot, alphaclip = 1.0;
559 rf->
xmin = minx * (ibuf->
x);
560 rf->
xmax = maxx * (ibuf->
x);
561 rf->
ymin = miny * (ibuf->
y);
562 rf->
ymax = maxy * (ibuf->
y);
570 else if (imaprepeat) {
576 if (alphaclip <= 0.0f) {
586 else if (imaprepeat) {
592 if (alphaclip <= 0.0f) {
615 texres->
trgba[0] /= tot;
616 texres->
trgba[1] /= tot;
617 texres->
trgba[2] /= tot;
619 texres->
trgba[3] /= tot;
627 if (texres->
talpha == 0) {
628 texres->
trgba[3] = 1.0;
631 if (alphaclip != 1.0f) {
633 texres->
trgba[0] *= alphaclip;
634 texres->
trgba[1] *= alphaclip;
635 texres->
trgba[2] *= alphaclip;
636 texres->
trgba[3] *= alphaclip;
666 x +=
x < 0 ? 2 * ibuf->
x : 0;
667 x =
x >= ibuf->
x ? 2 * ibuf->
x -
x - 1 :
x;
669 y +=
y < 0 ? ibuf->
y : 0;
673 x +=
x < 0 ? ibuf->
x : 0;
675 y +=
y < 0 ? 2 * ibuf->
y : 0;
676 y =
y >= ibuf->
y ? 2 * ibuf->
y -
y - 1 :
y;
679 x = (
x < 0) ? 0 : ((
x >= ibuf->
x) ? (ibuf->
x - 1) :
x);
680 y = (
y < 0) ? 0 : ((
y >= ibuf->
y) ? (ibuf->
y - 1) :
y);
684 x += (
x < 0) ? ibuf->
x : 0;
686 y += (
y < 0) ? ibuf->
y : 0;
709 col[3] = clip ? 0.0f : (ibuf->
channels == 4 ? fp[3] : 1.0f);
714 float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
715 col[0] = rect[0] * inv_alpha_fac;
716 col[1] = rect[1] * inv_alpha_fac;
717 col[2] = rect[2] * inv_alpha_fac;
718 col[3] = clip ? 0.0f : rect[3] * (1.0f / 255.0f);
725 float col[4],
ImBuf *ibuf,
float u,
float v,
int intpol,
int extflag)
728 float c00[4], c01[4], c10[4], c11[4];
729 const float ufl =
floorf(u -= 0.5f), vfl =
floorf(
v -= 0.5f);
730 const float uf = u - ufl, vf =
v - vfl;
731 const float w00 = (1.0f - uf) * (1.0f - vf), w10 = uf * (1.0f - vf), w01 = (1.0f - uf) * vf,
733 const int x1 = int(ufl), y1 = int(vfl), x2 = x1 + 1, y2 = y1 + 1;
738 col[0] = w00 * c00[0] + w10 * c10[0] + w01 * c01[0] + w11 * c11[0];
739 col[1] = w00 * c00[1] + w10 * c10[1] + w01 * c01[1] + w11 * c11[1];
740 col[2] = w00 * c00[2] + w10 * c10[2] + w01 * c01[2] + w11 * c11[2];
741 col[3] = clip ? 0.0f : w00 * c00[3] + w10 * c10[3] + w01 * c01[3] + w11 * c11[3];
749 int xs, ys, clip = 0;
750 float tc[4], xsd, ysd, cw = 0.0f;
751 const float ux = ibuf->
x * AFD->
dxt[0], uy = ibuf->
y * AFD->
dxt[1];
752 const float vx = ibuf->
x * AFD->
dyt[0], vy = ibuf->
y * AFD->
dyt[1];
753 int xsam = int(0.5f *
sqrtf(ux * ux + uy * uy) + 0.5f);
754 int ysam = int(0.5f *
sqrtf(vx * vx + vy * vy) + 0.5f);
755 const int minsam = AFD->
intpol ? 2 : 4;
756 xsam = std::clamp(xsam, minsam, ibuf->
x * 2);
757 ysam = std::clamp(ysam, minsam, ibuf->
y * 2);
761 for (ys = 0; ys < ysam; ys++) {
762 for (xs = 0; xs < xsam; xs++) {
763 const float su = (xs + ((ys & 1) + 0.5f) * 0.5f) * xsd - 0.5f;
764 const float sv = (ys + ((xs & 1) + 0.5f) * 0.5f) * ysd - 0.5f;
765 const float pu = fx + su * AFD->
dxt[0] + sv * AFD->
dyt[0];
766 const float pv = fy + su * AFD->
dxt[1] + sv * AFD->
dyt[1];
770 cw +=
out ? 0.0f : 1.0f;
771 texr->
trgba[0] += tc[0];
772 texr->
trgba[1] += tc[1];
773 texr->
trgba[2] += tc[2];
778 texr->
trgba[0] *= xsd;
779 texr->
trgba[1] *= xsd;
780 texr->
trgba[2] *= xsd;
782 texr->
trgba[3] = texr->
talpha ? texr->
trgba[3] * xsd : (clip ? cw * xsd : 1.0f);
799 const float uv[2] = {fx, fy};
816 const int maxn = AFD->
iProbes - 1;
819 (maxn ?
float(maxn) : 1.0f);
820 float du = maxn ?
cosf(AFD->
theta) * ll : 0.0f;
821 float dv = maxn ?
sinf(AFD->
theta) * ll : 0.0f;
830 for (n = -maxn; n <= maxn; n += 2) {
832 const float hn = n * 0.5f;
833 const float u = fx + hn * du,
v = fy + hn * dv;
836 const float wt =
expf(n * n *
D);
838 const float wt =
EWA_WTS[int(n * n *
D)];
844 texr->
trgba[0] += tc[0] * wt;
845 texr->
trgba[1] += tc[1] * wt;
846 texr->
trgba[2] += tc[2] * wt;
847 texr->
trgba[3] += texr->
talpha ? tc[3] * wt : 0.0f;
876 rf.
xmin = minx * (ibuf->
x);
877 rf.
xmax = maxx * (ibuf->
x);
878 rf.
ymin = miny * (ibuf->
y);
879 rf.
ymax = maxy * (ibuf->
y);
883 alphaclip =
max_ff(alphaclip, 0.0f);
885 if (alphaclip != 1.0f) {
887 texres->
trgba[0] *= alphaclip;
888 texres->
trgba[1] *= alphaclip;
889 texres->
trgba[2] *= alphaclip;
890 texres->
trgba[3] *= alphaclip;
906 if (ibuf->
mipmap[0] ==
nullptr) {
908 if (ibuf->
mipmap[0] ==
nullptr) {
914 if (ibuf->
mipmap[0] ==
nullptr) {
923 const float texvec[3],
928 const bool skip_load_image)
931 float fx, fy, minx, maxx, miny, maxy;
933 int curmap, retval, intpol, extflag = 0;
954 if (ibuf ==
nullptr && ima ==
nullptr) {
965 if ((ibuf ==
nullptr) ||
1000 minx =
min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1001 maxx =
max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1002 miny =
min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1003 maxy =
max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1006 minx = (maxx - minx) * 0.5f;
1007 miny = (maxy - miny) * 0.5f;
1012 const float addval = (0.5f * tex->
filtersize) /
float(std::min(ibuf->
x, ibuf->
y));
1013 minx = std::max(addval, minx);
1014 miny = std::max(addval, miny);
1027 std::swap(minx, miny);
1041 minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1042 miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1078 int xs1 = int(
floorf(fx - minx));
1079 int ys1 = int(
floorf(fy - miny));
1080 int xs2 = int(
floorf(fx + minx));
1081 int ys2 = int(
floorf(fy + miny));
1082 if ((xs1 != xs2) || (ys1 != ys2)) {
1084 fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1085 fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1088 fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1089 fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1111 const float omcd = 1.0f / (1.0f - tex->
checkerdist);
1112 fx = (fx - 0.5f) * omcd + 0.5f;
1113 fy = (fy - 0.5f) * omcd + 0.5f;
1120 if ((fx + minx) < 0.0f || (fy + miny) < 0.0f || (fx - minx) > 1.0f || (fy - miny) > 1.0f ||
1121 texvec[2] < -1.0f || texvec[2] > 1.0f)
1130 if ((fx + minx) < 0.0f || (fy + miny) < 0.0f || (fx - minx) > 1.0f || (fy - miny) > 1.0f) {
1139 fx = (fx > 1.0f) ? 1.0f : ((fx < 0.0f) ? 0.0f : fx);
1140 fy = (fy > 1.0f) ? 1.0f : ((fy < 0.0f) ? 0.0f : fy);
1159 if (AFD.
dxt[0] * AFD.
dxt[0] + AFD.
dxt[1] * AFD.
dxt[1] > 2.0f * 2.0f) {
1162 if (AFD.
dyt[0] * AFD.
dyt[0] + AFD.
dyt[1] * AFD.
dyt[1] > 2.0f * 2.0f) {
1168 ImBuf *previbuf, *curibuf;
1176 const float ff =
sqrtf(ibuf->
x), q = ibuf->
y / ff;
1177 const float Ux = dxt[0] * ff, Vx = dxt[1] * q, Uy = dyt[0] * ff, Vy = dyt[1] * q;
1178 const float A = Vx * Vx + Vy * Vy;
1179 const float B = -2.0f * (Ux * Vx + Uy * Vy);
1180 const float C = Ux * Ux + Uy * Uy;
1181 const float F =
A *
C -
B *
B * 0.25f;
1182 float a,
b, th, ecc;
1190 fProbes = 2.0f * (a /
b) - 1.0f;
1194 b = 2.0f * a / float(AFD.
iProbes + 1);
1199 AFD.
dusc = 1.0f / ff;
1200 AFD.
dvsc = ff / float(ibuf->
y);
1203 if (ecc >
float(tex->
afmax)) {
1204 b = a / float(tex->
afmax);
1215 mipmaps[curmap + 1] = ibuf->
mipmap[curmap];
1216 if (ibuf->
mipmap[curmap]) {
1224 previbuf = curibuf = mipmaps[0];
1227 else if (levf >= maxlev - 1) {
1228 previbuf = curibuf = mipmaps[maxlev - 1];
1235 const int lev =
isnan(levf) ? 0 : int(levf);
1236 curibuf = mipmaps[lev];
1237 previbuf = mipmaps[lev + 1];
1242 filterfunc(texres, curibuf, fx, fy, &AFD);
1243 if (previbuf != curibuf) {
1244 filterfunc(&texr, previbuf, fx, fy, &AFD);
1252 alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
1258 const float ff =
sqrtf(ibuf->
x), q = ibuf->
y / ff;
1259 const float Ux = dxt[0] * ff, Vx = dxt[1] * q, Uy = dyt[0] * ff, Vy = dyt[1] * q;
1260 const float A = Vx * Vx + Vy * Vy;
1261 const float B = -2.0f * (Ux * Vx + Uy * Vy);
1262 const float C = Ux * Ux + Uy * Uy;
1263 const float F =
A *
C -
B *
B * 0.25f;
1264 float a,
b, th, ecc, fProbes;
1270 fProbes = 2.0f * (a /
b) - 1.0f;
1274 b = 2.0f * a / float(AFD.
iProbes + 1);
1279 AFD.
dusc = 1.0f / ff;
1280 AFD.
dvsc = ff / float(ibuf->
y);
1282 filterfunc(texres, ibuf, fx, fy, &AFD);
1284 alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
1308 fx = 1.0f / texres->
trgba[3];
1309 texres->
trgba[0] *= fx;
1310 texres->
trgba[1] *= fx;
1311 texres->
trgba[2] *= fx;
1326 const float texvec[3],
1331 const bool skip_load_image)
1334 float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
1335 float maxd, pixsize;
1336 int curmap, retval, imaprepeat, imapextend;
1345 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool, skip_load_image);
1353 if (ibuf ==
nullptr && ima ==
nullptr) {
1399 minx =
min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1400 maxx =
max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1401 miny =
min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1402 maxy =
max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1405 minx = (maxx - minx) / 2.0f;
1406 miny = (maxy - miny) / 2.0f;
1411 float addval = (0.5f * tex->
filtersize) /
float(std::min(ibuf->
x, ibuf->
y));
1413 minx = std::max(addval, minx);
1414 miny = std::max(addval, miny);
1427 std::swap(minx, miny);
1433 else if (minx < 0.00001f) {
1439 else if (miny < 0.00001f) {
1455 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1457 xs = int(
floor(fx));
1458 ys = int(
floor(fy));
1473 xs1 = int(
floor(fx - minx));
1474 ys1 = int(
floor(fy - miny));
1475 xs2 = int(
floor(fx + minx));
1476 ys2 = int(
floor(fy + miny));
1477 boundary = (xs1 != xs2) || (ys1 != ys2);
1479 if (boundary == 0) {
1481 if ((xs + ys) & 1) {
1492 if ((xs + ys) & 1) {
1504 if ((xs1 + ys) & 1) {
1511 if ((ys1 + xs) & 1) {
1519 if ((xs1 + ys) & 1) {
1526 if ((ys1 + xs) & 1) {
1538 fx = (fx - 0.5f) / (1.0f - tex->
checkerdist) + 0.5f;
1539 fy = (fy - 0.5f) / (1.0f - tex->
checkerdist) + 0.5f;
1546 if (fx + minx < 0.0f || fy + miny < 0.0f || fx - minx > 1.0f || fy - miny > 1.0f ||
1547 texvec[2] < -1.0f || texvec[2] > 1.0f)
1556 if (fx + minx < 0.0f || fy + miny < 0.0f || fx - minx > 1.0f || fy - miny > 1.0f) {
1568 else if (fx < 0.0f) {
1576 else if (fx < 0.0f) {
1585 else if (fy < 0.0f) {
1593 else if (fy < 0.0f) {
1601 ImBuf *previbuf, *curibuf;
1606 maxd = std::min(maxd, 0.5f);
1608 pixsize = 1.0f / float(std::min(ibuf->
x, ibuf->
y));
1611 previbuf = curibuf = ibuf;
1612 while (curmap < IMB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1613 if (maxd < pixsize) {
1617 curibuf = ibuf->
mipmap[curmap];
1618 pixsize = 1.0f / float(std::min(curibuf->
x, curibuf->
y));
1624 minx = std::max(minx, 0.5f / ibuf->
x);
1625 miny = std::max(miny, 0.5f / ibuf->
y);
1633 boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1635 if (previbuf != curibuf) {
1636 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1638 fx = 2.0f * (pixsize - maxd) / pixsize;
1659 minx = std::max(minx, 0.5f / ibuf->
x);
1660 miny = std::max(miny, 0.5f / ibuf->
y);
1663 boxsample(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, texres, imaprepeat, imapextend);
1705 boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
1728 ewa_eval(&texres, ibuf, fx, fy, &AFD);
int BKE_image_get_tile_from_pos(Image *ima, const float uv[2], float r_uv[2], float r_ofs[2])
ImBuf * BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool)
void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool)
bool BKE_image_has_loaded_ibuf(Image *image)
MINLINE float max_fff(float a, float b, float c)
MINLINE int round_fl_to_int(float a)
MINLINE float max_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
const float EWA_WTS[EWA_MAXIDX+1]
void BLI_ewa_filter(int width, int height, bool intpol, bool use_alpha, const float uv[2], const float du[2], const float dv[2], ewa_filter_read_pixel_cb read_pixel_cb, void *userdata, float result[4])
void BLI_ewa_imp2radangle(float A, float B, float C, float F, float *a, float *b, float *th, float *ecc)
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v4(float r[4])
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
void BLI_thread_unlock(int type)
void BLI_thread_lock(int type)
void IMB_makemipmap(ImBuf *ibuf, int use_filter)
void IMB_remakemipmap(ImBuf *ibuf, int use_filter)
#define IMB_MIPMAP_LEVELS
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
ImBuf * mipmap[IMB_MIPMAP_LEVELS]
void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4], ImagePool *pool)
void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres, ImagePool *pool, const bool skip_load_image)
static void feline_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, const afdata_t *AFD)
static float clipy_rctf(rctf *rf, float y1, float y2)
static float square_rctf(const rctf *rf)
int imagewrap(Tex *tex, Image *ima, const float texvec[3], TexResult *texres, ImagePool *pool, const bool skip_load_image)
static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend)
static int ibuf_get_color_clip_bilerp(float col[4], ImBuf *ibuf, float u, float v, int intpol, int extflag)
static float clipx_rctf(rctf *rf, float x1, float x2)
static void boxsampleclip(ImBuf *ibuf, const rctf *rf, TexResult *texres)
static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, const afdata_t *AFD)
static void ibuf_get_color(float col[4], ImBuf *ibuf, int x, int y)
int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], TexResult *texres, ImagePool *pool, const bool skip_load_image)
static void ewa_read_pixel_cb(void *userdata, int x, int y, float result[4])
static void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2)
static void ewa_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, const afdata_t *AFD)
static void alpha_clip_aniso(const ImBuf *ibuf, float minx, float miny, float maxx, float maxy, int extflag, TexResult *texres)
static void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2)
static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extflag)