• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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