1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 � Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6 All rights reserved.
7
8 1. INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28
29 2. COPYRIGHT LICENSE
30
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
53 3. NO PATENT LICENSE
54
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61
62 4. DISCLAIMER
63
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72
73 5. CONTACT INFORMATION
74
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83
84 /************************** Fraunhofer IIS FDK SysLib **********************
85
86 Author(s):
87 Description: command line parser
88
89 ******************************************************************************/
90
91
92
93 #define _CRT_SECURE_NO_WARNINGS
94
95 /* Work around for broken android toolchain: sys/types.h:137: error: 'uint64_t' does not name a type */
96 #define _SYS_TYPES_H_
97
98 #include <stdarg.h>
99 #include <stdio.h>
100 #include <string.h>
101 #include <stdlib.h>
102 #include <ctype.h>
103
104 #include "cmdl_parser.h"
105 #include "genericStds.h"
106
107
108
109 /************************ interface ************************/
110
111 static INT GetArgFromString(INT argc, TEXTCHAR* argv[], TEXTCHAR* search_string, TEXTCHAR type, TEXTCHAR* found_string , INT* switches_used);
112 static void RemoveWhiteSpace(const TEXTCHAR* pReqArgs, TEXTCHAR* Removed);
113 static INT CheckArg(TEXTCHAR* arg, TEXTCHAR* str, UINT numArgs, TEXTCHAR type, TEXTCHAR* current_str);
114 static INT CheckForUnusedSwitches(INT argc, /*TEXTCHAR* argv[],*/ INT* switches_used);
115 static INT ParseString(TEXTCHAR* str, INT*, TEXTCHAR*, TEXTCHAR*);
116 static void GetNumberOfArgs(TEXTCHAR* str, INT* nArgs);
117
118 static
removeQuotes(char * str)119 void removeQuotes(char *str)
120 {
121 if (str[0] == '"') {
122 FDKstrcpy(str, str+1);
123 str[FDKstrlen(str)-1] = 0;
124 }
125 }
126
127
128 /********************** implementation *********************/
129
IIS_ScanCmdl(INT argc,TEXTCHAR * argv[],const TEXTCHAR * str,...)130 INT IIS_ScanCmdl(INT argc, TEXTCHAR* argv[], const TEXTCHAR* str, ...)
131 {
132 INT i = 0;
133 INT found_and_set = 0;
134 INT nArgs = 0;
135 INT* switches_used = 0;
136 INT* b_str_opt = 0;
137 TEXTCHAR* s_str = 0;
138 TEXTCHAR* c_str_type = 0;
139 TEXTCHAR* str_clean = 0;
140
141 va_list ap;
142
143 if (argc == 0 || argc == 1)
144 {
145 FDKprintf("No command line arguments\n");
146 goto bail;
147 }
148
149 str_clean = (TEXTCHAR*) FDKcalloc((unsigned int)_tcslen(str), sizeof(TEXTCHAR));
150 if (str_clean == NULL) {
151 FDKprintf("Error allocating memory line %d, file %s\n", __LINE__, __FILE__);
152 return 0;
153 }
154
155 RemoveWhiteSpace(str, str_clean );
156 GetNumberOfArgs(str_clean, &nArgs);
157
158 b_str_opt = (INT*) FDKcalloc(nArgs, sizeof(INT));
159 s_str = (TEXTCHAR*) FDKcalloc(nArgs*CMDL_MAX_ARGC, sizeof(TEXTCHAR) );
160 c_str_type = (TEXTCHAR*) FDKcalloc(nArgs, sizeof(TEXTCHAR));
161 switches_used = (INT*) FDKcalloc(argc, sizeof(INT));
162
163 if (b_str_opt == NULL || s_str == NULL || c_str_type == NULL || switches_used == NULL) {
164 FDKprintf("Error allocating memory line %d, file %s\n", __LINE__, __FILE__);
165 goto bail;
166 }
167
168 if ( ParseString( str_clean, b_str_opt, s_str, c_str_type )) {
169 goto bail;
170 }
171
172 va_start(ap, str);
173
174 for ( i = 0; i < nArgs; i++ )
175 {
176 TEXTCHAR arg[CMDL_MAX_STRLEN] = {L'\0'};
177 TEXTCHAR* p_arg = arg;
178 TEXTCHAR* current_str = &(s_str[i*CMDL_MAX_ARGC]);
179
180 if (GetArgFromString(argc, argv, current_str, c_str_type[i], arg, switches_used )
181 && !b_str_opt[i] )
182 {
183 #ifdef _UNICODE
184 _ftprintf(stderr, _TEXT("\n\nError: Parsing argument for required switch '%ls'.\n" ), current_str);
185 #else
186 _ftprintf(stderr, _TEXT("\n\nError: Parsing argument for required switch '%s'.\n" ), current_str);
187 #endif
188 found_and_set = 0;
189 goto bail;
190 }
191 if (CheckArg(p_arg, s_str, nArgs, c_str_type[i], current_str))
192 {
193 goto bail;
194 }
195
196 switch (c_str_type[i] )
197 {
198 case 's':
199 {
200 TEXTCHAR* tmp;
201 tmp = va_arg(ap, TEXTCHAR*);
202
203 if ( arg[0] == '\0' )
204 break;
205
206 _tcsncpy( tmp, arg, CMDL_MAX_STRLEN );
207 /* Remove quotes. Windows Mobile Workaround. */
208 removeQuotes(tmp);
209 found_and_set++;
210 break;
211 }
212 case 'd':
213 {
214 INT* tmp = va_arg(ap, INT*);
215
216 if ( arg[0] == '\0' )
217 break;
218
219 *tmp = _tcstol(arg, NULL, 0);
220 found_and_set++;
221 break;
222 }
223 case 'c':
224 {
225 char* tmp = va_arg(ap, char*);
226
227 if ( arg[0] == '\0' )
228 break;
229
230 *tmp = *arg;
231 found_and_set++;
232 break;
233 }
234 case 'u':
235 {
236 UCHAR* tmp = va_arg(ap, UCHAR*);
237
238 if ( arg[0] == '\0' )
239 break;
240
241 *tmp = _tstoi(arg);
242 found_and_set++;
243 break;
244 }
245 case 'f':
246 {
247 float* tmp = (float*) va_arg( ap,double*);
248
249 if ( arg[0] == '\0' )
250 break;
251
252 *tmp = (float) _tstof(arg);
253 found_and_set++;
254 break;
255 }
256 case 'y': // support 'data type double'
257 {
258 double* tmp = (double*) va_arg( ap,double*);
259 // use sscanf instead _tstof because of gcc
260 //_tstof(arg,"%lf",tmp); // '%lf' reads as double
261 *tmp = _tstof(arg); // '%lf' reads as double
262 found_and_set++;
263 break;
264 }
265 case '1':
266 {
267
268 INT* tmp = va_arg( ap, INT*);
269
270 if ( arg[0] == '\0' )
271 break;
272
273 *tmp = 1;
274 found_and_set++;
275 break;
276 }
277
278 default:
279 FDKprintfErr("Bug: unsupported data identifier \"%c\"\n", c_str_type[i]);
280 break;
281
282 }
283
284 }
285
286 va_end(ap);
287
288 CheckForUnusedSwitches(argc, /*argv,*/ switches_used);
289
290 bail:
291 if (b_str_opt) FDKfree(b_str_opt);
292 if (s_str) FDKfree(s_str);
293 if (c_str_type) FDKfree(c_str_type);
294 if (str_clean) FDKfree(str_clean);
295 if (switches_used) FDKfree(switches_used);
296
297 return found_and_set;
298 }
299
300
GetNumberOfArgs(TEXTCHAR * str,INT * nArgs)301 void GetNumberOfArgs(TEXTCHAR* str, INT* nArgs)
302 {
303 UINT i = 0;
304 for ( i = 0; i < _tcslen(str); ++i )
305 {
306 if ( str[i] == '%')
307 *nArgs+= 1;
308 }
309
310 }
311
ParseString(TEXTCHAR * str,INT * b_str_opt,TEXTCHAR * s_str,TEXTCHAR * c_str_type)312 INT ParseString(TEXTCHAR* str, INT* b_str_opt, TEXTCHAR* s_str, TEXTCHAR* c_str_type )
313 {
314 UINT i = 0;
315 INT argCounter = 0;
316
317 TEXTCHAR* str_start = 0;
318 TEXTCHAR* str_stop = 0;
319
320
321 str_start = str;
322 str_stop = str_start;
323
324 for ( i = 0; i < _tcslen(str) - 1; ++i )
325 {
326 if ( str[i] == '%' ) /* We have an Argument */
327 {
328 if ( argCounter )
329 {
330 if ( b_str_opt[argCounter-1] )
331 str_start = str_stop + 3;
332
333 else
334 str_start = str_stop + 2;
335 }
336
337 /* Save Argument type */
338 c_str_type[argCounter] = str[i+1];
339
340 if ( *str_start == '(' ) /* Optional Argument */
341 {
342 b_str_opt[argCounter] = 1;
343 str_start++;
344 }
345
346 /* Save Argument */
347 str[i] = '\0';
348
349 _tcsncpy(&(s_str[argCounter*CMDL_MAX_ARGC]), str_start, CMDL_MAX_ARGC );
350
351 str[i] = '%';
352
353 str_stop = &(str[i]);
354
355 if ( b_str_opt[argCounter] )
356 {
357 if ( i+2 > ( _tcslen(str) -1 ))
358 {
359 _ftprintf(stderr,_TEXT("\n\nInternal Parser Error: Strlen Problem\n") );
360 return 1;
361 }
362 if ( str[i+2] != ')' )
363 {
364 _ftprintf(stderr,_TEXT("\n\nInternal Parser Error: Missing bracket ')'\n") );
365 return 1;
366 }
367
368 }
369
370
371 argCounter++;
372 }
373
374
375 }
376
377 return 0;
378 }
379
380
381
382
RemoveWhiteSpace(const TEXTCHAR * pReqArgs,TEXTCHAR * pRemoved)383 void RemoveWhiteSpace(const TEXTCHAR* pReqArgs, TEXTCHAR* pRemoved)
384 {
385 UINT i = 0;
386 INT k = 0;
387 UINT len = (UINT)_tcslen(pReqArgs);
388
389
390 for ( i = 0; i < len; ++i )
391 {
392
393 if ( pReqArgs[i] != ' ' )
394 {
395 pRemoved[k] = pReqArgs[i];
396 k++;
397 }
398 }
399 }
400
401
GetArgFromString(INT argc,TEXTCHAR * argv[],TEXTCHAR * search_string,TEXTCHAR type,TEXTCHAR * found_string,INT * sw_used)402 INT GetArgFromString(INT argc, TEXTCHAR* argv[], TEXTCHAR* search_string, TEXTCHAR type, TEXTCHAR* found_string, INT* sw_used )
403 {
404 INT i = 0;
405
406 for (i = 1; i < argc; ++i ) {
407 if ( !_tcscmp(search_string, argv[i]) ) /* Strings are equal */
408 {
409 if ( type == '1' ) /* Switch without argument */
410 {
411 _tcsncpy( found_string, _TEXT("1"), 1);
412 sw_used[i] = 1;
413 return 0;
414
415 }
416
417 if ( i == (argc - 1)) /* We have %s or %d but are finished*/
418 return 1;
419
420 if ( _tcslen(argv[i+1]) > CMDL_MAX_STRLEN )
421 {
422 #ifdef _UNICODE
423 _ftprintf (stderr,_TEXT("Warning: Ignoring argument for switch '%ls'. "), search_string );
424 #else
425 _ftprintf (stderr,_TEXT("Warning: Ignoring argument for switch '%s'. "), search_string );
426 #endif
427 _ftprintf (stderr,_TEXT("Argument is too LONG.\n") );
428 return 1;
429 }
430 else
431 {
432 _tcsncpy( found_string, argv[i+1], CMDL_MAX_STRLEN);
433 sw_used[i] = 1;
434 sw_used[i+1] = 1;
435 return 0;
436 }
437 }
438 }
439 return 1;
440 }
441
442
443
CheckArg(TEXTCHAR * arg,TEXTCHAR * str,UINT numArgs,TEXTCHAR type,TEXTCHAR * cur_str)444 INT CheckArg(TEXTCHAR* arg, TEXTCHAR* str, UINT numArgs, TEXTCHAR type, TEXTCHAR* cur_str)
445 {
446 UINT i = 0;
447
448 /* No argument given-> return */
449 if (arg[0] == '\0')
450 return 0;
451
452
453 /* Check if arg is switch */
454 for ( i = 0; i < numArgs; ++i )
455 {
456 if (!_tcscmp(arg, &(str[i*CMDL_MAX_ARGC])))
457 {
458 #ifdef _UNICODE
459 _ftprintf(stderr, _TEXT("\n\nError: Argument '%ls' for switch '%ls' is not valid \n" ), arg, cur_str );
460 #else
461 _ftprintf(stderr, _TEXT("\n\nError: Argument '%s' for switch '%s' is not valid \n" ), arg, cur_str );
462 #endif
463 return 1;
464 }
465
466 }
467 /* Check if type is %d but a string is given */
468
469 for ( i = 0; i < _tcslen(arg); ++i )
470 {
471 if ( (type == 'd') && !_istdigit(arg[i]) && arg[i] != 'x' )
472 {
473 #ifdef _UNICODE
474 _ftprintf(stderr, _TEXT("\n\nError: Argument '%ls' for switch '%ls' is not a valid number.\n" ), arg, cur_str);
475 #else
476 _ftprintf(stderr, _TEXT("\n\nError: Argument '%s' for switch '%s' is not a valid number.\n" ), arg, cur_str);
477 #endif
478 return 1;
479 }
480 }
481
482
483 return 0;
484 }
485
486
CheckForUnusedSwitches(INT argc,INT * switches_used)487 INT CheckForUnusedSwitches(INT argc, /*TEXTCHAR* argv[],*/ INT* switches_used)
488 {
489 INT i = 0;
490
491 for( i = 1; i < argc; ++i )
492 {
493 if ( !switches_used[i] )
494 {
495 ++i;
496 }
497 }
498
499 return 0;
500 }
501
502
503
504 static char line[CMDL_MAX_STRLEN*CMDL_MAX_ARGC];
505 static char *argv_ptr[CMDL_MAX_ARGC];
506 #ifdef CMDFILE_PREFIX
507 static char tmp[256]; /* this array is used to store the prefix and the filepath/name */
508 #endif
509
IIS_ProcessCmdlList(const char * param_filename,int (* pFunction)(int,TEXTCHAR **))510 int IIS_ProcessCmdlList(const char* param_filename, int (*pFunction)(int, TEXTCHAR**))
511 {
512 /* static to reduce required stack size */
513
514 FDKFILE *config_fp;
515 int argc;
516 char *line_ptr;
517
518 #ifdef CMDFILE_PREFIX
519 FDKstrcpy(tmp, CMDFILE_PREFIX);
520 FDKstrcpy(tmp+FDKstrlen(CMDFILE_PREFIX), param_filename);
521 /* Open the file with command lines */
522 config_fp = FDKfopen(tmp, "r");
523 #else
524 /* Open the file with command lines */
525 config_fp = FDKfopen(param_filename, "r");
526 #endif
527
528 if(config_fp == NULL)
529 {
530 #ifdef CMDFILE_PREFIX
531 FDKprintf("\ncould not open config file %s", tmp);
532 #else
533 FDKprintf("\ncould not open config file %s", param_filename);
534 #endif
535 return 1;
536 }
537
538 /* Obtain a command line from config file */
539 while (FDKfgets(line, CMDL_MAX_STRLEN*CMDL_MAX_ARGC, config_fp) != NULL)
540 {
541 argc = 1;
542
543 /* Eat \n */
544 line_ptr = (char*)FDKstrchr(line, '\n');
545 if (line_ptr != NULL)
546 *line_ptr = ' ';
547
548 line_ptr = line;
549
550 /* Scan the line and put the command line params into argv */
551 do {
552 /* Skip consecutive blanks. */
553 while (*line_ptr == ' ' && line_ptr < line+CMDL_MAX_STRLEN)
554 line_ptr++;
555 /* Assign argument. TODO: maybe handle quotes */
556 argv_ptr[argc] = line_ptr;
557 /* Get pointer to next blank. */
558 line_ptr = (char*)FDKstrchr(line_ptr, ' ');
559 /* */
560 if (line_ptr != NULL) {
561 /* Null terminate */
562 *line_ptr = 0;
563 /* Skip former blank (now null character) */
564 line_ptr++;
565 /* Advance argument counter */
566 }
567 argc++;
568 } while ( line_ptr != NULL && argc < CMDL_MAX_ARGC);
569
570 /* call "would be main()" */
571 if (argc > 2 && *argv_ptr[1] != '#' && FDKstrlen(argv_ptr[1])>1)
572 {
573 int retval;
574
575 retval = (*pFunction)(argc, argv_ptr);
576
577 FDKprintf("main returned %d\n", retval);
578 }
579 }
580
581 FDKfclose(config_fp);
582 return 0;
583 }
584
585