]> 4ch.mooo.com Git - 16.git/blob - src/lib/dl/ext/lame/main.c
meh did some cleanings and i will work on mapread to mm thingy sometime soon! oops...
[16.git] / src / lib / dl / ext / lame / main.c
1 /*
2  *      Command line frontend program
3  *
4  *      Copyright (c) 1999 Mark Taylor
5  *                    2000 Takehiro TOMINAGA
6  *                    2010-2011 Robert Hegemann
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /* $Id: main.c,v 1.127 2011/10/02 14:52:20 robert Exp $ */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #include <assert.h>
31 #include <stdio.h>
32
33 #ifdef STDC_HEADERS
34 # include <stdlib.h>
35 # include <string.h>
36 #else
37 # ifndef HAVE_STRCHR
38 #  define strchr index
39 #  define strrchr rindex
40 # endif
41 char   *strchr(), *strrchr();
42 # ifndef HAVE_MEMCPY
43 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
44 #  define memmove(d, s, n) bcopy ((s), (d), (n))
45 # endif
46 #endif
47
48 #ifdef HAVE_FCNTL_H
49 # include <fcntl.h>
50 #endif
51
52 #ifdef __sun__
53 /* woraround for SunOS 4.x, it has SEEK_* defined here */
54 #include <unistd.h>
55 #endif
56
57 #ifdef __OS2__
58 #include <os2.h>
59 #define PRTYC_IDLE 1
60 #define PRTYC_REGULAR 2
61 #define PRTYD_MINIMUM -31
62 #define PRTYD_MAXIMUM 31
63 #endif
64
65 #if defined(_WIN32)
66 # include <windows.h>
67 #endif
68
69
70 /*
71  main.c is example code for how to use libmp3lame.a.  To use this library,
72  you only need the library and lame.h.  All other .h files are private
73  to the library.
74 */
75 #include "lame.h"
76
77 #include "console.h"
78 #include "main.h"
79
80 /* PLL 14/04/2000 */
81 #if macintosh
82 #include <console.h>
83 #endif
84
85 #ifdef WITH_DMALLOC
86 #include <dmalloc.h>
87 #endif
88
89
90 static int c_main(int argc, char *argv[]);
91 extern int lame_main(lame_t gf, int argc, char *argv[]);
92
93
94 /************************************************************************
95 *
96 * main
97 *
98 * PURPOSE:  MPEG-1,2 Layer III encoder with GPSYCHO
99 * psychoacoustic model.
100 *
101 ************************************************************************/
102
103
104 #if defined( _WIN32 ) && !defined(__MINGW32__)
105 static void
106 set_process_affinity()
107 {
108 #if 0
109     /* rh 061207
110        the following fix seems to be a workaround for a problem in the
111        parent process calling LAME. It would be better to fix the broken
112        application => code disabled.
113      */
114 #if defined(_WIN32)
115     /* set affinity back to all CPUs.  Fix for EAC/lame on SMP systems from
116        "Todd Richmond" <todd.richmond@openwave.com> */
117     typedef BOOL(WINAPI * SPAMFunc) (HANDLE, DWORD_PTR);
118     SPAMFunc func;
119     SYSTEM_INFO si;
120
121     if ((func = (SPAMFunc) GetProcAddress(GetModuleHandleW(L"KERNEL32.DLL"),
122                                           "SetProcessAffinityMask")) != NULL) {
123         GetSystemInfo(&si);
124         func(GetCurrentProcess(), si.dwActiveProcessorMask);
125     }
126 #endif
127 #endif
128 }
129 #endif
130
131 #if defined(WIN32)
132
133 /**
134  *  Long Filename support for the WIN32 platform
135  *
136  */
137
138 void
139 dosToLongFileName(char *fn)
140 {
141     const int MSIZE = PATH_MAX + 1 - 4; /*  we wanna add ".mp3" later */
142     WIN32_FIND_DATAA lpFindFileData;
143     HANDLE  h = FindFirstFileA(fn, &lpFindFileData);
144     if (h != INVALID_HANDLE_VALUE) {
145         int     a;
146         char   *q, *p;
147         FindClose(h);
148         for (a = 0; a < MSIZE; a++) {
149             if ('\0' == lpFindFileData.cFileName[a])
150                 break;
151         }
152         if (a >= MSIZE || a == 0)
153             return;
154         q = strrchr(fn, '\\');
155         p = strrchr(fn, '/');
156         if (p - q > 0)
157             q = p;
158         if (q == NULL)
159             q = strrchr(fn, ':');
160         if (q == NULL)
161             strncpy(fn, lpFindFileData.cFileName, a);
162         else {
163             a += q - fn + 1;
164             if (a >= MSIZE)
165                 return;
166             strncpy(++q, lpFindFileData.cFileName, MSIZE - a);
167         }
168     }
169 }
170
171 BOOL
172 SetPriorityClassMacro(DWORD p)
173 {
174     HANDLE  op = GetCurrentProcess();
175     return SetPriorityClass(op, p);
176 }
177
178 void
179 setProcessPriority(int Priority)
180 {
181     switch (Priority) {
182     case 0:
183     case 1:
184         SetPriorityClassMacro(IDLE_PRIORITY_CLASS);
185         console_printf("==> Priority set to Low.\n");
186         break;
187     default:
188     case 2:
189         SetPriorityClassMacro(NORMAL_PRIORITY_CLASS);
190         console_printf("==> Priority set to Normal.\n");
191         break;
192     case 3:
193     case 4:
194         SetPriorityClassMacro(HIGH_PRIORITY_CLASS);
195         console_printf("==> Priority set to High.\n");
196         break;
197     }
198 }
199 #endif
200
201
202 #if defined(__OS2__)
203 /* OS/2 priority functions */
204 static void
205 setProcessPriority(int Priority)
206 {
207     int     rc;
208
209     switch (Priority) {
210
211     case 0:
212         rc = DosSetPriority(0, /* Scope: only one process */
213                             PRTYC_IDLE, /* select priority class (idle, regular, etc) */
214                             0, /* set delta */
215                             0); /* Assume current process */
216         console_printf("==> Priority set to 0 (Low priority).\n");
217         break;
218
219     case 1:
220         rc = DosSetPriority(0, /* Scope: only one process */
221                             PRTYC_IDLE, /* select priority class (idle, regular, etc) */
222                             PRTYD_MAXIMUM, /* set delta */
223                             0); /* Assume current process */
224         console_printf("==> Priority set to 1 (Medium priority).\n");
225         break;
226
227     case 2:
228         rc = DosSetPriority(0, /* Scope: only one process */
229                             PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
230                             PRTYD_MINIMUM, /* set delta */
231                             0); /* Assume current process */
232         console_printf("==> Priority set to 2 (Regular priority).\n");
233         break;
234
235     case 3:
236         rc = DosSetPriority(0, /* Scope: only one process */
237                             PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
238                             0, /* set delta */
239                             0); /* Assume current process */
240         console_printf("==> Priority set to 3 (High priority).\n");
241         break;
242
243     case 4:
244         rc = DosSetPriority(0, /* Scope: only one process */
245                             PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
246                             PRTYD_MAXIMUM, /* set delta */
247                             0); /* Assume current process */
248         console_printf("==> Priority set to 4 (Maximum priority). I hope you enjoy it :)\n");
249         break;
250
251     default:
252         console_printf("==> Invalid priority specified! Assuming idle priority.\n");
253     }
254 }
255 #endif
256
257
258 /***********************************************************************
259 *
260 *  Message Output
261 *
262 ***********************************************************************/
263
264
265 #if defined( _WIN32 ) && !defined(__MINGW32__)
266 /* Idea for unicode support in LAME, work in progress
267  * - map UTF-16 to UTF-8
268  * - advantage, the rest can be kept unchanged (mostly)
269  * - make sure, fprintf on console is in correct code page
270  *   + normal text in source code is in ASCII anyway
271  *   + ID3 tags and filenames coming from command line need attention
272  * - call wfopen with UTF-16 names where needed
273  *
274  * why not wchar_t all the way?
275  * well, that seems to be a big mess and not portable at all
276  */
277 #include <wchar.h>
278 #include <mbstring.h>
279
280 static wchar_t *mbsToUnicode(const char *mbstr, int code_page)
281 {
282   int n = MultiByteToWideChar(code_page, 0, mbstr, -1, NULL, 0);
283   wchar_t* wstr = malloc( n*sizeof(wstr[0]) );
284   if ( wstr !=0 ) {
285     n = MultiByteToWideChar(code_page, 0, mbstr, -1, wstr, n);
286     if ( n==0 ) {
287       free( wstr );
288       wstr = 0;
289     }
290   }
291   return wstr;
292 }
293
294 static char *unicodeToMbs(const wchar_t *wstr, int code_page)
295 {
296   int n = 1+WideCharToMultiByte(code_page, 0, wstr, -1, 0, 0, 0, 0);
297   char* mbstr = malloc( n*sizeof(mbstr[0]) );
298   if ( mbstr !=0 ) {
299     n = WideCharToMultiByte(code_page, 0, wstr, -1, mbstr, n, 0, 0);
300     if( n == 0 ){
301       free( mbstr );
302       mbstr = 0;
303     }
304   }
305   return mbstr;
306 }
307
308 char* mbsToMbs(const char* str, int cp_from, int cp_to)
309 {
310   wchar_t* wstr = mbsToUnicode(str, cp_from);
311   if ( wstr != 0 ) {
312     char* local8bit = unicodeToMbs(wstr, cp_to);
313     free( wstr );
314     return local8bit;
315   }
316   return 0;
317 }
318
319 enum { cp_utf8, cp_console, cp_actual };
320
321 wchar_t *utf8ToUnicode(const char *mbstr)
322 {
323   return mbsToUnicode(mbstr, CP_UTF8);
324 }
325
326 char *unicodeToUtf8(const wchar_t *wstr)
327 {
328   return unicodeToMbs(wstr, CP_UTF8);
329 }
330
331 char* utf8ToLocal8Bit(const char* str)
332 {
333   return mbsToMbs(str, CP_UTF8, CP_ACP);
334 }
335
336 char* utf8ToConsole8Bit(const char* str)
337 {
338   return mbsToMbs(str, CP_UTF8, GetConsoleOutputCP());
339 }
340
341 char* local8BitToUtf8(const char* str)
342 {
343   return mbsToMbs(str, CP_ACP, CP_UTF8);
344 }
345
346 char* console8BitToUtf8(const char* str)
347 {
348   return mbsToMbs(str, GetConsoleOutputCP(), CP_UTF8);
349 }
350  
351 char* utf8ToLatin1(char const* str)
352 {
353   return mbsToMbs(str, CP_UTF8, 28591); /* Latin-1 is code page 28591 */
354 }
355
356 unsigned short* utf8ToUtf16(char const* mbstr) /* additional Byte-Order-Marker */
357 {
358   int n = MultiByteToWideChar(CP_UTF8, 0, mbstr, -1, NULL, 0);
359   wchar_t* wstr = malloc( (n+1)*sizeof(wstr[0]) );
360   if ( wstr !=0 ) {
361     wstr[0] = 0xfeff; /* BOM */
362     n = MultiByteToWideChar(CP_UTF8, 0, mbstr, -1, wstr+1, n);
363     if ( n==0 ) {
364       free( wstr );
365       wstr = 0;
366     }
367   }
368   return wstr;
369 }
370
371
372
373 int wmain(int argc, wchar_t* argv[])
374 {
375   char **utf8_argv;
376   int i, ret;
377
378   utf8_argv = calloc(argc, sizeof(char*));
379   for (i = 0; i < argc; ++i) {
380     utf8_argv[i] = unicodeToUtf8(argv[i]);
381   }
382   ret = c_main(argc, utf8_argv);
383   for (i = 0; i < argc; ++i) {
384     free( utf8_argv[i] );
385   }
386   free( utf8_argv );
387   return ret;
388 }
389
390 FILE* lame_fopen(char const* file, char const* mode)
391 {
392     FILE* fh = 0;
393     wchar_t* wfile = utf8ToUnicode(file);
394     wchar_t* wmode = utf8ToUnicode(mode);
395     if (wfile != 0 && wmode != 0) {
396         fh = _wfopen(wfile, wmode);
397     }
398     else {
399         fh = fopen(file, mode);
400     }
401     free(wfile);
402     free(wmode);
403     return fh;
404 }
405
406 char* lame_getenv(char const* var)
407 {
408     char* str = 0;
409     wchar_t* wvar = utf8ToUnicode(var);
410     wchar_t* wstr = 0;
411     if (wvar != 0) {
412         wstr = _wgetenv(wvar);
413         str = unicodeToUtf8(wstr);
414     }
415     free(wvar);
416     free(wstr);
417     return str;
418 }
419
420 #else
421
422 FILE* lame_fopen(char const* file, char const* mode)
423 {
424     return fopen(file, mode);
425 }
426
427 char* lame_getenv(char const* var)
428 {
429     char* str = getenv(var);
430     if (str) {
431         return strdup(str);
432     }
433     return 0;
434 }
435
436 int main(int argc, char *argv[])
437 {
438     return c_main(argc, argv);
439 }
440
441 #endif
442
443
444
445
446 static int
447 c_main(int argc, char *argv[])
448 {
449     lame_t  gf;
450     int     ret;
451
452 #if macintosh
453     argc = ccommand(&argv);
454 #endif
455 #ifdef __EMX__
456     /* This gives wildcard expansion on Non-POSIX shells with OS/2 */
457     _wildcard(&argc, &argv);
458 #endif
459 #if defined( _WIN32 ) && !defined(__MINGW32__)
460     set_process_affinity();
461 #endif
462
463     frontend_open_console();    
464     gf = lame_init(); /* initialize libmp3lame */
465     if (NULL == gf) {
466         error_printf("fatal error during initialization\n");
467         ret = 1;
468     }
469     else {
470         ret = lame_main(gf, argc, argv);
471         lame_close(gf);
472     }
473     frontend_close_console();
474     return ret;
475 }