LCOV - code coverage report
Current view: top level - src - common.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 241 282 85.5 %
Date: 2025-03-29 09:04:10 Functions: 32 38 84.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 60 75 80.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file is part of libplacebo.
       3                 :            :  *
       4                 :            :  * libplacebo is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Lesser General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2.1 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * libplacebo is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12                 :            :  * GNU Lesser General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Lesser General Public
      15                 :            :  * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include <math.h>
      19                 :            : 
      20                 :            : #include "common.h"
      21                 :            : #include "version.h"
      22                 :            : 
      23                 :            : #include <libplacebo/common.h>
      24                 :            : 
      25                 :          0 : int pl_fix_ver(void)
      26                 :            : {
      27                 :          0 :     return BUILD_FIX_VER;
      28                 :            : }
      29                 :            : 
      30                 :         11 : const char *pl_version(void)
      31                 :            : {
      32                 :         11 :     return BUILD_VERSION;
      33                 :            : }
      34                 :            : 
      35                 :       1898 : void pl_rect2d_normalize(pl_rect2d *rc)
      36                 :            : {
      37                 :       1898 :     *rc = (pl_rect2d) {
      38                 :       1898 :         .x0 = PL_MIN(rc->x0, rc->x1),
      39                 :       1898 :         .x1 = PL_MAX(rc->x0, rc->x1),
      40                 :       1898 :         .y0 = PL_MIN(rc->y0, rc->y1),
      41                 :       1898 :         .y1 = PL_MAX(rc->y0, rc->y1),
      42                 :            :     };
      43                 :       1898 : }
      44                 :            : 
      45                 :        409 : void pl_rect3d_normalize(pl_rect3d *rc)
      46                 :            : {
      47                 :        409 :     *rc = (pl_rect3d) {
      48                 :        409 :         .x0 = PL_MIN(rc->x0, rc->x1),
      49                 :        409 :         .x1 = PL_MAX(rc->x0, rc->x1),
      50                 :        409 :         .y0 = PL_MIN(rc->y0, rc->y1),
      51                 :        409 :         .y1 = PL_MAX(rc->y0, rc->y1),
      52                 :        409 :         .z0 = PL_MIN(rc->z0, rc->z1),
      53                 :        409 :         .z1 = PL_MAX(rc->z0, rc->z1),
      54                 :            :     };
      55                 :        409 : }
      56                 :            : 
      57                 :       3930 : void pl_rect2df_normalize(pl_rect2df *rc)
      58                 :            : {
      59                 :       3930 :     *rc = (pl_rect2df) {
      60         [ +  + ]:       3930 :         .x0 = PL_MIN(rc->x0, rc->x1),
      61         [ +  + ]:       3930 :         .x1 = PL_MAX(rc->x0, rc->x1),
      62         [ +  + ]:       3930 :         .y0 = PL_MIN(rc->y0, rc->y1),
      63         [ +  + ]:       3930 :         .y1 = PL_MAX(rc->y0, rc->y1),
      64                 :            :     };
      65                 :       3930 : }
      66                 :            : 
      67                 :          1 : void pl_rect3df_normalize(pl_rect3df *rc)
      68                 :            : {
      69                 :          1 :     *rc = (pl_rect3df) {
      70         [ +  - ]:          1 :         .x0 = PL_MIN(rc->x0, rc->x1),
      71         [ -  + ]:          1 :         .x1 = PL_MAX(rc->x0, rc->x1),
      72         [ +  - ]:          1 :         .y0 = PL_MIN(rc->y0, rc->y1),
      73         [ -  + ]:          1 :         .y1 = PL_MAX(rc->y0, rc->y1),
      74         [ +  - ]:          1 :         .z0 = PL_MIN(rc->z0, rc->z1),
      75         [ -  + ]:          1 :         .z1 = PL_MAX(rc->z0, rc->z1),
      76                 :            :     };
      77                 :          1 : }
      78                 :            : 
      79                 :          1 : pl_rect2d pl_rect2df_round(const pl_rect2df *rc)
      80                 :            : {
      81                 :          1 :     return (pl_rect2d) {
      82                 :          1 :         .x0 = roundf(rc->x0),
      83                 :          1 :         .x1 = roundf(rc->x1),
      84                 :          1 :         .y0 = roundf(rc->y0),
      85                 :          1 :         .y1 = roundf(rc->y1),
      86                 :            :     };
      87                 :            : }
      88                 :            : 
      89                 :          1 : pl_rect3d pl_rect3df_round(const pl_rect3df *rc)
      90                 :            : {
      91                 :          1 :     return (pl_rect3d) {
      92                 :          1 :         .x0 = roundf(rc->x0),
      93                 :          1 :         .x1 = roundf(rc->x1),
      94                 :          1 :         .y0 = roundf(rc->y0),
      95                 :          1 :         .y1 = roundf(rc->y1),
      96                 :          1 :         .z0 = roundf(rc->z0),
      97                 :          1 :         .z1 = roundf(rc->z1),
      98                 :            :     };
      99                 :            : }
     100                 :            : 
     101                 :            : const pl_matrix3x3 pl_matrix3x3_identity = {{
     102                 :            :     { 1, 0, 0 },
     103                 :            :     { 0, 1, 0 },
     104                 :            :     { 0, 0, 1 },
     105                 :            : }};
     106                 :            : 
     107                 :        271 : void pl_matrix3x3_apply(const pl_matrix3x3 *mat, float vec[3])
     108                 :            : {
     109                 :        271 :     float x = vec[0], y = vec[1], z = vec[2];
     110                 :            : 
     111         [ +  + ]:       1084 :     for (int i = 0; i < 3; i++)
     112                 :        813 :         vec[i] = mat->m[i][0] * x + mat->m[i][1] * y + mat->m[i][2] * z;
     113                 :        271 : }
     114                 :            : 
     115                 :          0 : void pl_matrix3x3_apply_rc(const pl_matrix3x3 *mat, pl_rect3df *rc)
     116                 :            : {
     117                 :          0 :     float x0 = rc->x0, x1 = rc->x1,
     118                 :          0 :           y0 = rc->y0, y1 = rc->y1,
     119                 :          0 :           z0 = rc->z0, z1 = rc->z1;
     120                 :            : 
     121                 :          0 :     rc->x0 = mat->m[0][0] * x0 + mat->m[0][1] * y0 + mat->m[0][2] * z0;
     122                 :          0 :     rc->y0 = mat->m[1][0] * x0 + mat->m[1][1] * y0 + mat->m[1][2] * z0;
     123                 :          0 :     rc->z0 = mat->m[2][0] * x0 + mat->m[2][1] * y0 + mat->m[2][2] * z0;
     124                 :            : 
     125                 :          0 :     rc->x1 = mat->m[0][0] * x1 + mat->m[0][1] * y1 + mat->m[0][2] * z1;
     126                 :          0 :     rc->y1 = mat->m[1][0] * x1 + mat->m[1][1] * y1 + mat->m[1][2] * z1;
     127                 :          0 :     rc->z1 = mat->m[2][0] * x1 + mat->m[2][1] * y1 + mat->m[2][2] * z1;
     128                 :          0 : }
     129                 :            : 
     130                 :        989 : void pl_matrix3x3_scale(pl_matrix3x3 *mat, float scale)
     131                 :            : {
     132         [ +  + ]:       3956 :     for (int i = 0; i < 3; i++) {
     133         [ +  + ]:      11868 :         for (int j = 0; j < 3; j++)
     134                 :       8901 :             mat->m[i][j] *= scale;
     135                 :            :     }
     136                 :        989 : }
     137                 :            : 
     138                 :       5908 : void pl_matrix3x3_invert(pl_matrix3x3 *mat)
     139                 :            : {
     140                 :       5908 :     double m00 = mat->m[0][0], m01 = mat->m[0][1], m02 = mat->m[0][2],
     141                 :       5908 :            m10 = mat->m[1][0], m11 = mat->m[1][1], m12 = mat->m[1][2],
     142                 :       5908 :            m20 = mat->m[2][0], m21 = mat->m[2][1], m22 = mat->m[2][2];
     143                 :            : 
     144                 :            :     // calculate the adjoint
     145                 :       5908 :     double a00 =  (m11 * m22 - m21 * m12);
     146                 :       5908 :     double a01 = -(m01 * m22 - m21 * m02);
     147                 :       5908 :     double a02 =  (m01 * m12 - m11 * m02);
     148                 :       5908 :     double a10 = -(m10 * m22 - m20 * m12);
     149                 :       5908 :     double a11 =  (m00 * m22 - m20 * m02);
     150                 :       5908 :     double a12 = -(m00 * m12 - m10 * m02);
     151                 :       5908 :     double a20 =  (m10 * m21 - m20 * m11);
     152                 :       5908 :     double a21 = -(m00 * m21 - m20 * m01);
     153                 :       5908 :     double a22 =  (m00 * m11 - m10 * m01);
     154                 :            : 
     155                 :            :     // calculate the determinant (as inverse == 1/det * adjoint,
     156                 :            :     // adjoint * m == identity * det, so this calculates the det)
     157                 :       5908 :     double det = m00 * a00 + m10 * a01 + m20 * a02;
     158                 :       5908 :     det = 1.0 / det;
     159                 :            : 
     160                 :       5908 :     mat->m[0][0] = det * a00;
     161                 :       5908 :     mat->m[0][1] = det * a01;
     162                 :       5908 :     mat->m[0][2] = det * a02;
     163                 :       5908 :     mat->m[1][0] = det * a10;
     164                 :       5908 :     mat->m[1][1] = det * a11;
     165                 :       5908 :     mat->m[1][2] = det * a12;
     166                 :       5908 :     mat->m[2][0] = det * a20;
     167                 :       5908 :     mat->m[2][1] = det * a21;
     168                 :       5908 :     mat->m[2][2] = det * a22;
     169                 :       5908 : }
     170                 :            : 
     171                 :       3328 : void pl_matrix3x3_mul(pl_matrix3x3 *a, const pl_matrix3x3 *b)
     172                 :            : {
     173                 :       3328 :     float a00 = a->m[0][0], a01 = a->m[0][1], a02 = a->m[0][2],
     174                 :       3328 :           a10 = a->m[1][0], a11 = a->m[1][1], a12 = a->m[1][2],
     175                 :       3328 :           a20 = a->m[2][0], a21 = a->m[2][1], a22 = a->m[2][2];
     176                 :            : 
     177         [ +  + ]:      13312 :     for (int i = 0; i < 3; i++) {
     178                 :       9984 :         a->m[0][i] = a00 * b->m[0][i] + a01 * b->m[1][i] + a02 * b->m[2][i];
     179                 :       9984 :         a->m[1][i] = a10 * b->m[0][i] + a11 * b->m[1][i] + a12 * b->m[2][i];
     180                 :       9984 :         a->m[2][i] = a20 * b->m[0][i] + a21 * b->m[1][i] + a22 * b->m[2][i];
     181                 :            :     }
     182                 :       3328 : }
     183                 :            : 
     184                 :          4 : void pl_matrix3x3_rmul(const pl_matrix3x3 *a, pl_matrix3x3 *b)
     185                 :            : {
     186                 :          4 :     pl_matrix3x3 m = *a;
     187                 :          4 :     pl_matrix3x3_mul(&m, b);
     188                 :          4 :     *b = m;
     189                 :          4 : }
     190                 :            : 
     191                 :            : const pl_transform3x3 pl_transform3x3_identity = {
     192                 :            :     .mat = {{
     193                 :            :         { 1, 0, 0 },
     194                 :            :         { 0, 1, 0 },
     195                 :            :         { 0, 0, 1 },
     196                 :            :     }},
     197                 :            : };
     198                 :            : 
     199                 :        135 : void pl_transform3x3_apply(const pl_transform3x3 *t, float vec[3])
     200                 :            : {
     201                 :        135 :     pl_matrix3x3_apply(&t->mat, vec);
     202                 :            : 
     203         [ +  + ]:        540 :     for (int i = 0; i < 3; i++)
     204                 :        405 :         vec[i] += t->c[i];
     205                 :        135 : }
     206                 :            : 
     207                 :          0 : void pl_transform3x3_apply_rc(const pl_transform3x3 *t, pl_rect3df *rc)
     208                 :            : {
     209                 :          0 :     pl_matrix3x3_apply_rc(&t->mat, rc);
     210                 :            : 
     211                 :          0 :     rc->x0 += t->c[0];
     212                 :          0 :     rc->x1 += t->c[0];
     213                 :          0 :     rc->y0 += t->c[1];
     214                 :          0 :     rc->y1 += t->c[1];
     215                 :          0 :     rc->z0 += t->c[2];
     216                 :          0 :     rc->z1 += t->c[2];
     217                 :          0 : }
     218                 :            : 
     219                 :          2 : void pl_transform3x3_scale(pl_transform3x3 *t, float scale)
     220                 :            : {
     221                 :          2 :     pl_matrix3x3_scale(&t->mat, scale);
     222                 :            : 
     223         [ +  + ]:          8 :     for (int i = 0; i < 3; i++)
     224                 :          6 :         t->c[i] *= scale;
     225                 :          2 : }
     226                 :            : 
     227                 :            : // based on DarkPlaces engine (relicensed from GPL to LGPL)
     228                 :        145 : void pl_transform3x3_invert(pl_transform3x3 *t)
     229                 :            : {
     230                 :        145 :     pl_matrix3x3_invert(&t->mat);
     231                 :            : 
     232                 :        145 :     float m00 = t->mat.m[0][0], m01 = t->mat.m[0][1], m02 = t->mat.m[0][2],
     233                 :        145 :           m10 = t->mat.m[1][0], m11 = t->mat.m[1][1], m12 = t->mat.m[1][2],
     234                 :        145 :           m20 = t->mat.m[2][0], m21 = t->mat.m[2][1], m22 = t->mat.m[2][2];
     235                 :            : 
     236                 :            :     // fix the constant coefficient
     237                 :            :     // rgb = M * yuv + C
     238                 :            :     // M^-1 * rgb = yuv + M^-1 * C
     239                 :            :     // yuv = M^-1 * rgb - M^-1 * C
     240                 :            :     //                  ^^^^^^^^^^
     241                 :        145 :     float c0 = t->c[0], c1 = t->c[1], c2 = t->c[2];
     242                 :        145 :     t->c[0] = -(m00 * c0 + m01 * c1 + m02 * c2);
     243                 :        145 :     t->c[1] = -(m10 * c0 + m11 * c1 + m12 * c2);
     244                 :        145 :     t->c[2] = -(m20 * c0 + m21 * c1 + m22 * c2);
     245                 :        145 : }
     246                 :            : 
     247                 :            : const pl_matrix2x2 pl_matrix2x2_identity = {{
     248                 :            :     { 1, 0 },
     249                 :            :     { 0, 1 },
     250                 :            : }};
     251                 :            : 
     252                 :          0 : pl_matrix2x2 pl_matrix2x2_rotation(float a)
     253                 :            : {
     254                 :          0 :     return (pl_matrix2x2) {{
     255                 :          0 :         { cosf(a), -sinf(a) },
     256                 :            :         { sinf(a),  cosf(a) },
     257                 :            :     }};
     258                 :            : }
     259                 :            : 
     260                 :        280 : void pl_matrix2x2_apply(const pl_matrix2x2 *mat, float vec[2])
     261                 :            : {
     262                 :        280 :     float x = vec[0], y = vec[1];
     263                 :            : 
     264         [ +  + ]:        840 :     for (int i = 0; i < 2; i++)
     265                 :        560 :         vec[i] = mat->m[i][0] * x + mat->m[i][1] * y;
     266                 :        280 : }
     267                 :            : 
     268                 :          0 : void pl_matrix2x2_apply_rc(const pl_matrix2x2 *mat, pl_rect2df *rc)
     269                 :            : {
     270                 :          0 :     float x0 = rc->x0, x1 = rc->x1,
     271                 :          0 :           y0 = rc->y0, y1 = rc->y1;
     272                 :            : 
     273                 :          0 :     rc->x0 = mat->m[0][0] * x0 + mat->m[0][1] * y0;
     274                 :          0 :     rc->y0 = mat->m[1][0] * x0 + mat->m[1][1] * y0;
     275                 :            : 
     276                 :          0 :     rc->x1 = mat->m[0][0] * x1 + mat->m[0][1] * y1;
     277                 :          0 :     rc->y1 = mat->m[1][0] * x1 + mat->m[1][1] * y1;
     278                 :          0 : }
     279                 :            : 
     280                 :         72 : void pl_matrix2x2_mul(pl_matrix2x2 *a, const pl_matrix2x2 *b)
     281                 :            : {
     282                 :         72 :     float a00 = a->m[0][0], a01 = a->m[0][1],
     283                 :         72 :           a10 = a->m[1][0], a11 = a->m[1][1];
     284                 :            : 
     285         [ +  + ]:        216 :     for (int i = 0; i < 2; i++) {
     286                 :        144 :         a->m[0][i] = a00 * b->m[0][i] + a01 * b->m[1][i];
     287                 :        144 :         a->m[1][i] = a10 * b->m[0][i] + a11 * b->m[1][i];
     288                 :            :     }
     289                 :         72 : }
     290                 :            : 
     291                 :         48 : void pl_matrix2x2_rmul(const pl_matrix2x2 *a, pl_matrix2x2 *b)
     292                 :            : {
     293                 :         48 :     pl_matrix2x2 m = *a;
     294                 :         48 :     pl_matrix2x2_mul(&m, b);
     295                 :         48 :     *b = m;
     296                 :         48 : }
     297                 :            : 
     298                 :          4 : void pl_matrix2x2_scale(pl_matrix2x2 *mat, float scale)
     299                 :            : {
     300         [ +  + ]:         12 :     for (int i = 0; i < 2; i++) {
     301         [ +  + ]:         24 :         for (int j = 0; j < 2; j++)
     302                 :         16 :             mat->m[i][j] *= scale;
     303                 :            :     }
     304                 :          4 : }
     305                 :            : 
     306                 :         24 : void pl_matrix2x2_invert(pl_matrix2x2 *mat)
     307                 :            : {
     308                 :         24 :     float m00 = mat->m[0][0], m01 = mat->m[0][1],
     309                 :         24 :           m10 = mat->m[1][0], m11 = mat->m[1][1];
     310                 :         24 :     float invdet = 1.0f / (m11 * m00 - m10 * m01);
     311                 :            : 
     312                 :         24 :     mat->m[0][0] =  m11 * invdet;
     313                 :         24 :     mat->m[0][1] = -m01 * invdet;
     314                 :         24 :     mat->m[1][0] = -m10 * invdet;
     315                 :         24 :     mat->m[1][1] =  m00 * invdet;
     316                 :         24 : }
     317                 :            : 
     318                 :            : const pl_transform2x2 pl_transform2x2_identity = {
     319                 :            :     .mat = {{
     320                 :            :         { 1, 0 },
     321                 :            :         { 0, 1 },
     322                 :            :     }},
     323                 :            : };
     324                 :            : 
     325                 :        280 : void pl_transform2x2_apply(const pl_transform2x2 *t, float vec[2])
     326                 :            : {
     327                 :        280 :     pl_matrix2x2_apply(&t->mat, vec);
     328                 :            : 
     329         [ +  + ]:        840 :     for (int i = 0; i < 2; i++)
     330                 :        560 :         vec[i] += t->c[i];
     331                 :        280 : }
     332                 :            : 
     333                 :          0 : void pl_transform2x2_apply_rc(const pl_transform2x2 *t, pl_rect2df *rc)
     334                 :            : {
     335                 :          0 :     pl_matrix2x2_apply_rc(&t->mat, rc);
     336                 :            : 
     337                 :          0 :     rc->x0 += t->c[0];
     338                 :          0 :     rc->x1 += t->c[0];
     339                 :          0 :     rc->y0 += t->c[1];
     340                 :          0 :     rc->y1 += t->c[1];
     341                 :          0 : }
     342                 :            : 
     343                 :         24 : void pl_transform2x2_mul(pl_transform2x2 *a, const pl_transform2x2 *b)
     344                 :            : {
     345                 :         24 :     float c[2] = { b->c[0], b->c[1] };
     346                 :         24 :     pl_transform2x2_apply(a, c);
     347                 :         24 :     memcpy(a->c, c, sizeof(c));
     348                 :         24 :     pl_matrix2x2_mul(&a->mat, &b->mat);
     349                 :         24 : }
     350                 :            : 
     351                 :         48 : void pl_transform2x2_rmul(const pl_transform2x2 *a, pl_transform2x2 *b)
     352                 :            : {
     353                 :         48 :     pl_transform2x2_apply(a, b->c);
     354                 :         48 :     pl_matrix2x2_rmul(&a->mat, &b->mat);
     355                 :         48 : }
     356                 :            : 
     357                 :          4 : void pl_transform2x2_scale(pl_transform2x2 *t, float scale)
     358                 :            : {
     359                 :          4 :     pl_matrix2x2_scale(&t->mat, scale);
     360                 :            : 
     361         [ +  + ]:         12 :     for (int i = 0; i < 2; i++)
     362                 :          8 :         t->c[i] *= scale;
     363                 :          4 : }
     364                 :            : 
     365                 :         24 : void pl_transform2x2_invert(pl_transform2x2 *t)
     366                 :            : {
     367                 :         24 :     pl_matrix2x2_invert(&t->mat);
     368                 :            : 
     369                 :         24 :     float m00 = t->mat.m[0][0], m01 = t->mat.m[0][1],
     370                 :         24 :           m10 = t->mat.m[1][0], m11 = t->mat.m[1][1];
     371                 :         24 :     float c0 = t->c[0], c1 = t->c[1];
     372                 :         24 :     t->c[0] = -(m00 * c0 + m01 * c1);
     373                 :         24 :     t->c[1] = -(m10 * c0 + m11 * c1);
     374                 :         24 : }
     375                 :            : 
     376                 :         28 : pl_rect2df pl_transform2x2_bounds(const pl_transform2x2 *t, const pl_rect2df *rc)
     377                 :            : {
     378                 :         28 :     float p[4][2] = {
     379                 :         28 :         { rc->x0, rc->y0 },
     380                 :         28 :         { rc->x0, rc->y1 },
     381                 :         28 :         { rc->x1, rc->y0 },
     382                 :            :         { rc->x1, rc->y1 },
     383                 :            :     };
     384         [ +  + ]:        140 :     for (int i = 0; i < PL_ARRAY_SIZE(p); i++)
     385                 :        112 :         pl_transform2x2_apply(t, p[i]);
     386                 :            : 
     387                 :         28 :     return (pl_rect2df) {
     388                 :         28 :         .x0 = fminf(fminf(p[0][0], p[1][0]), fminf(p[2][0], p[3][0])),
     389                 :         28 :         .x1 = fmaxf(fmaxf(p[0][0], p[1][0]), fmaxf(p[2][0], p[3][0])),
     390                 :         28 :         .y0 = fminf(fminf(p[0][1], p[1][1]), fminf(p[2][1], p[3][1])),
     391                 :         28 :         .y1 = fmaxf(fmaxf(p[0][1], p[1][1]), fmaxf(p[2][1], p[3][1])),
     392                 :            :     };
     393                 :            : }
     394                 :            : 
     395                 :         74 : float pl_rect2df_aspect(const pl_rect2df *rc)
     396                 :            : {
     397                 :         74 :     float w = fabsf(pl_rect_w(*rc)), h = fabsf(pl_rect_h(*rc));
     398         [ +  - ]:         74 :     return h ? (w / h) : 0.0;
     399                 :            : }
     400                 :            : 
     401                 :         22 : void pl_rect2df_aspect_set(pl_rect2df *rc, float aspect, float panscan)
     402                 :            : {
     403         [ -  + ]:         22 :     pl_assert(aspect >= 0);
     404                 :         22 :     float orig_aspect = pl_rect2df_aspect(rc);
     405         [ +  - ]:         22 :     if (!aspect || !orig_aspect)
     406                 :            :         return;
     407                 :            : 
     408                 :            :     float scale_x, scale_y;
     409         [ +  + ]:         22 :     if (aspect > orig_aspect) {
     410                 :            :         // New aspect is wider than the original, so we need to either grow in
     411                 :            :         // scale_x (panscan=1) or shrink in scale_y (panscan=0)
     412                 :         10 :         scale_x = powf(aspect / orig_aspect, panscan);
     413                 :         10 :         scale_y = powf(aspect / orig_aspect, panscan - 1.0);
     414         [ +  - ]:         12 :     } else if (aspect < orig_aspect) {
     415                 :            :         // New aspect is taller, so either grow in scale_y (panscan=1) or
     416                 :            :         // shrink in scale_x (panscan=0)
     417                 :         12 :         scale_x = powf(orig_aspect / aspect, panscan - 1.0);
     418                 :         12 :         scale_y = powf(orig_aspect / aspect, panscan);
     419                 :            :     } else {
     420                 :            :         return; // No change in aspect
     421                 :            :     }
     422                 :            : 
     423                 :         22 :     pl_rect2df_stretch(rc, scale_x, scale_y);
     424                 :            : }
     425                 :            : 
     426                 :          2 : void pl_rect2df_aspect_fit(pl_rect2df *rc, const pl_rect2df *src, float panscan)
     427                 :            : {
     428                 :          2 :     float orig_w = fabs(pl_rect_w(*rc)),
     429                 :          2 :           orig_h = fabs(pl_rect_h(*rc));
     430         [ +  - ]:          2 :     if (!orig_w || !orig_h)
     431                 :            :         return;
     432                 :            : 
     433                 :            :     // If either one of these is larger than 1, then we need to shrink to fit,
     434                 :            :     // otherwise we can just directly stretch the rect.
     435                 :          2 :     float scale_x = fabs(pl_rect_w(*src)) / orig_w,
     436                 :          2 :           scale_y = fabs(pl_rect_h(*src)) / orig_h;
     437                 :            : 
     438   [ +  +  -  + ]:          2 :     if (scale_x > 1.0 || scale_y > 1.0) {
     439                 :          1 :         pl_rect2df_aspect_copy(rc, src, panscan);
     440                 :            :     } else {
     441                 :          1 :         pl_rect2df_stretch(rc, scale_x, scale_y);
     442                 :            :     }
     443                 :            : }
     444                 :            : 
     445                 :         51 : void pl_rect2df_stretch(pl_rect2df *rc, float stretch_x, float stretch_y)
     446                 :            : {
     447                 :         51 :     float midx = (rc->x0 + rc->x1) / 2.0,
     448                 :         51 :           midy = (rc->y0 + rc->y1) / 2.0;
     449                 :            : 
     450                 :         51 :     rc->x0 = rc->x0 * stretch_x + midx * (1.0 - stretch_x);
     451                 :         51 :     rc->x1 = rc->x1 * stretch_x + midx * (1.0 - stretch_x);
     452                 :         51 :     rc->y0 = rc->y0 * stretch_y + midy * (1.0 - stretch_y);
     453                 :         51 :     rc->y1 = rc->y1 * stretch_y + midy * (1.0 - stretch_y);
     454                 :         51 : }
     455                 :            : 
     456                 :          1 : void pl_rect2df_offset(pl_rect2df *rc, float offset_x, float offset_y)
     457                 :            : {
     458         [ +  - ]:          1 :     if (rc->x1 < rc->x0)
     459                 :          1 :         offset_x = -offset_x;
     460         [ +  - ]:          1 :     if (rc->y1 < rc->y0)
     461                 :          1 :         offset_y = -offset_y;
     462                 :            : 
     463                 :          1 :     rc->x0 += offset_x;
     464                 :          1 :     rc->x1 += offset_x;
     465                 :          1 :     rc->y0 += offset_y;
     466                 :          1 :     rc->y1 += offset_y;
     467                 :          1 : }
     468                 :            : 
     469         [ +  + ]:       1437 : void pl_rect2df_rotate(pl_rect2df *rc, pl_rotation rot)
     470                 :            : {
     471         [ +  + ]:       1437 :     if (!(rot = pl_rotation_normalize(rot)))
     472                 :            :         return;
     473                 :            : 
     474                 :        952 :     float x0 = rc->x0, y0 = rc->y0, x1 = rc->x1, y1 = rc->y1;
     475         [ +  + ]:        952 :     if (rot >= PL_ROTATION_180) {
     476                 :          8 :         rot -= PL_ROTATION_180;
     477                 :            :         PL_SWAP(x0, x1);
     478                 :            :         PL_SWAP(y0, y1);
     479                 :            :     }
     480                 :            : 
     481      [ +  +  - ]:        952 :     switch (rot) {
     482                 :          4 :     case PL_ROTATION_0:
     483                 :          4 :         *rc = (pl_rect2df) {
     484                 :            :             .x0 = x0,
     485                 :            :             .y0 = y0,
     486                 :            :             .x1 = x1,
     487                 :            :             .y1 = y1,
     488                 :            :         };
     489                 :          4 :         return;
     490                 :        948 :     case PL_ROTATION_90:
     491                 :        948 :         *rc = (pl_rect2df) {
     492                 :            :             .x0 = y1,
     493                 :            :             .y0 = x0,
     494                 :            :             .x1 = y0,
     495                 :            :             .y1 = x1,
     496                 :            :         };
     497                 :        948 :         return;
     498                 :          0 :     default: pl_unreachable();
     499                 :            :     }
     500                 :            : }

Generated by: LCOV version 1.16