• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <debug.h>
2 #include <cmdline.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <getopt.h>
6 #include <string.h>
7 #include <ctype.h>
8 
9 extern char *optarg;
10 extern int optind, opterr, optopt;
11 
12 static struct option long_options[] = {
13     {"output",  required_argument, 0, 'o'},
14     {"height",  required_argument, 0, 'h'},
15     {"width",   required_argument, 0, 'w'},
16     {"gray",    no_argument,       0, 'g'},
17     {"type",    required_argument, 0, 't'},
18     {"rotate",  required_argument, 0, 'r'},
19     {"verbose", no_argument,       0, 'V'},
20     {"help",    no_argument,       0, 1},
21     {0, 0, 0, 0},
22 };
23 
24 /* This array must parallel long_options[] */
25 static const char *descriptions[] = {
26     "output file",
27     "image height in pixels",
28     "image width in pixels",
29     "process the luma plane only",
30     "encode as one of { 'ppm', 'rgb', or 'argb' }",
31     "rotate (90, -90, 180 degrees)",
32     "print verbose output",
33     "print this help screen",
34 };
35 
print_help(const char * name)36 void print_help(const char *name) {
37     fprintf(stdout,
38             "Converts yuv 4:2:0 to rgb24 and generates a PPM file.\n"
39             "invokation:\n"
40             "\t%s infile --height <height> --width <width> --output <outfile> -t <ppm|grb|argb> [ --gray ] [ --rotate <degrees> ] [ --verbose ]\n"
41             "\t%s infile --help\n",
42             name, name);
43     fprintf(stdout, "options:\n");
44     struct option *opt = long_options;
45     const char **desc = descriptions;
46     while (opt->name) {
47         fprintf(stdout, "\t-%c/--%s%s: %s\n",
48                 isprint(opt->val) ? opt->val : ' ',
49                 opt->name,
50                 (opt->has_arg ? " (argument)" : ""),
51                 *desc);
52         opt++;
53         desc++;
54     }
55 }
56 
get_options(int argc,char ** argv,char ** outfile,int * height,int * width,int * gray,char ** type,int * rotate,int * verbose)57 int get_options(int argc, char **argv,
58                 char **outfile,
59                 int *height,
60                 int *width,
61                 int *gray,
62                 char **type,
63                 int *rotate,
64                 int *verbose) {
65     int c;
66 
67     ASSERT(outfile); *outfile = NULL;
68     ASSERT(height); *height = -1;
69     ASSERT(width); *width = -1;
70     ASSERT(gray); *gray = 0;
71     ASSERT(rotate); *rotate = 0;
72     ASSERT(verbose); *verbose = 0;
73     ASSERT(type); *type = NULL;
74 
75     while (1) {
76         /* getopt_long stores the option index here. */
77         int option_index = 0;
78 
79         c = getopt_long (argc, argv,
80                          "Vgo:h:w:r:t:",
81                          long_options,
82                          &option_index);
83         /* Detect the end of the options. */
84         if (c == -1) break;
85 
86         if (isgraph(c)) {
87             INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
88         }
89 
90 #define SET_STRING_OPTION(name) do {                                   \
91     ASSERT(optarg);                                                    \
92     (*name) = strdup(optarg);                                          \
93 } while(0)
94 
95 #define SET_INT_OPTION(val) do {                                       \
96     ASSERT(optarg);                                                    \
97 	if (strlen(optarg) >= 2 && optarg[0] == '0' && optarg[1] == 'x') { \
98 			FAILIF(1 != sscanf(optarg+2, "%x", val),                   \
99 				   "Expecting a hexadecimal argument!\n");             \
100 	} else {                                                           \
101 		FAILIF(1 != sscanf(optarg, "%d", val),                         \
102 			   "Expecting a decimal argument!\n");                     \
103 	}                                                                  \
104 } while(0)
105 
106         switch (c) {
107         case 0:
108             /* If this option set a flag, do nothing else now. */
109             if (long_options[option_index].flag != 0)
110                 break;
111             INFO ("option %s", long_options[option_index].name);
112             if (optarg)
113                 INFO (" with arg %s", optarg);
114             INFO ("\n");
115             break;
116         case 1: print_help(argv[0]); exit(1); break;
117 		case 'o':
118 			SET_STRING_OPTION(outfile);
119 			break;
120 		case 't':
121 			SET_STRING_OPTION(type);
122 			break;
123         case 'h':
124             SET_INT_OPTION(height);
125             break;
126         case 'w':
127             SET_INT_OPTION(width);
128             break;
129         case 'r':
130             SET_INT_OPTION(rotate);
131             break;
132         case 'g': *gray = 1; break;
133         case 'V': *verbose = 1; break;
134         case '?':
135             /* getopt_long already printed an error message. */
136             break;
137 
138 #undef SET_STRING_OPTION
139 #undef SET_INT_OPTION
140 
141         default:
142             FAILIF(1, "Unknown option");
143         }
144     }
145 
146     return optind;
147 }
148