LCOV - code coverage report
Current view: top level - libavutil - color_utils.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 104 116 89.7 %
Date: 2017-10-20 23:03:07 Functions: 15 15 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <stddef.h>
      22             : #include <math.h>
      23             : 
      24             : #include "common.h"
      25             : #include "libavutil/color_utils.h"
      26             : #include "libavutil/pixfmt.h"
      27             : 
      28         241 : double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
      29             : {
      30             :     double gamma;
      31         241 :     switch (trc) {
      32           0 :         case AVCOL_TRC_BT709:
      33             :         case AVCOL_TRC_SMPTE170M:
      34             :         case AVCOL_TRC_SMPTE240M:
      35             :         case AVCOL_TRC_BT1361_ECG:
      36             :         case AVCOL_TRC_BT2020_10:
      37             :         case AVCOL_TRC_BT2020_12:
      38             :             /* these share a segmented TRC, but gamma 1.961 is a close
      39             :               approximation, and also more correct for decoding content */
      40           0 :             gamma = 1.961;
      41           0 :             break;
      42           0 :         case AVCOL_TRC_GAMMA22:
      43             :         case AVCOL_TRC_IEC61966_2_1:
      44           0 :             gamma = 2.2;
      45           0 :             break;
      46           0 :         case AVCOL_TRC_GAMMA28:
      47           0 :             gamma = 2.8;
      48           0 :             break;
      49           0 :         case AVCOL_TRC_LINEAR:
      50           0 :             gamma = 1.0;
      51           0 :             break;
      52         241 :         default:
      53         241 :             gamma = 0.0; // Unknown value representation
      54             :     }
      55         241 :     return gamma;
      56             : }
      57             : 
      58             : #define BT709_alpha 1.099296826809442
      59             : #define BT709_beta 0.018053968510807
      60             : 
      61          76 : static double avpriv_trc_bt709(double Lc)
      62             : {
      63          76 :     const double a = BT709_alpha;
      64          76 :     const double b = BT709_beta;
      65             : 
      66             :     return (0.0 > Lc) ? 0.0
      67         136 :          : (  b > Lc) ? 4.500 * Lc
      68          60 :          :              a * pow(Lc, 0.45) - (a - 1.0);
      69             : }
      70             : 
      71          19 : static double avpriv_trc_gamma22(double Lc)
      72             : {
      73          19 :     return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
      74             : }
      75             : 
      76          19 : static double avpriv_trc_gamma28(double Lc)
      77             : {
      78          19 :     return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
      79             : }
      80             : 
      81          19 : static double avpriv_trc_smpte240M(double Lc)
      82             : {
      83          19 :     const double a = 1.1115;
      84          19 :     const double b = 0.0228;
      85             : 
      86             :     return (0.0 > Lc) ? 0.0
      87          34 :          : (  b > Lc) ? 4.000 * Lc
      88          15 :          :              a * pow(Lc, 0.45) - (a - 1.0);
      89             : }
      90             : 
      91          19 : static double avpriv_trc_linear(double Lc)
      92             : {
      93          19 :     return Lc;
      94             : }
      95             : 
      96          19 : static double avpriv_trc_log(double Lc)
      97             : {
      98          19 :     return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
      99             : }
     100             : 
     101          19 : static double avpriv_trc_log_sqrt(double Lc)
     102             : {
     103             :     // sqrt(10) / 1000
     104          19 :     return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
     105             : }
     106             : 
     107          19 : static double avpriv_trc_iec61966_2_4(double Lc)
     108             : {
     109          19 :     const double a = BT709_alpha;
     110          19 :     const double b = BT709_beta;
     111             : 
     112          21 :     return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
     113          38 :          : ( b >  Lc) ? 4.500 * Lc
     114          17 :          :               a * pow( Lc, 0.45) - (a - 1.0);
     115             : }
     116             : 
     117          19 : static double avpriv_trc_bt1361(double Lc)
     118             : {
     119          19 :     const double a = BT709_alpha;
     120          19 :     const double b = BT709_beta;
     121             : 
     122           3 :     return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
     123          38 :          : ( b >  Lc) ? 4.500 * Lc
     124          16 :          :               a * pow( Lc, 0.45) - (a - 1.0);
     125             : }
     126             : 
     127          19 : static double avpriv_trc_iec61966_2_1(double Lc)
     128             : {
     129          19 :     const double a = 1.055;
     130          19 :     const double b = 0.0031308;
     131             : 
     132             :     return (0.0 > Lc) ? 0.0
     133          34 :          : (  b > Lc) ? 12.92 * Lc
     134          15 :          :              a * pow(Lc, 1.0  / 2.4) - (a - 1.0);
     135             : }
     136             : 
     137          19 : static double avpriv_trc_smpte_st2084(double Lc)
     138             : {
     139          19 :     const double c1 =         3424.0 / 4096.0; // c3-c2 + 1
     140          19 :     const double c2 =  32.0 * 2413.0 / 4096.0;
     141          19 :     const double c3 =  32.0 * 2392.0 / 4096.0;
     142          19 :     const double m  = 128.0 * 2523.0 / 4096.0;
     143          19 :     const double n  =  0.25 * 2610.0 / 4096.0;
     144          19 :     const double L  = Lc / 10000.0;
     145          19 :     const double Ln = pow(L, n);
     146             : 
     147             :     return (0.0 > Lc) ? 0.0
     148          19 :          :              pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
     149             : 
     150             : }
     151             : 
     152          19 : static double avpriv_trc_smpte_st428_1(double Lc)
     153             : {
     154             :     return (0.0 > Lc) ? 0.0
     155          19 :          :              pow(48.0 * Lc / 52.37, 1.0 / 2.6);
     156             : }
     157             : 
     158             : 
     159          19 : static double avpriv_trc_arib_std_b67(double Lc) {
     160             :     // The function uses the definition from HEVC, which assumes that the peak
     161             :     // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
     162             :     // using the definition from the ARIB STD-B67 spec)
     163          19 :     const double a = 0.17883277;
     164          19 :     const double b = 0.28466892;
     165          19 :     const double c = 0.55991073;
     166          34 :     return (0.0 > Lc) ? 0.0 :
     167          15 :         (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
     168             : }
     169             : 
     170        4665 : avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc)
     171             : {
     172        4665 :     avpriv_trc_function func = NULL;
     173        4665 :     switch (trc) {
     174           4 :         case AVCOL_TRC_BT709:
     175             :         case AVCOL_TRC_SMPTE170M:
     176             :         case AVCOL_TRC_BT2020_10:
     177             :         case AVCOL_TRC_BT2020_12:
     178           4 :             func = avpriv_trc_bt709;
     179           4 :             break;
     180             : 
     181           1 :         case AVCOL_TRC_GAMMA22:
     182           1 :             func = avpriv_trc_gamma22;
     183           1 :             break;
     184           1 :         case AVCOL_TRC_GAMMA28:
     185           1 :             func = avpriv_trc_gamma28;
     186           1 :             break;
     187             : 
     188           1 :         case AVCOL_TRC_SMPTE240M:
     189           1 :             func = avpriv_trc_smpte240M;
     190           1 :             break;
     191             : 
     192           1 :         case AVCOL_TRC_LINEAR:
     193           1 :             func = avpriv_trc_linear;
     194           1 :             break;
     195             : 
     196           1 :         case AVCOL_TRC_LOG:
     197           1 :             func = avpriv_trc_log;
     198           1 :             break;
     199             : 
     200           1 :         case AVCOL_TRC_LOG_SQRT:
     201           1 :             func = avpriv_trc_log_sqrt;
     202           1 :             break;
     203             : 
     204           1 :         case AVCOL_TRC_IEC61966_2_4:
     205           1 :             func = avpriv_trc_iec61966_2_4;
     206           1 :             break;
     207             : 
     208           1 :         case AVCOL_TRC_BT1361_ECG:
     209           1 :             func = avpriv_trc_bt1361;
     210           1 :             break;
     211             : 
     212           1 :         case AVCOL_TRC_IEC61966_2_1:
     213           1 :             func = avpriv_trc_iec61966_2_1;
     214           1 :             break;
     215             : 
     216           1 :         case AVCOL_TRC_SMPTEST2084:
     217           1 :             func = avpriv_trc_smpte_st2084;
     218           1 :             break;
     219             : 
     220           1 :         case AVCOL_TRC_SMPTEST428_1:
     221           1 :             func = avpriv_trc_smpte_st428_1;
     222           1 :             break;
     223             : 
     224           1 :         case AVCOL_TRC_ARIB_STD_B67:
     225           1 :             func = avpriv_trc_arib_std_b67;
     226           1 :             break;
     227             : 
     228        4649 :         case AVCOL_TRC_RESERVED0:
     229             :         case AVCOL_TRC_UNSPECIFIED:
     230             :         case AVCOL_TRC_RESERVED:
     231             :         default:
     232        4649 :             break;
     233             :     }
     234        4665 :     return func;
     235             : }

Generated by: LCOV version 1.13