• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavutil/parseutils.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of Libav.
00003  *
00004  * Libav is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * Libav is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with Libav; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00017  */
00018 
00024 #include <sys/time.h>
00025 #include <time.h>
00026 
00027 #include "avstring.h"
00028 #include "avutil.h"
00029 #include "eval.h"
00030 #include "log.h"
00031 #include "random_seed.h"
00032 #include "parseutils.h"
00033 
00034 typedef struct {
00035     const char *abbr;
00036     int width, height;
00037 } VideoSizeAbbr;
00038 
00039 typedef struct {
00040     const char *abbr;
00041     AVRational rate;
00042 } VideoRateAbbr;
00043 
00044 static const VideoSizeAbbr video_size_abbrs[] = {
00045     { "ntsc",      720, 480 },
00046     { "pal",       720, 576 },
00047     { "qntsc",     352, 240 }, /* VCD compliant NTSC */
00048     { "qpal",      352, 288 }, /* VCD compliant PAL */
00049     { "sntsc",     640, 480 }, /* square pixel NTSC */
00050     { "spal",      768, 576 }, /* square pixel PAL */
00051     { "film",      352, 240 },
00052     { "ntsc-film", 352, 240 },
00053     { "sqcif",     128,  96 },
00054     { "qcif",      176, 144 },
00055     { "cif",       352, 288 },
00056     { "4cif",      704, 576 },
00057     { "16cif",    1408,1152 },
00058     { "qqvga",     160, 120 },
00059     { "qvga",      320, 240 },
00060     { "vga",       640, 480 },
00061     { "svga",      800, 600 },
00062     { "xga",      1024, 768 },
00063     { "uxga",     1600,1200 },
00064     { "qxga",     2048,1536 },
00065     { "sxga",     1280,1024 },
00066     { "qsxga",    2560,2048 },
00067     { "hsxga",    5120,4096 },
00068     { "wvga",      852, 480 },
00069     { "wxga",     1366, 768 },
00070     { "wsxga",    1600,1024 },
00071     { "wuxga",    1920,1200 },
00072     { "woxga",    2560,1600 },
00073     { "wqsxga",   3200,2048 },
00074     { "wquxga",   3840,2400 },
00075     { "whsxga",   6400,4096 },
00076     { "whuxga",   7680,4800 },
00077     { "cga",       320, 200 },
00078     { "ega",       640, 350 },
00079     { "hd480",     852, 480 },
00080     { "hd720",    1280, 720 },
00081     { "hd1080",   1920,1080 },
00082 };
00083 
00084 static const VideoRateAbbr video_rate_abbrs[]= {
00085     { "ntsc",      { 30000, 1001 } },
00086     { "pal",       {    25,    1 } },
00087     { "qntsc",     { 30000, 1001 } }, /* VCD compliant NTSC */
00088     { "qpal",      {    25,    1 } }, /* VCD compliant PAL */
00089     { "sntsc",     { 30000, 1001 } }, /* square pixel NTSC */
00090     { "spal",      {    25,    1 } }, /* square pixel PAL */
00091     { "film",      {    24,    1 } },
00092     { "ntsc-film", { 24000, 1001 } },
00093 };
00094 
00095 int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
00096 {
00097     int i;
00098     int n = FF_ARRAY_ELEMS(video_size_abbrs);
00099     char *p;
00100     int width = 0, height = 0;
00101 
00102     for (i = 0; i < n; i++) {
00103         if (!strcmp(video_size_abbrs[i].abbr, str)) {
00104             width  = video_size_abbrs[i].width;
00105             height = video_size_abbrs[i].height;
00106             break;
00107         }
00108     }
00109     if (i == n) {
00110         p = str;
00111         width = strtol(p, &p, 10);
00112         if (*p)
00113             p++;
00114         height = strtol(p, &p, 10);
00115     }
00116     if (width <= 0 || height <= 0)
00117         return AVERROR(EINVAL);
00118     *width_ptr  = width;
00119     *height_ptr = height;
00120     return 0;
00121 }
00122 
00123 int av_parse_video_rate(AVRational *rate, const char *arg)
00124 {
00125     int i, ret;
00126     int n = FF_ARRAY_ELEMS(video_rate_abbrs);
00127     double res;
00128 
00129     /* First, we check our abbreviation table */
00130     for (i = 0; i < n; ++i)
00131         if (!strcmp(video_rate_abbrs[i].abbr, arg)) {
00132             *rate = video_rate_abbrs[i].rate;
00133             return 0;
00134         }
00135 
00136     /* Then, we try to parse it as fraction */
00137     if ((ret = av_expr_parse_and_eval(&res, arg, NULL, NULL, NULL, NULL, NULL, NULL,
00138                                       NULL, 0, NULL)) < 0)
00139         return ret;
00140     *rate = av_d2q(res, 1001000);
00141     if (rate->num <= 0 || rate->den <= 0)
00142         return AVERROR(EINVAL);
00143     return 0;
00144 }
00145 
00146 typedef struct {
00147     const char *name;            
00148     uint8_t     rgb_color[3];    
00149 } ColorEntry;
00150 
00151 static ColorEntry color_table[] = {
00152     { "AliceBlue",            { 0xF0, 0xF8, 0xFF } },
00153     { "AntiqueWhite",         { 0xFA, 0xEB, 0xD7 } },
00154     { "Aqua",                 { 0x00, 0xFF, 0xFF } },
00155     { "Aquamarine",           { 0x7F, 0xFF, 0xD4 } },
00156     { "Azure",                { 0xF0, 0xFF, 0xFF } },
00157     { "Beige",                { 0xF5, 0xF5, 0xDC } },
00158     { "Bisque",               { 0xFF, 0xE4, 0xC4 } },
00159     { "Black",                { 0x00, 0x00, 0x00 } },
00160     { "BlanchedAlmond",       { 0xFF, 0xEB, 0xCD } },
00161     { "Blue",                 { 0x00, 0x00, 0xFF } },
00162     { "BlueViolet",           { 0x8A, 0x2B, 0xE2 } },
00163     { "Brown",                { 0xA5, 0x2A, 0x2A } },
00164     { "BurlyWood",            { 0xDE, 0xB8, 0x87 } },
00165     { "CadetBlue",            { 0x5F, 0x9E, 0xA0 } },
00166     { "Chartreuse",           { 0x7F, 0xFF, 0x00 } },
00167     { "Chocolate",            { 0xD2, 0x69, 0x1E } },
00168     { "Coral",                { 0xFF, 0x7F, 0x50 } },
00169     { "CornflowerBlue",       { 0x64, 0x95, 0xED } },
00170     { "Cornsilk",             { 0xFF, 0xF8, 0xDC } },
00171     { "Crimson",              { 0xDC, 0x14, 0x3C } },
00172     { "Cyan",                 { 0x00, 0xFF, 0xFF } },
00173     { "DarkBlue",             { 0x00, 0x00, 0x8B } },
00174     { "DarkCyan",             { 0x00, 0x8B, 0x8B } },
00175     { "DarkGoldenRod",        { 0xB8, 0x86, 0x0B } },
00176     { "DarkGray",             { 0xA9, 0xA9, 0xA9 } },
00177     { "DarkGreen",            { 0x00, 0x64, 0x00 } },
00178     { "DarkKhaki",            { 0xBD, 0xB7, 0x6B } },
00179     { "DarkMagenta",          { 0x8B, 0x00, 0x8B } },
00180     { "DarkOliveGreen",       { 0x55, 0x6B, 0x2F } },
00181     { "Darkorange",           { 0xFF, 0x8C, 0x00 } },
00182     { "DarkOrchid",           { 0x99, 0x32, 0xCC } },
00183     { "DarkRed",              { 0x8B, 0x00, 0x00 } },
00184     { "DarkSalmon",           { 0xE9, 0x96, 0x7A } },
00185     { "DarkSeaGreen",         { 0x8F, 0xBC, 0x8F } },
00186     { "DarkSlateBlue",        { 0x48, 0x3D, 0x8B } },
00187     { "DarkSlateGray",        { 0x2F, 0x4F, 0x4F } },
00188     { "DarkTurquoise",        { 0x00, 0xCE, 0xD1 } },
00189     { "DarkViolet",           { 0x94, 0x00, 0xD3 } },
00190     { "DeepPink",             { 0xFF, 0x14, 0x93 } },
00191     { "DeepSkyBlue",          { 0x00, 0xBF, 0xFF } },
00192     { "DimGray",              { 0x69, 0x69, 0x69 } },
00193     { "DodgerBlue",           { 0x1E, 0x90, 0xFF } },
00194     { "FireBrick",            { 0xB2, 0x22, 0x22 } },
00195     { "FloralWhite",          { 0xFF, 0xFA, 0xF0 } },
00196     { "ForestGreen",          { 0x22, 0x8B, 0x22 } },
00197     { "Fuchsia",              { 0xFF, 0x00, 0xFF } },
00198     { "Gainsboro",            { 0xDC, 0xDC, 0xDC } },
00199     { "GhostWhite",           { 0xF8, 0xF8, 0xFF } },
00200     { "Gold",                 { 0xFF, 0xD7, 0x00 } },
00201     { "GoldenRod",            { 0xDA, 0xA5, 0x20 } },
00202     { "Gray",                 { 0x80, 0x80, 0x80 } },
00203     { "Green",                { 0x00, 0x80, 0x00 } },
00204     { "GreenYellow",          { 0xAD, 0xFF, 0x2F } },
00205     { "HoneyDew",             { 0xF0, 0xFF, 0xF0 } },
00206     { "HotPink",              { 0xFF, 0x69, 0xB4 } },
00207     { "IndianRed",            { 0xCD, 0x5C, 0x5C } },
00208     { "Indigo",               { 0x4B, 0x00, 0x82 } },
00209     { "Ivory",                { 0xFF, 0xFF, 0xF0 } },
00210     { "Khaki",                { 0xF0, 0xE6, 0x8C } },
00211     { "Lavender",             { 0xE6, 0xE6, 0xFA } },
00212     { "LavenderBlush",        { 0xFF, 0xF0, 0xF5 } },
00213     { "LawnGreen",            { 0x7C, 0xFC, 0x00 } },
00214     { "LemonChiffon",         { 0xFF, 0xFA, 0xCD } },
00215     { "LightBlue",            { 0xAD, 0xD8, 0xE6 } },
00216     { "LightCoral",           { 0xF0, 0x80, 0x80 } },
00217     { "LightCyan",            { 0xE0, 0xFF, 0xFF } },
00218     { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
00219     { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
00220     { "LightGreen",           { 0x90, 0xEE, 0x90 } },
00221     { "LightPink",            { 0xFF, 0xB6, 0xC1 } },
00222     { "LightSalmon",          { 0xFF, 0xA0, 0x7A } },
00223     { "LightSeaGreen",        { 0x20, 0xB2, 0xAA } },
00224     { "LightSkyBlue",         { 0x87, 0xCE, 0xFA } },
00225     { "LightSlateGray",       { 0x77, 0x88, 0x99 } },
00226     { "LightSteelBlue",       { 0xB0, 0xC4, 0xDE } },
00227     { "LightYellow",          { 0xFF, 0xFF, 0xE0 } },
00228     { "Lime",                 { 0x00, 0xFF, 0x00 } },
00229     { "LimeGreen",            { 0x32, 0xCD, 0x32 } },
00230     { "Linen",                { 0xFA, 0xF0, 0xE6 } },
00231     { "Magenta",              { 0xFF, 0x00, 0xFF } },
00232     { "Maroon",               { 0x80, 0x00, 0x00 } },
00233     { "MediumAquaMarine",     { 0x66, 0xCD, 0xAA } },
00234     { "MediumBlue",           { 0x00, 0x00, 0xCD } },
00235     { "MediumOrchid",         { 0xBA, 0x55, 0xD3 } },
00236     { "MediumPurple",         { 0x93, 0x70, 0xD8 } },
00237     { "MediumSeaGreen",       { 0x3C, 0xB3, 0x71 } },
00238     { "MediumSlateBlue",      { 0x7B, 0x68, 0xEE } },
00239     { "MediumSpringGreen",    { 0x00, 0xFA, 0x9A } },
00240     { "MediumTurquoise",      { 0x48, 0xD1, 0xCC } },
00241     { "MediumVioletRed",      { 0xC7, 0x15, 0x85 } },
00242     { "MidnightBlue",         { 0x19, 0x19, 0x70 } },
00243     { "MintCream",            { 0xF5, 0xFF, 0xFA } },
00244     { "MistyRose",            { 0xFF, 0xE4, 0xE1 } },
00245     { "Moccasin",             { 0xFF, 0xE4, 0xB5 } },
00246     { "NavajoWhite",          { 0xFF, 0xDE, 0xAD } },
00247     { "Navy",                 { 0x00, 0x00, 0x80 } },
00248     { "OldLace",              { 0xFD, 0xF5, 0xE6 } },
00249     { "Olive",                { 0x80, 0x80, 0x00 } },
00250     { "OliveDrab",            { 0x6B, 0x8E, 0x23 } },
00251     { "Orange",               { 0xFF, 0xA5, 0x00 } },
00252     { "OrangeRed",            { 0xFF, 0x45, 0x00 } },
00253     { "Orchid",               { 0xDA, 0x70, 0xD6 } },
00254     { "PaleGoldenRod",        { 0xEE, 0xE8, 0xAA } },
00255     { "PaleGreen",            { 0x98, 0xFB, 0x98 } },
00256     { "PaleTurquoise",        { 0xAF, 0xEE, 0xEE } },
00257     { "PaleVioletRed",        { 0xD8, 0x70, 0x93 } },
00258     { "PapayaWhip",           { 0xFF, 0xEF, 0xD5 } },
00259     { "PeachPuff",            { 0xFF, 0xDA, 0xB9 } },
00260     { "Peru",                 { 0xCD, 0x85, 0x3F } },
00261     { "Pink",                 { 0xFF, 0xC0, 0xCB } },
00262     { "Plum",                 { 0xDD, 0xA0, 0xDD } },
00263     { "PowderBlue",           { 0xB0, 0xE0, 0xE6 } },
00264     { "Purple",               { 0x80, 0x00, 0x80 } },
00265     { "Red",                  { 0xFF, 0x00, 0x00 } },
00266     { "RosyBrown",            { 0xBC, 0x8F, 0x8F } },
00267     { "RoyalBlue",            { 0x41, 0x69, 0xE1 } },
00268     { "SaddleBrown",          { 0x8B, 0x45, 0x13 } },
00269     { "Salmon",               { 0xFA, 0x80, 0x72 } },
00270     { "SandyBrown",           { 0xF4, 0xA4, 0x60 } },
00271     { "SeaGreen",             { 0x2E, 0x8B, 0x57 } },
00272     { "SeaShell",             { 0xFF, 0xF5, 0xEE } },
00273     { "Sienna",               { 0xA0, 0x52, 0x2D } },
00274     { "Silver",               { 0xC0, 0xC0, 0xC0 } },
00275     { "SkyBlue",              { 0x87, 0xCE, 0xEB } },
00276     { "SlateBlue",            { 0x6A, 0x5A, 0xCD } },
00277     { "SlateGray",            { 0x70, 0x80, 0x90 } },
00278     { "Snow",                 { 0xFF, 0xFA, 0xFA } },
00279     { "SpringGreen",          { 0x00, 0xFF, 0x7F } },
00280     { "SteelBlue",            { 0x46, 0x82, 0xB4 } },
00281     { "Tan",                  { 0xD2, 0xB4, 0x8C } },
00282     { "Teal",                 { 0x00, 0x80, 0x80 } },
00283     { "Thistle",              { 0xD8, 0xBF, 0xD8 } },
00284     { "Tomato",               { 0xFF, 0x63, 0x47 } },
00285     { "Turquoise",            { 0x40, 0xE0, 0xD0 } },
00286     { "Violet",               { 0xEE, 0x82, 0xEE } },
00287     { "Wheat",                { 0xF5, 0xDE, 0xB3 } },
00288     { "White",                { 0xFF, 0xFF, 0xFF } },
00289     { "WhiteSmoke",           { 0xF5, 0xF5, 0xF5 } },
00290     { "Yellow",               { 0xFF, 0xFF, 0x00 } },
00291     { "YellowGreen",          { 0x9A, 0xCD, 0x32 } },
00292 };
00293 
00294 static int color_table_compare(const void *lhs, const void *rhs)
00295 {
00296     return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
00297 }
00298 
00299 #define ALPHA_SEP '@'
00300 
00301 int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
00302                    void *log_ctx)
00303 {
00304     char *tail, color_string2[128];
00305     const ColorEntry *entry;
00306     int len, hex_offset = 0;
00307 
00308     if (color_string[0] == '#') {
00309         hex_offset = 1;
00310     } else if (!strncmp(color_string, "0x", 2))
00311         hex_offset = 2;
00312 
00313     if (slen < 0)
00314         slen = strlen(color_string);
00315     av_strlcpy(color_string2, color_string + hex_offset,
00316                FFMIN(slen-hex_offset+1, sizeof(color_string2)));
00317     if ((tail = strchr(color_string2, ALPHA_SEP)))
00318         *tail++ = 0;
00319     len = strlen(color_string2);
00320     rgba_color[3] = 255;
00321 
00322     if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
00323         int rgba = av_get_random_seed();
00324         rgba_color[0] = rgba >> 24;
00325         rgba_color[1] = rgba >> 16;
00326         rgba_color[2] = rgba >> 8;
00327         rgba_color[3] = rgba;
00328     } else if (hex_offset ||
00329                strspn(color_string2, "0123456789ABCDEFabcdef") == len) {
00330         char *tail;
00331         unsigned int rgba = strtoul(color_string2, &tail, 16);
00332 
00333         if (*tail || (len != 6 && len != 8)) {
00334             av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
00335             return AVERROR(EINVAL);
00336         }
00337         if (len == 8) {
00338             rgba_color[3] = rgba;
00339             rgba >>= 8;
00340         }
00341         rgba_color[0] = rgba >> 16;
00342         rgba_color[1] = rgba >> 8;
00343         rgba_color[2] = rgba;
00344     } else {
00345         entry = bsearch(color_string2,
00346                         color_table,
00347                         FF_ARRAY_ELEMS(color_table),
00348                         sizeof(ColorEntry),
00349                         color_table_compare);
00350         if (!entry) {
00351             av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
00352             return AVERROR(EINVAL);
00353         }
00354         memcpy(rgba_color, entry->rgb_color, 3);
00355     }
00356 
00357     if (tail) {
00358         unsigned long int alpha;
00359         const char *alpha_string = tail;
00360         if (!strncmp(alpha_string, "0x", 2)) {
00361             alpha = strtoul(alpha_string, &tail, 16);
00362         } else {
00363             alpha = 255 * strtod(alpha_string, &tail);
00364         }
00365 
00366         if (tail == alpha_string || *tail || alpha > 255) {
00367             av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
00368                    alpha_string, color_string);
00369             return AVERROR(EINVAL);
00370         }
00371         rgba_color[3] = alpha;
00372     }
00373 
00374     return 0;
00375 }
00376 
00377 /* get a positive number between n_min and n_max, for a maximum length
00378    of len_max. Return -1 if error. */
00379 static int date_get_num(const char **pp,
00380                         int n_min, int n_max, int len_max)
00381 {
00382     int i, val, c;
00383     const char *p;
00384 
00385     p = *pp;
00386     val = 0;
00387     for(i = 0; i < len_max; i++) {
00388         c = *p;
00389         if (!isdigit(c))
00390             break;
00391         val = (val * 10) + c - '0';
00392         p++;
00393     }
00394     /* no number read ? */
00395     if (p == *pp)
00396         return -1;
00397     if (val < n_min || val > n_max)
00398         return -1;
00399     *pp = p;
00400     return val;
00401 }
00402 
00403 static const char *small_strptime(const char *p, const char *fmt, struct tm *dt)
00404 {
00405     int c, val;
00406 
00407     for(;;) {
00408         c = *fmt++;
00409         if (c == '\0') {
00410             return p;
00411         } else if (c == '%') {
00412             c = *fmt++;
00413             switch(c) {
00414             case 'H':
00415                 val = date_get_num(&p, 0, 23, 2);
00416                 if (val == -1)
00417                     return NULL;
00418                 dt->tm_hour = val;
00419                 break;
00420             case 'M':
00421                 val = date_get_num(&p, 0, 59, 2);
00422                 if (val == -1)
00423                     return NULL;
00424                 dt->tm_min = val;
00425                 break;
00426             case 'S':
00427                 val = date_get_num(&p, 0, 59, 2);
00428                 if (val == -1)
00429                     return NULL;
00430                 dt->tm_sec = val;
00431                 break;
00432             case 'Y':
00433                 val = date_get_num(&p, 0, 9999, 4);
00434                 if (val == -1)
00435                     return NULL;
00436                 dt->tm_year = val - 1900;
00437                 break;
00438             case 'm':
00439                 val = date_get_num(&p, 1, 12, 2);
00440                 if (val == -1)
00441                     return NULL;
00442                 dt->tm_mon = val - 1;
00443                 break;
00444             case 'd':
00445                 val = date_get_num(&p, 1, 31, 2);
00446                 if (val == -1)
00447                     return NULL;
00448                 dt->tm_mday = val;
00449                 break;
00450             case '%':
00451                 goto match;
00452             default:
00453                 return NULL;
00454             }
00455         } else {
00456         match:
00457             if (c != *p)
00458                 return NULL;
00459             p++;
00460         }
00461     }
00462 }
00463 
00464 time_t av_timegm(struct tm *tm)
00465 {
00466     time_t t;
00467 
00468     int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
00469 
00470     if (m < 3) {
00471         m += 12;
00472         y--;
00473     }
00474 
00475     t = 86400 *
00476         (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
00477 
00478     t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
00479 
00480     return t;
00481 }
00482 
00483 int av_parse_time(int64_t *timeval, const char *timestr, int duration)
00484 {
00485     const char *p;
00486     int64_t t;
00487     struct tm dt;
00488     int i;
00489     static const char * const date_fmt[] = {
00490         "%Y-%m-%d",
00491         "%Y%m%d",
00492     };
00493     static const char * const time_fmt[] = {
00494         "%H:%M:%S",
00495         "%H%M%S",
00496     };
00497     const char *q;
00498     int is_utc, len;
00499     char lastch;
00500     int negative = 0;
00501 
00502 #undef time
00503     time_t now = time(0);
00504 
00505     len = strlen(timestr);
00506     if (len > 0)
00507         lastch = timestr[len - 1];
00508     else
00509         lastch = '\0';
00510     is_utc = (lastch == 'z' || lastch == 'Z');
00511 
00512     memset(&dt, 0, sizeof(dt));
00513 
00514     p = timestr;
00515     q = NULL;
00516     if (!duration) {
00517         if (!av_strncasecmp(timestr, "now", len)) {
00518             *timeval = (int64_t) now * 1000000;
00519             return 0;
00520         }
00521 
00522         /* parse the year-month-day part */
00523         for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
00524             q = small_strptime(p, date_fmt[i], &dt);
00525             if (q) {
00526                 break;
00527             }
00528         }
00529 
00530         /* if the year-month-day part is missing, then take the
00531          * current year-month-day time */
00532         if (!q) {
00533             if (is_utc) {
00534                 dt = *gmtime(&now);
00535             } else {
00536                 dt = *localtime(&now);
00537             }
00538             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
00539         } else {
00540             p = q;
00541         }
00542 
00543         if (*p == 'T' || *p == 't' || *p == ' ')
00544             p++;
00545 
00546         /* parse the hour-minute-second part */
00547         for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
00548             q = small_strptime(p, time_fmt[i], &dt);
00549             if (q) {
00550                 break;
00551             }
00552         }
00553     } else {
00554         /* parse timestr as a duration */
00555         if (p[0] == '-') {
00556             negative = 1;
00557             ++p;
00558         }
00559         /* parse timestr as HH:MM:SS */
00560         q = small_strptime(p, time_fmt[0], &dt);
00561         if (!q) {
00562             /* parse timestr as S+ */
00563             dt.tm_sec = strtol(p, (char **)&q, 10);
00564             if (q == p) {
00565                 /* the parsing didn't succeed */
00566                 *timeval = INT64_MIN;
00567                 return AVERROR(EINVAL);
00568             }
00569             dt.tm_min = 0;
00570             dt.tm_hour = 0;
00571         }
00572     }
00573 
00574     /* Now we have all the fields that we can get */
00575     if (!q) {
00576         *timeval = INT64_MIN;
00577         return AVERROR(EINVAL);
00578     }
00579 
00580     if (duration) {
00581         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
00582     } else {
00583         dt.tm_isdst = -1;       /* unknown */
00584         if (is_utc) {
00585             t = av_timegm(&dt);
00586         } else {
00587             t = mktime(&dt);
00588         }
00589     }
00590 
00591     t *= 1000000;
00592 
00593     /* parse the .m... part */
00594     if (*q == '.') {
00595         int val, n;
00596         q++;
00597         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
00598             if (!isdigit(*q))
00599                 break;
00600             val += n * (*q - '0');
00601         }
00602         t += val;
00603     }
00604     *timeval = negative ? -t : t;
00605     return 0;
00606 }
00607 
00608 int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
00609 {
00610     const char *p;
00611     char tag[128], *q;
00612 
00613     p = info;
00614     if (*p == '?')
00615         p++;
00616     for(;;) {
00617         q = tag;
00618         while (*p != '\0' && *p != '=' && *p != '&') {
00619             if ((q - tag) < sizeof(tag) - 1)
00620                 *q++ = *p;
00621             p++;
00622         }
00623         *q = '\0';
00624         q = arg;
00625         if (*p == '=') {
00626             p++;
00627             while (*p != '&' && *p != '\0') {
00628                 if ((q - arg) < arg_size - 1) {
00629                     if (*p == '+')
00630                         *q++ = ' ';
00631                     else
00632                         *q++ = *p;
00633                 }
00634                 p++;
00635             }
00636         }
00637         *q = '\0';
00638         if (!strcmp(tag, tag1))
00639             return 1;
00640         if (*p != '&')
00641             break;
00642         p++;
00643     }
00644     return 0;
00645 }
00646 
00647 #ifdef TEST
00648 
00649 #undef printf
00650 
00651 int main(void)
00652 {
00653     printf("Testing av_parse_video_rate()\n");
00654     {
00655         int i;
00656         const char *rates[] = {
00657             "-inf",
00658             "inf",
00659             "nan",
00660             "123/0",
00661             "-123 / 0",
00662             "",
00663             "/",
00664             " 123  /  321",
00665             "foo/foo",
00666             "foo/1",
00667             "1/foo",
00668             "0/0",
00669             "/0",
00670             "1/",
00671             "1",
00672             "0",
00673             "-123/123",
00674             "-foo",
00675             "123.23",
00676             ".23",
00677             "-.23",
00678             "-0.234",
00679             "-0.0000001",
00680             "  21332.2324   ",
00681             " -21332.2324   ",
00682         };
00683 
00684         for (i = 0; i < FF_ARRAY_ELEMS(rates); i++) {
00685             int ret;
00686             AVRational q = (AVRational){0, 0};
00687             ret = av_parse_video_rate(&q, rates[i]),
00688             printf("'%s' -> %d/%d ret:%d\n",
00689                    rates[i], q.num, q.den, ret);
00690         }
00691     }
00692 
00693     printf("\nTesting av_parse_color()\n");
00694     {
00695         int i;
00696         uint8_t rgba[4];
00697         const char *color_names[] = {
00698             "bikeshed",
00699             "RaNdOm",
00700             "foo",
00701             "red",
00702             "Red ",
00703             "RED",
00704             "Violet",
00705             "Yellow",
00706             "Red",
00707             "0x000000",
00708             "0x0000000",
00709             "0xff000000",
00710             "0x3e34ff",
00711             "0x3e34ffaa",
00712             "0xffXXee",
00713             "0xfoobar",
00714             "0xffffeeeeeeee",
00715             "#ff0000",
00716             "#ffXX00",
00717             "ff0000",
00718             "ffXX00",
00719             "red@foo",
00720             "random@10",
00721             "0xff0000@1.0",
00722             "red@",
00723             "red@0xfff",
00724             "red@0xf",
00725             "red@2",
00726             "red@0.1",
00727             "red@-1",
00728             "red@0.5",
00729             "red@1.0",
00730             "red@256",
00731             "red@10foo",
00732             "red@-1.0",
00733             "red@-0.0",
00734         };
00735 
00736         av_log_set_level(AV_LOG_DEBUG);
00737 
00738         for (i = 0;  i < FF_ARRAY_ELEMS(color_names); i++) {
00739             if (av_parse_color(rgba, color_names[i], -1, NULL) >= 0)
00740                 printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
00741         }
00742     }
00743 
00744     return 0;
00745 }
00746 
00747 #endif /* TEST */
Generated on Thu Jan 24 2013 17:08:56 for Libav by doxygen 1.7.1