1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 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 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 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 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 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 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 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 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 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