53 #define OFFSET(x) offsetof(V360Context, x)
54 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
55 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
259 #define DEFINE_REMAP1_LINE(bits, div) \
260 static void remap1_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
261 ptrdiff_t in_linesize, \
262 const int16_t *const u, const int16_t *const v, \
263 const int16_t *const ker) \
265 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
266 uint##bits##_t *d = (uint##bits##_t *)dst; \
268 in_linesize /= div; \
270 for (int x = 0; x < width; x++) \
271 d[x] = s[v[x] * in_linesize + u[x]]; \
283 #define DEFINE_REMAP(ws, bits) \
284 static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
286 ThreadData *td = arg; \
287 const V360Context *s = ctx->priv; \
288 const SliceXYRemap *r = &s->slice_remap[jobnr]; \
289 const AVFrame *in = td->in; \
290 AVFrame *out = td->out; \
292 av_assert1(s->nb_planes <= AV_VIDEO_MAX_PLANES); \
294 for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \
295 for (int plane = 0; plane < s->nb_planes; plane++) { \
296 const unsigned map = s->map[plane]; \
297 const int in_linesize = in->linesize[plane]; \
298 const int out_linesize = out->linesize[plane]; \
299 const int uv_linesize = s->uv_linesize[plane]; \
300 const int in_offset_w = stereo ? s->in_offset_w[plane] : 0; \
301 const int in_offset_h = stereo ? s->in_offset_h[plane] : 0; \
302 const int out_offset_w = stereo ? s->out_offset_w[plane] : 0; \
303 const int out_offset_h = stereo ? s->out_offset_h[plane] : 0; \
304 const uint8_t *const src = in->data[plane] + \
305 in_offset_h * in_linesize + in_offset_w * (bits >> 3); \
306 uint8_t *dst = out->data[plane] + out_offset_h * out_linesize + out_offset_w * (bits >> 3); \
307 const uint8_t *mask = plane == 3 ? r->mask : NULL; \
308 const int width = s->pr_width[plane]; \
309 const int height = s->pr_height[plane]; \
311 const int slice_start = (height * jobnr ) / nb_jobs; \
312 const int slice_end = (height * (jobnr + 1)) / nb_jobs; \
314 for (int y = slice_start; y < slice_end && !mask; y++) { \
315 const int16_t *const u = r->u[map] + (y - slice_start) * uv_linesize * ws * ws; \
316 const int16_t *const v = r->v[map] + (y - slice_start) * uv_linesize * ws * ws; \
317 const int16_t *const ker = r->ker[map] + (y - slice_start) * uv_linesize * ws * ws; \
319 s->remap_line(dst + y * out_linesize, width, src, in_linesize, u, v, ker); \
322 for (int y = slice_start; y < slice_end && mask; y++) { \
323 memcpy(dst + y * out_linesize, mask + \
324 (y - slice_start) * width * (bits >> 3), width * (bits >> 3)); \
341 #define DEFINE_REMAP_LINE(ws, bits, div) \
342 static void remap##ws##_##bits##bit_line_c(uint8_t *dst, int width, const uint8_t *const src, \
343 ptrdiff_t in_linesize, \
344 const int16_t *const u, const int16_t *const v, \
345 const int16_t *const ker) \
347 const uint##bits##_t *const s = (const uint##bits##_t *const)src; \
348 uint##bits##_t *d = (uint##bits##_t *)dst; \
350 in_linesize /= div; \
352 for (int x = 0; x < width; x++) { \
353 const int16_t *const uu = u + x * ws * ws; \
354 const int16_t *const vv = v + x * ws * ws; \
355 const int16_t *const kker = ker + x * ws * ws; \
358 for (int i = 0; i < ws; i++) { \
359 const int iws = i * ws; \
360 for (int j = 0; j < ws; j++) { \
361 tmp += kker[iws + j] * s[vv[iws + j] * in_linesize + uu[iws + j]]; \
365 d[x] = av_clip_uint##bits(tmp >> 14); \
380 s->remap_line = depth <= 8 ? remap1_8bit_line_c : remap1_16bit_line_c;
383 s->remap_line = depth <= 8 ? remap2_8bit_line_c : remap2_16bit_line_c;
386 s->remap_line = depth <= 8 ? remap3_8bit_line_c : remap3_16bit_line_c;
393 s->remap_line = depth <= 8 ? remap4_8bit_line_c : remap4_16bit_line_c;
413 int16_t *
u, int16_t *v, int16_t *ker)
416 const int j =
lrintf(du) + 1;
418 u[0] = rmap->
u[
i][j];
419 v[0] = rmap->
v[
i][j];
433 int16_t *
u, int16_t *v, int16_t *ker)
435 for (
int i = 0;
i < 2;
i++) {
436 for (
int j = 0; j < 2; j++) {
437 u[
i * 2 + j] = rmap->
u[
i + 1][j + 1];
438 v[
i * 2 + j] = rmap->
v[
i + 1][j + 1];
442 ker[0] =
lrintf((1.
f - du) * (1.
f - dv) * 16385.
f);
443 ker[1] =
lrintf( du * (1.
f - dv) * 16385.
f);
444 ker[2] =
lrintf((1.
f - du) * dv * 16385.
f);
445 ker[3] =
lrintf( du * dv * 16385.
f);
456 coeffs[0] = (t - 1.f) * (t - 2.
f) * 0.5f;
457 coeffs[1] = -t * (t - 2.f);
458 coeffs[2] = t * (t - 1.f) * 0.5
f;
472 int16_t *
u, int16_t *v, int16_t *ker)
480 for (
int i = 0;
i < 3;
i++) {
481 for (
int j = 0; j < 3; j++) {
482 u[
i * 3 + j] = rmap->
u[
i + 1][j + 1];
483 v[
i * 3 + j] = rmap->
v[
i + 1][j + 1];
484 ker[
i * 3 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
497 const float tt = t * t;
498 const float ttt = t * t * t;
500 coeffs[0] = - t / 3.f + tt / 2.f - ttt / 6.f;
501 coeffs[1] = 1.f - t / 2.f - tt + ttt / 2.f;
502 coeffs[2] = t + tt / 2.f - ttt / 2.f;
503 coeffs[3] = - t / 6.f + ttt / 6.f;
517 int16_t *
u, int16_t *v, int16_t *ker)
525 for (
int i = 0;
i < 4;
i++) {
526 for (
int j = 0; j < 4; j++) {
527 u[
i * 4 + j] = rmap->
u[
i][j];
528 v[
i * 4 + j] = rmap->
v[
i][j];
529 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
544 for (
int i = 0;
i < 4;
i++) {
545 const float x =
M_PI * (t -
i + 1);
549 coeffs[
i] =
sinf(x) *
sinf(x / 2.
f) / (x * x / 2.f);
554 for (
int i = 0;
i < 4;
i++) {
570 int16_t *
u, int16_t *v, int16_t *ker)
578 for (
int i = 0;
i < 4;
i++) {
579 for (
int j = 0; j < 4; j++) {
580 u[
i * 4 + j] = rmap->
u[
i][j];
581 v[
i * 4 + j] = rmap->
v[
i][j];
582 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
595 coeffs[0] = ((-1.f / 3.f * t + 0.8f) * t - 7.
f / 15.
f) * t;
596 coeffs[1] = ((t - 9.f / 5.f) * t - 0.2
f) * t + 1.f;
597 coeffs[2] = ((6.f / 5.f - t) * t + 0.8
f) * t;
598 coeffs[3] = ((1.f / 3.f * t - 0.2f) * t - 2.
f / 15.
f) * t;
612 int16_t *
u, int16_t *v, int16_t *ker)
620 for (
int i = 0;
i < 4;
i++) {
621 for (
int j = 0; j < 4; j++) {
622 u[
i * 4 + j] = rmap->
u[
i][j];
623 v[
i * 4 + j] = rmap->
v[
i][j];
624 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
639 for (
int i = 0;
i < 4;
i++) {
640 const float x = t - (
i - 1);
644 coeffs[
i] =
expf(-2.
f * x * x) *
expf(-x * x / 2.
f);
649 for (
int i = 0;
i < 4;
i++) {
665 int16_t *
u, int16_t *v, int16_t *ker)
673 for (
int i = 0;
i < 4;
i++) {
674 for (
int j = 0; j < 4; j++) {
675 u[
i * 4 + j] = rmap->
u[
i][j];
676 v[
i * 4 + j] = rmap->
v[
i][j];
677 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
692 float p0 = (6.f - 2.f *
b) / 6.
f,
693 p2 = (-18.
f + 12.
f *
b + 6.
f *
c) / 6.f,
694 p3 = (12.f - 9.f *
b - 6.f *
c) / 6.
f,
695 q0 = (8.
f *
b + 24.
f *
c) / 6.f,
696 q1 = (-12.f *
b - 48.f *
c) / 6.
f,
697 q2 = (6.
f *
b + 30.
f *
c) / 6.f,
698 q3 = (-
b - 6.f *
c) / 6.
f;
700 for (
int i = 0;
i < 4;
i++) {
701 const float x =
fabsf(t -
i + 1.
f);
703 coeffs[
i] = (p0 + x * x * (p2 + x * p3)) *
704 (p0 + x * x * (p2 + x * p3 / 2.f) / 4.
f);
705 }
else if (x < 2.
f) {
706 coeffs[
i] = (
q0 + x * (
q1 + x * (q2 + x * q3))) *
707 (
q0 + x * (
q1 + x * (q2 + x / 2.
f * q3) / 2.f) / 2.
f);
714 for (
int i = 0;
i < 4;
i++) {
730 int16_t *
u, int16_t *v, int16_t *ker)
738 for (
int i = 0;
i < 4;
i++) {
739 for (
int j = 0; j < 4; j++) {
740 u[
i * 4 + j] = rmap->
u[
i][j];
741 v[
i * 4 + j] = rmap->
v[
i][j];
742 ker[
i * 4 + j] =
lrintf(du_coeffs[j] * dv_coeffs[
i] * 16385.
f);
757 const int res =
a %
b;
889 for (
int face = 0; face <
NB_FACES; face++) {
890 const char c =
s->in_forder[face];
895 "Incomplete in_forder option. Direction for all 6 faces should be specified.\n");
900 if (direction == -1) {
902 "Incorrect direction symbol '%c' in in_forder option.\n",
c);
906 s->in_cubemap_face_order[direction] = face;
909 for (
int face = 0; face <
NB_FACES; face++) {
910 const char c =
s->in_frot[face];
915 "Incomplete in_frot option. Rotation for all 6 faces should be specified.\n");
920 if (rotation == -1) {
922 "Incorrect rotation symbol '%c' in in_frot option.\n",
c);
926 s->in_cubemap_face_rotation[face] = rotation;
943 for (
int face = 0; face <
NB_FACES; face++) {
944 const char c =
s->out_forder[face];
949 "Incomplete out_forder option. Direction for all 6 faces should be specified.\n");
954 if (direction == -1) {
956 "Incorrect direction symbol '%c' in out_forder option.\n",
c);
960 s->out_cubemap_direction_order[face] = direction;
963 for (
int face = 0; face <
NB_FACES; face++) {
964 const char c =
s->out_frot[face];
969 "Incomplete out_frot option. Rotation for all 6 faces should be specified.\n");
974 if (rotation == -1) {
976 "Incorrect rotation symbol '%c' in out_frot option.\n",
c);
980 s->out_cubemap_face_rotation[face] = rotation;
1056 const float norm =
sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
1076 float uf,
float vf,
int face,
1077 float *vec,
float scalew,
float scaleh)
1079 const int direction =
s->out_cubemap_direction_order[face];
1080 float l_x, l_y, l_z;
1087 switch (direction) {
1139 float *uf,
float *
vf,
int *direction)
1141 const float phi =
atan2f(vec[0], vec[2]);
1142 const float theta = asinf(vec[1]);
1143 float phi_norm, theta_threshold;
1157 phi_norm = phi + ((phi > 0.f) ? -
M_PI :
M_PI);
1160 theta_threshold =
atanf(
cosf(phi_norm));
1161 if (theta > theta_threshold) {
1163 }
else if (theta < -theta_threshold) {
1167 switch (*direction) {
1169 *uf = -vec[2] / vec[0];
1170 *
vf = vec[1] / vec[0];
1173 *uf = -vec[2] / vec[0];
1174 *
vf = -vec[1] / vec[0];
1177 *uf = -vec[0] / vec[1];
1178 *
vf = -vec[2] / vec[1];
1181 *uf = vec[0] / vec[1];
1182 *
vf = -vec[2] / vec[1];
1185 *uf = vec[0] / vec[2];
1186 *
vf = vec[1] / vec[2];
1189 *uf = vec[0] / vec[2];
1190 *
vf = -vec[1] / vec[2];
1196 face =
s->in_cubemap_face_order[*direction];
1213 float uf,
float vf,
int direction,
1214 float *new_uf,
float *new_vf,
int *face)
1233 *face =
s->in_cubemap_face_order[direction];
1236 if ((uf < -1.f || uf >= 1.
f) && (vf < -1.f || vf >= 1.
f)) {
1240 }
else if (uf < -1.
f) {
1242 switch (direction) {
1276 }
else if (uf >= 1.
f) {
1278 switch (direction) {
1312 }
else if (
vf < -1.
f) {
1314 switch (direction) {
1348 }
else if (
vf >= 1.
f) {
1350 switch (direction) {
1390 *face =
s->in_cubemap_face_order[direction];
1396 return (0.5
f * x + 0.5
f) * (
s - 1.f);
1401 return (2.
f * x + 1.
f) /
s - 1.f;
1418 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
1419 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
1421 const float ew =
width / 3.f;
1422 const float eh =
height / 2.f;
1424 const int u_face =
floorf(
i / ew);
1425 const int v_face =
floorf(j / eh);
1426 const int face = u_face + 3 * v_face;
1428 const int u_shift =
ceilf(ew * u_face);
1429 const int v_shift =
ceilf(eh * v_face);
1430 const int ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1431 const int ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1433 const float uf =
rescale(
i - u_shift, ewi);
1434 const float vf =
rescale(j - v_shift, ehi);
1455 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1457 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
1458 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
1459 const float ew =
width / 3.f;
1460 const float eh =
height / 2.f;
1464 int direction, face;
1472 face =
s->in_cubemap_face_order[direction];
1475 ewi =
ceilf(ew * (u_face + 1)) -
ceilf(ew * u_face);
1476 ehi =
ceilf(eh * (v_face + 1)) -
ceilf(eh * v_face);
1478 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1479 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1487 for (
int i = 0;
i < 4;
i++) {
1488 for (
int j = 0; j < 4; j++) {
1489 int new_ui =
ui + j - 1;
1490 int new_vi = vi +
i - 1;
1491 int u_shift, v_shift;
1492 int new_ewi, new_ehi;
1494 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1495 face =
s->in_cubemap_face_order[direction];
1499 u_shift =
ceilf(ew * u_face);
1500 v_shift =
ceilf(eh * v_face);
1502 uf = 2.f * new_ui / ewi - 1.f;
1503 vf = 2.f * new_vi / ehi - 1.f;
1515 u_shift =
ceilf(ew * u_face);
1516 v_shift =
ceilf(eh * v_face);
1517 new_ewi =
ceilf(ew * (u_face + 1)) - u_shift;
1518 new_ehi =
ceilf(eh * (v_face + 1)) - v_shift;
1520 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1524 us[
i][j] = u_shift + new_ui;
1525 vs[
i][j] = v_shift + new_vi;
1546 const float scalew =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
width : 1.f -
s->out_pad;
1547 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 6.f) : 1.
f -
s->out_pad;
1549 const float ew =
width;
1550 const float eh =
height / 6.f;
1552 const int face =
floorf(j / eh);
1554 const int v_shift =
ceilf(eh * face);
1555 const int ehi =
ceilf(eh * (face + 1)) - v_shift;
1558 const float vf =
rescale(j - v_shift, ehi);
1579 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 6.f) : 1.
f -
s->out_pad;
1580 const float scaleh =
s->fout_pad > 0 ? 1.f - (
float)(
s->fout_pad) /
height : 1.
f -
s->out_pad;
1582 const float ew =
width / 6.f;
1585 const int face =
floorf(
i / ew);
1587 const int u_shift =
ceilf(ew * face);
1588 const int ewi =
ceilf(ew * (face + 1)) - u_shift;
1590 const float uf =
rescale(
i - u_shift, ewi);
1612 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1614 const float scalew =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
width : 1.f -
s->in_pad;
1615 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 6.f) : 1.
f -
s->in_pad;
1616 const float eh =
height / 6.f;
1617 const int ewi =
width;
1621 int direction, face;
1628 face =
s->in_cubemap_face_order[direction];
1629 ehi =
ceilf(eh * (face + 1)) -
ceilf(eh * face);
1631 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1632 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1640 for (
int i = 0;
i < 4;
i++) {
1641 for (
int j = 0; j < 4; j++) {
1642 int new_ui =
ui + j - 1;
1643 int new_vi = vi +
i - 1;
1647 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1648 face =
s->in_cubemap_face_order[direction];
1650 v_shift =
ceilf(eh * face);
1652 uf = 2.f * new_ui / ewi - 1.f;
1653 vf = 2.f * new_vi / ehi - 1.f;
1663 v_shift =
ceilf(eh * face);
1664 new_ehi =
ceilf(eh * (face + 1)) - v_shift;
1671 vs[
i][j] = v_shift + new_vi;
1692 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1694 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 6.f) : 1.
f -
s->in_pad;
1695 const float scaleh =
s->fin_pad > 0 ? 1.f - (
float)(
s->fin_pad) /
height : 1.
f -
s->in_pad;
1696 const float ew =
width / 6.f;
1701 int direction, face;
1708 face =
s->in_cubemap_face_order[direction];
1709 ewi =
ceilf(ew * (face + 1)) -
ceilf(ew * face);
1711 uf = 0.5f * ewi * (uf + 1.f) - 0.5
f;
1712 vf = 0.5f * ehi * (
vf + 1.f) - 0.5
f;
1720 for (
int i = 0;
i < 4;
i++) {
1721 for (
int j = 0; j < 4; j++) {
1722 int new_ui =
ui + j - 1;
1723 int new_vi = vi +
i - 1;
1727 if (new_ui >= 0 && new_ui < ewi && new_vi >= 0 && new_vi < ehi) {
1728 face =
s->in_cubemap_face_order[direction];
1730 u_shift =
ceilf(ew * face);
1732 uf = 2.f * new_ui / ewi - 1.f;
1733 vf = 2.f * new_vi / ehi - 1.f;
1743 u_shift =
ceilf(ew * face);
1744 new_ewi =
ceilf(ew * (face + 1)) - u_shift;
1746 new_ui =
av_clip(
lrintf(0.5
f * new_ewi * (uf + 1.
f)), 0, new_ewi - 1);
1750 us[
i][j] = u_shift + new_ui;
1769 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
1770 s->flat_range[1] =
s->v_fov *
M_PI / 360.f;
1792 const float sin_phi =
sinf(phi);
1793 const float cos_phi =
cosf(phi);
1794 const float sin_theta =
sinf(theta);
1795 const float cos_theta =
cosf(theta);
1797 vec[0] = cos_theta * sin_phi;
1799 vec[2] = cos_theta * cos_phi;
1821 const float sin_phi =
sinf(phi);
1822 const float cos_phi =
cosf(phi);
1823 const float sin_theta =
sinf(theta);
1824 const float cos_theta =
cosf(theta);
1826 vec[0] = cos_theta * sin_phi;
1828 vec[2] = cos_theta * cos_phi;
1844 s->flat_range[0] = tanf(
FFMIN(
s->h_fov, 359.f) *
M_PI / 720.f);
1845 s->flat_range[1] = tanf(
FFMIN(
s->v_fov, 359.f) *
M_PI / 720.f);
1866 const float r = hypotf(x, y);
1867 const float theta =
atanf(
r) * 2.f;
1868 const float sin_theta =
sinf(theta);
1870 vec[0] = x /
r * sin_theta;
1871 vec[1] = y /
r * sin_theta;
1872 vec[2] =
cosf(theta);
1888 s->iflat_range[0] = tanf(
FFMIN(
s->ih_fov, 359.f) *
M_PI / 720.f);
1889 s->iflat_range[1] = tanf(
FFMIN(
s->iv_fov, 359.f) *
M_PI / 720.f);
1908 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
1910 const float theta = acosf(vec[2]);
1911 const float r = tanf(theta * 0.5
f);
1912 const float c =
r / hypotf(vec[0], vec[1]);
1913 const float x = vec[0] *
c /
s->iflat_range[0];
1914 const float y = vec[1] *
c /
s->iflat_range[1];
1924 *du = visible ? uf -
ui : 0.f;
1925 *dv = visible ?
vf - vi : 0.f;
1927 for (
int i = 0;
i < 4;
i++) {
1928 for (
int j = 0; j < 4; j++) {
1948 s->flat_range[0] =
sinf(
s->h_fov *
M_PI / 720.f);
1949 s->flat_range[1] =
sinf(
s->v_fov *
M_PI / 720.f);
1970 const float r = hypotf(x, y);
1971 const float theta = asinf(
r) * 2.f;
1972 const float sin_theta =
sinf(theta);
1974 vec[0] = x /
r * sin_theta;
1975 vec[1] = y /
r * sin_theta;
1976 vec[2] =
cosf(theta);
2012 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2014 const float theta = acosf(vec[2]);
2015 const float r =
sinf(theta * 0.5
f);
2016 const float c =
r / hypotf(vec[0], vec[1]);
2017 const float x = vec[0] *
c /
s->iflat_range[0];
2018 const float y = vec[1] *
c /
s->iflat_range[1];
2028 *du = visible ? uf -
ui : 0.f;
2029 *dv = visible ?
vf - vi : 0.f;
2031 for (
int i = 0;
i < 4;
i++) {
2032 for (
int j = 0; j < 4; j++) {
2074 const float r = hypotf(x, y);
2075 const float theta = asinf(
r);
2077 vec[2] =
cosf(theta);
2123 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2125 const float theta = acosf(vec[2]);
2126 const float r =
sinf(theta);
2127 const float c =
r / hypotf(vec[0], vec[1]);
2128 const float x = vec[0] *
c /
s->iflat_range[0];
2129 const float y = vec[1] *
c /
s->iflat_range[1];
2137 const int visible = vec[2] >= 0.f &&
isfinite(x) &&
isfinite(y) && vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2139 *du = visible ? uf -
ui : 0.f;
2140 *dv = visible ?
vf - vi : 0.f;
2142 for (
int i = 0;
i < 4;
i++) {
2143 for (
int j = 0; j < 4; j++) {
2163 s->iflat_range[0] =
s->ih_fov *
M_PI / 360.f;
2164 s->iflat_range[1] =
s->iv_fov *
M_PI / 360.f;
2183 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2185 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
2186 const float theta = asinf(vec[1]) /
s->iflat_range[1];
2198 visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width;
2200 for (
int i = 0;
i < 4;
i++) {
2201 for (
int j = 0; j < 4; j++) {
2224 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2227 const float theta = asinf(vec[1]) /
M_PI_2;
2240 for (
int i = 0;
i < 4;
i++) {
2241 for (
int j = 0; j < 4; j++) {
2261 s->iflat_range[0] = tanf(0.5
f *
s->ih_fov *
M_PI / 180.f);
2262 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
2281 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2283 const float theta = acosf(vec[2]);
2284 const float r = tanf(theta);
2286 const float zf = vec[2];
2287 const float h = hypotf(vec[0], vec[1]);
2288 const float c =
h <= 1e-6
f ? 1.f : rr /
h;
2289 float uf = vec[0] *
c /
s->iflat_range[0];
2290 float vf = vec[1] *
c /
s->iflat_range[1];
2291 int visible,
ui, vi;
2299 visible = vi >= 0 && vi < height && ui >= 0 && ui < width && zf >= 0.f;
2304 for (
int i = 0;
i < 4;
i++) {
2305 for (
int j = 0; j < 4; j++) {
2328 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2330 const float phi =
atan2f(vec[0], vec[2]) /
M_PI;
2331 const float theta =
av_clipf(logf((1.
f + vec[1]) / (1.
f - vec[1])) / (2.
f *
M_PI), -1.
f, 1.
f);
2342 for (
int i = 0;
i < 4;
i++) {
2343 for (
int j = 0; j < 4; j++) {
2368 const float div =
expf(2.
f * y) + 1.f;
2370 const float sin_phi =
sinf(phi);
2371 const float cos_phi =
cosf(phi);
2372 const float sin_theta = 2.f *
expf(y) / div;
2373 const float cos_theta = (
expf(2.
f * y) - 1.f) / div;
2375 vec[0] = -sin_theta * cos_phi;
2377 vec[2] = sin_theta * sin_phi;
2396 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2398 const float l = hypotf(vec[0], vec[1]);
2400 const float d = l > 0.f ? l : 1.f;
2411 for (
int i = 0;
i < 4;
i++) {
2412 for (
int j = 0; j < 4; j++) {
2437 const float l = hypotf(x, y);
2440 const float z = 2.f * l *
sqrtf(1.
f - l * l);
2442 vec[0] = z * x / (l > 0.f ? l : 1.f);
2443 vec[1] = z * y / (l > 0.f ? l : 1.f);
2444 vec[2] = 1.f - 2.f * l * l;
2472 const float xx = x * x;
2473 const float yy = y * y;
2475 const float z =
sqrtf(1.
f - xx * 0.5
f - yy * 0.5
f);
2478 const float b = 2.f * z * z - 1.f;
2480 const float aa =
a *
a;
2481 const float bb =
b *
b;
2483 const float w =
sqrtf(1.
f - 2.
f * yy * z * z);
2485 vec[0] =
w * 2.f *
a *
b / (aa + bb);
2487 vec[2] =
w * (bb - aa) / (aa + bb);
2506 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2508 const float theta =
atan2f(vec[0], vec[2]);
2511 const float x =
sqrtf(1.
f - vec[1] * vec[1]) *
sinf(theta * 0.5
f) / z;
2512 const float y = vec[1] / z;
2514 const float uf = (x + 1.f) *
width / 2.
f;
2515 const float vf = (y + 1.f) *
height / 2.
f;
2523 for (
int i = 0;
i < 4;
i++) {
2524 for (
int j = 0; j < 4; j++) {
2550 const float sin_phi =
sinf(phi);
2551 const float cos_phi =
cosf(phi);
2552 const float sin_theta =
sinf(theta);
2553 const float cos_theta =
cosf(theta);
2555 vec[0] = cos_theta * sin_phi;
2557 vec[2] = cos_theta * cos_phi;
2576 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2578 const float theta = asinf(vec[1]);
2579 const float phi =
atan2f(vec[0], vec[2]) *
cosf(theta);
2590 for (
int i = 0;
i < 4;
i++) {
2591 for (
int j = 0; j < 4; j++) {
2670 const float pixel_pad = 2;
2671 const float u_pad = pixel_pad /
width;
2672 const float v_pad = pixel_pad /
height;
2674 int u_face, v_face, face;
2676 float l_x, l_y, l_z;
2678 float uf = (
i + 0.5f) /
width;
2686 uf = 3.f * (uf - u_pad) / (1.
f - 2.
f * u_pad);
2690 }
else if (uf >= 3.
f) {
2695 uf = fmodf(uf, 1.
f) - 0.5f;
2700 vf = (
vf - v_pad - 0.5f * v_face) / (0.5
f - 2.
f * v_pad) - 0.5f;
2702 if (uf >= -0.5
f && uf < 0.5
f) {
2707 if (
vf >= -0.5
f &&
vf < 0.5
f) {
2713 face = u_face + 3 * v_face;
2771 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2773 const float pixel_pad = 2;
2774 const float u_pad = pixel_pad /
width;
2775 const float v_pad = pixel_pad /
height;
2779 int direction, face;
2784 face =
s->in_cubemap_face_order[direction];
2792 uf = (uf + u_face) * (1.
f - 2.
f * u_pad) / 3.f + u_pad;
2793 vf =
vf * (0.5f - 2.f * v_pad) + v_pad + 0.5
f * v_face;
2807 for (
int i = 0;
i < 4;
i++) {
2808 for (
int j = 0; j < 4; j++) {
2828 s->flat_range[0] = tanf(0.5
f *
s->h_fov *
M_PI / 180.f);
2829 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
2869 s->flat_range[0] =
s->h_fov / 180.f;
2870 s->flat_range[1] =
s->v_fov / 180.f;
2893 const float theta =
M_PI_2 * (1.f - hypotf(uf,
vf));
2895 const float sin_phi =
sinf(phi);
2896 const float cos_phi =
cosf(phi);
2897 const float sin_theta =
sinf(theta);
2898 const float cos_theta =
cosf(theta);
2900 vec[0] = cos_theta * cos_phi;
2901 vec[1] = cos_theta * sin_phi;
2918 s->iflat_range[0] =
s->ih_fov / 180.f;
2919 s->iflat_range[1] =
s->iv_fov / 180.f;
2938 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
2940 const float h = hypotf(vec[0], vec[1]);
2941 const float lh =
h > 0.f ?
h : 1.f;
2944 float uf = vec[0] / lh * phi /
s->iflat_range[0];
2945 float vf = vec[1] / lh * phi /
s->iflat_range[1];
2947 const int visible = -0.5f < uf && uf < 0.5f && -0.5f <
vf &&
vf < 0.5f;
2956 *du = visible ? uf -
ui : 0.f;
2957 *dv = visible ?
vf - vi : 0.f;
2959 for (
int i = 0;
i < 4;
i++) {
2960 for (
int j = 0; j < 4; j++) {
2986 const float d =
s->h_fov;
2987 const float k = uf * uf / ((d + 1.f) * (d + 1.
f));
2988 const float dscr = k * k * d * d - (k + 1.f) * (k * d * d - 1.
f);
2989 const float clon = (-k * d +
sqrtf(dscr)) / (k + 1.
f);
2990 const float S = (d + 1.f) / (d + clon);
2991 const float lon =
atan2f(uf,
S * clon);
3015 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3017 const float phi =
atan2f(vec[0], vec[2]);
3018 const float theta = asinf(vec[1]);
3020 const float d =
s->ih_fov;
3021 const float S = (d + 1.f) / (d +
cosf(phi));
3023 const float x =
S *
sinf(phi);
3024 const float y =
S * tanf(theta);
3032 const int visible = vi >= 0 && vi < height && ui >= 0 && ui < width && vec[2] >= 0.f;
3037 for (
int i = 0;
i < 4;
i++) {
3038 for (
int j = 0; j < 4; j++) {
3058 s->flat_range[0] =
M_PI *
s->h_fov / 360.f;
3059 s->flat_range[1] = tanf(0.5
f *
s->v_fov *
M_PI / 180.f);
3081 const float phi = uf;
3082 const float theta =
atanf(
vf);
3084 const float sin_phi =
sinf(phi);
3085 const float cos_phi =
cosf(phi);
3086 const float sin_theta =
sinf(theta);
3087 const float cos_theta =
cosf(theta);
3089 vec[0] = cos_theta * sin_phi;
3091 vec[2] = cos_theta * cos_phi;
3107 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3108 s->iflat_range[1] = tanf(0.5
f *
s->iv_fov *
M_PI / 180.f);
3127 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3129 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3130 const float theta = asinf(vec[1]);
3138 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3139 theta <=
M_PI *
s->iv_fov / 180.f &&
3140 theta >= -
M_PI *
s->iv_fov / 180.f;
3145 for (
int i = 0;
i < 4;
i++) {
3146 for (
int j = 0; j < 4; j++) {
3166 s->flat_range[0] =
s->h_fov *
M_PI / 360.f;
3167 s->flat_range[1] =
s->v_fov / 180.f;
3183 s->iflat_range[0] =
M_PI *
s->ih_fov / 360.f;
3184 s->iflat_range[1] =
s->iv_fov / 180.f;
3206 const float phi = uf;
3207 const float theta = asinf(
vf);
3209 const float sin_phi =
sinf(phi);
3210 const float cos_phi =
cosf(phi);
3211 const float sin_theta =
sinf(theta);
3212 const float cos_theta =
cosf(theta);
3214 vec[0] = cos_theta * sin_phi;
3216 vec[2] = cos_theta * cos_phi;
3235 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3237 const float phi =
atan2f(vec[0], vec[2]) /
s->iflat_range[0];
3238 const float theta = asinf(vec[1]);
3246 const int visible = vi >= 0 && vi < height && ui >= 0 &&
ui <
width &&
3247 theta <=
M_PI *
s->iv_fov / 180.f &&
3248 theta >= -
M_PI *
s->iv_fov / 180.f;
3253 for (
int i = 0;
i < 4;
i++) {
3254 for (
int j = 0; j < 4; j++) {
3279 const float rh = hypotf(uf,
vf);
3280 const float sinzz = 1.f - rh * rh;
3281 const float h = 1.f +
s->v_fov;
3282 const float sinz = (
h -
sqrtf(sinzz)) / (
h / rh + rh /
h);
3283 const float sinz2 = sinz * sinz;
3286 const float cosz =
sqrtf(1.
f - sinz2);
3288 const float theta = asinf(cosz);
3291 const float sin_phi =
sinf(phi);
3292 const float cos_phi =
cosf(phi);
3293 const float sin_theta =
sinf(theta);
3294 const float cos_theta =
cosf(theta);
3296 vec[0] = cos_theta * sin_phi;
3297 vec[1] = cos_theta * cos_phi;
3326 vec[0] = uf < 0.5f ? uf * 4.f - 1.f : 3.f - uf * 4.f;
3327 vec[1] = 1.f -
vf * 2.f;
3347 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3349 const float d0 = vec[0] * 1.f + vec[1] * 1.f + vec[2] *-1.f;
3350 const float d1 = vec[0] *-1.f + vec[1] *-1.f + vec[2] *-1.f;
3351 const float d2 = vec[0] * 1.f + vec[1] *-1.f + vec[2] * 1.f;
3352 const float d3 = vec[0] *-1.f + vec[1] * 1.f + vec[2] * 1.f;
3355 float uf,
vf, x, y, z;
3362 vf = 0.5f - y * 0.5f;
3364 if ((x + y >= 0.
f && y + z >= 0.
f && -z - x <= 0.
f) ||
3365 (x + y <= 0.f && -y + z >= 0.
f && z - x >= 0.
f)) {
3366 uf = 0.25f * x + 0.25f;
3368 uf = 0.75f - 0.25f * x;
3380 for (
int i = 0;
i < 4;
i++) {
3381 for (
int j = 0; j < 4; j++) {
3401 s->iflat_range[0] =
s->ih_fov / 360.f;
3402 s->iflat_range[1] =
s->iv_fov / 360.f;
3421 const float ew =
width * 0.5f;
3424 const int ei =
i >= ew ?
i - ew :
i;
3425 const float m =
i >= ew ? 1.f : -1.f;
3427 const float uf =
s->flat_range[0] *
rescale(ei, ew);
3428 const float vf =
s->flat_range[1] *
rescale(j, eh);
3430 const float h = hypotf(uf,
vf);
3431 const float lh =
h > 0.f ?
h : 1.f;
3432 const float theta = m *
M_PI_2 * (1.f -
h);
3434 const float sin_theta =
sinf(theta);
3435 const float cos_theta =
cosf(theta);
3437 vec[0] = cos_theta * m * uf / lh;
3438 vec[1] = cos_theta *
vf / lh;
3458 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3460 const float ew =
width * 0.5f;
3463 const float h = hypotf(vec[0], vec[1]);
3464 const float lh =
h > 0.f ?
h : 1.f;
3465 const float theta = acosf(
fabsf(vec[2])) /
M_PI;
3467 float uf =
scale(theta * (vec[0] / lh) /
s->iflat_range[0], ew);
3468 float vf =
scale(theta * (vec[1] / lh) /
s->iflat_range[1], eh);
3473 if (vec[2] >= 0.
f) {
3474 u_shift =
ceilf(ew);
3486 for (
int i = 0;
i < 4;
i++) {
3487 for (
int j = 0; j < 4; j++) {
3510 const float scale = 0.99f;
3511 float l_x, l_y, l_z;
3514 const float theta_range =
M_PI_4;
3516 const int ew = 4 *
width / 5;
3520 const float theta =
rescale(j, eh) * theta_range /
scale;
3522 const float sin_phi =
sinf(phi);
3523 const float cos_phi =
cosf(phi);
3524 const float sin_theta =
sinf(theta);
3525 const float cos_theta =
cosf(theta);
3527 l_x = cos_theta * sin_phi;
3529 l_z = cos_theta * cos_phi;
3531 const int ew =
width / 5;
3532 const int eh =
height / 2;
3580 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3582 const float scale = 0.99f;
3584 const float phi =
atan2f(vec[0], vec[2]);
3585 const float theta = asinf(vec[1]);
3586 const float theta_range =
M_PI_4;
3589 int u_shift, v_shift;
3593 if (theta > -theta_range && theta < theta_range) {
3601 vf = (theta / theta_range *
scale + 1.f) * eh / 2.
f;
3609 uf = -vec[0] / vec[1];
3610 vf = -vec[2] / vec[1];
3613 uf = vec[0] / vec[1];
3614 vf = -vec[2] / vec[1];
3618 uf = 0.5f * ew * (uf *
scale + 1.f);
3628 for (
int i = 0;
i < 4;
i++) {
3629 for (
int j = 0; j < 4; j++) {
3631 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3652 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3654 const float phi =
atan2f(vec[0], vec[2]);
3655 const float theta = asinf(vec[1]);
3657 const float theta_range =
M_PI_4;
3660 int u_shift, v_shift;
3664 if (theta >= -theta_range && theta <= theta_range) {
3665 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width * 2.f / 3.f) : 1.
f -
s->in_pad;
3666 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 2.f) : 1.f -
s->in_pad;
3678 uf = uf >= 0.f ? fmodf(uf - 1.
f, 1.
f) : fmodf(uf + 1.
f, 1.
f);
3680 uf = (uf * scalew + 1.f) *
width / 3.
f;
3683 const float scalew =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
width / 3.f) : 1.
f -
s->in_pad;
3684 const float scaleh =
s->fin_pad > 0 ? 1.f -
s->fin_pad / (
height / 4.f) : 1.f -
s->in_pad;
3691 uf = vec[0] / vec[1] * scalew;
3692 vf = vec[2] / vec[1] * scaleh;
3694 if (theta <= 0.f && theta >= -
M_PI_2 &&
3695 phi <= M_PI_2 && phi >= -
M_PI_2) {
3698 vf = -(
vf + 1.f) * scaleh + 1.
f;
3700 }
else if (theta >= 0.
f && theta <=
M_PI_2 &&
3701 phi <= M_PI_2 && phi >= -
M_PI_2) {
3703 vf = -(
vf - 1.f) * scaleh;
3704 v_shift =
height * 0.25f;
3705 }
else if (theta <= 0.f && theta >= -
M_PI_2) {
3707 vf = (
vf - 1.f) * scaleh + 1.
f;
3712 vf = (
vf + 1.f) * scaleh;
3713 v_shift =
height * 0.75f;
3716 uf = 0.5f *
width / 3.f * (uf + 1.f);
3726 for (
int i = 0;
i < 4;
i++) {
3727 for (
int j = 0; j < 4; j++) {
3729 vs[
i][j] = v_shift +
av_clip(vi +
i - 1, 0, eh - 1);
3750 const float x = (
i + 0.5f) /
width;
3751 const float y = (j + 0.5f) /
height;
3752 float l_x, l_y, l_z;
3755 if (x < 2.
f / 3.
f) {
3756 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width * 2.f / 3.f) : 1.
f -
s->out_pad;
3757 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 2.f) : 1.f -
s->out_pad;
3759 const float back =
floorf(y * 2.
f);
3761 const float phi = ((3.f / 2.f * x - 0.5f) / scalew - back) *
M_PI;
3762 const float theta = (y - 0.25f - 0.5f * back) / scaleh *
M_PI;
3764 const float sin_phi =
sinf(phi);
3765 const float cos_phi =
cosf(phi);
3766 const float sin_theta =
sinf(theta);
3767 const float cos_theta =
cosf(theta);
3769 l_x = cos_theta * sin_phi;
3771 l_z = cos_theta * cos_phi;
3775 const float scalew =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
width / 3.f) : 1.
f -
s->out_pad;
3776 const float scaleh =
s->fout_pad > 0 ? 1.f -
s->fout_pad / (
height / 4.f) : 1.f -
s->out_pad;
3778 const float facef =
floorf(y * 4.
f);
3779 const int face = facef;
3780 const float dir_vert = (face == 1 || face == 3) ? 1.0
f : -1.0
f;
3789 vf = (0.5f - 2.f * y) / scaleh + facef;
3793 vf = (y * 2.f - 1.5f) / scaleh + 3.
f - facef;
3798 l_x = (0.5f - uf) / scalew;
3799 l_y = 0.5f * dir_vert;
3800 l_z = (
vf - 0.5f) * dir_vert / scaleh;
3801 ret = (l_x * l_x * scalew * scalew + l_z * l_z * scaleh * scaleh) < 0.5
f * 0.5
f;
3825 const float x = (
i + 0.5f) /
width;
3826 const float y = (j + 0.5f) /
height;
3829 vec[0] = x * 4.f - 1.f;
3830 vec[1] = (y * 2.f - 1.f);
3832 }
else if (x >= 0.6875
f && x < 0.8125
f &&
3833 y >= 0.375
f && y < 0.625
f) {
3834 vec[0] = -(x - 0.6875f) * 16.
f + 1.
f;
3835 vec[1] = (y - 0.375f) * 8.
f - 1.
f;
3837 }
else if (0.5
f <= x && x < 0.6875
f &&
3838 ((0.
f <= y && y < 0.375f && y >= 2.
f * (x - 0.5
f)) ||
3839 (0.375
f <= y && y < 0.625
f) ||
3840 (0.625f <= y && y < 1.f && y <= 2.f * (1.f - x)))) {
3842 vec[1] = 2.f * (y - 2.f * x + 1.f) / (3.
f - 4.
f * x) - 1.f;
3843 vec[2] = -2.f * (x - 0.5f) / 0.1875
f + 1.
f;
3844 }
else if (0.8125
f <= x && x < 1.
f &&
3845 ((0.
f <= y && y < 0.375f && x >= (1.
f - y / 2.
f)) ||
3846 (0.375
f <= y && y < 0.625
f) ||
3847 (0.625f <= y && y < 1.f && y <= (2.f * x - 1.f)))) {
3849 vec[1] = 2.f * (y + 2.f * x - 2.f) / (4.
f * x - 3.
f) - 1.f;
3850 vec[2] = 2.f * (x - 0.8125f) / 0.1875
f - 1.
f;
3851 }
else if (0.
f <= y && y < 0.375
f &&
3852 ((0.5
f <= x && x < 0.8125
f && y < 2.
f * (x - 0.5
f)) ||
3853 (0.6875
f <= x && x < 0.8125
f) ||
3854 (0.8125f <= x && x < 1.f && x < (1.f - y / 2.f)))) {
3855 vec[0] = 2.f * (1.f - x - 0.5f * y) / (0.5
f - y) - 1.f;
3857 vec[2] = 2.f * (0.375f - y) / 0.375
f - 1.
f;
3859 vec[0] = 2.f * (0.5f - x + 0.5f * y) / (y - 0.5
f) - 1.f;
3861 vec[2] = -2.f * (1.f - y) / 0.375
f + 1.
f;
3881 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
3889 uf = (uf + 1.f) * 0.5
f;
3890 vf = (
vf + 1.f) * 0.5
f;
3894 uf = 0.1875f *
vf - 0.375f * uf *
vf - 0.125f * uf + 0.8125f;
3895 vf = 0.375f - 0.375f *
vf;
3901 uf = 1.f - 0.1875f *
vf - 0.5f * uf + 0.375f * uf *
vf;
3902 vf = 1.f - 0.375f *
vf;
3905 vf = 0.25f *
vf + 0.75f * uf *
vf - 0.375f * uf + 0.375f;
3906 uf = 0.1875f * uf + 0.8125f;
3909 vf = 0.375f * uf - 0.75f * uf *
vf +
vf;
3910 uf = 0.1875f * uf + 0.5f;
3913 uf = 0.125f * uf + 0.6875f;
3914 vf = 0.25f *
vf + 0.375f;
3927 for (
int i = 0;
i < 4;
i++) {
3928 for (
int j = 0; j < 4; j++) {
3953 const float ax =
fabsf(x);
3954 const float ay =
fabsf(y);
3956 vec[2] = 1.f - (ax + ay);
3957 if (ax + ay > 1.
f) {
3958 vec[0] = (1.f - ay) *
FFSIGN(x);
3959 vec[1] = (1.f - ax) *
FFSIGN(y);
3982 int16_t
us[4][4], int16_t vs[4][4],
float *du,
float *dv)
4007 for (
int i = 0;
i < 4;
i++) {
4008 for (
int j = 0; j < 4; j++) {
4019 c[0] =
a[0] *
b[0] -
a[1] *
b[1] -
a[2] *
b[2] -
a[3] *
b[3];
4020 c[1] =
a[1] *
b[0] +
a[0] *
b[1] +
a[2] *
b[3] -
a[3] *
b[2];
4021 c[2] =
a[2] *
b[0] +
a[0] *
b[2] +
a[3] *
b[1] -
a[1] *
b[3];
4022 c[3] =
a[3] *
b[0] +
a[0] *
b[3] +
a[1] *
b[2] -
a[2] *
b[1];
4037 float rot_quaternion[2][4],
4038 const int rotation_order[3])
4040 const float yaw_rad = yaw *
M_PI / 180.f;
4041 const float pitch_rad = pitch *
M_PI / 180.f;
4042 const float roll_rad = roll *
M_PI / 180.f;
4044 const float sin_yaw =
sinf(yaw_rad * 0.5
f);
4045 const float cos_yaw =
cosf(yaw_rad * 0.5
f);
4046 const float sin_pitch =
sinf(pitch_rad * 0.5
f);
4047 const float cos_pitch =
cosf(pitch_rad * 0.5
f);
4048 const float sin_roll =
sinf(roll_rad * 0.5
f);
4049 const float cos_roll =
cosf(roll_rad * 0.5
f);
4054 m[0][0] = cos_yaw; m[0][1] = 0.f; m[0][2] = sin_yaw; m[0][3] = 0.f;
4055 m[1][0] = cos_pitch; m[1][1] = sin_pitch; m[1][2] = 0.f; m[1][3] = 0.f;
4056 m[2][0] = cos_roll; m[2][1] = 0.f; m[2][2] = 0.f; m[2][3] = sin_roll;
4071 static inline void rotate(
const float rot_quaternion[2][4],
4074 float qv[4],
temp[4], rqv[4];
4092 modifier[0] = h_flip ? -1.f : 1.f;
4093 modifier[1] = v_flip ? -1.f : 1.f;
4094 modifier[2] = d_flip ? -1.f : 1.f;
4097 static inline void mirror(
const float *modifier,
float *vec)
4099 vec[0] *= modifier[0];
4100 vec[1] *= modifier[1];
4101 vec[2] *= modifier[2];
4104 static inline void input_flip(int16_t
u[4][4], int16_t v[4][4],
int w,
int h,
int hflip,
int vflip)
4107 for (
int i = 0;
i < 4;
i++) {
4108 for (
int j = 0; j < 4; j++)
4109 u[
i][j] =
w - 1 -
u[
i][j];
4114 for (
int i = 0;
i < 4;
i++) {
4115 for (
int j = 0; j < 4; j++)
4116 v[
i][j] =
h - 1 - v[
i][j];
4123 const int pr_height =
s->pr_height[p];
4125 for (
int n = 0; n <
s->nb_threads; n++) {
4127 const int slice_start = (pr_height * n ) /
s->nb_threads;
4128 const int slice_end = (pr_height * (n + 1)) /
s->nb_threads;
4135 if (!
r->u[p] || !
r->v[p])
4144 if (sizeof_mask && !p) {
4160 *v_fov = d_fov * 0.5f;
4164 const float d = 0.5f * hypotf(
w,
h);
4165 const float l =
sinf(d_fov *
M_PI / 360.
f) / d;
4167 *h_fov = asinf(
w * 0.5
f * l) * 360.f /
M_PI;
4168 *v_fov = asinf(
h * 0.5
f * l) * 360.f /
M_PI;
4170 if (d_fov > 180.
f) {
4171 *h_fov = 180.f - *h_fov;
4172 *v_fov = 180.f - *v_fov;
4178 const float d = 0.5f * hypotf(
w,
h);
4179 const float l = d / (
sinf(d_fov *
M_PI / 720.
f));
4181 *h_fov = 2.f * asinf(
w * 0.5
f / l) * 360.f /
M_PI;
4182 *v_fov = 2.f * asinf(
h * 0.5
f / l) * 360.f /
M_PI;
4187 const float d = 0.5f * hypotf(
w,
h);
4188 const float l = d / (tanf(d_fov *
M_PI / 720.
f));
4196 const float d = hypotf(
w * 0.5
f,
h);
4198 *h_fov = 0.5f *
w / d * d_fov;
4199 *v_fov =
h / d * d_fov;
4204 const float d = hypotf(
w,
h);
4206 *h_fov =
w / d * d_fov;
4207 *v_fov =
h / d * d_fov;
4213 const float da = tanf(0.5
f *
FFMIN(d_fov, 359.
f) *
M_PI / 180.
f);
4214 const float d = hypotf(
w,
h);
4231 outw[0] = outw[3] =
w;
4233 outh[0] = outh[3] =
h;
4242 for (
int p = 0; p <
s->nb_allocated; p++) {
4243 const int max_value =
s->max_value;
4244 const int width =
s->pr_width[p];
4245 const int uv_linesize =
s->uv_linesize[p];
4246 const int height =
s->pr_height[p];
4247 const int in_width =
s->inplanewidth[p];
4248 const int in_height =
s->inplaneheight[p];
4262 uint16_t *mask16 = p ?
NULL : (uint16_t *)
r->mask + ((j -
slice_start) *
s->pr_width[0] +
i);
4263 int in_mask, out_mask;
4265 if (
s->out_transpose)
4272 rotate(
s->rot_quaternion, vec);
4275 mirror(
s->output_mirror_modifier, vec);
4276 if (
s->in_transpose)
4277 in_mask =
s->in_transform(
s, vec, in_height, in_width, rmap.
v, rmap.
u, &du, &dv);
4279 in_mask =
s->in_transform(
s, vec, in_width, in_height, rmap.
u, rmap.
v, &du, &dv);
4280 input_flip(rmap.
u, rmap.
v, in_width, in_height,
s->ih_flip,
s->iv_flip);
4282 s->calculate_kernel(du, dv, &rmap,
u, v, ker);
4284 if (!p &&
r->mask) {
4285 if (
s->mask_size == 1) {
4286 mask8[0] = 255 * (out_mask & in_mask);
4288 mask16[0] = max_value * (out_mask & in_mask);
4304 const int depth =
desc->comp[0].depth;
4305 const int sizeof_mask =
s->mask_size = (depth + 7) >> 3;
4306 float default_h_fov = 360.f;
4307 float default_v_fov = 180.f;
4308 float default_ih_fov = 360.f;
4309 float default_iv_fov = 180.f;
4314 int in_offset_h, in_offset_w;
4315 int out_offset_h, out_offset_w;
4320 s->max_value = (1 << depth) - 1;
4322 switch (
s->interp) {
4325 s->remap_slice = depth <= 8 ? remap1_8bit_slice : remap1_16bit_slice;
4327 sizeof_uv =
sizeof(int16_t) *
s->elements;
4332 s->remap_slice = depth <= 8 ? remap2_8bit_slice : remap2_16bit_slice;
4333 s->elements = 2 * 2;
4334 sizeof_uv =
sizeof(int16_t) *
s->elements;
4335 sizeof_ker =
sizeof(int16_t) *
s->elements;
4339 s->remap_slice = depth <= 8 ? remap3_8bit_slice : remap3_16bit_slice;
4340 s->elements = 3 * 3;
4341 sizeof_uv =
sizeof(int16_t) *
s->elements;
4342 sizeof_ker =
sizeof(int16_t) *
s->elements;
4346 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4347 s->elements = 4 * 4;
4348 sizeof_uv =
sizeof(int16_t) *
s->elements;
4349 sizeof_ker =
sizeof(int16_t) *
s->elements;
4353 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4354 s->elements = 4 * 4;
4355 sizeof_uv =
sizeof(int16_t) *
s->elements;
4356 sizeof_ker =
sizeof(int16_t) *
s->elements;
4360 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4361 s->elements = 4 * 4;
4362 sizeof_uv =
sizeof(int16_t) *
s->elements;
4363 sizeof_ker =
sizeof(int16_t) *
s->elements;
4367 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4368 s->elements = 4 * 4;
4369 sizeof_uv =
sizeof(int16_t) *
s->elements;
4370 sizeof_ker =
sizeof(int16_t) *
s->elements;
4374 s->remap_slice = depth <= 8 ? remap4_8bit_slice : remap4_16bit_slice;
4375 s->elements = 4 * 4;
4376 sizeof_uv =
sizeof(int16_t) *
s->elements;
4377 sizeof_ker =
sizeof(int16_t) *
s->elements;
4385 for (
int order = 0; order <
NB_RORDERS; order++) {
4386 const char c =
s->rorder[order];
4391 "Incomplete rorder option. Direction for all 3 rotation orders should be specified. Switching to default rorder.\n");
4392 s->rotation_order[0] =
YAW;
4393 s->rotation_order[1] =
PITCH;
4394 s->rotation_order[2] =
ROLL;
4401 "Incorrect rotation order symbol '%c' in rorder option. Switching to default rorder.\n",
c);
4402 s->rotation_order[0] =
YAW;
4403 s->rotation_order[1] =
PITCH;
4404 s->rotation_order[2] =
ROLL;
4408 s->rotation_order[order] = rorder;
4411 switch (
s->in_stereo) {
4415 in_offset_w = in_offset_h = 0;
4436 s->in_width =
s->inplanewidth[0];
4437 s->in_height =
s->inplaneheight[0];
4442 default_ih_fov = 90.f;
4443 default_iv_fov = 45.f;
4450 default_ih_fov = 180.f;
4451 default_iv_fov = 180.f;
4456 if (
s->ih_fov == 0.f)
4457 s->ih_fov = default_ih_fov;
4459 if (
s->iv_fov == 0.f)
4460 s->iv_fov = default_iv_fov;
4462 if (
s->id_fov > 0.f)
4465 if (
s->in_transpose)
4466 FFSWAP(
int,
s->in_width,
s->in_height);
4782 if (
s->width > 0 &&
s->height <= 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4783 s->out ==
FLAT &&
s->d_fov == 0.f) {
4785 h =
w / tanf(
s->h_fov *
M_PI / 360.f) * tanf(
s->v_fov *
M_PI / 360.f);
4786 }
else if (
s->width <= 0 &&
s->height > 0 &&
s->h_fov > 0.f &&
s->v_fov > 0.f &&
4787 s->out ==
FLAT &&
s->d_fov == 0.f) {
4789 w =
h / tanf(
s->v_fov *
M_PI / 360.f) * tanf(
s->h_fov *
M_PI / 360.f);
4790 }
else if (
s->width > 0 &&
s->height > 0) {
4793 }
else if (
s->width > 0 ||
s->height > 0) {
4797 if (
s->out_transpose)
4800 if (
s->in_transpose)
4810 default_h_fov = 90.f;
4811 default_v_fov = 45.f;