LCOV - code coverage report
Current view: top level - media/libav/libavutil - parseutils.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 233 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * This file is part of Libav.
       3             :  *
       4             :  * Libav 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             :  * Libav 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 GNU
      12             :  * 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 Libav; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      17             :  */
      18             : 
      19             : /**
      20             :  * @file
      21             :  * misc parsing utilities
      22             :  */
      23             : 
      24             : #include <time.h>
      25             : 
      26             : #include "avstring.h"
      27             : #include "avutil.h"
      28             : #include "common.h"
      29             : #include "eval.h"
      30             : #include "log.h"
      31             : #include "random_seed.h"
      32             : #include "parseutils.h"
      33             : 
      34             : typedef struct {
      35             :     const char *abbr;
      36             :     int width, height;
      37             : } VideoSizeAbbr;
      38             : 
      39             : typedef struct {
      40             :     const char *abbr;
      41             :     AVRational rate;
      42             : } VideoRateAbbr;
      43             : 
      44             : static const VideoSizeAbbr video_size_abbrs[] = {
      45             :     { "ntsc",      720, 480 },
      46             :     { "pal",       720, 576 },
      47             :     { "qntsc",     352, 240 }, /* VCD compliant NTSC */
      48             :     { "qpal",      352, 288 }, /* VCD compliant PAL */
      49             :     { "sntsc",     640, 480 }, /* square pixel NTSC */
      50             :     { "spal",      768, 576 }, /* square pixel PAL */
      51             :     { "film",      352, 240 },
      52             :     { "ntsc-film", 352, 240 },
      53             :     { "sqcif",     128,  96 },
      54             :     { "qcif",      176, 144 },
      55             :     { "cif",       352, 288 },
      56             :     { "4cif",      704, 576 },
      57             :     { "16cif",    1408,1152 },
      58             :     { "qqvga",     160, 120 },
      59             :     { "qvga",      320, 240 },
      60             :     { "vga",       640, 480 },
      61             :     { "svga",      800, 600 },
      62             :     { "xga",      1024, 768 },
      63             :     { "uxga",     1600,1200 },
      64             :     { "qxga",     2048,1536 },
      65             :     { "sxga",     1280,1024 },
      66             :     { "qsxga",    2560,2048 },
      67             :     { "hsxga",    5120,4096 },
      68             :     { "wvga",      852, 480 },
      69             :     { "wxga",     1366, 768 },
      70             :     { "wsxga",    1600,1024 },
      71             :     { "wuxga",    1920,1200 },
      72             :     { "woxga",    2560,1600 },
      73             :     { "wqsxga",   3200,2048 },
      74             :     { "wquxga",   3840,2400 },
      75             :     { "whsxga",   6400,4096 },
      76             :     { "whuxga",   7680,4800 },
      77             :     { "cga",       320, 200 },
      78             :     { "ega",       640, 350 },
      79             :     { "hd480",     852, 480 },
      80             :     { "hd720",    1280, 720 },
      81             :     { "hd1080",   1920,1080 },
      82             : };
      83             : 
      84             : static const VideoRateAbbr video_rate_abbrs[]= {
      85             :     { "ntsc",      { 30000, 1001 } },
      86             :     { "pal",       {    25,    1 } },
      87             :     { "qntsc",     { 30000, 1001 } }, /* VCD compliant NTSC */
      88             :     { "qpal",      {    25,    1 } }, /* VCD compliant PAL */
      89             :     { "sntsc",     { 30000, 1001 } }, /* square pixel NTSC */
      90             :     { "spal",      {    25,    1 } }, /* square pixel PAL */
      91             :     { "film",      {    24,    1 } },
      92             :     { "ntsc-film", { 24000, 1001 } },
      93             : };
      94             : 
      95           0 : int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
      96             : {
      97             :     int i;
      98           0 :     int n = FF_ARRAY_ELEMS(video_size_abbrs);
      99             :     char *p;
     100           0 :     int width = 0, height = 0;
     101             : 
     102           0 :     for (i = 0; i < n; i++) {
     103           0 :         if (!strcmp(video_size_abbrs[i].abbr, str)) {
     104           0 :             width  = video_size_abbrs[i].width;
     105           0 :             height = video_size_abbrs[i].height;
     106           0 :             break;
     107             :         }
     108             :     }
     109           0 :     if (i == n) {
     110           0 :         width = strtol(str, &p, 10);
     111           0 :         if (*p)
     112           0 :             p++;
     113           0 :         height = strtol(p, &p, 10);
     114             :     }
     115           0 :     if (width <= 0 || height <= 0)
     116           0 :         return AVERROR(EINVAL);
     117           0 :     *width_ptr  = width;
     118           0 :     *height_ptr = height;
     119           0 :     return 0;
     120             : }
     121             : 
     122           0 : int av_parse_video_rate(AVRational *rate, const char *arg)
     123             : {
     124             :     int i, ret;
     125           0 :     int n = FF_ARRAY_ELEMS(video_rate_abbrs);
     126             :     double res;
     127             : 
     128             :     /* First, we check our abbreviation table */
     129           0 :     for (i = 0; i < n; ++i)
     130           0 :         if (!strcmp(video_rate_abbrs[i].abbr, arg)) {
     131           0 :             *rate = video_rate_abbrs[i].rate;
     132           0 :             return 0;
     133             :         }
     134             : 
     135             :     /* Then, we try to parse it as fraction */
     136           0 :     if ((ret = av_expr_parse_and_eval(&res, arg, NULL, NULL, NULL, NULL, NULL, NULL,
     137             :                                       NULL, 0, NULL)) < 0)
     138           0 :         return ret;
     139           0 :     *rate = av_d2q(res, 1001000);
     140           0 :     if (rate->num <= 0 || rate->den <= 0)
     141           0 :         return AVERROR(EINVAL);
     142           0 :     return 0;
     143             : }
     144             : 
     145             : typedef struct {
     146             :     const char *name;            ///< a string representing the name of the color
     147             :     uint8_t     rgb_color[3];    ///< RGB values for the color
     148             : } ColorEntry;
     149             : 
     150             : static ColorEntry color_table[] = {
     151             :     { "AliceBlue",            { 0xF0, 0xF8, 0xFF } },
     152             :     { "AntiqueWhite",         { 0xFA, 0xEB, 0xD7 } },
     153             :     { "Aqua",                 { 0x00, 0xFF, 0xFF } },
     154             :     { "Aquamarine",           { 0x7F, 0xFF, 0xD4 } },
     155             :     { "Azure",                { 0xF0, 0xFF, 0xFF } },
     156             :     { "Beige",                { 0xF5, 0xF5, 0xDC } },
     157             :     { "Bisque",               { 0xFF, 0xE4, 0xC4 } },
     158             :     { "Black",                { 0x00, 0x00, 0x00 } },
     159             :     { "BlanchedAlmond",       { 0xFF, 0xEB, 0xCD } },
     160             :     { "Blue",                 { 0x00, 0x00, 0xFF } },
     161             :     { "BlueViolet",           { 0x8A, 0x2B, 0xE2 } },
     162             :     { "Brown",                { 0xA5, 0x2A, 0x2A } },
     163             :     { "BurlyWood",            { 0xDE, 0xB8, 0x87 } },
     164             :     { "CadetBlue",            { 0x5F, 0x9E, 0xA0 } },
     165             :     { "Chartreuse",           { 0x7F, 0xFF, 0x00 } },
     166             :     { "Chocolate",            { 0xD2, 0x69, 0x1E } },
     167             :     { "Coral",                { 0xFF, 0x7F, 0x50 } },
     168             :     { "CornflowerBlue",       { 0x64, 0x95, 0xED } },
     169             :     { "Cornsilk",             { 0xFF, 0xF8, 0xDC } },
     170             :     { "Crimson",              { 0xDC, 0x14, 0x3C } },
     171             :     { "Cyan",                 { 0x00, 0xFF, 0xFF } },
     172             :     { "DarkBlue",             { 0x00, 0x00, 0x8B } },
     173             :     { "DarkCyan",             { 0x00, 0x8B, 0x8B } },
     174             :     { "DarkGoldenRod",        { 0xB8, 0x86, 0x0B } },
     175             :     { "DarkGray",             { 0xA9, 0xA9, 0xA9 } },
     176             :     { "DarkGreen",            { 0x00, 0x64, 0x00 } },
     177             :     { "DarkKhaki",            { 0xBD, 0xB7, 0x6B } },
     178             :     { "DarkMagenta",          { 0x8B, 0x00, 0x8B } },
     179             :     { "DarkOliveGreen",       { 0x55, 0x6B, 0x2F } },
     180             :     { "Darkorange",           { 0xFF, 0x8C, 0x00 } },
     181             :     { "DarkOrchid",           { 0x99, 0x32, 0xCC } },
     182             :     { "DarkRed",              { 0x8B, 0x00, 0x00 } },
     183             :     { "DarkSalmon",           { 0xE9, 0x96, 0x7A } },
     184             :     { "DarkSeaGreen",         { 0x8F, 0xBC, 0x8F } },
     185             :     { "DarkSlateBlue",        { 0x48, 0x3D, 0x8B } },
     186             :     { "DarkSlateGray",        { 0x2F, 0x4F, 0x4F } },
     187             :     { "DarkTurquoise",        { 0x00, 0xCE, 0xD1 } },
     188             :     { "DarkViolet",           { 0x94, 0x00, 0xD3 } },
     189             :     { "DeepPink",             { 0xFF, 0x14, 0x93 } },
     190             :     { "DeepSkyBlue",          { 0x00, 0xBF, 0xFF } },
     191             :     { "DimGray",              { 0x69, 0x69, 0x69 } },
     192             :     { "DodgerBlue",           { 0x1E, 0x90, 0xFF } },
     193             :     { "FireBrick",            { 0xB2, 0x22, 0x22 } },
     194             :     { "FloralWhite",          { 0xFF, 0xFA, 0xF0 } },
     195             :     { "ForestGreen",          { 0x22, 0x8B, 0x22 } },
     196             :     { "Fuchsia",              { 0xFF, 0x00, 0xFF } },
     197             :     { "Gainsboro",            { 0xDC, 0xDC, 0xDC } },
     198             :     { "GhostWhite",           { 0xF8, 0xF8, 0xFF } },
     199             :     { "Gold",                 { 0xFF, 0xD7, 0x00 } },
     200             :     { "GoldenRod",            { 0xDA, 0xA5, 0x20 } },
     201             :     { "Gray",                 { 0x80, 0x80, 0x80 } },
     202             :     { "Green",                { 0x00, 0x80, 0x00 } },
     203             :     { "GreenYellow",          { 0xAD, 0xFF, 0x2F } },
     204             :     { "HoneyDew",             { 0xF0, 0xFF, 0xF0 } },
     205             :     { "HotPink",              { 0xFF, 0x69, 0xB4 } },
     206             :     { "IndianRed",            { 0xCD, 0x5C, 0x5C } },
     207             :     { "Indigo",               { 0x4B, 0x00, 0x82 } },
     208             :     { "Ivory",                { 0xFF, 0xFF, 0xF0 } },
     209             :     { "Khaki",                { 0xF0, 0xE6, 0x8C } },
     210             :     { "Lavender",             { 0xE6, 0xE6, 0xFA } },
     211             :     { "LavenderBlush",        { 0xFF, 0xF0, 0xF5 } },
     212             :     { "LawnGreen",            { 0x7C, 0xFC, 0x00 } },
     213             :     { "LemonChiffon",         { 0xFF, 0xFA, 0xCD } },
     214             :     { "LightBlue",            { 0xAD, 0xD8, 0xE6 } },
     215             :     { "LightCoral",           { 0xF0, 0x80, 0x80 } },
     216             :     { "LightCyan",            { 0xE0, 0xFF, 0xFF } },
     217             :     { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
     218             :     { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
     219             :     { "LightGreen",           { 0x90, 0xEE, 0x90 } },
     220             :     { "LightPink",            { 0xFF, 0xB6, 0xC1 } },
     221             :     { "LightSalmon",          { 0xFF, 0xA0, 0x7A } },
     222             :     { "LightSeaGreen",        { 0x20, 0xB2, 0xAA } },
     223             :     { "LightSkyBlue",         { 0x87, 0xCE, 0xFA } },
     224             :     { "LightSlateGray",       { 0x77, 0x88, 0x99 } },
     225             :     { "LightSteelBlue",       { 0xB0, 0xC4, 0xDE } },
     226             :     { "LightYellow",          { 0xFF, 0xFF, 0xE0 } },
     227             :     { "Lime",                 { 0x00, 0xFF, 0x00 } },
     228             :     { "LimeGreen",            { 0x32, 0xCD, 0x32 } },
     229             :     { "Linen",                { 0xFA, 0xF0, 0xE6 } },
     230             :     { "Magenta",              { 0xFF, 0x00, 0xFF } },
     231             :     { "Maroon",               { 0x80, 0x00, 0x00 } },
     232             :     { "MediumAquaMarine",     { 0x66, 0xCD, 0xAA } },
     233             :     { "MediumBlue",           { 0x00, 0x00, 0xCD } },
     234             :     { "MediumOrchid",         { 0xBA, 0x55, 0xD3 } },
     235             :     { "MediumPurple",         { 0x93, 0x70, 0xD8 } },
     236             :     { "MediumSeaGreen",       { 0x3C, 0xB3, 0x71 } },
     237             :     { "MediumSlateBlue",      { 0x7B, 0x68, 0xEE } },
     238             :     { "MediumSpringGreen",    { 0x00, 0xFA, 0x9A } },
     239             :     { "MediumTurquoise",      { 0x48, 0xD1, 0xCC } },
     240             :     { "MediumVioletRed",      { 0xC7, 0x15, 0x85 } },
     241             :     { "MidnightBlue",         { 0x19, 0x19, 0x70 } },
     242             :     { "MintCream",            { 0xF5, 0xFF, 0xFA } },
     243             :     { "MistyRose",            { 0xFF, 0xE4, 0xE1 } },
     244             :     { "Moccasin",             { 0xFF, 0xE4, 0xB5 } },
     245             :     { "NavajoWhite",          { 0xFF, 0xDE, 0xAD } },
     246             :     { "Navy",                 { 0x00, 0x00, 0x80 } },
     247             :     { "OldLace",              { 0xFD, 0xF5, 0xE6 } },
     248             :     { "Olive",                { 0x80, 0x80, 0x00 } },
     249             :     { "OliveDrab",            { 0x6B, 0x8E, 0x23 } },
     250             :     { "Orange",               { 0xFF, 0xA5, 0x00 } },
     251             :     { "OrangeRed",            { 0xFF, 0x45, 0x00 } },
     252             :     { "Orchid",               { 0xDA, 0x70, 0xD6 } },
     253             :     { "PaleGoldenRod",        { 0xEE, 0xE8, 0xAA } },
     254             :     { "PaleGreen",            { 0x98, 0xFB, 0x98 } },
     255             :     { "PaleTurquoise",        { 0xAF, 0xEE, 0xEE } },
     256             :     { "PaleVioletRed",        { 0xD8, 0x70, 0x93 } },
     257             :     { "PapayaWhip",           { 0xFF, 0xEF, 0xD5 } },
     258             :     { "PeachPuff",            { 0xFF, 0xDA, 0xB9 } },
     259             :     { "Peru",                 { 0xCD, 0x85, 0x3F } },
     260             :     { "Pink",                 { 0xFF, 0xC0, 0xCB } },
     261             :     { "Plum",                 { 0xDD, 0xA0, 0xDD } },
     262             :     { "PowderBlue",           { 0xB0, 0xE0, 0xE6 } },
     263             :     { "Purple",               { 0x80, 0x00, 0x80 } },
     264             :     { "Red",                  { 0xFF, 0x00, 0x00 } },
     265             :     { "RosyBrown",            { 0xBC, 0x8F, 0x8F } },
     266             :     { "RoyalBlue",            { 0x41, 0x69, 0xE1 } },
     267             :     { "SaddleBrown",          { 0x8B, 0x45, 0x13 } },
     268             :     { "Salmon",               { 0xFA, 0x80, 0x72 } },
     269             :     { "SandyBrown",           { 0xF4, 0xA4, 0x60 } },
     270             :     { "SeaGreen",             { 0x2E, 0x8B, 0x57 } },
     271             :     { "SeaShell",             { 0xFF, 0xF5, 0xEE } },
     272             :     { "Sienna",               { 0xA0, 0x52, 0x2D } },
     273             :     { "Silver",               { 0xC0, 0xC0, 0xC0 } },
     274             :     { "SkyBlue",              { 0x87, 0xCE, 0xEB } },
     275             :     { "SlateBlue",            { 0x6A, 0x5A, 0xCD } },
     276             :     { "SlateGray",            { 0x70, 0x80, 0x90 } },
     277             :     { "Snow",                 { 0xFF, 0xFA, 0xFA } },
     278             :     { "SpringGreen",          { 0x00, 0xFF, 0x7F } },
     279             :     { "SteelBlue",            { 0x46, 0x82, 0xB4 } },
     280             :     { "Tan",                  { 0xD2, 0xB4, 0x8C } },
     281             :     { "Teal",                 { 0x00, 0x80, 0x80 } },
     282             :     { "Thistle",              { 0xD8, 0xBF, 0xD8 } },
     283             :     { "Tomato",               { 0xFF, 0x63, 0x47 } },
     284             :     { "Turquoise",            { 0x40, 0xE0, 0xD0 } },
     285             :     { "Violet",               { 0xEE, 0x82, 0xEE } },
     286             :     { "Wheat",                { 0xF5, 0xDE, 0xB3 } },
     287             :     { "White",                { 0xFF, 0xFF, 0xFF } },
     288             :     { "WhiteSmoke",           { 0xF5, 0xF5, 0xF5 } },
     289             :     { "Yellow",               { 0xFF, 0xFF, 0x00 } },
     290             :     { "YellowGreen",          { 0x9A, 0xCD, 0x32 } },
     291             : };
     292             : 
     293           0 : static int color_table_compare(const void *lhs, const void *rhs)
     294             : {
     295           0 :     return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
     296             : }
     297             : 
     298             : #define ALPHA_SEP '@'
     299             : 
     300           0 : int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
     301             :                    void *log_ctx)
     302             : {
     303             :     char *tail, color_string2[128];
     304             :     const ColorEntry *entry;
     305           0 :     int len, hex_offset = 0;
     306             : 
     307           0 :     if (color_string[0] == '#') {
     308           0 :         hex_offset = 1;
     309           0 :     } else if (!strncmp(color_string, "0x", 2))
     310           0 :         hex_offset = 2;
     311             : 
     312           0 :     if (slen < 0)
     313           0 :         slen = strlen(color_string);
     314           0 :     av_strlcpy(color_string2, color_string + hex_offset,
     315           0 :                FFMIN(slen-hex_offset+1, sizeof(color_string2)));
     316           0 :     if ((tail = strchr(color_string2, ALPHA_SEP)))
     317           0 :         *tail++ = 0;
     318           0 :     len = strlen(color_string2);
     319           0 :     rgba_color[3] = 255;
     320             : 
     321           0 :     if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
     322           0 :         int rgba = av_get_random_seed();
     323           0 :         rgba_color[0] = rgba >> 24;
     324           0 :         rgba_color[1] = rgba >> 16;
     325           0 :         rgba_color[2] = rgba >> 8;
     326           0 :         rgba_color[3] = rgba;
     327           0 :     } else if (hex_offset ||
     328           0 :                strspn(color_string2, "0123456789ABCDEFabcdef") == len) {
     329             :         char *tail;
     330           0 :         unsigned int rgba = strtoul(color_string2, &tail, 16);
     331             : 
     332           0 :         if (*tail || (len != 6 && len != 8)) {
     333           0 :             av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
     334           0 :             return AVERROR(EINVAL);
     335             :         }
     336           0 :         if (len == 8) {
     337           0 :             rgba_color[3] = rgba;
     338           0 :             rgba >>= 8;
     339             :         }
     340           0 :         rgba_color[0] = rgba >> 16;
     341           0 :         rgba_color[1] = rgba >> 8;
     342           0 :         rgba_color[2] = rgba;
     343             :     } else {
     344           0 :         entry = bsearch(color_string2,
     345             :                         color_table,
     346             :                         FF_ARRAY_ELEMS(color_table),
     347             :                         sizeof(ColorEntry),
     348             :                         color_table_compare);
     349           0 :         if (!entry) {
     350           0 :             av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
     351           0 :             return AVERROR(EINVAL);
     352             :         }
     353           0 :         memcpy(rgba_color, entry->rgb_color, 3);
     354             :     }
     355             : 
     356           0 :     if (tail) {
     357             :         double alpha;
     358           0 :         const char *alpha_string = tail;
     359           0 :         if (!strncmp(alpha_string, "0x", 2)) {
     360           0 :             alpha = strtoul(alpha_string, &tail, 16);
     361             :         } else {
     362           0 :             alpha = 255 * strtod(alpha_string, &tail);
     363             :         }
     364             : 
     365           0 :         if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) {
     366           0 :             av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
     367             :                    alpha_string, color_string);
     368           0 :             return AVERROR(EINVAL);
     369             :         }
     370           0 :         rgba_color[3] = alpha;
     371             :     }
     372             : 
     373           0 :     return 0;
     374             : }
     375             : 
     376             : /* get a positive number between n_min and n_max, for a maximum length
     377             :    of len_max. Return -1 if error. */
     378           0 : static int date_get_num(const char **pp,
     379             :                         int n_min, int n_max, int len_max)
     380             : {
     381             :     int i, val, c;
     382             :     const char *p;
     383             : 
     384           0 :     p = *pp;
     385           0 :     val = 0;
     386           0 :     for(i = 0; i < len_max; i++) {
     387           0 :         c = *p;
     388           0 :         if (!av_isdigit(c))
     389           0 :             break;
     390           0 :         val = (val * 10) + c - '0';
     391           0 :         p++;
     392             :     }
     393             :     /* no number read ? */
     394           0 :     if (p == *pp)
     395           0 :         return -1;
     396           0 :     if (val < n_min || val > n_max)
     397           0 :         return -1;
     398           0 :     *pp = p;
     399           0 :     return val;
     400             : }
     401             : 
     402           0 : static const char *small_strptime(const char *p, const char *fmt, struct tm *dt)
     403             : {
     404             :     int c, val;
     405             : 
     406             :     for(;;) {
     407           0 :         c = *fmt++;
     408           0 :         if (c == '\0') {
     409           0 :             return p;
     410           0 :         } else if (c == '%') {
     411           0 :             c = *fmt++;
     412           0 :             switch(c) {
     413             :             case 'H':
     414           0 :                 val = date_get_num(&p, 0, 23, 2);
     415           0 :                 if (val == -1)
     416           0 :                     return NULL;
     417           0 :                 dt->tm_hour = val;
     418           0 :                 break;
     419             :             case 'M':
     420           0 :                 val = date_get_num(&p, 0, 59, 2);
     421           0 :                 if (val == -1)
     422           0 :                     return NULL;
     423           0 :                 dt->tm_min = val;
     424           0 :                 break;
     425             :             case 'S':
     426           0 :                 val = date_get_num(&p, 0, 59, 2);
     427           0 :                 if (val == -1)
     428           0 :                     return NULL;
     429           0 :                 dt->tm_sec = val;
     430           0 :                 break;
     431             :             case 'Y':
     432           0 :                 val = date_get_num(&p, 0, 9999, 4);
     433           0 :                 if (val == -1)
     434           0 :                     return NULL;
     435           0 :                 dt->tm_year = val - 1900;
     436           0 :                 break;
     437             :             case 'm':
     438           0 :                 val = date_get_num(&p, 1, 12, 2);
     439           0 :                 if (val == -1)
     440           0 :                     return NULL;
     441           0 :                 dt->tm_mon = val - 1;
     442           0 :                 break;
     443             :             case 'd':
     444           0 :                 val = date_get_num(&p, 1, 31, 2);
     445           0 :                 if (val == -1)
     446           0 :                     return NULL;
     447           0 :                 dt->tm_mday = val;
     448           0 :                 break;
     449             :             case '%':
     450           0 :                 goto match;
     451             :             default:
     452           0 :                 return NULL;
     453             :             }
     454             :         } else {
     455             :         match:
     456           0 :             if (c != *p)
     457           0 :                 return NULL;
     458           0 :             p++;
     459             :         }
     460             :     }
     461             : }
     462             : 
     463           0 : time_t av_timegm(struct tm *tm)
     464             : {
     465             :     time_t t;
     466             : 
     467           0 :     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
     468             : 
     469           0 :     if (m < 3) {
     470           0 :         m += 12;
     471           0 :         y--;
     472             :     }
     473             : 
     474           0 :     t = 86400 *
     475           0 :         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
     476             : 
     477           0 :     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
     478             : 
     479           0 :     return t;
     480             : }
     481             : 
     482           0 : int av_parse_time(int64_t *timeval, const char *timestr, int duration)
     483             : {
     484             :     const char *p;
     485             :     int64_t t;
     486           0 :     struct tm dt = { 0 };
     487             :     int i;
     488             :     static const char * const date_fmt[] = {
     489             :         "%Y-%m-%d",
     490             :         "%Y%m%d",
     491             :     };
     492             :     static const char * const time_fmt[] = {
     493             :         "%H:%M:%S",
     494             :         "%H%M%S",
     495             :     };
     496             :     const char *q;
     497             :     int is_utc, len;
     498             :     char lastch;
     499           0 :     int negative = 0;
     500             : 
     501           0 :     time_t now = time(0);
     502             : 
     503           0 :     len = strlen(timestr);
     504           0 :     if (len > 0)
     505           0 :         lastch = timestr[len - 1];
     506             :     else
     507           0 :         lastch = '\0';
     508           0 :     is_utc = (lastch == 'z' || lastch == 'Z');
     509             : 
     510           0 :     p = timestr;
     511           0 :     q = NULL;
     512           0 :     if (!duration) {
     513           0 :         if (!av_strncasecmp(timestr, "now", len)) {
     514           0 :             *timeval = (int64_t) now * 1000000;
     515           0 :             return 0;
     516             :         }
     517             : 
     518             :         /* parse the year-month-day part */
     519           0 :         for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
     520           0 :             q = small_strptime(p, date_fmt[i], &dt);
     521           0 :             if (q) {
     522           0 :                 break;
     523             :             }
     524             :         }
     525             : 
     526             :         /* if the year-month-day part is missing, then take the
     527             :          * current year-month-day time */
     528           0 :         if (!q) {
     529           0 :             if (is_utc) {
     530           0 :                 dt = *gmtime(&now);
     531             :             } else {
     532           0 :                 dt = *localtime(&now);
     533             :             }
     534           0 :             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
     535             :         } else {
     536           0 :             p = q;
     537             :         }
     538             : 
     539           0 :         if (*p == 'T' || *p == 't' || *p == ' ')
     540           0 :             p++;
     541             : 
     542             :         /* parse the hour-minute-second part */
     543           0 :         for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
     544           0 :             q = small_strptime(p, time_fmt[i], &dt);
     545           0 :             if (q) {
     546           0 :                 break;
     547             :             }
     548             :         }
     549             :     } else {
     550             :         /* parse timestr as a duration */
     551           0 :         if (p[0] == '-') {
     552           0 :             negative = 1;
     553           0 :             ++p;
     554             :         }
     555             :         /* parse timestr as HH:MM:SS */
     556           0 :         q = small_strptime(p, time_fmt[0], &dt);
     557           0 :         if (!q) {
     558             :             char *o;
     559             :             /* parse timestr as S+ */
     560           0 :             dt.tm_sec = strtol(p, &o, 10);
     561           0 :             if (o == p) {
     562             :                 /* the parsing didn't succeed */
     563           0 :                 *timeval = INT64_MIN;
     564           0 :                 return AVERROR(EINVAL);
     565             :             }
     566           0 :             dt.tm_min = 0;
     567           0 :             dt.tm_hour = 0;
     568           0 :             q = o;
     569             :         }
     570             :     }
     571             : 
     572             :     /* Now we have all the fields that we can get */
     573           0 :     if (!q) {
     574           0 :         *timeval = INT64_MIN;
     575           0 :         return AVERROR(EINVAL);
     576             :     }
     577             : 
     578           0 :     if (duration) {
     579           0 :         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
     580             :     } else {
     581           0 :         dt.tm_isdst = -1;       /* unknown */
     582           0 :         if (is_utc) {
     583           0 :             t = av_timegm(&dt);
     584             :         } else {
     585           0 :             t = mktime(&dt);
     586             :         }
     587             :     }
     588             : 
     589           0 :     t *= 1000000;
     590             : 
     591             :     /* parse the .m... part */
     592           0 :     if (*q == '.') {
     593             :         int val, n;
     594           0 :         q++;
     595           0 :         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
     596           0 :             if (!av_isdigit(*q))
     597           0 :                 break;
     598           0 :             val += n * (*q - '0');
     599             :         }
     600           0 :         t += val;
     601             :     }
     602           0 :     *timeval = negative ? -t : t;
     603           0 :     return 0;
     604             : }
     605             : 
     606           0 : int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
     607             : {
     608             :     const char *p;
     609             :     char tag[128], *q;
     610             : 
     611           0 :     p = info;
     612           0 :     if (*p == '?')
     613           0 :         p++;
     614             :     for(;;) {
     615           0 :         q = tag;
     616           0 :         while (*p != '\0' && *p != '=' && *p != '&') {
     617           0 :             if ((q - tag) < sizeof(tag) - 1)
     618           0 :                 *q++ = *p;
     619           0 :             p++;
     620             :         }
     621           0 :         *q = '\0';
     622           0 :         q = arg;
     623           0 :         if (*p == '=') {
     624           0 :             p++;
     625           0 :             while (*p != '&' && *p != '\0') {
     626           0 :                 if ((q - arg) < arg_size - 1) {
     627           0 :                     if (*p == '+')
     628           0 :                         *q++ = ' ';
     629             :                     else
     630           0 :                         *q++ = *p;
     631             :                 }
     632           0 :                 p++;
     633             :             }
     634             :         }
     635           0 :         *q = '\0';
     636           0 :         if (!strcmp(tag, tag1))
     637           0 :             return 1;
     638           0 :         if (*p != '&')
     639           0 :             break;
     640           0 :         p++;
     641             :     }
     642           0 :     return 0;
     643             : }
     644             : 
     645             : #ifdef TEST
     646             : 
     647             : int main(void)
     648             : {
     649             :     printf("Testing av_parse_video_rate()\n");
     650             :     {
     651             :         int i;
     652             :         static const char *const rates[] = {
     653             :             "-inf",
     654             :             "inf",
     655             :             "nan",
     656             :             "123/0",
     657             :             "-123 / 0",
     658             :             "",
     659             :             "/",
     660             :             " 123  /  321",
     661             :             "foo/foo",
     662             :             "foo/1",
     663             :             "1/foo",
     664             :             "0/0",
     665             :             "/0",
     666             :             "1/",
     667             :             "1",
     668             :             "0",
     669             :             "-123/123",
     670             :             "-foo",
     671             :             "123.23",
     672             :             ".23",
     673             :             "-.23",
     674             :             "-0.234",
     675             :             "-0.0000001",
     676             :             "  21332.2324   ",
     677             :             " -21332.2324   ",
     678             :         };
     679             : 
     680             :         for (i = 0; i < FF_ARRAY_ELEMS(rates); i++) {
     681             :             int ret;
     682             :             AVRational q = { 0, 0 };
     683             :             ret = av_parse_video_rate(&q, rates[i]);
     684             :             printf("'%s' -> %d/%d %s\n",
     685             :                    rates[i], q.num, q.den, ret ? "ERROR" : "OK");
     686             :         }
     687             :     }
     688             : 
     689             :     printf("\nTesting av_parse_color()\n");
     690             :     {
     691             :         int i;
     692             :         uint8_t rgba[4];
     693             :         static const char *const color_names[] = {
     694             :             "foo",
     695             :             "red",
     696             :             "Red ",
     697             :             "RED",
     698             :             "Violet",
     699             :             "Yellow",
     700             :             "Red",
     701             :             "0x000000",
     702             :             "0x0000000",
     703             :             "0xff000000",
     704             :             "0x3e34ff",
     705             :             "0x3e34ffaa",
     706             :             "0xffXXee",
     707             :             "0xfoobar",
     708             :             "0xffffeeeeeeee",
     709             :             "#ff0000",
     710             :             "#ffXX00",
     711             :             "ff0000",
     712             :             "ffXX00",
     713             :             "red@foo",
     714             :             "random@10",
     715             :             "0xff0000@1.0",
     716             :             "red@",
     717             :             "red@0xfff",
     718             :             "red@0xf",
     719             :             "red@2",
     720             :             "red@0.1",
     721             :             "red@-1",
     722             :             "red@0.5",
     723             :             "red@1.0",
     724             :             "red@256",
     725             :             "red@10foo",
     726             :             "red@-1.0",
     727             :             "red@-0.0",
     728             :         };
     729             : 
     730             :         av_log_set_level(AV_LOG_DEBUG);
     731             : 
     732             :         for (i = 0;  i < FF_ARRAY_ELEMS(color_names); i++) {
     733             :             if (av_parse_color(rgba, color_names[i], -1, NULL) >= 0)
     734             :                 printf("%s -> R(%d) G(%d) B(%d) A(%d)\n",
     735             :                        color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
     736             :         }
     737             :     }
     738             : 
     739             :     return 0;
     740             : }
     741             : 
     742             : #endif /* TEST */

Generated by: LCOV version 1.13