45 const short imaprepeat,
46 const short imapextend);
53 int ofs = y * ibuf->
x +
x;
73 col[0] =
float(rect[0]) * (1.0f / 255.0f);
74 col[1] =
float(rect[1]) * (1.0f / 255.0f);
75 col[2] =
float(rect[2]) * (1.0f / 255.0f);
76 col[3] =
float(rect[3]) * (1.0f / 255.0f);
87 const float texvec[3],
90 const bool skip_load_image)
101 if (ima ==
nullptr) {
115 iuser = &local_iuser;
180 if (x < 0 ||
y < 0 || x >= ibuf->
x || y >= ibuf->
y || texvec[2] < -1.0f || texvec[2] > 1.0f) {
237 float filterx, filtery;
267 texres->
trgba[3] = texres->
tin = 1.0;
277 fx = 1.0f / texres->
trgba[3];
278 texres->
trgba[0] *= fx;
279 texres->
trgba[1] *= fx;
280 texres->
trgba[2] *= fx;
302 rf->
xmin += (x2 - x1);
303 rf->
xmax += (x2 - x1);
309 newrct = stack + *
count;
313 newrct->
xmin = rf->
xmin + (x2 - x1);
324 else if (rf->
xmax > x2) {
326 rf->
xmin -= (x2 - x1);
327 rf->
xmax -= (x2 - x1);
333 newrct = stack + *
count;
337 newrct->
xmax = rf->
xmax - (x2 - x1);
362 rf->
ymin += (y2 - y1);
363 rf->
ymax += (y2 - y1);
369 newrct = stack + *
count;
373 newrct->
ymin = rf->
ymin + (y2 - y1);
384 else if (rf->
ymax > y2) {
386 rf->
ymin -= (y2 - y1);
387 rf->
ymax -= (y2 - y1);
393 newrct = stack + *
count;
397 newrct->
ymax = rf->
ymax - (y2 - y1);
471 float muly, mulx, div,
col[4];
472 int x,
y, startx, endx, starty, endy;
485 if (endx >= ibuf->
x) {
488 if (endy >= ibuf->
y) {
492 if (starty == endy && startx == endx) {
497 for (y = starty; y <= endy; y++) {
501 if (starty == endy) {
506 muly = 1.0f - (rf->
ymin -
y);
509 muly = (rf->
ymax -
y);
513 if (startx == endx) {
521 for (x = startx; x <= endx; x++) {
524 mulx *= 1.0f - (rf->
xmin -
x);
527 mulx *= (rf->
xmax -
x);
561 const short imaprepeat,
562 const short imapextend)
576 float opp, tot, alphaclip = 1.0;
580 rf->
xmin = minx * (ibuf->
x);
581 rf->
xmax = maxx * (ibuf->
x);
582 rf->
ymin = miny * (ibuf->
y);
583 rf->
ymax = maxy * (ibuf->
y);
591 else if (imaprepeat) {
597 if (alphaclip <= 0.0f) {
607 else if (imaprepeat) {
613 if (alphaclip <= 0.0f) {
636 texres->
trgba[0] /= tot;
637 texres->
trgba[1] /= tot;
638 texres->
trgba[2] /= tot;
640 texres->
trgba[3] /= tot;
648 if (texres->
talpha == 0) {
649 texres->
trgba[3] = 1.0;
652 if (alphaclip != 1.0f) {
654 texres->
trgba[0] *= alphaclip;
655 texres->
trgba[1] *= alphaclip;
656 texres->
trgba[2] *= alphaclip;
657 texres->
trgba[3] *= alphaclip;
687 x += x < 0 ? 2 * ibuf->
x : 0;
688 x = x >= ibuf->
x ? 2 * ibuf->
x - x - 1 :
x;
690 y += y < 0 ? ibuf->
y : 0;
694 x += x < 0 ? ibuf->
x : 0;
696 y += y < 0 ? 2 * ibuf->
y : 0;
697 y = y >= ibuf->
y ? 2 * ibuf->
y - y - 1 :
y;
700 x = (x < 0) ? 0 : ((x >= ibuf->
x) ? (ibuf->
x - 1) :
x);
701 y = (y < 0) ? 0 : ((y >= ibuf->
y) ? (ibuf->
y - 1) :
y);
705 x += (x < 0) ? ibuf->
x : 0;
707 y += (y < 0) ? ibuf->
y : 0;
734 col[3] = clip ? 0.0f : (ibuf->
channels == 4 ? fp[3] : 1.0f);
739 float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
740 col[0] = rect[0] * inv_alpha_fac;
741 col[1] = rect[1] * inv_alpha_fac;
742 col[2] = rect[2] * inv_alpha_fac;
743 col[3] = clip ? 0.0f : rect[3] * (1.0f / 255.0f);
750 float col[4],
ImBuf *ibuf,
float u,
float v,
int intpol,
int extflag)
753 float c00[4], c01[4], c10[4], c11[4];
754 const float ufl =
floorf(u -= 0.5f), vfl =
floorf(
v -= 0.5f);
755 const float uf = u - ufl, vf =
v - vfl;
756 const float w00 = (1.0f - uf) * (1.0f - vf), w10 = uf * (1.0f - vf), w01 = (1.0f - uf) * vf,
758 const int x1 =
int(ufl), y1 =
int(vfl), x2 = x1 + 1, y2 = y1 + 1;
763 col[0] = w00 * c00[0] + w10 * c10[0] + w01 * c01[0] + w11 * c11[0];
764 col[1] = w00 * c00[1] + w10 * c10[1] + w01 * c01[1] + w11 * c11[1];
765 col[2] = w00 * c00[2] + w10 * c10[2] + w01 * c01[2] + w11 * c11[2];
766 col[3] = clip ? 0.0f : w00 * c00[3] + w10 * c10[3] + w01 * c01[3] + w11 * c11[3];
774 int xs, ys, clip = 0;
775 float tc[4], xsd, ysd, cw = 0.0f;
776 const float ux = ibuf->
x * AFD->
dxt[0], uy = ibuf->
y * AFD->
dxt[1];
777 const float vx = ibuf->
x * AFD->
dyt[0], vy = ibuf->
y * AFD->
dyt[1];
778 int xsam =
int(0.5f *
sqrtf(ux * ux + uy * uy) + 0.5f);
779 int ysam =
int(0.5f *
sqrtf(vx * vx + vy * vy) + 0.5f);
780 const int minsam = AFD->
intpol ? 2 : 4;
781 xsam = std::clamp(xsam, minsam, ibuf->
x * 2);
782 ysam = std::clamp(ysam, minsam, ibuf->
y * 2);
786 for (ys = 0; ys < ysam; ys++) {
787 for (xs = 0; xs < xsam; xs++) {
788 const float su = (xs + ((ys & 1) + 0.5f) * 0.5f) * xsd - 0.5f;
789 const float sv = (ys + ((xs & 1) + 0.5f) * 0.5f) * ysd - 0.5f;
790 const float pu = fx + su * AFD->
dxt[0] + sv * AFD->
dyt[0];
791 const float pv = fy + su * AFD->
dxt[1] + sv * AFD->
dyt[1];
795 cw += out ? 0.0f : 1.0f;
796 texr->
trgba[0] += tc[0];
797 texr->
trgba[1] += tc[1];
798 texr->
trgba[2] += tc[2];
803 texr->
trgba[0] *= xsd;
804 texr->
trgba[1] *= xsd;
805 texr->
trgba[2] *= xsd;
807 texr->
trgba[3] = texr->
talpha ? texr->
trgba[3] * xsd : (clip ? cw * xsd : 1.0f);
824 const float uv[2] = {fx, fy};
841 const int maxn = AFD->
iProbes - 1;
844 (maxn ?
float(maxn) : 1.0f);
845 float du = maxn ?
cosf(AFD->
theta) * ll : 0.0f;
846 float dv = maxn ?
sinf(AFD->
theta) * ll : 0.0f;
855 for (n = -maxn; n <= maxn; n += 2) {
857 const float hn = n * 0.5f;
858 const float u = fx + hn * du,
v = fy + hn * dv;
861 const float wt =
expf(n * n * D);
869 texr->
trgba[0] += tc[0] * wt;
870 texr->
trgba[1] += tc[1] * wt;
871 texr->
trgba[2] += tc[2] * wt;
872 texr->
trgba[3] += texr->
talpha ? tc[3] * wt : 0.0f;
901 rf.
xmin = minx * (ibuf->
x);
902 rf.
xmax = maxx * (ibuf->
x);
903 rf.
ymin = miny * (ibuf->
y);
904 rf.
ymax = maxy * (ibuf->
y);
908 alphaclip =
max_ff(alphaclip, 0.0f);
910 if (alphaclip != 1.0f) {
912 texres->
trgba[0] *= alphaclip;
913 texres->
trgba[1] *= alphaclip;
914 texres->
trgba[2] *= alphaclip;
915 texres->
trgba[3] *= alphaclip;
931 if (ibuf->
mipmap[0] ==
nullptr) {
933 if (ibuf->
mipmap[0] ==
nullptr) {
939 if (ibuf->
mipmap[0] ==
nullptr) {
948 const float texvec[3],
953 const bool skip_load_image)
956 float fx, fy, minx, maxx, miny, maxy;
958 int curmap, retval, intpol, extflag = 0;
979 if (ibuf ==
nullptr && ima ==
nullptr) {
990 if ((ibuf ==
nullptr) ||
1025 minx =
min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1026 maxx =
max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1027 miny =
min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1028 maxy =
max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1031 minx = (maxx - minx) * 0.5f;
1032 miny = (maxy - miny) * 0.5f;
1037 const float addval = (0.5f *
tex->
filtersize) /
float(std::min(ibuf->
x, ibuf->
y));
1038 if (addval > minx) {
1041 if (addval > miny) {
1056 std::swap(minx, miny);
1070 minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1071 miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1111 if ((xs1 != xs2) || (ys1 != ys2)) {
1113 fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1114 fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1117 fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1118 fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1141 fx = (fx - 0.5f) * omcd + 0.5f;
1142 fy = (fy - 0.5f) * omcd + 0.5f;
1149 if ((fx + minx) < 0.0f || (fy + miny) < 0.0f || (fx - minx) > 1.0f || (fy - miny) > 1.0f ||
1150 texvec[2] < -1.0f || texvec[2] > 1.0f)
1159 if ((fx + minx) < 0.0f || (fy + miny) < 0.0f || (fx - minx) > 1.0f || (fy - miny) > 1.0f) {
1168 fx = (fx > 1.0f) ? 1.0f : ((fx < 0.0f) ? 0.0f : fx);
1169 fy = (fy > 1.0f) ? 1.0f : ((fy < 0.0f) ? 0.0f : fy);
1188 if (AFD.
dxt[0] * AFD.
dxt[0] + AFD.
dxt[1] * AFD.
dxt[1] > 2.0f * 2.0f) {
1191 if (AFD.
dyt[0] * AFD.
dyt[0] + AFD.
dyt[1] * AFD.
dyt[1] > 2.0f * 2.0f) {
1197 ImBuf *previbuf, *curibuf;
1205 const float ff =
sqrtf(ibuf->
x), q = ibuf->
y / ff;
1206 const float Ux = dxt[0] * ff, Vx = dxt[1] * q, Uy = dyt[0] * ff, Vy = dyt[1] * q;
1207 const float A = Vx * Vx + Vy * Vy;
1208 const float B = -2.0f * (Ux * Vx + Uy * Vy);
1209 const float C = Ux * Ux + Uy * Uy;
1210 const float F = A * C -
B *
B * 0.25f;
1211 float a,
b, th, ecc;
1219 fProbes = 2.0f * (a /
b) - 1.0f;
1228 AFD.
dusc = 1.0f / ff;
1244 mipmaps[curmap + 1] = ibuf->
mipmap[curmap];
1245 if (ibuf->
mipmap[curmap]) {
1253 previbuf = curibuf = mipmaps[0];
1256 else if (levf >= maxlev - 1) {
1257 previbuf = curibuf = mipmaps[maxlev - 1];
1264 const int lev = isnan(levf) ? 0 :
int(levf);
1265 curibuf = mipmaps[lev];
1266 previbuf = mipmaps[lev + 1];
1271 filterfunc(texres, curibuf, fx, fy, &AFD);
1272 if (previbuf != curibuf) {
1273 filterfunc(&texr, previbuf, fx, fy, &AFD);
1281 alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
1287 const float ff =
sqrtf(ibuf->
x), q = ibuf->
y / ff;
1288 const float Ux = dxt[0] * ff, Vx = dxt[1] * q, Uy = dyt[0] * ff, Vy = dyt[1] * q;
1289 const float A = Vx * Vx + Vy * Vy;
1290 const float B = -2.0f * (Ux * Vx + Uy * Vy);
1291 const float C = Ux * Ux + Uy * Uy;
1292 const float F = A * C -
B *
B * 0.25f;
1293 float a,
b, th, ecc, fProbes;
1299 fProbes = 2.0f * (a /
b) - 1.0f;
1308 AFD.
dusc = 1.0f / ff;
1311 filterfunc(texres, ibuf, fx, fy, &AFD);
1313 alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
1337 fx = 1.0f / texres->
trgba[3];
1338 texres->
trgba[0] *= fx;
1339 texres->
trgba[1] *= fx;
1340 texres->
trgba[2] *= fx;
1355 const float texvec[3],
1360 const bool skip_load_image)
1363 float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
1364 float maxd, pixsize;
1365 int curmap, retval, imaprepeat, imapextend;
1382 if (ibuf ==
nullptr && ima ==
nullptr) {
1428 minx =
min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1429 maxx =
max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1430 miny =
min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1431 maxy =
max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1434 minx = (maxx - minx) / 2.0f;
1435 miny = (maxy - miny) / 2.0f;
1440 float addval = (0.5f *
tex->
filtersize) /
float(std::min(ibuf->
x, ibuf->
y));
1442 if (addval > minx) {
1445 if (addval > miny) {
1460 std::swap(minx, miny);
1466 else if (minx < 0.00001f) {
1472 else if (miny < 0.00001f) {
1488 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1510 boundary = (xs1 != xs2) || (ys1 != ys2);
1512 if (boundary == 0) {
1514 if ((xs + ys) & 1) {
1525 if ((xs + ys) & 1) {
1537 if ((xs1 + ys) & 1) {
1544 if ((ys1 + xs) & 1) {
1552 if ((xs1 + ys) & 1) {
1559 if ((ys1 + xs) & 1) {
1579 if (fx + minx < 0.0f || fy + miny < 0.0f || fx - minx > 1.0f || fy - miny > 1.0f ||
1580 texvec[2] < -1.0f || texvec[2] > 1.0f)
1589 if (fx + minx < 0.0f || fy + miny < 0.0f || fx - minx > 1.0f || fy - miny > 1.0f) {
1601 else if (fx < 0.0f) {
1609 else if (fx < 0.0f) {
1618 else if (fy < 0.0f) {
1626 else if (fy < 0.0f) {
1634 ImBuf *previbuf, *curibuf;
1643 pixsize = 1.0f /
float(std::min(ibuf->
x, ibuf->
y));
1646 previbuf = curibuf = ibuf;
1647 while (curmap < IMB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1648 if (maxd < pixsize) {
1652 curibuf = ibuf->
mipmap[curmap];
1653 pixsize = 1.0f /
float(std::min(curibuf->
x, curibuf->
y));
1659 if (minx < 0.5f / ibuf->x) {
1660 minx = 0.5f / ibuf->
x;
1662 if (miny < 0.5f / ibuf->y) {
1663 miny = 0.5f / ibuf->
y;
1672 boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1674 if (previbuf != curibuf) {
1675 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1677 fx = 2.0f * (pixsize - maxd) / pixsize;
1698 if (minx < 0.5f / ibuf->x) {
1699 minx = 0.5f / ibuf->
x;
1701 if (miny < 0.5f / ibuf->y) {
1702 miny = 0.5f / ibuf->
y;
1706 boxsample(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, texres, imaprepeat, imapextend);
1737 Image *ima,
float fx,
float fy,
float dx,
float dy,
float result[4],
ImagePool *pool)
1748 boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
1771 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)
Contains defines and structs used throughout the imbuf module.
#define IMB_MIPMAP_LEVELS
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
ccl_device_inline float2 floor(const float2 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)